diff --git a/ldns-1.6.13-readzone.patch b/ldns-1.6.13-readzone.patch deleted file mode 100644 index e126474..0000000 --- a/ldns-1.6.13-readzone.patch +++ /dev/null @@ -1,156 +0,0 @@ -diff --git a/examples/ldns-read-zone.1 b/examples/ldns-read-zone.1 -index 81f238d..7d4fd7d 100644 ---- a/examples/ldns-read-zone.1 -+++ b/examples/ldns-read-zone.1 -@@ -22,6 +22,12 @@ that is not of type NSEC, NSEC3, RRSIG or DNSKEY. DS records are not - printed. - - .TP -+\fB-0\fR -+Print a 0 for the RRSIG inception, expiry and key data. This option -+can be used when comparing different signing systems that use the same -+DNSKEYs for signing but would have a slightly different timings/jitter. -+ -+.TP - \fB-h\fR - Show usage and exit - -@@ -30,6 +36,11 @@ Show usage and exit - Do not print the SOA record - - .TP -+\fB-p\fR -+Pad the SOA serial number with spaces so the number and the spaces together -+take ten characters. This is useful for in file serial number increments -+ that want to use mmap() -+.TP - \fB-s\fR - Strip DNSSEC data from the zone. This option skips every record - that is of type NSEC, NSEC3, RRSIG or DNSKEY. DS records are still -diff --git a/examples/ldns-read-zone.c b/examples/ldns-read-zone.c -index ac32bac..df2b2c2 100644 ---- a/examples/ldns-read-zone.c -+++ b/examples/ldns-read-zone.c -@@ -33,14 +33,23 @@ main(int argc, char **argv) - ldns_rr_list *stripped_list; - ldns_rr *cur_rr; - ldns_rr_type cur_rr_type; -- const ldns_output_format *fmt = NULL; -+ ldns_output_format fmt = { -+ ldns_output_format_default->flags, -+ ldns_output_format_default->data -+ }; - ldns_soa_serial_increment_func_t soa_serial_increment_func = NULL; - int soa_serial_increment_func_data = 0; - -- while ((c = getopt(argc, argv, "bcdhnsvzS:")) != -1) { -+ while ((c = getopt(argc, argv, "0bcdhnpsvzS:")) != -1) { - switch(c) { - case 'b': -- fmt = ldns_output_format_bubblebabble; -+ fmt.flags |= -+ ( LDNS_COMMENT_BUBBLEBABBLE | -+ LDNS_COMMENT_FLAGS ); -+ break; -+ case '0': -+ fmt.flags |= LDNS_FMT_ZEROIZE_RRSIGS; -+ break; - case 'c': - canonicalize = true; - break; -@@ -55,10 +64,13 @@ main(int argc, char **argv) - printf("\tReads the zonefile and prints it.\n"); - printf("\tThe RR count of the zone is printed to stderr.\n"); - printf("\t-b include bubblebabble of DS's.\n"); -+ printf("\t-0 zeroize timestamps and signature in RRSIG records.\n"); - printf("\t-c canonicalize all rrs in the zone.\n"); - printf("\t-d only show DNSSEC data from the zone\n"); - printf("\t-h show this text\n"); - printf("\t-n do not print the SOA record\n"); -+ printf("\t-p prepend SOA serial with spaces so" -+ " it takes exactly ten characters.\n"); - printf("\t-s strip DNSSEC data from the zone\n"); - printf("\t-S [[+|-] | YYYYMMDDxx | " - " unixtime ]\n" -@@ -80,6 +92,9 @@ main(int argc, char **argv) - case 'n': - print_soa = false; - break; -+ case 'p': -+ fmt.flags |= LDNS_FMT_PAD_SOA_SERIAL; -+ break; - case 's': - strip = true; - if (only_dnssec) { -@@ -195,9 +210,9 @@ main(int argc, char **argv) - , soa_serial_increment_func_data - ); - } -- ldns_rr_print_fmt(stdout, fmt, ldns_zone_soa(z)); -+ ldns_rr_print_fmt(stdout, &fmt, ldns_zone_soa(z)); - } -- ldns_rr_list_print_fmt(stdout, fmt, ldns_zone_rrs(z)); -+ ldns_rr_list_print_fmt(stdout, &fmt, ldns_zone_rrs(z)); - - ldns_zone_deep_free(z); - } else { -diff --git a/host2str.c b/host2str.c -index 636d80d..2ec8ae1 100644 ---- a/host2str.c -+++ b/host2str.c -@@ -123,6 +123,7 @@ const ldns_output_format *ldns_output_format_onlykeyids - = &ldns_output_format_onlykeyids_record; - const ldns_output_format *ldns_output_format_default - = &ldns_output_format_onlykeyids_record; -+ - const ldns_output_format ldns_output_format_bubblebabble_record = { - LDNS_COMMENT_KEY | LDNS_COMMENT_BUBBLEBABBLE | LDNS_COMMENT_FLAGS, NULL - }; -@@ -1231,7 +1232,33 @@ ldns_rr2buffer_str_fmt(ldns_buffer *output, - - for (i = 0; i < ldns_rr_rd_count(rr); i++) { - /* ldns_rdf2buffer_str handles NULL input fine! */ -- status = ldns_rdf2buffer_str(output, ldns_rr_rdf(rr, i)); -+ if ((fmt->flags & LDNS_FMT_ZEROIZE_RRSIGS) && -+ (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) && -+ ((/* inception */ i == 4 && -+ ldns_rdf_get_type(ldns_rr_rdf(rr, 4)) == -+ LDNS_RDF_TYPE_TIME) || -+ (/* expiration */ i == 5 && -+ ldns_rdf_get_type(ldns_rr_rdf(rr, 5)) == -+ LDNS_RDF_TYPE_TIME) || -+ (/* signature */ i == 8 && -+ ldns_rdf_get_type(ldns_rr_rdf(rr, 8)) == -+ LDNS_RDF_TYPE_B64))) { -+ -+ ldns_buffer_printf(output, "0"); -+ status = ldns_buffer_status(output); -+ } else if ((fmt->flags & LDNS_FMT_PAD_SOA_SERIAL) && -+ (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) && -+ /* serial */ i == 2 && -+ ldns_rdf_get_type(ldns_rr_rdf(rr, 2)) == -+ LDNS_RDF_TYPE_INT32) { -+ ldns_buffer_printf(output, "%10lu", -+ (unsigned long) ldns_read_uint32( -+ ldns_rdf_data(ldns_rr_rdf(rr, 2)))); -+ status = ldns_buffer_status(output); -+ } else { -+ status = ldns_rdf2buffer_str(output, -+ ldns_rr_rdf(rr, i)); -+ } - if(status != LDNS_STATUS_OK) - return status; - if (i < ldns_rr_rd_count(rr) - 1) { -diff --git a/ldns/host2str.h b/ldns/host2str.h -index f0a14a4..32cdd60 100644 ---- a/ldns/host2str.h -+++ b/ldns/host2str.h -@@ -64,6 +64,8 @@ extern "C" { - #define LDNS_COMMENT_LAYOUT 0x0080 - /** Also comment KEY_ID with RRSIGS **/ - #define LDNS_COMMENT_RRSIGS 0x0100 -+#define LDNS_FMT_ZEROIZE_RRSIGS 0x0200 -+#define LDNS_FMT_PAD_SOA_SERIAL 0x0400 - - /** - * Output format specifier diff --git a/ldns-fragmentdrop.patch b/ldns-fragmentdrop.patch deleted file mode 100644 index 0305016..0000000 --- a/ldns-fragmentdrop.patch +++ /dev/null @@ -1,70 +0,0 @@ -Index: resolver.c -=================================================================== ---- resolver.c (revision 3550) -+++ resolver.c (revision 3551) -@@ -1031,12 +1031,41 @@ - return pkt; - } - -+static size_t * -+ldns_resolver_backup_rtt(ldns_resolver *r) -+{ -+ size_t *new_rtt; -+ size_t *old_rtt = ldns_resolver_rtt(r); -+ -+ if (old_rtt && ldns_resolver_nameserver_count(r)) { -+ new_rtt = LDNS_XMALLOC(size_t -+ , ldns_resolver_nameserver_count(r)); -+ memcpy(new_rtt, old_rtt, sizeof(size_t) -+ * ldns_resolver_nameserver_count(r)); -+ ldns_resolver_set_rtt(r, new_rtt); -+ return old_rtt; -+ } -+ return NULL; -+} -+ -+static void -+ldns_resolver_restore_rtt(ldns_resolver *r, size_t *old_rtt) -+{ -+ size_t *cur_rtt = ldns_resolver_rtt(r); -+ -+ if (cur_rtt) { -+ LDNS_FREE(cur_rtt); -+ } -+ ldns_resolver_set_rtt(r, old_rtt); -+} -+ - ldns_status - ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r, - ldns_pkt *query_pkt) - { - ldns_pkt *answer_pkt = NULL; - ldns_status stat = LDNS_STATUS_OK; -+ size_t *rtt; - - stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt); - if (stat != LDNS_STATUS_OK) { -@@ -1051,9 +1080,21 @@ - if (ldns_pkt_tc(answer_pkt)) { - /* was EDNS0 set? */ - if (ldns_pkt_edns_udp_size(query_pkt) == 0) { -- ldns_pkt_set_edns_udp_size(query_pkt, 4096); -+ ldns_pkt_set_edns_udp_size(query_pkt -+ , 4096); - ldns_pkt_free(answer_pkt); -- stat = ldns_send(&answer_pkt, r, query_pkt); -+ /* Nameservers should not become -+ * unreachable because fragments are -+ * dropped (network error). We might -+ * still have success with TCP. -+ * Therefore maintain reachability -+ * statuses of the nameservers by -+ * backup and restore the rtt list. -+ */ -+ rtt = ldns_resolver_backup_rtt(r); -+ stat = ldns_send(&answer_pkt, r -+ , query_pkt); -+ ldns_resolver_restore_rtt(r, rtt); - } - /* either way, if it is still truncated, use TCP */ - if (stat != LDNS_STATUS_OK || diff --git a/ldns-installfix-r3167.patch b/ldns-installfix-r3167.patch deleted file mode 100644 index 1fbdfc8..0000000 --- a/ldns-installfix-r3167.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- Makefile.in.org 2010-01-22 11:09:15.671232722 -0500 -+++ Makefile.in 2010-01-22 11:10:08.346392415 -0500 -@@ -203,8 +203,8 @@ - - install-pyldns: @PYLDNS@ - $(INSTALL) -m 755 -d $(DESTDIR)$(python_site)/ldns -- $(INSTALL) -c -m 644 $(pywrapdir)/ldns.py $(DESTDIR)$(python_site)/ldns/__init__.py -- $(INSTALL) -c -m 755 _ldns.* $(DESTDIR)$(python_site)/ldns/ -+ $(INSTALL) -c -m 644 $(pywrapdir)/ldns.py $(DESTDIR)$(python_site)/ldns.py -+ $(LIBTOOL) --mode=install cp _ldns.la $(DESTDIR)$(python_site) - - uninstall-pyldns: - rm -f $(DESTDIR)$(python_site)/ldns/* diff --git a/ldns-keygen-hmac-memory.patch b/ldns-keygen-hmac-memory.patch deleted file mode 100644 index 2fa05a7..0000000 --- a/ldns-keygen-hmac-memory.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: keys.c -=================================================================== ---- keys.c (revision 2895) -+++ keys.c (revision 2897) -@@ -1050,7 +1050,7 @@ - case LDNS_SIGN_HMACMD5: - case LDNS_SIGN_HMACSHA1: - case LDNS_SIGN_HMACSHA256: -- bin = LDNS_XMALLOC(unsigned char, size); -+ bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k)); - if (!bin) { - return NULL; - } diff --git a/ldns-rpathfix.patch b/ldns-rpathfix.patch deleted file mode 100644 index ed5b4d1..0000000 --- a/ldns-rpathfix.patch +++ /dev/null @@ -1,23 +0,0 @@ -Index: configure.ac -=================================================================== ---- configure.ac (revision 3167) -+++ configure.ac (working copy) -@@ -163,16 +163,8 @@ - fi - AC_SUBST(INSTALL_LDNS_CONFIG) - --# add option to disable the evil rpath --dnl Check whether to use rpath or not --AC_ARG_ENABLE(rpath, -- [ --disable-rpath disable hardcoded rpath (default=enabled)], -- enable_rpath=$enableval, enable_rpath=yes) -+ACX_ARG_RPATH - --if test "x$enable_rpath" = xyes; then -- RPATH_VAL="-Wl,-rpath=\${libdir}" --fi -- - #AC_TRY_RUN( - #[ - #int main() - diff --git a/ldns-ssl.patch b/ldns-ssl.patch deleted file mode 100644 index 793a83d..0000000 --- a/ldns-ssl.patch +++ /dev/null @@ -1,55 +0,0 @@ -diff -Naur ldns-1.6.0.org/examples/ldns-nsec3-hash.c ldns-1.6.0/examples/ldns-nsec3-hash.c ---- ldns-1.6.0.org/examples/ldns-nsec3-hash.c 2009-07-11 00:09:45.000000000 -0400 -+++ ldns-1.6.0/examples/ldns-nsec3-hash.c 2009-07-11 00:10:13.000000000 -0400 -@@ -16,8 +16,10 @@ - #include - #include - -+#ifdef HAVE_SSL - #include - #include -+#endif - - - #define MAX_FILENAME_LEN 250 -diff -Naur ldns-1.6.0.org/examples/ldns-revoke.c ldns-1.6.0/examples/ldns-revoke.c ---- ldns-1.6.0.org/examples/ldns-revoke.c 2009-07-11 00:10:07.000000000 -0400 -+++ ldns-1.6.0/examples/ldns-revoke.c 2009-07-11 00:10:13.000000000 -0400 -@@ -8,7 +8,9 @@ - #include "config.h" - - #include -+#ifdef HAVE_SSL - #include -+#endif - - #include - -diff -Naur ldns-1.6.0.org/higher.c ldns-1.6.0/higher.c ---- ldns-1.6.0.org/higher.c 2007-08-09 05:03:41.000000000 -0400 -+++ ldns-1.6.0/higher.c 2009-07-11 00:11:55.000000000 -0400 -@@ -15,8 +15,10 @@ - - #include - -+#ifdef HAVE_SSL - #include - #include -+#endif - - - -diff -Naur ldns-1.6.0.org/examples/ldns-signzone.c ldns-1.6.0/examples/ldns-signzone.c ---- ldns-1.6.0.org/examples/ldns-signzone.c 2009-07-09 04:35:25.000000000 -0400 -+++ ldns-1.6.0/examples/ldns-signzone.c 2009-07-13 15:36:31.000000000 -0400 -@@ -16,8 +16,10 @@ - #include - #include - -+#ifdef HAVE_SSL - #include - #include -+#endif - - - #define MAX_FILENAME_LEN 250 diff --git a/ldnsx.py b/ldnsx.py deleted file mode 100644 index d6ddfc9..0000000 --- a/ldnsx.py +++ /dev/null @@ -1,923 +0,0 @@ -# (c) Christopher Olah , 2011. Xelerance . -# License: BSD - - -""" Easy DNS (including DNSSEC) via ldns. - -ldns is a great library. It is a powerfull tool for -working with DNS. python-ldns it is a straight up clone of the C -interface, howver that is not a very good interface for python. Its -documentation is incomplete and some functions don't work as -described. And some objects don't have a full python API. - -ldnsx aims to fix this. It wraps around the ldns python bindings, -working around its limitations and providing a well-documented, more -pythonistic interface. - -**WARNING:** - -**API subject to change.** No backwards compatibility guarantee. Write software using this version at your own risk! - -Examples --------- - -Query the default resolver for google.com's A records. Print the response -packet. - ->>> import ldnsx ->>> resolver = ldnsx.resolver() ->>> print resolver.query("google.com","A") - - -Print the root NS records from f.root-servers.net; if we get a -response, else an error message. - ->>> import ldnsx ->>> pkt = ldnsx.resolver("f.root-servers.net").query(".", "NS") ->>> if pkt: ->>> for rr in pkt.answer(): ->>> print rr ->>> else: ->>> print "response not received" - -""" - -import time, sys, calendar, warnings -try: - import ipcalc -except ImportError: - print >> sys.stderr, "ldnsx requires the python-ipcalc" - print >> sys.stderr, "Fedora/CentOS: yum install python-ipcalc" - print >> sys.stderr, "Debian/Ubuntu: apt-get install python-ipcalc" - print >> sys.stderr, "openSUSE: zypper in python-ipcalc" - sys.exit(1) -try: - import ldns -except ImportError: - print >> sys.stderr, "ldnsx requires the ldns-python sub-package from http://www.nlnetlabs.nl/projects/ldns/" - print >> sys.stderr, "Fedora/CentOS: yum install ldns-python" - print >> sys.stderr, "Debian/Ubuntu: apt-get install python-ldns" - print >> sys.stderr, "openSUSE: zypper in python-ldns" - sys.exit(1) - -__version__ = "0.1" - -def isValidIP(ipaddr): - try: - bits_to_type = { 32 : 4, 128 : 6} - bits = len(ipcalc.IP(ipaddr).bin()) - return bits_to_type[bits] - except: - return 0 - -def query(name, rr_type, rr_class="IN", flags=["RD"], tries = 3, res=None): - """Convenience function. Creates a resolver and then queries it. Refer to resolver.query() - * name -- domain to query for - * rr_type -- rr_type to query for - * flags -- flags for query (list of strings) - * tries -- number of times to retry the query on failure - * res -- configurations for the resolver as a dict -- see resolver() - """ - if isinstance(res, list) or isinstance(res, tuple): - res = resolver(*res) - elif isinstance(res, dict): - res = resolver(**res) - else: - res = resolver(res) - return res.query(name, rr_type, rr_class, flags, tries) - -def get_rrs(name, rr_type, rr_class="IN", tries = 3, strict = False, res=None, **kwds): - """Convenience function. Gets RRs for name of type rr_type trying tries times. - If strict, it raises and exception on failure, otherwise it returns []. - * name -- domain to query for - * rr_type -- rr_type to query for - * flags -- flags for query (list of strings) - * tries -- number of times to retry the query on failure - * strict -- if the query fails, do we return [] or raise an exception? - * res -- configurations for the resolver as a dict -- see resolver() - * kwds -- query filters, refer to packet.answer() - """ - if isinstance(res, list) or isinstance(res, tuple): - res = resolver(*res) - elif isinstance(res, dict): - res = resolver(**res) - else: - res = resolver(res) - if "|" in rr_type: - pkt = res.query(name, "ANY", rr_class=rr_class, tries=tries) - else: - pkt = res.query(name, rr_type, rr_class=rr_class, tries=tries) - if pkt: - if rr_type in ["", "ANY", "*"]: - return pkt.answer( **kwds) - else: - return pkt.answer(rr_type=rr_type, **kwds) - else: - if strict: - raise Exception("LDNS couldn't complete query") - else: - return [] - -def secure_query(name, rr_type, rr_class="IN", flags=["RD"], tries = 1, flex=False, res=None): - """Convenience function. Creates a resolver and then does a DNSSEC query. Refer to resolver.query() - * name -- domain to query for - * rr_type -- rr_type to query for - * flags -- flags for query (list of strings) - * tries -- number of times to retry the query on failure - * flex -- if we can't verify data, exception or warning? - * res -- configurations for the resolver as a dict -- see resolver()""" - if isinstance(res, list) or isinstance(res, tuple): - res = resolver(*res) - elif isinstance(res, dict): - res = resolver(**res) - else: - res = resolver(res) - pkt = res.query(name, rr_type, rr_class, flags, tries) - if pkt.rcode() == "SERVFAIL": - raise Exception("%s lookup failed (server error or dnssec validation failed)" % name) - if pkt.rcode() == "NXDOMAIN": - if "AD" in pkt.flags(): - raise Exception("%s lookup failed (non-existence proven by DNSSEC)" % hostname ) - else: - raise Exception("%s lookup failed" % hostname ) - if pkt.rcode() == "NOERROR": - if "AD" not in pkt.flags(): - if not flex: - raise Exception("DNS lookup was insecure") - else: - warnings.warn("DNS lookup was insecure") - return pkt - else: - raise Exception("unknown ldns error, %s" % pkt.rcode()) - - - -class resolver: - """ A wrapper around ldns.ldns_resolver. - - **Examples** - - Making resolvers is easy! - - >>> from ldnsx import resolver - >>> resolver() # from /etc/resolv.conf - - >>> resolver("") # resolver with no nameservers - - >>> resolver("193.110.157.135") #resolver pointing to ip addr - - >>> resolver("f.root-servers.net") # resolver pointing ip address(es) resolved from name - - >>> resolver("193.110.157.135, 193.110.157.136") - >>> # resolver pointing to multiple ip addr, first takes precedence. - - - So is playing around with their nameservers! - - >>> import ldnsx - >>> res = ldnsx.resolver("192.168.1.1") - >>> res.add_nameserver("192.168.1.2") - >>> res.add_nameserver("192.168.1.3") - >>> res.nameservers_ip() - ["192.168.1.1","192.168.1.2","192.168.1.3"] - - And querying! - - >>> from ldnsx import resolver - >>> res= resolver() - >>> res.query("cow.com","A") - ;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 7663 - ;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 - ;; QUESTION SECTION: - ;; cow.com. IN A - ;; ANSWER SECTION: - cow.com. 300 IN A 208.87.34.18 - ;; AUTHORITY SECTION: - ;; ADDITIONAL SECTION: - ;; Query time: 313 msec - ;; SERVER: 192.168.111.9 - ;; WHEN: Fri Jun 3 11:01:02 2011 - ;; MSG SIZE rcvd: 41 - - - """ - - def __init__(self, ns = None, dnssec = False, tcp = 'auto', port = 53): - """resolver constructor - - * ns -- the nameserver/comma delimited nameserver list - defaults to settings from /etc/resolv.conf - * dnssec -- should the resolver try and use dnssec or not? - * tcp -- should the resolve try to connect with TCP? - 'auto' tries without tcp, and falls back to it - to work around both ldns choking on truncated packets - and nameservers that don't support tcp. - * port -- the port to use, must be the same for all nameservers - - """ - # We construct based on a file and dump the nameservers rather than using - # ldns_resolver_new() to avoid environment/configuration/magic specific - # bugs. - self._ldns_resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") - if ns != None: - self.drop_nameservers() - nm_list = ns.split(',') - nm_list = map(lambda s: s.strip(), nm_list) - nm_list = filter(lambda s: s != "", nm_list) - nm_list.reverse() - for nm in nm_list: - self.add_nameserver(nm) - # Configure DNSSEC, tcp and port - self.set_dnssec(dnssec) - if tcp == 'auto': - self.autotcp = True - self._ldns_resolver.set_usevc(False) - else: - self.autotcp = False - self._ldns_resolver.set_usevc(tcp) - self._ldns_resolver.set_port(port) - - - def query(self, name, rr_type, rr_class="IN", flags=["RD"], tries = 3): - """Run a query on the resolver. - - * name -- name to query for - * rr_type -- the record type to query for - * rr_class -- the class to query for, defaults to IN (Internet) - * flags -- the flags to send the query with - * tries -- the number of times to attempt to acheive query in case of packet loss, etc - - **Examples** - - Let's get some A records! - - >>> google_a_records = resolver.query("google.com","A").answer() - - Using DNSSEC is easy :) - - >>> dnssec_pkt = ldnsx.resolver(dnssec=True).query("xelerance.com") - - We let you use strings to make things easy, but if you prefer stay close to DNS... - - >>> AAAA = 28 - >>> resolver.query("ipv6.google.com", AAAA) - - **More about rr_type** - - rr_type must be a supported resource record type. There are a large number of RR types: - - =========== =================================== ================== - TYPE Value and meaning Reference - =========== =================================== ================== - A 1 a host address [RFC1035] - NS 2 an authoritative name server [RFC1035] - ... - AAAA 28 IP6 Address [RFC3596] - ... - DS 43 Delegation Signer [RFC4034][RFC3658] - ... - DNSKEY 48 DNSKEY [RFC4034][RFC3755] - ... - Unassigned 32770-65279 - Private use 65280-65534 - Reserved 65535 - =========== =================================== ================== - - (From http://www.iana.org/assignments/dns-parameters) - - RR types are given as a string (eg. "A"). In the case of Unassigned/Private use/Reserved ones, - they are given as "TYPEXXXXX" where XXXXX is the number. ie. RR type 65280 is "TYPE65280". You - may also pass the integer, but you always be given the string. - - If the version of ldnsx you are using is old, it is possible that there could be new rr_types that - we don't recognise mnemonic for. You can still use the number XXX or the string "TYPEXXX". To - determine what rr_type menmonics we support, please refer to resolver.supported_rr_types() - - """ - # Determine rr_type int - if rr_type in _rr_types.keys(): - _rr_type = _rr_types[rr_type] - elif isinstance(rr_type,int): - _rr_type = rr_type - elif isinstance(rr_type,str) and rr_type[0:4] == "TYPE": - try: - _rr_type = int(rr_type[4:]) - except: - raise Exception("%s is a bad RR type. TYPEXXXX: XXXX must be a number") - else: - raise Exception("ldnsx (version %s) does not support the RR type %s." % (__version__, str(rr_type)) ) - # Determine rr_class int - if rr_class == "IN": _rr_class = ldns.LDNS_RR_CLASS_IN - elif rr_class == "CH": _rr_class = ldns.LDNS_RR_CLASS_CH - elif rr_class == "HS": _rr_class = ldns.LDNS_RR_CLASS_HS - else: - raise Exception("ldnsx (version %s) does not support the RR class %s." % (__version__, str(rr_class)) ) - # Determine flags int - _flags = 0 - if "QR" in flags: _flags |= ldns.LDNS_QR - if "AA" in flags: _flags |= ldns.LDNS_AA - if "TC" in flags: _flags |= ldns.LDNS_TC - if "RD" in flags: _flags |= ldns.LDNS_RD - if "CD" in flags: _flags |= ldns.LDNS_CD - if "RA" in flags: _flags |= ldns.LDNS_RA - if "AD" in flags: _flags |= ldns.LDNS_AD - # Query - if tries == 0: return None - try: - pkt = self._ldns_resolver.query(name, _rr_type, _rr_class, _flags) - except KeyboardInterrupt: #Since so much time is spent waiting on ldns, this is very common place for Ctr-C to fall - raise - except: #Since the ldns exceptiion is not very descriptive... - raise Exception("ldns backend ran into problems. Likely, the name you were querying for, %s, was invalid." % name) - #Deal with failed queries - if not pkt: - if tries <= 1: - return None - else: - # One of the major causes of none-packets is truncation of packets - # When autotcp is set, we are in a flexible enough position to try and use tcp - # to get around this. - # Either way, we want to replace the resolver, since resolvers will sometimes - # just freeze up. - if self.autotcp: - self = resolver( ",".join(self.nameservers_ip()),tcp=True) - self.autotcp = True - pkt = self.query(name, rr_type, rr_class=rr_class, flags=flags, tries = tries-1) - self._ldns_resolver.set_usevc(False) - return pkt - else: - self = resolver( ",".join(self.nameservers_ip()) ) - time.sleep(1) # It could be that things are failing because of a brief outage - return self.query(name, rr_type, rr_class=rr_class, flags=flags, tries = tries-1) - elif self.autotcp: - pkt = packet(pkt) - if "TC" in pkt.flags(): - self._ldns_resolver.set_usevc(True) - pkt2 = self.query(name, rr_type, rr_class=rr_class, flags=flags, tries = tries-1) - self._ldns_resolver.set_usevc(False) - if pkt2: return packet(pkt2) - return pkt - return packet(pkt) - #ret = [] - #for rr in pkt.answer().rrs(): - # ret.append([str(rr.owner()),rr.ttl(),rr.get_class_str(),rr.get_type_str()]+[str(rdf) for rdf in rr.rdfs()]) - #return ret - - def suported_rr_types(self): - """ Returns the supported DNS resource record types. - - Refer to resolver.query() for thorough documentation of resource - record types or refer to: - - http://www.iana.org/assignments/dns-parameters - - """ - return _rr_types.keys() - - def AXFR(self,name): - """AXFR for name - - * name -- name to AXFR for - - This function is a generator. As it AXFRs it will yield you the records. - - **Example** - - Let's get a list of the tlds (gotta catch em all!): - - >>> tlds = [] - >>> for rr in resolver("f.root-servers.net").AXFR("."): - >>> if rr.rr_type() == "NS": - >>> tlds.append(rr.owner()) - - """ - #Dname seems to be unecessary on some computers, but it is on others. Avoid bugs. - if self._ldns_resolver.axfr_start(ldns.ldns_dname(name), ldns.LDNS_RR_CLASS_IN) != ldns.LDNS_STATUS_OK: - raise Exception("Starting AXFR failed. Error: %s" % ldns.ldns_get_errorstr_by_id(status)) - pres = self._ldns_resolver.axfr_next() - while pres: - yield resource_record(pres) - pres = self._ldns_resolver.axfr_next() - - def nameservers_ip(self): - """ returns a list of the resolvers nameservers (as IP addr) - - """ - nm_stack2 =[] - nm_str_stack2=[] - nm = self._ldns_resolver.pop_nameserver() - while nm: - nm_stack2.append(nm) - nm_str_stack2.append(str(nm)) - nm = self._ldns_resolver.pop_nameserver() - for nm in nm_stack2: - self._ldns_resolver.push_nameserver(nm) - nm_str_stack2.reverse() - return nm_str_stack2 - - - def add_nameserver(self,ns): - """ Add a nameserver, IPv4/IPv6/name. - - """ - if isValidIP(ns) == 4: - address = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A,ns) - self._ldns_resolver.push_nameserver(address) - elif isValidIP(ns) == 6: - address = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_AAAA,ns) - self._ldns_resolver.push_nameserver(address) - else: - resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") - #address = resolver.get_addr_by_name(ns) - address = resolver.get_addr_by_name(ldns.ldns_dname(ns)) - if not address: - address = resolver.get_addr_by_name(ldns.ldns_dname(ns)) - if not address: - raise Exception("Failed to resolve address for %s" % ns) - for rr in address.rrs(): - self._ldns_resolver.push_nameserver_rr(rr) - - def drop_nameservers(self): - """Drops all nameservers. - This function causes the resolver to forget all nameservers. - - """ - while self._ldns_resolver.pop_nameserver(): - pass - - def set_nameservers(self, nm_list): - """Takes a list of nameservers and sets the resolver to use them - - """ - self.drop_nameservers() - for nm in nm_list: - self.add_nameserver(nm) - - def __repr__(self): - return "" % ", ".join(self.nameservers_ip()) - __str__ = __repr__ - - def set_dnssec(self,new_dnssec_status): - """Set whether the resolver uses DNSSEC. - - """ - self._ldns_resolver.set_dnssec(new_dnssec_status) - -class packet: - - def _construct_rr_filter(self, **kwds): - def match(pattern, target): - if pattern[0] in ["<",">","!"]: - rel = pattern[0] - pattern=pattern[1:] - elif pattern[0:2] in ["<=","=>"]: - rel = pattern[0:2] - pattern=pattern[2:] - else: - rel = "=" - for val in pattern.split("|"): - if {"<" : target < val, - ">" : target > val, - "!" : target != val, - "=" : target == val, - ">=": target >= val, - "<=": target <= val}[rel]: - return True - return False - def f(rr): - for key in kwds.keys(): - if ( ( isinstance(kwds[key], list) and str(rr[key]) not in map(str,kwds[key]) ) - or ( not isinstance(kwds[key], list) and not match(str(kwds[key]), str(rr[key])))): - return False - return True - return f - - def __init__(self, pkt): - self._ldns_pkt = pkt - - def __repr__(self): - return str(self._ldns_pkt) - __str__ = __repr__ - - def rcode(self): - """Returns the rcode. - - Example returned value: "NOERROR" - - possilbe rcodes (via ldns): "FORMERR", "MASK", "NOERROR", - "NOTAUTH", "NOTIMPL", "NOTZONE", "NXDOMAIN", - "NXRSET", "REFUSED", "SERVFAIL", "SHIFT", - "YXDOMAIN", "YXRRSET" - - Refer to http://www.iana.org/assignments/dns-parameters - section: DNS RCODEs - """ - return self._ldns_pkt.rcode2str() - - def opcode(self): - """Returns the rcode. - - Example returned value: "QUERY" - - """ - return self._ldns_pkt.opcode2str() - - def flags(self): - """Return packet flags (as list of strings). - - Example returned value: ['QR', 'RA', 'RD'] - - **What are the flags?** - - ======== ==== ===================== ========= - Bit Flag Description Reference - ======== ==== ===================== ========= - bit 5 AA Authoritative Answer [RFC1035] - bit 6 TC Truncated Response [RFC1035] - bit 7 RD Recursion Desired [RFC1035] - bit 8 RA Recursion Allowed [RFC1035] - bit 9 Reserved - bit 10 AD Authentic Data [RFC4035] - bit 11 CD Checking Disabled [RFC4035] - ======== ==== ===================== ========= - - (from http://www.iana.org/assignments/dns-parameters) - - There is also QR. It is mentioned in other sources, - though not the above page. It being false means that - the packet is a query, it being true means that it is - a response. - - """ - ret = [] - if self._ldns_pkt.aa(): ret += ["AA"] - if self._ldns_pkt.ad(): ret += ["AD"] - if self._ldns_pkt.cd(): ret += ["CD"] - if self._ldns_pkt.qr(): ret += ["QR"] - if self._ldns_pkt.ra(): ret += ["RA"] - if self._ldns_pkt.rd(): ret += ["RD"] - if self._ldns_pkt.tc(): ret += ["TC"] - return ret - - def answer(self, **filters): - """Returns the answer section. - - * filters -- a filtering mechanism - - Since a very common desire is to filter the resource records in a packet - section, we provide a special tool for doing this: filters. They are a - lot like regular python filters, but more convenient. If you set a - field equal to some value, you will only receive resource records for which - it holds true. - - **Examples** - - >>> res = ldnsx.resolver() - >>> pkt = res.query("google.ca","A") - >>> pkt.answer() - [google.ca. 28 IN A 74.125.91.99 - , google.ca. 28 IN A 74.125.91.105 - , google.ca. 28 IN A 74.125.91.147 - , google.ca. 28 IN A 74.125.91.103 - , google.ca. 28 IN A 74.125.91.104 - , google.ca. 28 IN A 74.125.91.106 - ] - - To understand filters, consider the following: - - >>> pkt = ldnsx.query("cow.com","ANY") - >>> pkt.answer() - [cow.com. 276 IN A 208.87.32.75 - , cow.com. 3576 IN NS sell.internettraffic.com. - , cow.com. 3576 IN NS buy.internettraffic.com. - , cow.com. 3576 IN SOA buy.internettraffic.com. hostmaster.hostingnet.com. 1308785320 10800 3600 604800 3600 - ] - >>> pkt.answer(rr_type="A") - [cow.com. 276 IN A 208.87.32.75 - ] - >>> pkt.answer(rr_type="A|NS") - [cow.com. 276 IN A 208.87.32.75 - , cow.com. 3576 IN NS sell.internettraffic.com. - , cow.com. 3576 IN NS buy.internettraffic.com. - ] - >>> pkt.answer(rr_type="!NS") - [cow.com. 276 IN A 208.87.32.75 - , cow.com. 3576 IN SOA buy.internettraffic.com. hostmaster.hostingnet.com. 1308785320 10800 3600 604800 3600 - ] - - fields are the same as when indexing a resource record. - note: ordering is alphabetical. - """ - ret = [resource_record(rr) for rr in self._ldns_pkt.answer().rrs()] - return filter(self._construct_rr_filter(**filters), ret) - - def authority(self, **filters): - """Returns the authority section. - - * filters -- a filtering mechanism - - Since a very common desire is to filter the resource records in a packet - section, we provide a special tool for doing this: filters. They are a - lot like regular python filters, but more convenient. If you set a - field equal to some value, you will only receive resource records for which - it holds true. See answer() for details. - - **Examples** - - >>> res = ldnsx.resolver() - >>> pkt = res.query("google.ca","A") - >>> pkt.authority() - [google.ca. 251090 IN NS ns3.google.com. - , google.ca. 251090 IN NS ns1.google.com. - , google.ca. 251090 IN NS ns2.google.com. - , google.ca. 251090 IN NS ns4.google.com. - ] - - """ - ret = [resource_record(rr) for rr in self._ldns_pkt.authority().rrs()] - return filter(self._construct_rr_filter(**filters), ret) - - def additional(self, **filters): - """Returns the additional section. - - * filters -- a filtering mechanism - - Since a very common desire is to filter the resource records in a packet - section, we provide a special tool for doing this: filters. They are a - lot like regular python filters, but more convenient. If you set a - field equal to some value, you will only receive resource records for which - it holds true. See answer() for details. - - **Examples** - - >>> res = ldnsx.resolver() - >>> pkt = res.query("google.ca","A") - >>> pkt.additional() - [ns3.google.com. 268778 IN A 216.239.36.10 - , ns1.google.com. 262925 IN A 216.239.32.10 - , ns2.google.com. 255659 IN A 216.239.34.10 - , ns4.google.com. 264489 IN A 216.239.38.10 - ] - - """ - ret = [resource_record(rr) for rr in self._ldns_pkt.additional().rrs()] - return filter(self._construct_rr_filter(**filters), ret) - - def question(self, **filters): - """Returns the question section. - - * filters -- a filtering mechanism - - Since a very common desire is to filter the resource records in a packet - section, we provide a special tool for doing this: filters. They are a - lot like regular python filters, but more convenient. If you set a - field equal to some value, you will only receive resource records for which - it holds true. See answer() for details. - - """ - ret = [resource_record(rr) for rr in self._ldns_pkt.question().rrs()] - return filter(self._construct_rr_filter(**filters), ret) - -class resource_record: - - _rdfs = None - _iter_pos = None - - def __init__(self, rr): - self._ldns_rr = rr - self._rdfs = [str(rr.owner()),rr.ttl(),rr.get_class_str(),rr.get_type_str()]+[str(rdf) for rdf in rr.rdfs()] - - def __repr__(self): - return str(self._ldns_rr) - - __str__ = __repr__ - - def __iter__(self): - self._iter_pos = 0 - return self - - def next(self): - if self._iter_pos < len(self._rdfs): - self._iter_pos += 1 - return self._rdfs[self._iter_pos-1] - else: - raise StopIteration - - def __len__(self): - try: - return len(_rdfs) - except: - return 0 - - def __getitem__(self, n): - if isinstance(n, int): - return self._rdfs[n] - elif isinstance(n, str): - n = n.lower() - if n in ["owner"]: - return self.owner() - elif n in ["rr_type", "rr type", "type"]: - return self.rr_type() - elif n in ["rr_class", "rr class", "class"]: - return self.rr_class() - elif n in ["covered_type", "covered type", "type2"]: - return self.covered_type() - elif n in ["ttl"]: - return self.ttl() - elif n in ["ip"]: - return self.ip() - elif n in ["alg", "algorithm"]: - return self.alg() - elif n in ["protocol"]: - return self.protocol() - elif n in ["flags"]: - return self.flags() - else: - raise Exception("ldnsx (version %s) does not recognize the rr field %s" % (__version__,n) ) - else: - raise TypeError("bad type %s for index resource record" % type(n) ) - - - #def rdfs(self): - # return self._rdfs.clone() - - def owner(self): - """Get the RR's owner""" - return str(self._ldns_rr.owner()) - - def rr_type(self): - """Get a RR's type """ - return self._ldns_rr.get_type_str() - - def covered_type(self): - """Get an RRSIG RR's covered type""" - if self.rr_type() == "RRSIG": - return self[4] - else: - return "" - - def rr_class(self): - """Get the RR's collapse""" - return self._ldns_rr.get_class_str() - - def ttl(self): - """Get the RR's TTL""" - return self._ldns_rr.ttl() - - def inception(self, out_format="UTC"): - """returns the inception time in format out_format, defaulting to a UTC string. - options for out_format are: - - UTC -- a UTC string eg. 20110712192610 (2011/07/12 19:26:10) - unix -- number of seconds since the epoch, Jan 1, 1970 - struct_time -- the format used by python's time library - """ - # Something very strange is going on with inception/expiration dates in DNS. - # According to RFC 4034 section 3.1.5 (http://tools.ietf.org/html/rfc4034#page-9) - # the inception/expiration fields should be in seconds since Jan 1, 1970, the Unix - # epoch (as is standard in unix). Yet all the packets I've seen provide UTC encoded - # as a string instead, eg. "20110712192610" which is 2011/07/12 19:26:10. - # - # It turns out that this is a standard thing that ldns is doing before the data gets - # to us. - if self.rr_type() == "RRSIG": - if out_format.lower() in ["utc", "utc str", "utc_str"]: - return self[9] - elif out_format.lower() in ["unix", "posix", "ctime"]: - return calendar.timegm(time.strptime(self[9], "%Y%m%d%H%M%S")) - elif out_format.lower() in ["relative"]: - return calendar.timegm(time.strptime(self[9], "%Y%m%d%H%M%S")) - time.time() - elif out_format.lower() in ["struct_time", "time.struct_time"]: - return time.strptime(self[9], "%Y%m%d%H%M%S") - else: - raise Exception("unrecognized time format") - else: - return "" - - def expiration(self, out_format="UTC"): - """get expiration time. see inception() for more information""" - if self.rr_type() == "RRSIG": - if out_format.lower() in ["utc", "utc str", "utc_str"]: - return self[8] - elif out_format.lower() in ["unix", "posix", "ctime"]: - return calendar.timegm(time.strptime(self[8], "%Y%m%d%H%M%S")) - elif out_format.lower() in ["relative"]: - return calendar.timegm(time.strptime(self[8], "%Y%m%d%H%M%S")) - time.time() - elif out_format.lower() in ["struct_time", "time.struct_time"]: - return time.strptime(self[8], "%Y%m%d%H%M%S") - else: - raise Exception("unrecognized time format") - else: - return "" - - def ip(self): - """ IP address form A/AAAA record""" - if self.rr_type() in ["A", "AAAA"]: - return self[4] - else: - raise Exception("ldnsx does not support ip for records other than A/AAAA") - - def alg(self): - """Returns algorithm of RRSIG/DNSKEY/DS""" - t = self.rr_type() - if t == "RRSIG": - return int(self[5]) - elif t == "DNSKEY": - return int(self[6]) - elif t == "DS": - return int(self[5]) - else: - return -1 - - def protocol(self): - """ Returns proticol of the DNSKEY""" - t = self.rr_type() - if t == "DNSKEY": - return int(self[5]) - else: - return -1 - - def flags(self): - """Return RR flags for DNSKEY """ - t = self.rr_type() - if t == "DNSKEY": - ret = [] - n = int(self[4]) - for m in range(1): - if 2**(15-m) & n: - if m == 7: ret.append("ZONE") - elif m == 8: ret.append("REVOKE") - elif m ==15: ret.append("SEP") - else: ret.append(m) - return ret - else: - return [] - -_rr_types={ - "A" : ldns.LDNS_RR_TYPE_A, - "A6" : ldns.LDNS_RR_TYPE_A6, - "AAAA" : ldns.LDNS_RR_TYPE_AAAA, - "AFSDB": ldns.LDNS_RR_TYPE_AFSDB, - "ANY" : ldns.LDNS_RR_TYPE_ANY, - "APL" : ldns.LDNS_RR_TYPE_APL, - "ATMA" : ldns.LDNS_RR_TYPE_ATMA, - "AXFR" : ldns.LDNS_RR_TYPE_AXFR, - "CERT" : ldns.LDNS_RR_TYPE_CERT, - "CNAME": ldns.LDNS_RR_TYPE_CNAME, - "COUNT": ldns.LDNS_RR_TYPE_COUNT, - "DHCID": ldns.LDNS_RR_TYPE_DHCID, - "DLV" : ldns.LDNS_RR_TYPE_DLV, - "DNAME": ldns.LDNS_RR_TYPE_DNAME, - "DNSKEY": ldns.LDNS_RR_TYPE_DNSKEY, - "DS" : ldns.LDNS_RR_TYPE_DS, - "EID" : ldns.LDNS_RR_TYPE_EID, - "FIRST": ldns.LDNS_RR_TYPE_FIRST, - "GID" : ldns.LDNS_RR_TYPE_GID, - "GPOS" : ldns.LDNS_RR_TYPE_GPOS, - "HINFO": ldns.LDNS_RR_TYPE_HINFO, - "IPSECKEY": ldns.LDNS_RR_TYPE_IPSECKEY, - "ISDN" : ldns.LDNS_RR_TYPE_ISDN, - "IXFR" : ldns.LDNS_RR_TYPE_IXFR, - "KEY" : ldns.LDNS_RR_TYPE_KEY, - "KX" : ldns.LDNS_RR_TYPE_KX, - "LAST" : ldns.LDNS_RR_TYPE_LAST, - "LOC" : ldns.LDNS_RR_TYPE_LOC, - "MAILA": ldns.LDNS_RR_TYPE_MAILA, - "MAILB": ldns.LDNS_RR_TYPE_MAILB, - "MB" : ldns.LDNS_RR_TYPE_MB, - "MD" : ldns.LDNS_RR_TYPE_MD, - "MF" : ldns.LDNS_RR_TYPE_MF, - "MG" : ldns.LDNS_RR_TYPE_MG, - "MINFO": ldns.LDNS_RR_TYPE_MINFO, - "MR" : ldns.LDNS_RR_TYPE_MR, - "MX" : ldns.LDNS_RR_TYPE_MX, - "NAPTR": ldns.LDNS_RR_TYPE_NAPTR, - "NIMLOC": ldns.LDNS_RR_TYPE_NIMLOC, - "NS" : ldns.LDNS_RR_TYPE_NS, - "NSAP" : ldns.LDNS_RR_TYPE_NSAP, - "NSAP_PTR" : ldns.LDNS_RR_TYPE_NSAP_PTR, - "NSEC" : ldns.LDNS_RR_TYPE_NSEC, - "NSEC3": ldns.LDNS_RR_TYPE_NSEC3, - "NSEC3PARAMS" : ldns.LDNS_RR_TYPE_NSEC3PARAMS, - "NULL" : ldns.LDNS_RR_TYPE_NULL, - "NXT" : ldns.LDNS_RR_TYPE_NXT, - "OPT" : ldns.LDNS_RR_TYPE_OPT, - "PTR" : ldns.LDNS_RR_TYPE_PTR, - "PX" : ldns.LDNS_RR_TYPE_PX, - "RP" : ldns.LDNS_RR_TYPE_RP, - "RRSIG": ldns.LDNS_RR_TYPE_RRSIG, - "RT" : ldns.LDNS_RR_TYPE_RT, - "SIG" : ldns.LDNS_RR_TYPE_SIG, - "SINK" : ldns.LDNS_RR_TYPE_SINK, - "SOA" : ldns.LDNS_RR_TYPE_SOA, - "SRV" : ldns.LDNS_RR_TYPE_SRV, - "SSHFP": ldns.LDNS_RR_TYPE_SSHFP, - "TSIG" : ldns.LDNS_RR_TYPE_TSIG, - "TXT" : ldns.LDNS_RR_TYPE_TXT, - "UID" : ldns.LDNS_RR_TYPE_UID, - "UINFO": ldns.LDNS_RR_TYPE_UINFO, - "UNSPEC": ldns.LDNS_RR_TYPE_UNSPEC, - "WKS" : ldns.LDNS_RR_TYPE_WKS, - "X25" : ldns.LDNS_RR_TYPE_X25 -} -