diff options
author | Mats Dufberg <mats.dufberg@iis.se> | 2022-12-19 10:33:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-19 10:33:04 +0100 |
commit | 6352fde044dde0e04f2e39a1250120d700d90cc6 (patch) | |
tree | c590c335aa09094cda82355504c98d6afd978253 | |
parent | d8c6f4ce62da15d028094541367dc5aa5f5fb762 (diff) | |
parent | 804707451e8aed14c9cfd72698f66ca3f63945c4 (diff) |
Merge pull request #164 from matsduf/merge-develop-into-master
Merge develop into master (zonemaster-ldns)
-rw-r--r-- | Changes | 23 | ||||
-rw-r--r-- | Dockerfile | 4 | ||||
-rw-r--r-- | MANIFEST | 8 | ||||
-rw-r--r-- | MANIFEST.SKIP | 1 | ||||
-rw-r--r-- | Makefile.PL | 209 | ||||
-rw-r--r-- | README.md | 48 | ||||
-rw-r--r-- | include/LDNS.h | 1 | ||||
m--------- | ldns | 0 | ||||
-rw-r--r-- | lib/Zonemaster/LDNS.pm | 10 | ||||
-rw-r--r-- | lib/Zonemaster/LDNS/RR/SPF.pm | 14 | ||||
-rw-r--r-- | lib/Zonemaster/LDNS/RR/TXT.pm | 14 | ||||
-rw-r--r-- | src/LDNS.xs | 113 | ||||
-rw-r--r-- | src/assist.c | 17 | ||||
-rw-r--r-- | t/nsid.t | 22 | ||||
-rw-r--r-- | t/packet.t | 31 | ||||
-rw-r--r-- | t/rr.t | 50 |
16 files changed, 458 insertions, 107 deletions
@@ -1,5 +1,28 @@ Release history for Zonemaster component Zonemaster-LDNS +3.0.0 2022-12-19 + + [Breaking change] + - Improves access to text data in TXT and SPF resource records + (#157, #155) + + [Features] + - Uses internal LDNS for docker image (#162) + - Adds support for NSID option (#151) + - Updates internal LDNS to 1.8.3 (#151, #143) + - Adds options to build with Libidn and LDNS in custom locations + (#152) + + [Fixes] + - Fixes a bug when building LDNS with link to OpenSSL (#161) + - Corrects the license statement in LDNS.pm (#159) + - Fixes unsafe string manipulations in XS code (#153, #149) + - Automatically reconfigures internal libldns on "ldns/Changelog" + updates (#158) + - URL fragments referring to internal headings in lowercase + (#154) + + 2.2.2 2022-06-09 [Features] @@ -3,7 +3,6 @@ FROM alpine:3.14 as build RUN apk add --no-cache \ # Compile-time dependencies build-base \ - ldns-dev \ libidn2-dev \ make \ openssl-dev \ @@ -20,7 +19,7 @@ ARG version COPY ./Zonemaster-LDNS-${version}.tar.gz ./Zonemaster-LDNS-${version}.tar.gz -RUN cpanm --notest --no-wget --configure-args="--no-internal-ldns" \ +RUN cpanm --notest --no-wget \ ./Zonemaster-LDNS-${version}.tar.gz FROM alpine:3.14 @@ -31,6 +30,5 @@ COPY --from=build /usr/local/lib/perl5/site_perl/Zonemaster /usr/local/lib/perl5 RUN apk add --no-cache \ # Run-time dependencies - ldns \ libidn2 \ perl @@ -11,7 +11,10 @@ inc/Module/Install/Win32.pm inc/Module/Install/WriteAll.pm inc/Module/Install/XSUtil.pm include/LDNS.h +ldns/.github/FUNDING.yml +ldns/.github/workflows/testsuite.yml ldns/buffer.c +ldns/Changelog ldns/compat/b64_ntop.c ldns/compat/b64_pton.c ldns/compat/strlcpy.c @@ -25,6 +28,7 @@ ldns/dnssec_sign.c ldns/dnssec_verify.c ldns/dnssec_zone.c ldns/duration.c +ldns/edns.c ldns/error.c ldns/higher.c ldns/host2str.c @@ -41,6 +45,7 @@ ldns/ldns/dnssec_sign.h ldns/ldns/dnssec_verify.h ldns/ldns/dnssec_zone.h ldns/ldns/duration.h +ldns/ldns/edns.h ldns/ldns/error.h ldns/ldns/higher.h ldns/ldns/host2str.h @@ -64,6 +69,7 @@ ldns/ldns/update.h ldns/ldns/util.h.in ldns/ldns/wire2host.h ldns/ldns/zone.h +ldns/libdns.doxygen.in ldns/LICENSE ldns/ltmain.sh ldns/Makefile.in @@ -75,6 +81,7 @@ ldns/parse.c ldns/radix.c ldns/rbtree.c ldns/rdata.c +ldns/README-Travis.md ldns/resolver.c ldns/rr.c ldns/rr_functions.c @@ -180,6 +187,7 @@ t/example.org t/idn.t t/load_zonefile.t t/netldns.t +t/nsid.t t/packet.t t/regression.t t/resolver.t diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP index f70a36d..e32c894 100644 --- a/MANIFEST.SKIP +++ b/MANIFEST.SKIP @@ -16,7 +16,6 @@ \.ac$ # Avoid ldns files we don't need -^ldns/Changelog$ ^ldns/README$ ^ldns/README\. ^ldns/\.libs/ diff --git a/Makefile.PL b/Makefile.PL index cf5c342..ea715c2 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -58,6 +58,26 @@ The PATH is passed to the LDNS compiler via the CFLAGS variable. Search for OpenSSL library in PATH. The PATH is passed to the LDNS compiler via the LDFLAGS variable. +=item --libidn-inc=PATH + +Search for Libidn include in PATH. + +=item --libidn-lib=PATH + +Search for Libidn library in PATH. + +=item --ldns-inc=PATH + +Search for LDNS include in PATH. + +=item --ldns-lib=PATH + +Search for LDNS library in PATH. + +=item --debug + +Enable debug mode, more verbose output. + =back =cut @@ -66,17 +86,36 @@ my $opt_ed25519 = 1; my $opt_idn = 1; my $opt_internal_ldns = 1; my $opt_randomize = 0; -my $opt_prefix_openssl = ""; -my $opt_openssl_inc = ""; -my $opt_openssl_lib = ""; +my $opt_debug = 0; +my $opt_assets = { + openssl => { + prefix => "", + inc => "", + lib => "" + }, + ldns => { + inc => "", + lib => "" + }, + libidn => { + inc => "", + lib => "" + } +}; + GetOptions( 'ed25519!' => \$opt_ed25519, 'idn!' => \$opt_idn, 'internal-ldns!' => \$opt_internal_ldns, 'randomize!' => \$opt_randomize, - 'prefix-openssl=s' => \$opt_prefix_openssl, - 'openssl-inc=s' => \$opt_openssl_inc, - 'openssl-lib=s' => \$opt_openssl_lib, + 'debug!' => \$opt_debug, + 'prefix-openssl=s' => \$$opt_assets{openssl}{prefix}, + 'openssl-inc=s' => \$$opt_assets{openssl}{inc}, + 'openssl-lib=s' => \$$opt_assets{openssl}{lib}, + 'libidn-inc=s' => \$$opt_assets{libidn}{inc}, + 'libidn-lib=s' => \$$opt_assets{libidn}{lib}, + 'ldns-inc=s' => \$$opt_assets{ldns}{inc}, + 'ldns-lib=s' => \$$opt_assets{ldns}{lib}, ); configure_requires 'Devel::CheckLib'; @@ -91,52 +130,82 @@ cc_include_paths 'include'; cc_src_paths 'src'; -# OpenSSL - -my %assert_lib_args_openssl; -my $custom_openssl = ( $opt_prefix_openssl or $opt_openssl_inc or $opt_openssl_lib ); -if ( $custom_openssl ) { - my $openssl_incpath = ""; - my $openssl_libpath = ""; +my %assert_lib_args = ( + openssl => {}, + libidn => {}, + ldns => {} +); - if ( $opt_prefix_openssl ) { - print "Custom prefix for OpenSSL: $opt_prefix_openssl\n"; - $openssl_incpath = "$opt_prefix_openssl/include"; - $openssl_libpath = "$opt_prefix_openssl/lib"; +sub custom_assets +{ + my ( $href ) = @_; + # $href = { key => "openssl", lib => "crypto", name => "OpenSSL" } + + my $key = $$href{key}; + my $name = $$href{name}; + my $lib = $$href{lib}; + + my $input_prefix = $$opt_assets{$key}{prefix}; + my $input_inc = $$opt_assets{$key}{inc}; + my $input_lib = $$opt_assets{$key}{lib}; + + my $custom_lib = ( $input_prefix or $input_inc or $input_lib ); + if ( $custom_lib ) { + my $incpath = ""; + my $libpath = ""; + + if ( $input_prefix ) { + print "Custom prefix for $name: $input_prefix\n"; + $incpath = "$input_prefix/include"; + $libpath = "$input_prefix/lib"; + } + + if ( $input_inc ) { + print "Custom include directory for $name: $input_inc\n"; + $incpath = "$input_inc"; + } + + if ( $input_lib ) { + print "Custom library directory for $name: $input_lib\n"; + $libpath = "$input_lib"; + } + + cc_include_paths "$incpath"; + cc_libs "-L$libpath", "$lib"; + + $assert_lib_args{$key}{incpath} = "$incpath"; + $assert_lib_args{$key}{libpath} = "$libpath"; } - - if ( $opt_openssl_inc ) { - print "Custom include directory for OpenSSL: $opt_openssl_inc\n"; - $openssl_incpath = "$opt_openssl_inc"; + else { + cc_libs "$lib"; } +} - if ( $opt_openssl_lib ) { - print "Custom library directory for OpenSSL: $opt_openssl_lib\n"; - $openssl_libpath = "$opt_openssl_lib"; - } +# OpenSSL - cc_include_paths "$openssl_incpath"; - cc_libs "-L$openssl_libpath", "crypto"; - $assert_lib_args_openssl{incpath} = "$openssl_incpath"; - $assert_lib_args_openssl{libpath} = "$openssl_libpath"; -} -else { - cc_libs 'crypto'; -} +custom_assets( + { + name => "OpenSSL", + lib => "crypto", + key => "openssl" + } +); cc_assert_lib( + debug => $opt_debug, lib => 'crypto', header => 'openssl/crypto.h', function => 'if(SSLeay()) return 0; else return 1;', - %assert_lib_args_openssl, + %{ $assert_lib_args{openssl} }, ); if ( $opt_ed25519 ) { print "Feature Ed25519 enabled\n"; cc_assert_lib( + debug => $opt_debug, lib => 'crypto', header => 'openssl/evp.h', function => 'EVP_PKEY_ED25519; return 0;', - %assert_lib_args_openssl, + %{ $assert_lib_args{openssl} }, ); } else { @@ -144,37 +213,77 @@ else { } -# LDNS +# LDNS and NSID + +my $ldns_has_nsid; if ( $opt_internal_ldns ) { print "Feature internal ldns enabled\n"; cc_libs '-Lldns/lib'; cc_include_paths 'ldns'; + $ldns_has_nsid = 1; } else { print "Feature internal ldns disabled\n"; - cc_libs 'ldns'; + + custom_assets( + { + name => "LDNS", + lib => "ldns", + key => "ldns" + } + ); + if ( $opt_ed25519 ) { cc_assert_lib( + debug => $opt_debug, lib => 'ldns', header => 'ldns/ldns.h', + %{ $assert_lib_args{ldns} }, ccflags => '-DUSE_ED25519', function => 'if(LDNS_ED25519) return 0; else return 1;' ); } + + # NSID feature requires LDNS version >= 1.8.2 + $ldns_has_nsid = check_lib( + debug => $opt_debug, + lib => 'ldns', + header => 'ldns/util.h', + %{ $assert_lib_args{ldns} }, + function => 'if ( LDNS_REVISION >= ((1<<16)|(8<<8)|(2)) ) return 0; else return 1;' + ); } +if ( $ldns_has_nsid ) { + print "Feature NSID enabled\n"; + cc_define '-DNSID_SUPPORT'; +} +else { + print "Feature NSID disabled\n"; +} -# IDN + +# Libidn if ( $opt_idn ) { print "Feature idn enabled\n"; + + custom_assets( + { + name => "Libidn", + lib => "idn2", + key => "libidn" + } + ); + check_lib_or_exit( + debug => $opt_debug, lib => 'idn2', header => 'idn2.h', - function => - 'return IDN2_OK;'); - cc_libs 'idn2'; + %{ $assert_lib_args{libidn} }, + function => 'return IDN2_OK;' + ); cc_define '-DWE_CAN_HAZ_IDN'; } else { @@ -228,14 +337,14 @@ END_CONFIGURE_FLAGS my $openssl_make = <<END_OPENSSL_MAKE; -CONFIGURE_FLAGS += --with-ssl=$opt_prefix_openssl +CONFIGURE_FLAGS += --with-ssl=$$opt_assets{openssl}{prefix} END_OPENSSL_MAKE my $openssl_flags = <<END_OPENSSL_FLAGS; -CFLAGS += -I$opt_openssl_inc -LDFLAGS += -L$opt_openssl_lib +CFLAGS += -I$$opt_assets{openssl}{inc} +LDFLAGS += -L$$opt_assets{openssl}{lib} END_OPENSSL_FLAGS @@ -263,12 +372,14 @@ ldns/.libs/libldns.a: ldns/configure ./configure CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" $(CONFIGURE_FLAGS) ;\ make lib -ldns/configure: +ldns/configure: ldns/Changelog + cd ldns ; libtoolize -ci + cd ldns ; autoreconf -fi + +ldns/Changelog: git submodule init git submodule sync git submodule update - cd ldns ; libtoolize -ci - cd ldns ; autoreconf -fi END_INTERNAL_LDNS @@ -278,10 +389,10 @@ END_INTERNAL_LDNS $postamble .= $docker_make; if ( $opt_internal_ldns ) { $postamble .= $configure_flags_make; - $postamble .= $openssl_make if $opt_prefix_openssl; + $postamble .= $openssl_make if $$opt_assets{openssl}{prefix}; $postamble .= $ed25519_make if $opt_ed25519; $postamble .= $no_ed25519_make if !$opt_ed25519; - $postamble .= $openssl_flags if ( $opt_openssl_inc or $opt_openssl_lib ); + $postamble .= $openssl_flags if ( $$opt_assets{openssl}{inc} or $$opt_assets{openssl}{lib} ); $postamble .= $internal_ldns_make; } @@ -6,7 +6,7 @@ * [Dependencies and Compatibility](#dependencies-and-compatibility) * [Installation and verification](#installation-and-verification) * [Recommended installation](#recommended-installation) - * [Docker](#Docker) + * [Docker](#docker) * [Installation from source](#installation-from-source) * [Post-installation sanity check](#post-installation-sanity-check) * [Testing](#testing) @@ -15,7 +15,11 @@ * [IDN] * [Internal ldns] * [Randomized capitalization](#randomized-capitalization) - + * [Custom OpenSSL] + * [Custom LDNS] + * [Custom Libidn] + * [Debug] +* [License](#license) ## Introduction @@ -175,7 +179,7 @@ Randomizes the capitalization of returned domain names. Disabled by default. Enabled with `--prefix-openssl=/path/to/openssl` or -`--openssl-inc=/path/to/openssl_inc` or `--openssl-lib=/path/to/openssl_lib` +`--openssl-inc=/path/to/openssl_inc` or `--openssl-lib=/path/to/openssl_lib`. Enabling this makes the build tools look for OpenSSL in a non-standard place. @@ -192,6 +196,44 @@ same parent directory, use `--openssl-inc` and `--openssl-lib` options to specify both paths. +### Custom LDNS + +Disabled by default. +Enabled with `--ldns-inc=/path/to/ldns_inc` or `--ldns-lib=/path/to/ldns_lib`. + +Enabling this makes the build tools look for LDNS in a non-standard place. + +> Requires [Internal LDNS] to be disabled. + + +### Custom Libidn + +Disabled by default. +Enabled with `--libidn-inc=/path/to/libidn_inc` or +`--libidn-lib=/path/to/ldns_lib`. + +Enabling this makes the build tools look for Libidn in a non-standard place. + +> Requires [IDN] to be enabled. + + +### Debug + +Disabled by default. +Enabled with `--debug`. + +Gives a more verbose output. + +## License + +This is free software under a 2-clause BSD license. The full text of the license can +be found in the [LICENSE](LICENSE) file included in this respository. + + +[Custom LDNS]: #custom-ldns +[Custom Libidn]: #custom-libidn +[Custom OpenSSL]: #custom-openssl +[Debug]: #debug [DNS::LDNS]: http://search.cpan.org/~erikoest/DNS-LDNS/ [Docker Hub]: https://hub.docker.com/u/zonemaster [Docker Image Creation]: https://github.com/zonemaster/zonemaster/blob/master/docs/internal-documentation/maintenance/ReleaseProcess-create-docker-image.md diff --git a/include/LDNS.h b/include/LDNS.h index 9de985a..813b00e 100644 --- a/include/LDNS.h +++ b/include/LDNS.h @@ -108,6 +108,7 @@ typedef ldns_rr *Zonemaster__LDNS__RR__X25; SV *rr2sv(ldns_rr *rr); char *randomize_capitalization(char *in); +void strip_newline(char* in); #ifdef USE_ITHREADS void net_ldns_remember_resolver(SV *rv); diff --git a/ldns b/ldns -Subproject 53bc57512c19b11eebc403a4cb2bbf7295eb0db +Subproject 173fbf303518d060e0d2bdc0bbd1830c0ec8f21 diff --git a/lib/Zonemaster/LDNS.pm b/lib/Zonemaster/LDNS.pm index 1bea10b..a9b88e8 100644 --- a/lib/Zonemaster/LDNS.pm +++ b/lib/Zonemaster/LDNS.pm @@ -2,7 +2,7 @@ package Zonemaster::LDNS; use 5.014; -our $VERSION = '2.2.2'; +our $VERSION = '3.0.0'; use parent 'Exporter'; our @EXPORT_OK = qw[to_idn has_idn ldns_version load_zonefile]; @@ -212,11 +212,7 @@ Calle Dybedahl <calle@init.se> =head1 LICENSE -This is free software, licensed under: - -The (three-clause) BSD License - -The full text of the license can be found in the -F<LICENSE> file included with this distribution. +This is free software under a 2-clause BSD license. The full text of the license can +be found in the F<LICENSE> file included with this distribution. =cut diff --git a/lib/Zonemaster/LDNS/RR/SPF.pm b/lib/Zonemaster/LDNS/RR/SPF.pm index 48e4fec..9ff290f 100644 --- a/lib/Zonemaster/LDNS/RR/SPF.pm +++ b/lib/Zonemaster/LDNS/RR/SPF.pm @@ -5,6 +5,12 @@ use warnings; use parent 'Zonemaster::LDNS::RR'; +sub spfdata() { + my ($rr) = @_; + + return join( "", map { substr($rr->rdf($_ - 1), 1) } 1..$rr->rd_count() ); +} + 1; =head1 NAME @@ -21,6 +27,12 @@ A subclass of L<Zonemaster::LDNS::RR>, so it has all the methods of that class a =item spfdata() -Returns the SPF string. +Returns the concatenation of all the strings composing the data of the resource record. + +For example, if an SPF resource record has the following presentation format: + + test.example. 3600 IN SPF "v=spf1 " "mx " "a " "-all" + +then C<spfdata()> returns the string C<"v=spf1 mx a -all">. =back diff --git a/lib/Zonemaster/LDNS/RR/TXT.pm b/lib/Zonemaster/LDNS/RR/TXT.pm index 1df7069..27b694a 100644 --- a/lib/Zonemaster/LDNS/RR/TXT.pm +++ b/lib/Zonemaster/LDNS/RR/TXT.pm @@ -5,6 +5,12 @@ use warnings; use parent 'Zonemaster::LDNS::RR'; +sub txtdata() { + my ($rr) = @_; + + return join( "", map { substr($rr->rdf($_ - 1), 1) } 1..$rr->rd_count() ); +} + 1; =head1 NAME @@ -21,6 +27,12 @@ A subclass of L<Zonemaster::LDNS::RR>, so it has all the methods of that class a =item txtdata() -Returns the text data. +Returns the concatenation of all the strings composing the data of the resource record. + +For example, if a TXT resource record has the following presentation format: + + txt.test.example. 3600 IN TXT "I " "am " "split up in " "lit" "tle pieces" + +then C<txtdata()> returns the string C<"I am split up in little pieces">. =back diff --git a/src/LDNS.xs b/src/LDNS.xs index becb907..e4b63a9 100644 --- a/src/LDNS.xs +++ b/src/LDNS.xs @@ -1233,7 +1233,14 @@ packet_string(obj) Zonemaster::LDNS::Packet obj; CODE: RETVAL = ldns_pkt2str(obj); - RETVAL[strlen(RETVAL)-1] = '\0'; + if(RETVAL == NULL || RETVAL[0] == '\0') + { + croak("Failed to convert packet to string"); + } + else + { + strip_newline(RETVAL); + } OUTPUT: RETVAL CLEANUP: @@ -1407,6 +1414,76 @@ packet_needs_edns(obj) OUTPUT: RETVAL +# +# Function: nsid +# -------------- +# Set the EDNS option NSID in the packet +# +void +packet_nsid(obj) + Zonemaster::LDNS::Packet obj; + CODE: + { +#ifdef NSID_SUPPORT + ldns_edns_option_list* edns_list; + ldns_edns_option* edns_opt; + + edns_list = ldns_pkt_edns_get_option_list(obj); + + if ( !edns_list ) + edns_list = ldns_edns_option_list_new(); + + edns_opt = ldns_edns_new_from_data(LDNS_EDNS_NSID, 0, NULL); + if ( edns_list == NULL || edns_opt == NULL ) + croak("Could not allocate EDNS option"); + if ( ! ldns_edns_option_list_push(edns_list, edns_opt) ) + croak("Could not attach EDNS option NSID"); + ldns_pkt_set_edns_option_list(obj, edns_list); +#else + croak("NSID not supported"); +#endif + } + +# +# Function: get_nsid +# ------------------ +# Get the EDNS option NSID if any from the packet +# +# returns: a bytes string (or undef if no NSID is found) +# +SV * +packet_get_nsid(obj) + Zonemaster::LDNS::Packet obj; + CODE: + { +#ifdef NSID_SUPPORT + ldns_edns_option_list* edns_list; + ldns_edns_option* edns_opt; + size_t i,count; + + edns_list = ldns_pkt_edns_get_option_list(obj); + if ( edns_list == NULL ) + XSRETURN_UNDEF; + + RETVAL = NULL; + count = ldns_edns_option_list_get_count(edns_list); + for ( i=0; i<count; i++ ) + { + edns_opt = ldns_edns_option_list_get_option(edns_list, i); + if ( edns_opt == NULL ) + continue; + if ( ldns_edns_get_code(edns_opt) == LDNS_EDNS_NSID ) + RETVAL = newSVpv(ldns_edns_get_data(edns_opt), ldns_edns_get_size(edns_opt)); + } + if ( RETVAL == NULL ) + XSRETURN_UNDEF; +#else + croak("NSID not supported"); +#endif + } + OUTPUT: + RETVAL + SV * packet_type(obj) Zonemaster::LDNS::Packet obj; @@ -1597,7 +1674,14 @@ rr_string(obj) Zonemaster::LDNS::RR obj; CODE: RETVAL = ldns_rr2str(obj); - RETVAL[strlen(RETVAL)-1] = '\0'; + if(RETVAL == NULL || RETVAL[0] == '\0') + { + croak("Failed to convert RR to string"); + } + else + { + strip_newline(RETVAL); + } OUTPUT: RETVAL CLEANUP: @@ -2366,31 +2450,6 @@ rr_cname_cname(obj) CLEANUP: free(RETVAL); - -MODULE = Zonemaster::LDNS PACKAGE = Zonemaster::LDNS::RR::TXT PREFIX=rr_txt_ - -char * -rr_txt_txtdata(obj) - Zonemaster::LDNS::RR::TXT obj; - CODE: - RETVAL = D_STRING(obj,0); - OUTPUT: - RETVAL - CLEANUP: - free(RETVAL); - -MODULE = Zonemaster::LDNS PACKAGE = Zonemaster::LDNS::RR::SPF PREFIX=rr_spf_ - -char * -rr_spf_spfdata(obj) - Zonemaster::LDNS::RR::SPF obj; - CODE: - RETVAL = D_STRING(obj,0); - OUTPUT: - RETVAL - CLEANUP: - free(RETVAL); - MODULE = Zonemaster::LDNS PACKAGE = Zonemaster::LDNS::RR::KEY PREFIX=rr_key_ U16 diff --git a/src/assist.c b/src/assist.c index 3f52792..413761e 100644 --- a/src/assist.c +++ b/src/assist.c @@ -228,3 +228,20 @@ rr2sv(ldns_rr *rr) return rr_sv; } + +void +strip_newline(char* in) +{ + size_t length; + + if (in == NULL || in[0] == '\0') + { + return; + } + + length = strlen(in); + if (in[length - 1] == '\n') + { + in[length - 1] = '\0'; + } +} diff --git a/t/nsid.t b/t/nsid.t new file mode 100644 index 0000000..f4a5478 --- /dev/null +++ b/t/nsid.t @@ -0,0 +1,22 @@ +use strict; +use warnings; + +use Test::More; +use Zonemaster::LDNS; + +SKIP: { + skip 'no network', 1 unless $ENV{TEST_WITH_NETWORK}; + + my $host = '192.134.4.1'; #ns1.nic.fr with nsid: ns1.th3.nic.fr + my $expected_nsid = "ns1.th3.nic.fr"; + + my $pkt = Zonemaster::LDNS::Packet->new('domain.example'); + $pkt->nsid; # set the NSID EDNS option + my $res = Zonemaster::LDNS->new($host)->query_with_pkt($pkt); + + my $nsid = $res->get_nsid(); + + is( $nsid, $expected_nsid, 'Correct NSID' ); +}; + +done_testing(); @@ -28,4 +28,35 @@ is($p->answerfrom, undef, 'No answerfrom'); $p->answerfrom('127.0.0.1'); is($p->answerfrom, '127.0.0.1', 'Localhost'); +subtest "croak when stringifying packet with malformed CAA" => sub { + my $will_croak = sub { + # Constructing a synthetic packet that would have the following string + # representation in dig-like format: + # + # ;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 13944 + # ;; flags: qr aa ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 + # ;; QUESTION SECTION: + # ;; bad-caa.example. IN CAA + # + # ;; ANSWER SECTION: + # bad-caa.example. 3600 IN CAA \# 4 C0000202 + # + # ;; AUTHORITY SECTION: + # + # ;; ADDITIONAL SECTION: + my $packet_bin = pack( + 'H*', + '367884000001000100000000' . # header + '076261642d636161076578616d706c650001010001' . # question + 'c00c0101000100000e100004c0000202' # bad answer + ); + + my $packet = Zonemaster::LDNS::Packet->new_from_wireformat( $packet_bin ); + + # This must croak + $packet->string; + }; + like( exception { $will_croak->() }, qr/^Failed to convert packet to string/ ); +}; + done_testing(); @@ -77,18 +77,18 @@ subtest 'AAAA' => sub { }; subtest 'TXT' => sub { - SKIP: { - skip 'no network', 1 unless $ENV{TEST_WITH_NETWORK}; - - my $se = Zonemaster::LDNS->new( '192.36.144.107' ); - my $pt = $se->query( 'se', 'TXT' ); - plan skip_all => 'No response, cannot test' if not $pt; - - foreach my $rr ( $pt->answer ) { - isa_ok( $rr, 'Zonemaster::LDNS::RR::TXT' ); - like( $rr->txtdata, qr/^"SE zone update: / ); - } + my @data = ( + q{txt.test. 3600 IN TXT "Handling TXT RRs can be challenging"}, + q{txt.test. 3600 IN TXT "because " "the data can " "be spl" "it up like " "this!"} + ); + my @rrs = map { Zonemaster::LDNS::RR->new($_) } @data; + + foreach my $rr ( @rrs ) { + isa_ok( $rr, 'Zonemaster::LDNS::RR::TXT' ); } + + is( $rrs[0]->txtdata(), q{Handling TXT RRs can be challenging} ); + is( $rrs[1]->txtdata(), q{because the data can be split up like this!} ); }; subtest 'DNSKEY' => sub { @@ -220,10 +220,30 @@ subtest 'SRV' => sub { }; subtest 'SPF' => sub { - my $spf = Zonemaster::LDNS::RR->new( - 'frobbit.se. 1127 IN SPF "v=spf1 ip4:85.30.129.185/24 mx:mail.frobbit.se ip6:2a02:80:3ffe::0/64 ~all"' ); - isa_ok( $spf, 'Zonemaster::LDNS::RR::SPF' ); - is( $spf->spfdata, '"v=spf1 ip4:85.30.129.185/24 mx:mail.frobbit.se ip6:2a02:80:3ffe::0/64 ~all"' ); + my @data = ( + q{frobbit.se. 1127 IN SPF "v=spf1 ip4:85.30.129.185/24 mx:mail.frobbit.se ip6:2a02:80:3ffe::0/64 ~all"}, + q{spf.example. 3600 IN SPF "v=spf1 " "ip4:192.0.2.25/24 " "mx:mail.spf.example " "ip6:2001:db8::25/64 -all"} + ); + + my @rr = map { Zonemaster::LDNS::RR->new($_) } @data; + for my $spf (@rr) { + isa_ok( $spf, 'Zonemaster::LDNS::RR::SPF' ); + } + + is( $rr[0]->spfdata(), 'v=spf1 ip4:85.30.129.185/24 mx:mail.frobbit.se ip6:2a02:80:3ffe::0/64 ~all' ); + is( $rr[1]->spfdata(), 'v=spf1 ip4:192.0.2.25/24 mx:mail.spf.example ip6:2001:db8::25/64 -all' ); + +}; + +subtest 'croak when given malformed CAA records' => sub { + my $will_croak = sub { + # This will croak if LDNS.xs is compiled with -DUSE_ITHREADS + my $bad_caa = Zonemaster::LDNS::RR->new( + 'bad-caa.example. 3600 IN CAA \# 4 C0000202' ); + # This will always croak + $bad_caa->string(); + }; + like( exception { $will_croak->() }, qr/^Failed to convert RR to string/ ); }; done_testing; |