def zone_for_name(name, rdclass=dns.rdataclass.IN, tcp=False, resolver=None): """Find the name of the zone which contains the specified name. @param name: the query name @type name: absolute dns.name.Name object or string @param rdclass: The query class @type rdclass: int @param tcp: use TCP to make the query (default is False). @type tcp: bool @param resolver: the resolver to use @type resolver: dns.resolver.Resolver object or None @rtype: dns.name.Name""" if isinstance(name, basestring): name = dns.name.from_text(name, dns.name.root) if resolver is None: resolver = get_default_resolver() if not name.is_absolute(): raise NotAbsolute(name) while 1: try: answer = resolver.query(name, dns.rdatatype.SOA, rdclass, tcp) if answer.rrset.name == name: return name # otherwise we were CNAMEd or DNAMEd and need to look higher except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer): pass try: name = name.parent() except dns.name.NoParent: raise NoRootSOA
def zone_for_name(name, rdclass=dns.rdataclass.IN, tcp=False, resolver=None): """Find the name of the zone which contains the specified name. @param name: the query name @type name: absolute dns.name.Name object or string @param rdclass: The query class @type rdclass: int @param tcp: use TCP to make the query (default is False). @type tcp: bool @param resolver: the resolver to use @type resolver: dns.resolver.Resolver object or None @rtype: dns.name.Name""" if isinstance(name, (str, unicode)): name = dns.name.from_text(name, dns.name.root) if resolver is None: resolver = get_default_resolver() if not name.is_absolute(): raise NotAbsolute(name) while 1: try: answer = resolver.query(name, dns.rdatatype.SOA, rdclass, tcp) if answer.rrset.name == name: return name # otherwise we were CNAMEd or DNAMEd and need to look higher except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer): pass try: name = name.parent() except dns.name.NoParent: raise NoRootSOA
def _validate_name(self, name): if name.is_absolute(): if not name.is_subdomain(self.zone.origin): raise KeyError("name is not a subdomain of the zone origin") if self.zone.relativize: name = name.relativize(self.origin) return name
def _validate_name(self, name): if name.is_absolute(): if not name.is_subdomain(self.zone.origin): raise KeyError("name is not a subdomain of the zone origin") if self.zone.relativize: # XXXRTH should it be an error if self.origin is still None? name = name.relativize(self.origin) return name
def _check_record_name(name, my_zones): """Check whether a given name is in one of the zones managed by Jinx.""" if not name.is_absolute(): raise JinxInvalidRequestError("Record names must be absolute (including trailing dot): %s" % str(name)) if _get_zone(name, my_zones) is None: raise JinxInvalidRequestError("Update received for a zone not managed by Jinx: %s" % str(name))
def _validate_name(self, name): if isinstance(name, (str, unicode)): name = dns.name.from_text(name, None) elif not isinstance(name, dns.name.Name): raise KeyError("name parameter must be convertable to a DNS name") if name.is_absolute(): if not name.is_subdomain(self.origin): raise KeyError("name parameter must be a subdomain of the zone origin") if self.relativize: name = name.relativize(self.origin) return name
def assert_absolute_dnsname(name): """Raise AssertionError if name is not DNSName or is not absolute. >>> assert_absolute_dnsname(DNSName('absolute.name.example.')) >>> assert_absolute_dnsname(DNSName('relative.name.example')) Traceback (most recent call last): ... AssertionError: name must be absolute, ... >>> assert_absolute_dnsname('absolute.string.example.') Traceback (most recent call last): ... AssertionError: name must be DNSName instance, ... """ assert isinstance(name, DNSName), ("name must be DNSName instance, " "got '%s'" % type(name)) assert name.is_absolute(), "name must be absolute, got '%s'" % name
def _validate_name(self, name: dns.name.Name) -> dns.name.Name: if name.is_absolute(): if self.origin is None: # This should probably never happen as other code (e.g. # _rr_line) will notice the lack of an origin before us, but # we check just in case! raise KeyError("no zone origin is defined") if not name.is_subdomain(self.origin): raise KeyError("name is not a subdomain of the zone origin") if self.zone.relativize: name = name.relativize(self.origin) elif not self.zone.relativize: # We have a relative name in a non-relative zone, so derelativize. if self.origin is None: raise KeyError("no zone origin is defined") name = name.derelativize(self.origin) return name
def _validate_name(self, name): if isinstance(name, str): name = dns.name.from_text(name, None) elif not isinstance(name, dns.name.Name): raise KeyError("name parameter must be convertible to a DNS name") if name.is_absolute(): if not name.is_subdomain(self.origin): raise KeyError( "name parameter must be a subdomain of the zone origin") if self.relativize: name = name.relativize(self.origin) elif not self.relativize: # We have a relative name in a non-relative zone, so derelativize. if self.origin is None: raise KeyError('no zone origin is defined') name = name.derelativize(self.origin) return name
def _validate_name(self, name: Union[dns.name.Name, str]) -> dns.name.Name: if isinstance(name, str): name = dns.name.from_text(name, None) elif not isinstance(name, dns.name.Name): raise KeyError("name parameter must be convertible to a DNS name") if name.is_absolute(): if self.origin is None: # This should probably never happen as other code (e.g. # _rr_line) will notice the lack of an origin before us, but # we check just in case! raise KeyError("no zone origin is defined") if not name.is_subdomain(self.origin): raise KeyError( "name parameter must be a subdomain of the zone origin") if self.relativize: name = name.relativize(self.origin) elif not self.relativize: # We have a relative name in a non-relative zone, so derelativize. if self.origin is None: raise KeyError("no zone origin is defined") name = name.derelativize(self.origin) return name
def zone_for_name(name, rdclass=dns.rdataclass.IN, tcp=False, resolver=None): """Find the name of the zone which contains the specified name. *name*, an absolute ``dns.name.Name`` or ``text``, the query name. *rdclass*, an ``int``, the query class. *tcp*, a ``bool``. If ``True``, use TCP to make the query. *resolver*, a ``dns.resolver.Resolver`` or ``None``, the resolver to use. If ``None``, the default resolver is used. Raises ``dns.resolver.NoRootSOA`` if there is no SOA RR at the DNS root. (This is only likely to happen if you're using non-default root servers in your network and they are misconfigured.) Returns a ``dns.name.Name``. """ if isinstance(name, str): name = dns.name.from_text(name, dns.name.root) if resolver is None: resolver = get_default_resolver() if not name.is_absolute(): raise NotAbsolute(name) while 1: try: answer = resolver.query(name, dns.rdatatype.SOA, rdclass, tcp) if answer.rrset.name == name: return name # otherwise we were CNAMEd or DNAMEd and need to look higher except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer): pass try: name = name.parent() except dns.name.NoParent: raise NoRootSOA
async def zone_for_name( name: Union[dns.name.Name, str], rdclass: dns.rdataclass.RdataClass = dns.rdataclass.IN, tcp: bool = False, resolver: Optional[Resolver] = None, backend: Optional[dns.asyncbackend.Backend] = None, ) -> dns.name.Name: """Find the name of the zone which contains the specified name. See :py:func:`dns.resolver.Resolver.zone_for_name` for more information on the parameters and possible exceptions. """ if isinstance(name, str): name = dns.name.from_text(name, dns.name.root) if resolver is None: resolver = get_default_resolver() if not name.is_absolute(): raise NotAbsolute(name) while True: try: answer = await resolver.resolve(name, dns.rdatatype.SOA, rdclass, tcp, backend=backend) assert answer.rrset is not None if answer.rrset.name == name: return name # otherwise we were CNAMEd or DNAMEd and need to look higher except (NXDOMAIN, NoAnswer): pass try: name = name.parent() except dns.name.NoParent: # pragma: no cover raise NoRootSOA
def resolve(self, name, response): assert not name.is_absolute() or name.is_subdomain(self.origin) _logger = logging.getLogger(__name__) #_logger.debug('Enter ODUPPolicyRealm.resolve(): name: %s' % (name)) # make sure name is relative to origin if name.is_absolute(): name = name.relativize(self.origin) if self.origin == dns.name.root: origin = '' else: origin = self.origin.to_text() # check for org/bound directives in names in ancestry longest_match = None longest_match_boundary = None existing_labels = 0 for i in range(len(name) + 1): if i == 0: test_domain = dns.name.empty wildcard_name = None else: test_domain = dns.name.Name(name[-i:]) wildcard_name = dns.name.from_text('*', test_domain.parent()) test_domain_qualified = dns.name.Name(test_domain.labels + ('_odup',) + self.origin.labels) policy = None # Name exists; check for policy if test_domain in self._policies: if i > 0: existing_labels += 1 if self._policies[test_domain] is not None: _logger.debug('%s/TXT: NOERROR (local): %s' % (test_domain_qualified, self._policies[test_domain])) policy = self._policies[test_domain] response.add_query(test_domain_qualified, dns.rcode.NOERROR, policy) else: # It's effectively a NODATA response _logger.debug('%s/TXT: NODATA (local)' % (test_domain_qualified)) response.add_query(test_domain_qualified, dns.rcode.NOERROR, None) pass # Name doesn't exist; check for wildcard elif wildcard_name in self._policies and self._policies[wildcard_name] is not None: _logger.debug('%s/TXT: NOERROR (wildcard local): %s' % (test_domain_qualified, self._policies[wildcard_name])) existing_labels += 1 policy = self._policies[wildcard_name] response.add_query(test_domain_qualified, dns.rcode.NOERROR, policy) # Effective NXDOMAIN: # An NXDOMAIN result means that no further lookups are # necessary, as there is no subtree else: _logger.debug('%s/TXT: NXDOMAIN (local)' % (test_domain_qualified)) response.add_query(test_domain_qualified, dns.rcode.NXDOMAIN, None) break if policy is not None: org_match = ORG_RE.search(policy) bound_match = BOUND_RE.search(policy) # Update longestMatch by giving org and bound highest # priority and ignoring policy statements below "bound". if org_match is not None or bound_match is not None or \ (longest_match is None or BOUND_RE.search(longest_match) is None): longest_match = policy longest_match_boundary = i # If this was a organizational domain designation, # then don't go any further; the organization will # dictate policy if org_match is not None: break # If this was a boundary designation, and the answer # was synthesized from a wildcard, no further # lookups must be performed if bound_match is not None and \ bound_match.group('labels') is not None and \ int(bound_match.group('labels')) < i + 1: break # Effective NODATA response else: pass if longest_match is not None: # If a policy has been found, then look for +org or +bound # directives, which will cause org names to be returned. # A +org directive indicates that the organizational domain and # policy are (at least) one level lower than the value of # longestMatchBoundary. if ORG_RE.search(longest_match) is not None: org_domain = dns.name.Name(name[-(longest_match_boundary+1):]).derelativize(self.origin) response.set_policy(None, org_domain, None) return response # A +bound directive indicates that the organizational domain # and policy are (at least) one level lower than the value of # longestExistingBoundary. if BOUND_RE.search(longest_match) is not None and \ existing_labels + 1 <= len(name): org_domain = dns.name.Name(name[-(existing_labels+1):]).derelativize(self.origin) response.set_policy(None, org_domain, None) return response # With no +org or +bound directives present, the orgDomain and # policy remain as they were looked up, and are returned with # the policy domain policy_domain = dns.name.Name(name[-(longest_match_boundary+1):]).derelativize(self.origin) response.set_policy(policy_domain, self.origin, longest_match) return response else: # Otherwise, return the policy for the orgDomain response.set_policy(None, self.origin, None) return response