Skip to content

Commit d302f8c

Browse files
authored
Merge pull request #181 from zonemaster/develop
Merge develop into master (Zonemaster-LDNS)
2 parents 4dac113 + 785cf01 commit d302f8c

File tree

13 files changed

+230
-29
lines changed

13 files changed

+230
-29
lines changed

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ env:
55

66
language: perl
77
perl:
8-
- "5.32"
8+
- "5.36"
99
- "5.30.2"
1010
- "5.26"
11-
- "5.14.4"
1211

1312
before_install:
1413
# quoting preserves newlines in the script and then avoid error if the

Changes

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
Release history for Zonemaster component Zonemaster-LDNS
22

3+
4.0.0 2024-03-18 (public release version)
4+
5+
[Breaking change]
6+
- Fix crashing induced by Zonemaster::LDNS::RR::NSEC3::salt()
7+
method (#177)
8+
- Fix other methods in Zonemaster::LDNS::RR::NSEC3 and
9+
::NSEC3PARAM (#178)
10+
11+
[Fixes]
12+
- Ignore incomplete RRs (#136)
13+
- Validate inputs to Zonemaster::LDNS::RR::NSEC3::covers()
14+
(#176)
15+
16+
317
3.2.0 2023-06-21 (public fix version)
418
[Feature]
519
- Expand DNAME support (#170)

Makefile.PL

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ configure_requires 'Module::Install::XSUtil';
124124
test_requires 'JSON::PP';
125125
test_requires 'Test::Fatal';
126126
test_requires 'Test::More' => 1.302015;
127+
test_requires 'MIME::Base32';
127128

128129
use_ppport 3.19;
129130
cc_include_paths 'include';

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ Compile-time dependencies (only when installing from source):
5959
* `automake` (if [Internal ldns] is enabled)
6060

6161
Test-time dependencies:
62+
* `MIME::Base32`
6263
* `Test::Fatal`
6364

6465
There is a small part in the code that may not be compatible with non-Unix

lib/Zonemaster/LDNS.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package Zonemaster::LDNS;
22

33
use 5.014;
44

5-
our $VERSION = '3.2.0';
5+
our $VERSION = '4.0.0';
66

77
use parent 'Exporter';
88
our @EXPORT_OK = qw[to_idn has_idn ldns_version load_zonefile];

lib/Zonemaster/LDNS/Packet.pm

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ sub answer {
3232
my @records = $self->answer_unfiltered;
3333

3434
for ( my $i = $#records ; $i >= 0 ; --$i ) {
35-
if ( $records[$i]->type() eq 'DNSKEY' && $records[$i]->keysize() == -1 ) {
35+
if ( !$records[$i]->check_rd_count()
36+
|| ( $records[$i]->type() eq 'DNSKEY' && $records[$i]->keysize() == -1 ) )
37+
{
3638
splice @records, $i, 1;
3739
}
3840
}
@@ -45,6 +47,12 @@ sub authority {
4547

4648
my @records = $self->authority_unfiltered;
4749

50+
for ( my $i = $#records ; $i >= 0 ; --$i ) {
51+
if ( !$records[$i]->check_rd_count() ) {
52+
splice @records, $i, 1;
53+
}
54+
}
55+
4856
return @records;
4957
}
5058

@@ -53,6 +61,12 @@ sub additional {
5361

5462
my @records = $self->additional_unfiltered;
5563

64+
for ( my $i = $#records ; $i >= 0 ; --$i ) {
65+
if ( !$records[$i]->check_rd_count() ) {
66+
splice @records, $i, 1;
67+
}
68+
}
69+
5670
return @records;
5771
}
5872

lib/Zonemaster/LDNS/RR.pm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ use Zonemaster::LDNS::RR::RKEY;
6060
use Zonemaster::LDNS::RR::RP;
6161
use Zonemaster::LDNS::RR::RRSIG;
6262
use Zonemaster::LDNS::RR::RT;
63+
use Zonemaster::LDNS::RR::SIG;
6364
use Zonemaster::LDNS::RR::SINK;
6465
use Zonemaster::LDNS::RR::SOA;
6566
use Zonemaster::LDNS::RR::SPF;

lib/Zonemaster/LDNS/RR/NSEC3.pm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ Returns the iteration count.
3737
3838
=item salt()
3939
40-
Returns the cryptographic salt, in binary form.
40+
Returns the contents of the salt field as a binary string, if non-empty; otherwise, returns an empty string. If there was a problem accessing the salt field, returns undef.
4141
4242
=item next_owner()
4343
44-
Returns the next owner field.
44+
Returns the next hashed owner name field, in binary form. To convert the return value to the human-readable presentation format, use L<MIME::Base32/encode_base32hex>.
4545
4646
=item typelist()
4747

lib/Zonemaster/LDNS/RR/NSEC3PARAM.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@ Returns the iteration count.
3333
3434
=item salt()
3535
36-
Returns the cryptographic salt in binary form.
36+
Returns the contents of the salt field as a binary string, if non-empty; otherwise, returns an empty string.
3737
3838
=back

src/LDNS.xs

Lines changed: 98 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,6 +1727,46 @@ rr_rdf(obj,n)
17271727
OUTPUT:
17281728
RETVAL
17291729

1730+
bool
1731+
rr_check_rd_count(obj)
1732+
Zonemaster::LDNS::RR obj;
1733+
CODE:
1734+
ldns_rr_type rr_type = ldns_rr_get_type(obj);
1735+
ldns_rr_descriptor *desc = ldns_rr_descript(rr_type);
1736+
size_t rd_min = ldns_rr_descriptor_minimum(desc);
1737+
size_t rd_max = ldns_rr_descriptor_maximum(desc);
1738+
size_t rd_count = ldns_rr_rd_count(obj);
1739+
1740+
// Workaround for when the last field is variable length with length
1741+
// zero, and ldns represents this by omitting the last field from
1742+
// the field list.
1743+
if (rd_min > 0 && rd_min == rd_max)
1744+
{
1745+
switch (ldns_rr_descriptor_field_type(desc,rd_min-1))
1746+
{
1747+
// This list is taken from ldns_wire2rdf()
1748+
case LDNS_RDF_TYPE_APL:
1749+
case LDNS_RDF_TYPE_B64:
1750+
case LDNS_RDF_TYPE_HEX:
1751+
case LDNS_RDF_TYPE_NSEC:
1752+
case LDNS_RDF_TYPE_UNKNOWN:
1753+
case LDNS_RDF_TYPE_SERVICE:
1754+
case LDNS_RDF_TYPE_LOC:
1755+
case LDNS_RDF_TYPE_WKS:
1756+
case LDNS_RDF_TYPE_NSAP:
1757+
case LDNS_RDF_TYPE_ATMA:
1758+
case LDNS_RDF_TYPE_IPSECKEY:
1759+
case LDNS_RDF_TYPE_LONG_STR:
1760+
case LDNS_RDF_TYPE_AMTRELAY:
1761+
case LDNS_RDF_TYPE_NONE:
1762+
rd_min -= 1;
1763+
}
1764+
}
1765+
1766+
RETVAL = rd_min <= rd_count && rd_count <= rd_max;
1767+
OUTPUT:
1768+
RETVAL
1769+
17301770
void
17311771
rr_DESTROY(obj)
17321772
Zonemaster::LDNS::RR obj;
@@ -2275,20 +2315,36 @@ rr_nsec3_iterations(obj)
22752315
SV *
22762316
rr_nsec3_salt(obj)
22772317
Zonemaster::LDNS::RR::NSEC3 obj;
2278-
PPCODE:
2279-
if(ldns_nsec3_salt_length(obj) > 0)
2280-
{
2281-
ldns_rdf *buf = ldns_nsec3_salt(obj);
2282-
ST(0) = sv_2mortal(newSVpvn((char *)ldns_rdf_data(buf), ldns_rdf_size(buf)));
2283-
ldns_rdf_deep_free(buf);
2318+
CODE:
2319+
{
2320+
uint8_t *salt = ldns_nsec3_salt_data(obj);
2321+
if (salt) {
2322+
RETVAL = newSVpvn((char *)salt, ldns_nsec3_salt_length(obj));
2323+
LDNS_FREE(salt);
22842324
}
2325+
}
2326+
OUTPUT:
2327+
RETVAL
22852328

22862329
SV *
22872330
rr_nsec3_next_owner(obj)
22882331
Zonemaster::LDNS::RR::NSEC3 obj;
2332+
INIT:
2333+
ldns_rdf *buf = NULL;
2334+
size_t size;
22892335
CODE:
2290-
ldns_rdf *buf = ldns_nsec3_next_owner(obj);
2291-
RETVAL = newSVpvn((char *)ldns_rdf_data(buf), ldns_rdf_size(buf));
2336+
buf = ldns_nsec3_next_owner(obj);
2337+
if (!buf) {
2338+
XSRETURN_UNDEF;
2339+
}
2340+
size = ldns_rdf_size(buf);
2341+
if (size < 1) {
2342+
XSRETURN_UNDEF;
2343+
}
2344+
2345+
/* ldns_rdf_data(buf) points to the hashed next owner name preceded by a
2346+
* length byte, which we don't want. */
2347+
RETVAL = newSVpvn((char *)(ldns_rdf_data(buf) + 1), size - 1);
22922348
OUTPUT:
22932349
RETVAL
22942350

@@ -2337,22 +2393,45 @@ bool
23372393
rr_nsec3_covers(obj,name)
23382394
Zonemaster::LDNS::RR::NSEC3 obj;
23392395
const char *name;
2396+
INIT:
2397+
/* Sanity test on owner name */
2398+
if (ldns_dname_label_count(ldns_rr_owner(obj)) == 0)
2399+
XSRETURN_UNDEF;
2400+
2401+
/* Sanity test on hashed next owner field */
2402+
ldns_rdf *next_owner = ldns_nsec3_next_owner(obj);
2403+
if (!next_owner || ldns_rdf_size(next_owner) <= 1)
2404+
XSRETURN_UNDEF;
2405+
23402406
CODE:
23412407
{
23422408
ldns_rr *clone;
23432409
ldns_rdf *dname;
23442410
ldns_rdf *hashed;
23452411
ldns_rdf *chopped;
23462412

2347-
clone = ldns_rr_clone(obj);
23482413
dname = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, name);
2414+
if (!dname)
2415+
XSRETURN_UNDEF;
2416+
23492417
ldns_dname2canonical(dname);
2418+
2419+
chopped = ldns_dname_left_chop(dname);
2420+
if (!chopped) {
2421+
ldns_rdf_deep_free(dname);
2422+
XSRETURN_UNDEF;
2423+
}
2424+
2425+
clone = ldns_rr_clone(obj);
23502426
ldns_rr2canonical(clone);
23512427
hashed = ldns_nsec3_hash_name_frm_nsec3(clone, dname);
2352-
chopped = ldns_dname_left_chop(dname);
2428+
23532429
ldns_rdf_deep_free(dname);
2430+
23542431
ldns_dname_cat(hashed,chopped);
2432+
23552433
RETVAL = ldns_nsec_covers_name(clone,hashed);
2434+
23562435
ldns_rdf_deep_free(hashed);
23572436
ldns_rdf_deep_free(chopped);
23582437
ldns_rr_free(clone);
@@ -2390,12 +2469,17 @@ rr_nsec3param_iterations(obj)
23902469
SV *
23912470
rr_nsec3param_salt(obj)
23922471
Zonemaster::LDNS::RR::NSEC3PARAM obj;
2393-
PPCODE:
2394-
ldns_rdf *rdf = ldns_rr_rdf(obj,3);
2395-
if(ldns_rdf_size(rdf) > 0)
2472+
CODE:
2473+
{
2474+
ldns_rdf *rdf = ldns_rr_rdf(obj, 3);
2475+
size_t size = ldns_rdf_size(rdf);
2476+
if (size > 0)
23962477
{
2397-
mPUSHs(newSVpvn((char *)ldns_rdf_data(rdf), ldns_rdf_size(rdf)));
2478+
RETVAL = newSVpvn((char *)(ldns_rdf_data(rdf) + 1), size - 1);
23982479
}
2480+
}
2481+
OUTPUT:
2482+
RETVAL
23992483

24002484
MODULE = Zonemaster::LDNS PACKAGE = Zonemaster::LDNS::RR::PTR PREFIX=rr_ptr_
24012485

0 commit comments

Comments
 (0)