コード例 #1
0
ファイル: probe.py プロジェクト: dalf/dnssecaudit
def _probe(
    analyst_cls: Analyst,
    name: str,
    config,
    rdclass,
    ceiling,
    query_class_mixin,
    explicit_delegations,
    odd_ports,
    cache,
    cache_lock,
    tm,
    resolver,
):
    if ceiling is not None and name.is_subdomain(ceiling):
        c = ceiling
    else:
        c = name
    try:
        a = analyst_cls(
            name,
            rdclass=rdclass,
            dlv_domain=config.dlv_domain,
            try_ipv4=config.try_ipv4,
            try_ipv6=config.try_ipv6,
            client_ipv4=config.client_ipv4,
            client_ipv6=config.client_ipv6,
            query_class_mixin=query_class_mixin,
            ceiling=c,
            edns_diagnostics=config.edns_diagnostics,
            explicit_delegations=explicit_delegations,
            stop_at_explicit=config.stop_at_explicit,
            odd_ports=odd_ports,
            extra_rdtypes=config.rdtypes,
            explicit_only=config.explicit_only,
            analysis_cache=cache,
            cache_level=config.cache_level,
            analysis_cache_lock=cache_lock,
            transport_manager=tm,
            th_factories=config.th_factories,
            resolver=resolver,
        )
        return a.analyze()
    # report exceptions related to network connectivity
    except (NetworkConnectivityException,
            transport.RemoteQueryTransportError) as e:
        logger.error("Error analyzing %s: %s" % (humanize_name(name), e))
    except:
        logger.exception("Error analyzing %s" % humanize_name(name))
    return None
コード例 #2
0
ファイル: forms.py プロジェクト: geosphere/dnsvizwww
 def clean_date(self):
     dt = datetime.datetime(self.cleaned_data['date'].year, self.cleaned_data['date'].month, self.cleaned_data['date'].day, \
             23, 59, 59, 999999, tzinfo=utc)
     self.name_obj = OfflineDomainNameAnalysis.objects.latest(name, dt)
     if self.name_obj is None:
         del self.name_obj
         raise forms.ValidationError(
             'No analysis for %s known prior to %s!' %
             (fmt.humanize_name(name), self.cleaned_data['date']))
コード例 #3
0
ファイル: probe.py プロジェクト: leonirlopes/dnsviz
def _analyze(args):
    (cls, name, dlv_domain, try_ipv4, try_ipv6, client_ipv4, client_ipv6, query_class_mixin, ceiling, edns_diagnostics, \
            stop_at_explicit, extra_rdtypes, explicit_only, cache, cache_level, cache_lock, th_factories) = args
    if ceiling is not None and name.is_subdomain(ceiling):
        c = ceiling
    else:
        c = name
    try:
        a = cls(name,
                dlv_domain=dlv_domain,
                try_ipv4=try_ipv4,
                try_ipv6=try_ipv6,
                client_ipv4=client_ipv4,
                client_ipv6=client_ipv6,
                query_class_mixin=query_class_mixin,
                ceiling=c,
                edns_diagnostics=edns_diagnostics,
                explicit_delegations=explicit_delegations,
                stop_at_explicit=stop_at_explicit,
                odd_ports=odd_ports,
                extra_rdtypes=extra_rdtypes,
                explicit_only=explicit_only,
                analysis_cache=cache,
                cache_level=cache_level,
                analysis_cache_lock=cache_lock,
                transport_manager=tm,
                th_factories=th_factories,
                resolver=full_resolver)
        return a.analyze()
    # re-raise a KeyboardInterrupt, as this means we've been interrupted
    except KeyboardInterrupt:
        raise
    # report exceptions related to network connectivity
    except (NetworkConnectivityException,
            transport.RemoteQueryTransportError) as e:
        logger.error('Error analyzing %s: %s' % (fmt.humanize_name(name), e))
    # don't report EOFError, as that is what is raised if there is a
    # KeyboardInterrupt in ParallelAnalyst
    except EOFError:
        pass
    except:
        logger.exception('Error analyzing %s' % fmt.humanize_name(name))
        return None
コード例 #4
0
ファイル: probe.py プロジェクト: mweinberg/dnsviz
def _analyze(args):
    (cls, name, dlv_domain, try_ipv4, try_ipv6, client_ipv4, client_ipv6, query_class_mixin, ceiling, edns_diagnostics, \
            stop_at_explicit, extra_rdtypes, explicit_only, cache, cache_level, cache_lock) = args
    if ceiling is not None and name.is_subdomain(ceiling):
        c = ceiling
    else:
        c = name
    try:
        a = cls(name, dlv_domain=dlv_domain, try_ipv4=try_ipv4, try_ipv6=try_ipv6, client_ipv4=client_ipv4, client_ipv6=client_ipv6, query_class_mixin=query_class_mixin, ceiling=c, edns_diagnostics=edns_diagnostics, explicit_delegations=explicit_delegations, stop_at_explicit=stop_at_explicit, odd_ports=odd_ports, extra_rdtypes=extra_rdtypes, explicit_only=explicit_only, analysis_cache=cache, cache_level=cache_level, analysis_cache_lock=cache_lock, transport_manager=tm, th_factories=th_factories, resolver=resolver)
        return a.analyze()
    # re-raise a KeyboardInterrupt, as this means we've been interrupted
    except KeyboardInterrupt:
        raise
    # report exceptions related to network connectivity
    except (NetworkConnectivityException, transport.RemoteQueryTransportError) as e:
        logger.error('Error analyzing %s: %s' % (fmt.humanize_name(name), e))
    # don't report EOFError, as that is what is raised if there is a
    # KeyboardInterrupt in ParallelAnalyst
    except EOFError:
        pass
    except:
        logger.exception('Error analyzing %s' % fmt.humanize_name(name))
        return None
コード例 #5
0
def _analyze((cls, name, dlv_domain, try_ipv4, try_ipv6, client_ipv4, client_ipv6, ceiling, edns_diagnostics, explicit_delegations, extra_rdtypes, explicit_only, cache, cache_level, cache_lock, th_factories)):
    if ceiling is not None and name.is_subdomain(ceiling):
        c = ceiling
    else:
        c = name
    try:
        a = cls(name, dlv_domain=dlv_domain, try_ipv4=try_ipv4, try_ipv6=try_ipv6, client_ipv4=client_ipv4, client_ipv6=client_ipv6, ceiling=c, edns_diagnostics=edns_diagnostics, explicit_delegations=explicit_delegations, extra_rdtypes=extra_rdtypes, explicit_only=explicit_only, analysis_cache=cache, cache_level=cache_level, analysis_cache_lock=cache_lock, transport_manager=tm, th_factories=th_factories)
        return a.analyze()
    # re-raise a KeyboardInterrupt, as this means we've been interrupted
    except KeyboardInterrupt:
        raise
    # report exceptions related to network connectivity
    except (NetworkConnectivityException, transport.RemoteQueryTransportError), e:
        logger.error('Error analyzing %s: %s' % (fmt.humanize_name(name), e))
コード例 #6
0
ファイル: forms.py プロジェクト: pecharmin/dnsvizwww
 def clean_date(self):
     dt = datetime.datetime(
         self.cleaned_data["date"].year,
         self.cleaned_data["date"].month,
         self.cleaned_data["date"].day,
         23,
         59,
         59,
         999999,
         tzinfo=utc,
     )
     self.name_obj = OfflineDomainNameAnalysis.objects.latest(name, dt)
     if self.name_obj is None:
         del self.name_obj
         raise forms.ValidationError(
             "No analysis for %s known prior to %s!" % (fmt.humanize_name(name), self.cleaned_data["date"])
         )
コード例 #7
0
ファイル: probe.py プロジェクト: edmonds/dnsviz
def _analyze((cls, name, dlv_domain, client_ipv4, client_ipv6, ceiling, edns_diagnostics, explicit_delegations, extra_rdtypes, explicit_only, cache, cache_level, cache_lock)):
    if ceiling is not None and name.is_subdomain(ceiling):
        c = ceiling
    else:
        c = name
    try:
        a = cls(name, dlv_domain=dlv_domain, client_ipv4=client_ipv4, client_ipv6=client_ipv6, ceiling=c, edns_diagnostics=edns_diagnostics, explicit_delegations=explicit_delegations, extra_rdtypes=extra_rdtypes, explicit_only=explicit_only, analysis_cache=cache, cache_level=cache_level, analysis_cache_lock=cache_lock)
        return a.analyze()
    # re-raise a KeyboardInterrupt, as this means we've been interrupted
    except KeyboardInterrupt:
        raise
    # don't report EOFError, as that is what is raised if there is a
    # KeyboardInterrupt in ParallelAnalyst
    except EOFError:
        pass
    except:
        logger.exception('Error analyzing %s' % fmt.humanize_name(name))
        return None
コード例 #8
0
        c = name
    try:
        a = cls(name, dlv_domain=dlv_domain, try_ipv4=try_ipv4, try_ipv6=try_ipv6, client_ipv4=client_ipv4, client_ipv6=client_ipv6, ceiling=c, edns_diagnostics=edns_diagnostics, explicit_delegations=explicit_delegations, extra_rdtypes=extra_rdtypes, explicit_only=explicit_only, analysis_cache=cache, cache_level=cache_level, analysis_cache_lock=cache_lock, transport_manager=tm, th_factories=th_factories)
        return a.analyze()
    # re-raise a KeyboardInterrupt, as this means we've been interrupted
    except KeyboardInterrupt:
        raise
    # report exceptions related to network connectivity
    except (NetworkConnectivityException, transport.RemoteQueryTransportError), e:
        logger.error('Error analyzing %s: %s' % (fmt.humanize_name(name), e))
    # don't report EOFError, as that is what is raised if there is a
    # KeyboardInterrupt in ParallelAnalyst
    except EOFError:
        pass
    except:
        logger.exception('Error analyzing %s' % fmt.humanize_name(name))
        return None

class BulkAnalyst(object):
    analyst_cls = PrivateAnalyst

    def __init__(self, try_ipv4, try_ipv6, client_ipv4, client_ipv6, ceiling, edns_diagnostics, cache_level, explicit_delegations, extra_rdtypes, explicit_only, dlv_domain, th_factories):
        self.try_ipv4 = try_ipv4
        self.try_ipv6 = try_ipv6
        self.client_ipv4 = client_ipv4
        self.client_ipv6 = client_ipv6
        self.ceiling = ceiling
        self.edns_diagnostics = edns_diagnostics
        self.cache_level = cache_level
        self.explicit_delegations = explicit_delegations
        self.extra_rdtypes = extra_rdtypes
コード例 #9
0
ファイル: forms.py プロジェクト: geosphere/dnsvizwww
        def clean_explicit_delegation(self):
            resolver = Resolver.from_file('/etc/resolv.conf',
                                          StandardRecursiveQueryCD)

            s = self.cleaned_data['explicit_delegation']
            mappings = set()
            i = 1
            for line in s.splitlines():
                line = line.strip()
                if not line:
                    continue
                # get ride of extra columns
                cols = line.split()
                if len(cols) > 1:
                    line = '%s %s' % (cols[0], cols[-1])
                try:
                    name, addr = line.split()
                except ValueError:
                    # first see if it's a plain IP address
                    try:
                        addr = IPAddr(line.strip())
                    except ValueError:
                        # if not, then assign name to mapping
                        name = line
                        addr = None
                    else:
                        # if it's an IP with no name specified, then create
                        # a name
                        name = 'ns%d' % i
                        i += 1
                try:
                    name = dns.name.from_text(name)
                except:
                    raise forms.ValidationError(
                        'The domain name was invalid: "%s"' % name)

                # no address is provided, so query A/AAAA records for the name
                if addr is None:
                    query_tuples = ((name, dns.rdatatype.A, dns.rdataclass.IN),
                                    (name, dns.rdatatype.AAAA,
                                     dns.rdataclass.IN))
                    answer_map = resolver.query_multiple_for_answer(
                        *query_tuples)
                    found_answer = False
                    for a in answer_map.values():
                        if isinstance(a, DNSAnswer):
                            found_answer = True
                            for a_rr in a.rrset:
                                mappings.add((name, IPAddr(a_rr.to_text())))
                        # negative responses
                        elif isinstance(
                                a,
                            (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer)):
                            pass
                        # error responses
                        elif isinstance(a, (dns.exception.Timeout,
                                            dns.resolver.NoNameservers)):
                            raise forms.ValidationError(
                                'There was an error resolving "%s".  Please specify an address or use a name that resolves properly.'
                                % fmt.humanize_name(name))

                    if not found_answer:
                        raise forms.ValidationError(
                            '"%s" did not resolve to an address.  Please specify an address or use a name that resolves properly.'
                            % fmt.humanize_name(name))

                # otherwise, add the address
                else:
                    if addr and addr[0] == '[' and addr[-1] == ']':
                        addr = addr[1:-1]
                    try:
                        addr = IPAddr(addr)
                    except ValueError:
                        raise forms.ValidationError(
                            'The IP address was invalid: "%s"' % addr)
                    mappings.add((name, addr))

            # if there something in the box, yet no mappings resulted, then raise a
            # validation error
            if self.cleaned_data['explicit_delegation'] and not mappings:
                raise forms.ValidationError(
                    'Unable to process address records!')

            return mappings
コード例 #10
0
ファイル: forms.py プロジェクト: geosphere/dnsvizwww
    class DomainNameAnalysisForm(forms.Form):
        EXTRA_TYPES = ((dns.rdatatype.A, dns.rdatatype.to_text(
            dns.rdatatype.A)), (dns.rdatatype.AAAA,
                                dns.rdatatype.to_text(dns.rdatatype.AAAA)),
                       (dns.rdatatype.TXT,
                        dns.rdatatype.to_text(dns.rdatatype.TXT)),
                       (dns.rdatatype.PTR,
                        dns.rdatatype.to_text(dns.rdatatype.PTR)),
                       (dns.rdatatype.MX,
                        dns.rdatatype.to_text(dns.rdatatype.MX)),
                       (dns.rdatatype.SOA,
                        dns.rdatatype.to_text(dns.rdatatype.SOA)),
                       (dns.rdatatype.CNAME,
                        dns.rdatatype.to_text(dns.rdatatype.CNAME)),
                       (dns.rdatatype.SRV,
                        dns.rdatatype.to_text(dns.rdatatype.SRV)),
                       (dns.rdatatype.NAPTR,
                        dns.rdatatype.to_text(dns.rdatatype.NAPTR)),
                       (dns.rdatatype.TLSA,
                        dns.rdatatype.to_text(dns.rdatatype.TLSA)))

        ANALYSIS_TYPES = ((ANALYSIS_TYPE_AUTHORITATIVE,
                           'Authoritative servers'), (ANALYSIS_TYPE_RECURSIVE,
                                                      'Recursive servers'))

        PERSPECTIVE = (('server', 'DNSViz server (me)'), ('client',
                                                          'Web client (you)'))

        force_ancestor = forms.TypedChoiceField(
            label='Force ancestor analysis',
            choices=ANCESTOR_CHOICES,
            initial=name.to_text(),
            required=True,
            coerce=dns.name.from_text,
            help_text=
            'Usually it is sufficient to select the name itself (%s) or its zone, in which case cached values will be used for the analysis of any ancestor names (unless it is determined that they are out of date).  Occasionally it is useful to re-analyze some portion of the ancestry, in which case the desired ancestor can be selected.  However, the overall analysis will take longer.'
            % (fmt.humanize_name(name, True)))
        extra_types = forms.TypedMultipleChoiceField(
            choices=EXTRA_TYPES,
            initial=(),
            required=False,
            coerce=int,
            help_text=
            'Select any extra RR types to query as part of this analysis.  A default set of types will already be queried based on the nature of the name, but any types selected here will assuredly be included.'
        )
        edns_diagnostics = forms.BooleanField(
            label='EDNS diagnostics',
            initial=False,
            required=False,
            help_text='Issue queries specific to EDNS diagnostics.')
        explicit_delegation = forms.CharField(
            initial='',
            required=False,
            widget=forms.Textarea(attrs={
                'cols': 50,
                'rows': 5
            }),
            help_text=
            'If you wish to designate servers explicitly for the "force ancestor" zone (rather than following delegation from the IANA root), enter the server names, one per line.  You may optionally include an IPv4 or IPv6 address on the same line as the name.'
        )
        analysis_type = forms.TypedChoiceField(
            choices=ANALYSIS_TYPES,
            initial=ANALYSIS_TYPE_AUTHORITATIVE,
            coerce=int,
            widget=forms.RadioSelect(),
            help_text=
            'If authoritative analysis is selected, then the authoritative servers will be analyzed, beginning at the root servers--or the servers explicitly designated; if recursive analysis is selected, then the designated recursive servers will be analyzed.'
        )
        perspective = forms.TypedChoiceField(
            choices=PERSPECTIVE,
            initial='server',
            widget=forms.RadioSelect(),
            help_text=
            'If \'DNSViz server\' is selected, then the diagnostic queries will be issued from the DNSViz server.  If \'Web client\' is selected, they will be issued from the browser (requires the use of a Java applet).'
        )
        sockname = forms.CharField(widget=forms.HiddenInput(), required=False)

        def clean(self):
            cleaned_data = super(DomainNameAnalysisForm, self).clean()
            if cleaned_data.get('analysis_type', None) == ANALYSIS_TYPE_RECURSIVE and \
                    not cleaned_data.get('explicit_delegation', None):
                raise forms.ValidationError(
                    'If recursive analysis is desired, then servers names and/or addresses must be specified.'
                )
            if cleaned_data.get('perspective', None) == 'client' and \
                    not cleaned_data.get('sockname', None):
                raise forms.ValidationError(
                    'No address supplied for WebSocket')
            return cleaned_data

        def clean_explicit_delegation(self):
            resolver = Resolver.from_file('/etc/resolv.conf',
                                          StandardRecursiveQueryCD)

            s = self.cleaned_data['explicit_delegation']
            mappings = set()
            i = 1
            for line in s.splitlines():
                line = line.strip()
                if not line:
                    continue
                # get ride of extra columns
                cols = line.split()
                if len(cols) > 1:
                    line = '%s %s' % (cols[0], cols[-1])
                try:
                    name, addr = line.split()
                except ValueError:
                    # first see if it's a plain IP address
                    try:
                        addr = IPAddr(line.strip())
                    except ValueError:
                        # if not, then assign name to mapping
                        name = line
                        addr = None
                    else:
                        # if it's an IP with no name specified, then create
                        # a name
                        name = 'ns%d' % i
                        i += 1
                try:
                    name = dns.name.from_text(name)
                except:
                    raise forms.ValidationError(
                        'The domain name was invalid: "%s"' % name)

                # no address is provided, so query A/AAAA records for the name
                if addr is None:
                    query_tuples = ((name, dns.rdatatype.A, dns.rdataclass.IN),
                                    (name, dns.rdatatype.AAAA,
                                     dns.rdataclass.IN))
                    answer_map = resolver.query_multiple_for_answer(
                        *query_tuples)
                    found_answer = False
                    for a in answer_map.values():
                        if isinstance(a, DNSAnswer):
                            found_answer = True
                            for a_rr in a.rrset:
                                mappings.add((name, IPAddr(a_rr.to_text())))
                        # negative responses
                        elif isinstance(
                                a,
                            (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer)):
                            pass
                        # error responses
                        elif isinstance(a, (dns.exception.Timeout,
                                            dns.resolver.NoNameservers)):
                            raise forms.ValidationError(
                                'There was an error resolving "%s".  Please specify an address or use a name that resolves properly.'
                                % fmt.humanize_name(name))

                    if not found_answer:
                        raise forms.ValidationError(
                            '"%s" did not resolve to an address.  Please specify an address or use a name that resolves properly.'
                            % fmt.humanize_name(name))

                # otherwise, add the address
                else:
                    if addr and addr[0] == '[' and addr[-1] == ']':
                        addr = addr[1:-1]
                    try:
                        addr = IPAddr(addr)
                    except ValueError:
                        raise forms.ValidationError(
                            'The IP address was invalid: "%s"' % addr)
                    mappings.add((name, addr))

            # if there something in the box, yet no mappings resulted, then raise a
            # validation error
            if self.cleaned_data['explicit_delegation'] and not mappings:
                raise forms.ValidationError(
                    'Unable to process address records!')

            return mappings
コード例 #11
0
ファイル: notices.py プロジェクト: stasic/dnsvizwww
def _get_label_for_node(notices, node_name, val):
    l = None
    m1 = _node_re.search(node_name)
    if m1 is not None:
        t1 = m1.group('node_type')
        #TODO sort keys by dns name (i.e., not simply by textual name)
        if t1 == 'RRset':
            m2 = _rrset_node_re.search(m1.group('remnant'))
            l = '%s/%s' % (fmt.humanize_name(dns.name.from_text(m2.group('name')), True), m2.group('rdtype'))
            if m1.group('id') == '0':
                l += ' (NXDOMAIN)'
            elif m1.group('id') == '1':
                l += ' (NODATA)'
            if m1.group('id') not in ('2', '3'):
                bisect.insort(notices['RRset status'][val[0]['status']],l)
        elif t1 == 'DNSKEY':
            m2 = _dnskey_node_re.search(m1.group('remnant'))
            l = '%s/DNSKEY (alg %s, id %s)' % (fmt.humanize_name(dns.name.from_text(m2.group('name')), True), m2.group('alg'), m2.group('key_tag'))
            bisect.insort(notices['DNSKEY/DS/NSEC status'][val[0]['status']],l)
        elif t1 in ('DS','DLV'):
            m2 = _ds_node_re.search(m1.group('remnant'))
            l = '%s/%s (alg %s, id %s)' % (fmt.humanize_name(dns.name.from_text(m2.group('name')), True), t1, m2.group('alg'), m2.group('key_tag'))
            bisect.insort(notices['DNSKEY/DS/NSEC status'][val[0]['status']],l)
        elif t1.startswith('NSEC'):
            m2 = _nsec_node_re.search(m1.group('remnant'))
            l = '%s proving non-existence of %s/%s' % (t1, fmt.humanize_name(dns.name.from_text(m2.group('name')), True), m2.group('rdtype'))
            bisect.insort(notices['DNSKEY/DS/NSEC status'][val[0]['status']],l)
    else:
        m1 = _edge_re.search(node_name)
        if m1 is not None:
            t1 = m1.group('node_type')
            if t1 == 'del':
                m2 = _del_re.search(m1.group('remnant'))
                l = '%s to %s' % (fmt.humanize_name(dns.name.from_text(m2.group('parent')), True), fmt.humanize_name(dns.name.from_text(m2.group('child')), True))
                bisect.insort(notices['delegation status'][val[0]['status']],l)
            elif t1 == 'digest':
                m2 = _digest_re.search(m1.group('remnant'))
                l = '%s/%s (alg %s, id %s)' % (fmt.humanize_name(dns.name.from_text(m2.group('name')), True), m2.group('type'), m2.group('alg'), m2.group('key_tag'))
            elif t1 == 'RRSIG':
                m2 = _node_re.search(m1.group('remnant'))
                m3 = _rrsig_dnskey_re.search(m2.group('remnant'))
                dnskey_str = 'alg %s, id %s' % (m3.group('alg'), m3.group('key_tag'))
                t2 = m2.group('node_type')
                if t2 == 'RRset':
                    m3 = _rrset_node_re.search(m2.group('remnant'))
                    l = 'RRSIG %s/%s %s' % (fmt.humanize_name(dns.name.from_text(m3.group('name')), True), m3.group('rdtype'), dnskey_str)
                elif t2 == 'DNSKEY':
                    m3 = _dnskey_node_re.search(m2.group('remnant'))
                    l = 'RRSIG %s/DNSKEY %s' % (fmt.humanize_name(dns.name.from_text(m3.group('name')), True), dnskey_str)
                elif t2 in ('DS','DLV'):
                    m3 = _ds_node_re.search(m2.group('remnant'))
                    l = 'RRSIG %s/%s %s' % (fmt.humanize_name(dns.name.from_text(m3.group('name')), True), t2, dnskey_str)
                elif t2.startswith('NSEC'):
                    m3 = _nsec_node_re.search(m2.group('remnant'))
                    l = 'RRSIG %s proving non-existence of %s/%s %s' % (t2, fmt.humanize_name(dns.name.from_text(m3.group('name')), True), m3.group('rdtype'), dnskey_str)
            elif t1.startswith('NSEC'):
                m2 = _nsecc_re.search(m1.group('remnant'))
                l = '%s proving non-existence of %s/%s' % (m2.group('type'), fmt.humanize_name(dns.name.from_text(m2.group('name')), True), m2.group('rdtype'))
            elif t1 == 'dname':
                m2 = _dname_re.search(m1.group('remnant'))
                l = 'CNAME synthesis of %s' % (fmt.humanize_name(dns.name.from_text(m2.group('name')), True))
        else:
            m1 = _zone_re.search(node_name)
            if m1 is not None:
                l = '%s zone' % (fmt.humanize_name(dns.name.from_text(m1.group('name')), True))

    return l
コード例 #12
0
ファイル: probe.py プロジェクト: mweinberg/dnsviz
def name_addr_mappings_from_string(domain, addr_mappings, delegation_mapping, require_name):
    global next_port

    addr_mappings = addr_mappings.split(',')
    i = 1
    for mapping in addr_mappings:

        # get rid of whitespace
        mapping = mapping.strip()

        # Determine whether there is a port stuck on there
        match = PORT_RE.search(mapping)
        if match is not None:
            mapping = match.group(1)
            port = int(match.group(2))
            port_str = ':%d' % port
        else:
            port = 53
            port_str = ''

        num_replacements = None

        # if the value is actually a path, then check it as a zone file
        if os.path.isfile(mapping):
            # if this is a file containing delegation records, then read the
            # file, create a name=value string, and call name_addr_mappings_from_string()
            if require_name:
                mappings_from_file = []
                try:
                    s = io.open(mapping, 'r', encoding='utf-8').read()
                except IOError as e:
                    usage('%s: "%s"' % (e.strerror, mapping))
                    sys.exit(3)

                try:
                    m = dns.message.from_text(str(';ANSWER\n'+s))
                except dns.exception.DNSException as e:
                    usage('Error reading delegation records from %s: "%s"' % (mapping, e))
                    sys.exit(3)

                try:
                    ns_rrset = m.find_rrset(m.answer, domain, dns.rdataclass.IN, dns.rdatatype.NS)
                except KeyError:
                    usage('No NS records for %s found in %s' % (lb2s(domain.canonicalize().to_text()), mapping))
                    sys.exit(3)

                for rdata in ns_rrset:
                    a_rrsets = [r for r in m.answer if r.name == rdata.target and r.rdtype in (dns.rdatatype.A, dns.rdatatype.AAAA)]
                    if not a_rrsets or not rdata.target.is_subdomain(domain.parent()):
                        mappings_from_file.append(lb2s(rdata.target.canonicalize().to_text()))
                    else:
                        for a_rrset in a_rrsets:
                            for a_rdata in a_rrset:
                                mappings_from_file.append('%s=%s' % (lb2s(rdata.target.canonicalize().to_text()), IPAddr(a_rdata.address)))

                name_addr_mappings_from_string(domain, ','.join(mappings_from_file), delegation_mapping, require_name)
                continue

            # otherwise (it is the zone proper), just serve the file
            else:
                if port_str == '':
                    #TODO assign random port here
                    port = next_port
                    next_port += 1
                _serve_zone(domain, mapping, port)
                name = 'localhost'
                addr = '127.0.0.1'

        else:
            # First determine whether the argument is name=value or simply value
            try:
                name, addr = NAME_VAL_DELIM_RE.split(mapping, 1)
            except ValueError:
                # Argument is a single value.  Now determine whether that value is
                # a name or an address.
                try:
                    IPAddr(BRACKETS_RE.sub(r'\1', mapping))
                except ValueError:
                    # see if this was an IPv6 address without a port
                    try:
                        IPAddr(mapping + port_str)
                    except ValueError:
                        pass
                    else:
                        usage('Brackets are required around IPv6 addresses.')
                        sys.exit(1)

                    # value is not an address
                    name = mapping
                    addr = None
                else:
                    if require_name:
                        usage('A name is required to accompany the address for this option.')
                        sys.exit(1)

                    # value is an address
                    name = 'ns%d' % i
                    addr, num_replacements = BRACKETS_RE.subn(r'\1', mapping)
                    i += 1
            else:
                # Argument is name=value
                addr, num_replacements = BRACKETS_RE.subn(r'\1', addr)

            if not name:
                usage('The domain name was empty.')
                sys.exit(1)

        # At this point, name is defined, and addr may or may not be defined.
        # Both are of type str.

        # Check that the name is valid
        try:
            name = dns.name.from_text(name)
        except dns.exception.DNSException:
            usage('The domain name was invalid: "%s"' % name)
            sys.exit(1)

        # Add the name to the NS RRset
        delegation_mapping[(domain, dns.rdatatype.NS)].add(dns.rdtypes.ANY.NS.NS(dns.rdataclass.IN, dns.rdatatype.NS, name))

        if addr is None:
            if not require_name:
                # If no address is provided, query A/AAAA records for the name
                query_tuples = ((name, dns.rdatatype.A, dns.rdataclass.IN), (name, dns.rdatatype.AAAA, dns.rdataclass.IN))
                answer_map = bootstrap_resolver.query_multiple_for_answer(*query_tuples)
                found_answer = False
                for (n, rdtype, rdclass) in answer_map:
                    a = answer_map[(n, rdtype, rdclass)]
                    if isinstance(a, DNSAnswer):
                        found_answer = True
                        delegation_mapping[(name, rdtype)] = dns.rrset.from_text_list(name, 0, dns.rdataclass.IN, rdtype, [IPAddr(r.address) for r in a.rrset])
                        if port != 53:
                            for r in a.rrset:
                                odd_ports[(domain, IPAddr(r.address))] = port
                    # negative responses
                    elif isinstance(a, (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer)):
                        pass
                    # error responses
                    elif isinstance(a, (dns.exception.Timeout, dns.resolver.NoNameservers)):
                        usage('There was an error resolving "%s".  Please specify an address or use a name that resolves properly.' % fmt.humanize_name(name))
                        sys.exit(1)

                if not found_answer:
                    usage('"%s" did not resolve to an address.  Please specify an address or use a name that resolves properly.' % fmt.humanize_name(name))
                    sys.exit(1)

        elif not addr:
            if not require_name:
                usage('The IP address was empty.')
                sys.exit(1)

        else:
            try:
                IPAddr(addr)
            except ValueError:
                # see if this was an IPv6 address without a port
                try:
                    IPAddr(addr + port_str)
                except ValueError:
                    usage('The IP address was invalid: "%s"' % addr)
                    sys.exit(1)
                else:
                    usage('Brackets are required around IPv6 addresses.')
                    sys.exit(1)

            if IPAddr(addr).version == 6:
                if num_replacements < 1:
                    usage('Brackets are required around IPv6 addresses.')
                    sys.exit(1)

                a_rdtype = dns.rdatatype.AAAA
                rdtype_cls = dns.rdtypes.IN.AAAA.AAAA
            else:
                a_rdtype = dns.rdatatype.A
                rdtype_cls = dns.rdtypes.IN.A.A
            if (name, a_rdtype) not in delegation_mapping:
                delegation_mapping[(name, a_rdtype)] = dns.rrset.RRset(name, dns.rdataclass.IN, a_rdtype)
            delegation_mapping[(name, a_rdtype)].add(rdtype_cls(dns.rdataclass.IN, a_rdtype, addr))
            if port != 53:
                odd_ports[(domain, IPAddr(addr))] = port
コード例 #13
0
    def _get(self, request, name_obj, timestamp, url_subdir, date_form):
        options_form, values = get_dnssec_options_form_data({})

        trusted_keys_explicit = values['tk']
        trusted_zones = values['ta']
        trusted_keys = trusted_keys_explicit + trusted_zones

        name_obj.retrieve_all()
        name_obj.populate_status(trusted_keys)

        zone_obj = name_obj.zone

        rdtypes = options_form.cleaned_data['rr']
        qrrsets = [(name_obj, name, rdtype)
                   for (name, rdtype) in name_obj.queries if rdtype in rdtypes]

        # if DANE, then add the A/AAAA records for the DANE host
        if len(name_obj.name) > 2 and name_obj.name[1] in ('_tcp', '_udp',
                                                           '_sctp'):
            dane_host_obj = name_obj.get_dane_hostname()
            if dane_host_obj is not None:
                dane_host_obj.retrieve_all()
                dane_host_obj.populate_status(trusted_keys)
                if dane_host_obj.zone.name == name_obj.zone.name:
                    if dns.rdatatype.A in rdtypes:
                        qrrsets.append((dane_host_obj, dane_host_obj.name,
                                        dns.rdatatype.A))
                    if dns.rdatatype.AAAA in rdtypes:
                        qrrsets.append((dane_host_obj, dane_host_obj.name,
                                        dns.rdatatype.AAAA))

        qrrsets.insert(0, (zone_obj, zone_obj.name, dns.rdatatype.NS))
        qrrsets.insert(0, (zone_obj, zone_obj.name, dns.rdatatype.DNSKEY))
        if zone_obj.parent is not None:
            qrrsets.insert(0, (zone_obj, zone_obj.name, dns.rdatatype.DS))
            parent_all_auth_servers = zone_obj.parent.get_auth_or_designated_servers(
            )
            parent_server_list = [(ip,
                                   zone_obj.parent.get_ns_name_for_ip(ip)[0])
                                  for ip in parent_all_auth_servers]
            parent_server_list.sort(cmp=util.ip_name_cmp)

        all_auth_servers = zone_obj.get_auth_or_designated_servers()
        server_list = [(ip, zone_obj.get_ns_name_for_ip(ip)[0])
                       for ip in all_auth_servers]
        server_list.sort(cmp=util.ip_name_cmp)
        response_consistency = []

        for my_name_obj, name, rdtype in qrrsets:
            if rdtype == dns.rdatatype.DS:
                slist = parent_server_list
                zone_name = my_name_obj.parent_name()
            else:
                slist = server_list
                zone_name = my_name_obj.zone.name

            pos_matrix = []

            # if all servers are unresponsive, some of the queries enumerated above
            # might not have been asked
            if (name, rdtype) not in my_name_obj.queries:
                continue

            query = my_name_obj.queries[(name, rdtype)]

            servers_pos_responses = set()
            #servers_neg_responses = set()
            servers_error_responses = set()
            for rrset_info in query.answer_info:
                servers_pos_responses.update(
                    [s[0] for s in rrset_info.servers_clients])
            #if (name, rdtype) in name_obj.nxdomain_servers_clients:
            #    servers_neg_responses.update([s[0] for s in name_obj.nxdomain_servers_clients[(name, rdtype)]])
            #if (name, rdtype) in name_obj.noanswer_servers_clients:
            #    servers_neg_responses.update([s[0] for s in name_obj.noanswer_servers_clients[(name, rdtype)]])
            #TODO error responses
            #TODO NSEC responses

            for rrset_info in query.answer_info:
                rrset_servers = set([s[0] for s in rrset_info.servers_clients])
                row_grouping = []
                row = []
                row.append((fmt.humanize_name(rrset_info.rrset.name,
                                              True), 'not-styled'))
                row.append((rrset_info.rrset.ttl, 'not-styled'))
                row.append((dns.rdatatype.to_text(rrset_info.rrset.rdtype),
                            'not-styled'))
                rrset_str = ''
                rrset_list = [
                    Response.RdataWrapper(x) for x in rrset_info.rrset
                ]
                rrset_list.sort()
                for rrw in rrset_list:
                    rr = rrw._rdata
                    rr_str = escape(rr.to_text(), quote=True)
                    if rrset_info.rrset.rdtype == dns.rdatatype.DNSKEY:
                        rr_str += ' ; <b>key tag = %d</b>' % Response.DNSKEYMeta.calc_key_tag(
                            rr)
                    rrset_str += '\n<div class="rr">%s</div>' % rr_str
                row.append((rrset_str, 'not-styled'))

                status = ('OK', 'valid')
                row.append(status)

                for server, names in slist:
                    if server in rrset_servers:
                        row.append((
                            'Y',
                            'valid',
                        ))
                    else:
                        server_queried = False
                        for q in query.queries.values():
                            if server in q.responses:
                                server_queried = True
                        if server_queried:
                            row.append(('', 'not-styled'))
                        else:
                            row.append(('', 'not-queried', None,
                                        'Server %s not queried for %s/%s.' %
                                        (server, fmt.humanize_name(name),
                                         dns.rdatatype.to_text(rdtype))))
                row_grouping.append(row)

                for rrsig in my_name_obj.rrsig_status[rrset_info]:
                    rrsig_servers = set([
                        s[0]
                        for s in rrset_info.rrsig_info[rrsig].servers_clients
                    ])
                    row = []
                    row.append(('', 'not-styled'))
                    row.append(
                        (rrset_info.rrsig_info[rrsig].ttl, 'not-styled'))
                    row.append(('RRSIG', 'not-styled'))
                    row.append(('<div class="rr">%s</div>' % rrsig.to_text(),
                                'not-styled'))

                    try:
                        status = filter(
                            lambda x: x.signature_valid == True,
                            my_name_obj.rrsig_status[rrset_info]
                            [rrsig].values())[0]
                    except IndexError:
                        status = my_name_obj.rrsig_status[rrset_info][
                            rrsig].values()[0]

                    style = Status.rrsig_status_mapping[
                        status.validation_status]
                    row.append(
                        (Status.rrsig_status_mapping[status.validation_status],
                         style))

                    for server, names in slist:
                        if server in rrsig_servers:
                            row.append(('Y', style))
                        elif server not in rrset_servers:
                            row.append(('', 'not-queried'))
                        else:
                            row.append(('', 'not-styled'))
                    row_grouping.append(row)
                pos_matrix.append(row_grouping)

            row_grouping = []
            row = []
            row.append(('RR count (Answer/Authority/Additional)', 'not-styled',
                        None, None, 4))
            row.append(('OK', 'valid'))
            for server, names in slist:
                server_queried = False
                response = None
                for q in query.queries.values():
                    if server in q.responses:
                        server_queried = True
                        r = q.responses[server].values()[0]
                        if r.is_complete_response():
                            response = r
                            break
                if server_queried and response is not None:
                    answer_ct = 0
                    for i in response.message.answer:
                        answer_ct += len(i)
                    authority_ct = 0
                    for i in response.message.authority:
                        authority_ct += len(i)
                    additional_ct = 0
                    for i in response.message.additional:
                        additional_ct += len(i)
                    if response.message.edns >= 0:
                        additional_ct += 1
                    row.append(
                        ('%d/%d/%d' % (answer_ct, authority_ct, additional_ct),
                         'valid'))
                elif not server_queried:
                    row.append(('', 'not-queried', None,
                                'Server %s not queried for %s/%s.' %
                                (server, fmt.humanize_name(name),
                                 dns.rdatatype.to_text(rdtype))))
                elif server:
                    row.append(('', 'not-styled'))
            row_grouping.append(row)
            pos_matrix.append(row_grouping)

            row_grouping = []
            row = []
            row.append(('Response size (bytes)', 'not-styled', None, None, 4))
            row.append(('OK', 'valid'))
            for server, names in slist:
                server_queried = False
                response = None
                for q in query.queries.values():
                    if server in q.responses:
                        server_queried = True
                        r = q.responses[server].values()[0]
                        if r.is_complete_response():
                            response = r
                            break
                if server_queried and response is not None:
                    row.append((response.msg_size, 'valid'))
                elif not server_queried:
                    row.append(('', 'not-queried', None,
                                'Server %s not queried for %s/%s.' %
                                (server, fmt.humanize_name(name),
                                 dns.rdatatype.to_text(rdtype))))
                elif server:
                    row.append(('', 'not-styled'))
            row_grouping.append(row)
            pos_matrix.append(row_grouping)

            row_grouping = []
            row = []
            row.append(('Response time (ms)', 'not-styled', None, None, 4))
            row.append(('OK', 'valid'))
            for server, names in slist:
                server_queried = False
                response = None
                for q in query.queries.values():
                    if server in q.responses:
                        server_queried = True
                        r = q.responses[server].values()[0]
                        if r.is_complete_response():
                            response = r
                            break
                if server_queried and response is not None:
                    row.append((int(response.response_time * 1e3), 'valid'))
                elif not server_queried:
                    row.append(('', 'not-queried', None,
                                'Server %s not queried for %s/%s.' %
                                (server, fmt.humanize_name(name),
                                 dns.rdatatype.to_text(rdtype))))
                elif server:
                    row.append(('', 'not-styled'))
            row_grouping.append(row)
            pos_matrix.append(row_grouping)

            if pos_matrix:
                response_consistency.append(
                    ('Responses for %s/%s' % (fmt.humanize_name(
                        name, True), dns.rdatatype.to_text(rdtype)), slist,
                     pos_matrix))

        return render_to_response('responses.html', {
            'name_obj': name_obj,
            'timestamp': timestamp,
            'url_subdir': url_subdir,
            'title': name_obj,
            'date_form': date_form,
            'response_consistency': response_consistency
        },
                                  context_instance=RequestContext(request))
コード例 #14
0
ファイル: probe.py プロジェクト: leonirlopes/dnsviz
def name_addr_mappings_from_string(domain, addr_mappings, delegation_mapping,
                                   require_name):
    global next_port

    addr_mappings = addr_mappings.split(',')
    i = 1
    for mapping in addr_mappings:

        # get rid of whitespace
        mapping = mapping.strip()

        # Determine whether there is a port stuck on there
        match = PORT_RE.search(mapping)
        if match is not None:
            mapping = match.group(1)
            port = int(match.group(2))
            port_str = ':%d' % port
        else:
            port = 53
            port_str = ''

        num_replacements = None

        # if the value is actually a path, then check it as a zone file
        if os.path.isfile(mapping):
            # if this is a file containing delegation records, then read the
            # file, create a name=value string, and call name_addr_mappings_from_string()
            if require_name:
                mappings_from_file = []
                try:
                    s = io.open(mapping, 'r', encoding='utf-8').read()
                except IOError as e:
                    usage('%s: "%s"' % (e.strerror, mapping))
                    sys.exit(3)

                try:
                    m = dns.message.from_text(str(';ANSWER\n' + s))
                except dns.exception.DNSException as e:
                    usage('Error reading delegation records from %s: "%s"' %
                          (mapping, e))
                    sys.exit(3)

                try:
                    ns_rrset = m.find_rrset(m.answer, domain,
                                            dns.rdataclass.IN,
                                            dns.rdatatype.NS)
                except KeyError:
                    usage('No NS records for %s found in %s' %
                          (lb2s(domain.canonicalize().to_text()), mapping))
                    sys.exit(3)

                for rdata in ns_rrset:
                    a_rrsets = [
                        r for r in m.answer
                        if r.name == rdata.target and r.rdtype in (
                            dns.rdatatype.A, dns.rdatatype.AAAA)
                    ]
                    if not a_rrsets or not rdata.target.is_subdomain(
                            domain.parent()):
                        mappings_from_file.append(
                            lb2s(rdata.target.canonicalize().to_text()))
                    else:
                        for a_rrset in a_rrsets:
                            for a_rdata in a_rrset:
                                mappings_from_file.append(
                                    '%s=%s' % (lb2s(
                                        rdata.target.canonicalize().to_text()),
                                               IPAddr(a_rdata.address)))

                name_addr_mappings_from_string(domain,
                                               ','.join(mappings_from_file),
                                               delegation_mapping,
                                               require_name)
                continue

            # otherwise (it is the zone proper), just serve the file
            else:
                if port_str == '':
                    #TODO assign random port here
                    port = next_port
                    next_port += 1
                _serve_zone(domain, mapping, port)
                name = 'localhost'
                addr = '127.0.0.1'

        else:
            # First determine whether the argument is name=value or simply value
            try:
                name, addr = NAME_VAL_DELIM_RE.split(mapping, 1)
            except ValueError:
                # Argument is a single value.  Now determine whether that value is
                # a name or an address.
                try:
                    IPAddr(BRACKETS_RE.sub(r'\1', mapping))
                except ValueError:
                    # see if this was an IPv6 address without a port
                    try:
                        IPAddr(mapping + port_str)
                    except ValueError:
                        pass
                    else:
                        usage('Brackets are required around IPv6 addresses.')
                        sys.exit(1)

                    # value is not an address
                    name = mapping
                    addr = None
                else:
                    if require_name:
                        usage(
                            'A name is required to accompany the address for this option.'
                        )
                        sys.exit(1)

                    # value is an address
                    name = 'ns%d' % i
                    addr, num_replacements = BRACKETS_RE.subn(r'\1', mapping)
                    i += 1
            else:
                # Argument is name=value
                addr, num_replacements = BRACKETS_RE.subn(r'\1', addr)

            if not name:
                usage('The domain name was empty.')
                sys.exit(1)

        # At this point, name is defined, and addr may or may not be defined.
        # Both are of type str.

        # Check that the name is valid
        try:
            name = dns.name.from_text(name)
        except dns.exception.DNSException:
            usage('The domain name was invalid: "%s"' % name)
            sys.exit(1)

        # Add the name to the NS RRset
        delegation_mapping[(domain, dns.rdatatype.NS)].add(
            dns.rdtypes.ANY.NS.NS(dns.rdataclass.IN, dns.rdatatype.NS, name))

        if addr is None:
            if not require_name:
                # If no address is provided, query A/AAAA records for the name
                query_tuples = ((name, dns.rdatatype.A, dns.rdataclass.IN),
                                (name, dns.rdatatype.AAAA, dns.rdataclass.IN))
                answer_map = stub_resolver.query_multiple_for_answer(
                    *query_tuples)
                found_answer = False
                for (n, rdtype, rdclass) in answer_map:
                    a = answer_map[(n, rdtype, rdclass)]
                    if isinstance(a, DNSAnswer):
                        found_answer = True
                        delegation_mapping[(
                            name, rdtype)] = dns.rrset.from_text_list(
                                name, 0, dns.rdataclass.IN, rdtype,
                                [IPAddr(r.address) for r in a.rrset])
                        if port != 53:
                            for r in a.rrset:
                                odd_ports[(domain, IPAddr(r.address))] = port
                    # negative responses
                    elif isinstance(
                            a, (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer)):
                        pass
                    # error responses
                    elif isinstance(
                            a,
                        (dns.exception.Timeout, dns.resolver.NoNameservers)):
                        usage(
                            'There was an error resolving "%s".  Please specify an address or use a name that resolves properly.'
                            % fmt.humanize_name(name))
                        sys.exit(1)

                if not found_answer:
                    usage(
                        '"%s" did not resolve to an address.  Please specify an address or use a name that resolves properly.'
                        % fmt.humanize_name(name))
                    sys.exit(1)

        elif not addr:
            if not require_name:
                usage('The IP address was empty.')
                sys.exit(1)

        else:
            try:
                IPAddr(addr)
            except ValueError:
                # see if this was an IPv6 address without a port
                try:
                    IPAddr(addr + port_str)
                except ValueError:
                    usage('The IP address was invalid: "%s"' % addr)
                    sys.exit(1)
                else:
                    usage('Brackets are required around IPv6 addresses.')
                    sys.exit(1)

            if IPAddr(addr).version == 6:
                if num_replacements < 1:
                    usage('Brackets are required around IPv6 addresses.')
                    sys.exit(1)

                a_rdtype = dns.rdatatype.AAAA
                rdtype_cls = dns.rdtypes.IN.AAAA.AAAA
            else:
                a_rdtype = dns.rdatatype.A
                rdtype_cls = dns.rdtypes.IN.A.A
            if (name, a_rdtype) not in delegation_mapping:
                delegation_mapping[(name, a_rdtype)] = dns.rrset.RRset(
                    name, dns.rdataclass.IN, a_rdtype)
            delegation_mapping[(name, a_rdtype)].add(
                rdtype_cls(dns.rdataclass.IN, a_rdtype, addr))
            if port != 53:
                odd_ports[(domain, IPAddr(addr))] = port
コード例 #15
0
    def _get(self, request, name_obj, timestamp, url_subdir, date_form):
        options_form, values = get_dnssec_options_form_data({})

        trusted_keys_explicit = values['tk']
        trusted_zones = values['ta']
        trusted_keys = trusted_keys_explicit + trusted_zones

        name_obj.retrieve_all()
        name_obj.populate_status(trusted_keys)

        zone_obj = name_obj.zone

        delegation_matrix = []

        def stealth_cmp(x, y):
            return cmp((y[0], x[1], x[2]), (x[0], y[1], y[2]))

        all_names_list = list(zone_obj.get_ns_names())
        if not all_names_list:
            all_names_list = list(zone_obj.get_auth_ns_ip_mapping())

        all_names_list.sort()

        if zone_obj.parent is not None and not zone_obj.get_auth_or_designated_servers(
        ).difference(zone_obj.parent.get_auth_or_designated_servers()):
            no_non_auth_parent_msg = 'All %s servers are also authoritative for %s' % (
                fmt.humanize_name(
                    zone_obj.parent_name()), fmt.humanize_name(zone_obj.name))
        else:
            no_non_auth_parent_msg = None
        #XXX need something equivalent here for lack of authoritative response for NS
        show_msg = False

        ips_from_child = zone_obj.get_servers_in_child()
        ips_from_parent = zone_obj.get_servers_in_parent()

        for name in all_names_list:
            if zone_obj.parent is not None:
                in_bailiwick = name.is_subdomain(zone_obj.parent_name())
                glue_required = name.is_subdomain(zone_obj.name)
            else:
                in_bailiwick = None
                glue_required = None
            parent_status = {
                'in_bailiwick': in_bailiwick,
                'glue_required': glue_required
            }

            row = []
            row.append(fmt.humanize_name(name))
            # (t/f in parent), (glue IPs (or error, if missing)), (real IPs)
            if zone_obj.get_ns_names_in_parent():
                glue_mapping = zone_obj.get_glue_ip_mapping()
                parent_status['in_parent'] = name in glue_mapping
                glue_ips_v4 = filter(lambda x: x.version == 4,
                                     glue_mapping.get(name, set()))
                glue_ips_v4.sort()
                glue_ips_v6 = filter(lambda x: x.version == 6,
                                     glue_mapping.get(name, set()))
                glue_ips_v6.sort()
            else:
                glue_ips_v4 = []
                glue_ips_v6 = []
                if zone_obj.delegation_status == Status.DELEGATION_STATUS_INCOMPLETE:
                    parent_status['in_parent'] = False
                else:
                    parent_status['in_parent'] = None
                    show_msg = True

            row.append({
                'parent_status': parent_status,
                'glue_ips_v4': glue_ips_v4,
                'glue_ips_v6': glue_ips_v6
            })

            # (t/f in parent), (glue IPs (or error, if missing)), (real IPs)
            names_in_child = zone_obj.get_ns_names_in_child()
            if names_in_child:
                in_child = name in zone_obj.get_ns_names_in_child()
            #XXX
            #elif zone_obj.get_servers_authoritative_for_query(zone_obj.name, dns.rdatatype.NS):
            #    in_child = None
            else:
                in_child = False

            auth_mapping = zone_obj.get_auth_ns_ip_mapping()
            auth_ips_v4 = filter(lambda x: x.version == 4,
                                 auth_mapping.get(name, set()))
            auth_ips_v4.sort()
            auth_ips_v6 = filter(lambda x: x.version == 6,
                                 auth_mapping.get(name, set()))
            auth_ips_v6.sort()

            row.append({
                'in_child': in_child,
                'auth_ips_v4': auth_ips_v4,
                'auth_ips_v6': auth_ips_v6
            })
            delegation_matrix.append(row)

        stealth_matrix = []
        stealth_rows = []
        for server in zone_obj.get_stealth_servers():
            names, ancestor_zone = zone_obj.get_ns_name_for_ip(server)
            stealth_rows.append((ancestor_zone, names, server))
        stealth_rows.sort(cmp=stealth_cmp)

        for ancestor_zone, names, server in stealth_rows:
            names = map(fmt.humanize_name, names)
            if ancestor_zone is not None:
                ancestor_zone = fmt.humanize_name(ancestor_zone)
            row = (names, ancestor_zone, server)
            stealth_matrix.append(row)

        return render_to_response('servers.html', {
            'name_obj': name_obj,
            'timestamp': timestamp,
            'url_subdir': url_subdir,
            'title': name_obj,
            'date_form': date_form,
            'zone_obj': zone_obj,
            'delegation': delegation_matrix,
            'stealth': stealth_matrix,
            'no_non_auth_parent_msg': no_non_auth_parent_msg,
            'show_msg': show_msg,
            'ips_from_parent': ips_from_parent,
            'ips_from_child': ips_from_child
        },
                                  context_instance=RequestContext(request))
コード例 #16
0
ファイル: probe.py プロジェクト: edmonds/dnsviz
def name_addr_mappings_from_string(mappings):
    mappings_set = set()
    mappings = mappings.split(',')
    i = 1
    for mapping in mappings:
        try:
            name, addr = mapping.rsplit('=', 1)
        except ValueError:
            # first see if it's a plain IP address
            try:
                addr = IPAddr(mapping.strip())
            except ValueError:
                # if not, then assign name to mapping
                name = mapping
                addr = None
            else:
                # if it's an IP with no name specified, then create
                # a name
                name = 'ns%d' % i
                i += 1
        else:
            addr = addr.strip()
        name = name.strip()
        try:
            name = dns.name.from_text(name)
        except dns.exception.DNSException:
            usage('The domain name was invalid: "%s"' % name)
            sys.exit(1)

        # no address is provided, so query A/AAAA records for the name
        if addr is None:
            query_tuples = ((name, dns.rdatatype.A, dns.rdataclass.IN), (name, dns.rdatatype.AAAA, dns.rdataclass.IN))
            answer_map = resolver.query_multiple_for_answer(*query_tuples)
            found_answer = False
            for a in answer_map.values():
                if isinstance(a, DNSAnswer):
                    found_answer = True
                    for a_rr in a.rrset:
                        mappings_set.add((name, IPAddr(a_rr.to_text())))
                # negative responses
                elif isinstance(a, (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer)):
                    pass
                # error responses
                elif isinstance(a, (dns.exception.Timeout, dns.resolver.NoNameservers)):
                    usage('There was an error resolving "%s".  Please specify an address or use a name that resolves properly.' % fmt.humanize_name(name))
                    sys.exit(1)

            if not found_answer:
                usage('"%s" did not resolve to an address.  Please specify an address or use a name that resolves properly.' % fmt.humanize_name(name))
                sys.exit(1)

        # otherwise, add the address
        elif not addr:
            usage('No IP address was supplied.')
            sys.exit(1)
        else:
            if addr and addr[0] == '[' and addr[-1] == ']':
                addr = addr[1:-1]
            try:
                addr = IPAddr(addr)
            except ValueError:
                usage('The IP address was invalid: "%s"' % addr)
                sys.exit(1)
            mappings_set.add((name, addr))
    return mappings_set
コード例 #17
0
def name_addr_mappings_from_string(mappings):
    mappings_set = set()
    mappings = mappings.split(',')
    i = 1
    for mapping in mappings:
        try:
            name, addr = mapping.rsplit('=', 1)
        except ValueError:
            # first see if it's a plain IP address
            try:
                addr = IPAddr(mapping.strip())
            except ValueError:
                # if not, then assign name to mapping
                name = mapping
                addr = None
            else:
                # if it's an IP with no name specified, then create
                # a name
                name = 'ns%d' % i
                i += 1
        else:
            addr = addr.strip()
        name = name.strip()
        try:
            name = dns.name.from_text(name)
        except dns.exception.DNSException:
            usage('The domain name was invalid: "%s"' % name)
            sys.exit(1)

        # no address is provided, so query A/AAAA records for the name
        if addr is None:
            query_tuples = ((name, dns.rdatatype.A, dns.rdataclass.IN), (name, dns.rdatatype.AAAA, dns.rdataclass.IN))
            answer_map = resolver.query_multiple_for_answer(*query_tuples)
            found_answer = False
            for a in answer_map.values():
                if isinstance(a, DNSAnswer):
                    found_answer = True
                    for a_rr in a.rrset:
                        mappings_set.add((name, IPAddr(a_rr.to_text())))
                # negative responses
                elif isinstance(a, (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer)):
                    pass
                # error responses
                elif isinstance(a, (dns.exception.Timeout, dns.resolver.NoNameservers)):
                    usage('There was an error resolving "%s".  Please specify an address or use a name that resolves properly.' % fmt.humanize_name(name))
                    sys.exit(1)

            if not found_answer:
                usage('"%s" did not resolve to an address.  Please specify an address or use a name that resolves properly.' % fmt.humanize_name(name))
                sys.exit(1)

        # otherwise, add the address
        elif not addr:
            usage('No IP address was supplied.')
            sys.exit(1)
        else:
            if addr and addr[0] == '[' and addr[-1] == ']':
                addr = addr[1:-1]
            try:
                addr = IPAddr(addr)
            except ValueError:
                usage('The IP address was invalid: "%s"' % addr)
                sys.exit(1)
            mappings_set.add((name, addr))
    return mappings_set
コード例 #18
0
ファイル: forms.py プロジェクト: pecharmin/dnsvizwww
        def clean_explicit_delegation(self):
            resolver = Resolver.from_file("/etc/resolv.conf", StandardRecursiveQueryCD)

            s = self.cleaned_data["explicit_delegation"]
            mappings = set()
            i = 1
            for line in s.splitlines():
                line = line.strip()
                if not line:
                    continue
                # get ride of extra columns
                cols = line.split()
                if len(cols) > 1:
                    line = "%s %s" % (cols[0], cols[-1])
                try:
                    name, addr = line.split()
                except ValueError:
                    # first see if it's a plain IP address
                    try:
                        addr = IPAddr(line.strip())
                    except ValueError:
                        # if not, then assign name to mapping
                        name = line
                        addr = None
                    else:
                        # if it's an IP with no name specified, then create
                        # a name
                        name = "ns%d" % i
                        i += 1
                try:
                    name = dns.name.from_text(name)
                except:
                    raise forms.ValidationError('The domain name was invalid: "%s"' % name)

                # no address is provided, so query A/AAAA records for the name
                if addr is None:
                    query_tuples = (
                        (name, dns.rdatatype.A, dns.rdataclass.IN),
                        (name, dns.rdatatype.AAAA, dns.rdataclass.IN),
                    )
                    answer_map = resolver.query_multiple_for_answer(*query_tuples)
                    found_answer = False
                    for a in answer_map.values():
                        if isinstance(a, DNSAnswer):
                            found_answer = True
                            for a_rr in a.rrset:
                                mappings.add((name, IPAddr(a_rr.to_text())))
                        # negative responses
                        elif isinstance(a, (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer)):
                            pass
                        # error responses
                        elif isinstance(a, (dns.exception.Timeout, dns.resolver.NoNameservers)):
                            raise forms.ValidationError(
                                'There was an error resolving "%s".  Please specify an address or use a name that resolves properly.'
                                % fmt.humanize_name(name)
                            )

                    if not found_answer:
                        raise forms.ValidationError(
                            '"%s" did not resolve to an address.  Please specify an address or use a name that resolves properly.'
                            % fmt.humanize_name(name)
                        )

                # otherwise, add the address
                else:
                    if addr and addr[0] == "[" and addr[-1] == "]":
                        addr = addr[1:-1]
                    try:
                        addr = IPAddr(addr)
                    except ValueError:
                        raise forms.ValidationError('The IP address was invalid: "%s"' % addr)
                    mappings.add((name, addr))

            # if there something in the box, yet no mappings resulted, then raise a
            # validation error
            if self.cleaned_data["explicit_delegation"] and not mappings:
                raise forms.ValidationError("Unable to process address records!")

            return mappings
コード例 #19
0
ファイル: forms.py プロジェクト: pecharmin/dnsvizwww
def domain_analysis_form(name):
    ANCESTOR_CHOICES = [(name.to_text(), fmt.humanize_name(name, True))]
    n = name
    while n != dns.name.root:
        n = n.parent()
        ANCESTOR_CHOICES.append((n.to_text(), fmt.humanize_name(n, True)))
    ANCESTOR_CHOICES.reverse()

    class DomainNameAnalysisForm(forms.Form):
        EXTRA_TYPES = (
            (dns.rdatatype.A, dns.rdatatype.to_text(dns.rdatatype.A)),
            (dns.rdatatype.AAAA, dns.rdatatype.to_text(dns.rdatatype.AAAA)),
            (dns.rdatatype.TXT, dns.rdatatype.to_text(dns.rdatatype.TXT)),
            (dns.rdatatype.PTR, dns.rdatatype.to_text(dns.rdatatype.PTR)),
            (dns.rdatatype.MX, dns.rdatatype.to_text(dns.rdatatype.MX)),
            (dns.rdatatype.SOA, dns.rdatatype.to_text(dns.rdatatype.SOA)),
            (dns.rdatatype.CNAME, dns.rdatatype.to_text(dns.rdatatype.CNAME)),
            (dns.rdatatype.SRV, dns.rdatatype.to_text(dns.rdatatype.SRV)),
            (dns.rdatatype.NAPTR, dns.rdatatype.to_text(dns.rdatatype.NAPTR)),
            (dns.rdatatype.TLSA, dns.rdatatype.to_text(dns.rdatatype.TLSA)),
        )

        ANALYSIS_TYPES = (
            (ANALYSIS_TYPE_AUTHORITATIVE, "Authoritative servers"),
            (ANALYSIS_TYPE_RECURSIVE, "Recursive servers"),
        )

        force_ancestor = forms.TypedChoiceField(
            label="Force ancestor analysis",
            choices=ANCESTOR_CHOICES,
            initial=name.to_text(),
            required=True,
            coerce=dns.name.from_text,
            help_text="Usually it is sufficient to select the name itself (%s) or its zone, in which case cached values will be used for the analysis of any ancestor names (unless it is determined that they are out of date).  Occasionally it is useful to re-analyze some portion of the ancestry, in which case the desired ancestor can be selected.  However, the overall analysis will take longer."
            % (fmt.humanize_name(name, True)),
        )
        extra_types = forms.TypedMultipleChoiceField(
            choices=EXTRA_TYPES,
            initial=(),
            required=False,
            coerce=int,
            help_text="Select any extra RR types to query as part of this analysis.  A default set of types will already be queried based on the nature of the name, but any types selected here will assuredly be included.",
        )
        edns_diagnostics = forms.BooleanField(
            label="EDNS diagnostics",
            initial=False,
            required=False,
            help_text="Issue queries specific to EDNS diagnostics.",
        )
        explicit_delegation = forms.CharField(
            initial="",
            required=False,
            widget=forms.Textarea(attrs={"cols": 50, "rows": 5}),
            help_text='If you wish to designate servers explicitly for the "force ancestor" zone (rather than following delegation from the IANA root), enter the server names, one per line.  You may optionally include an IPv4 or IPv6 address on the same line as the name.',
        )
        analysis_type = forms.TypedChoiceField(
            choices=ANALYSIS_TYPES,
            initial=ANALYSIS_TYPE_AUTHORITATIVE,
            coerce=int,
            widget=forms.RadioSelect(),
            help_text="If authoritative analysis is selected, then the authoritative servers will be analyzed, beginning at the root servers--or the servers explicitly designated; if recursive analysis is selected, then the designated recursive servers will be analyzed.",
        )

        def clean(self):
            cleaned_data = super(DomainNameAnalysisForm, self).clean()
            if cleaned_data.get("analysis_type", None) == ANALYSIS_TYPE_RECURSIVE and not cleaned_data.get(
                "explicit_delegation", None
            ):
                raise forms.ValidationError(
                    "If recursive analysis is desired, then servers names and/or addresses must be specified."
                )
            return cleaned_data

        def clean_explicit_delegation(self):
            resolver = Resolver.from_file("/etc/resolv.conf", StandardRecursiveQueryCD)

            s = self.cleaned_data["explicit_delegation"]
            mappings = set()
            i = 1
            for line in s.splitlines():
                line = line.strip()
                if not line:
                    continue
                # get ride of extra columns
                cols = line.split()
                if len(cols) > 1:
                    line = "%s %s" % (cols[0], cols[-1])
                try:
                    name, addr = line.split()
                except ValueError:
                    # first see if it's a plain IP address
                    try:
                        addr = IPAddr(line.strip())
                    except ValueError:
                        # if not, then assign name to mapping
                        name = line
                        addr = None
                    else:
                        # if it's an IP with no name specified, then create
                        # a name
                        name = "ns%d" % i
                        i += 1
                try:
                    name = dns.name.from_text(name)
                except:
                    raise forms.ValidationError('The domain name was invalid: "%s"' % name)

                # no address is provided, so query A/AAAA records for the name
                if addr is None:
                    query_tuples = (
                        (name, dns.rdatatype.A, dns.rdataclass.IN),
                        (name, dns.rdatatype.AAAA, dns.rdataclass.IN),
                    )
                    answer_map = resolver.query_multiple_for_answer(*query_tuples)
                    found_answer = False
                    for a in answer_map.values():
                        if isinstance(a, DNSAnswer):
                            found_answer = True
                            for a_rr in a.rrset:
                                mappings.add((name, IPAddr(a_rr.to_text())))
                        # negative responses
                        elif isinstance(a, (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer)):
                            pass
                        # error responses
                        elif isinstance(a, (dns.exception.Timeout, dns.resolver.NoNameservers)):
                            raise forms.ValidationError(
                                'There was an error resolving "%s".  Please specify an address or use a name that resolves properly.'
                                % fmt.humanize_name(name)
                            )

                    if not found_answer:
                        raise forms.ValidationError(
                            '"%s" did not resolve to an address.  Please specify an address or use a name that resolves properly.'
                            % fmt.humanize_name(name)
                        )

                # otherwise, add the address
                else:
                    if addr and addr[0] == "[" and addr[-1] == "]":
                        addr = addr[1:-1]
                    try:
                        addr = IPAddr(addr)
                    except ValueError:
                        raise forms.ValidationError('The IP address was invalid: "%s"' % addr)
                    mappings.add((name, addr))

            # if there something in the box, yet no mappings resulted, then raise a
            # validation error
            if self.cleaned_data["explicit_delegation"] and not mappings:
                raise forms.ValidationError("Unable to process address records!")

            return mappings

    return DomainNameAnalysisForm