Skip to content

Commit 4dac113

Browse files
authored
Merge pull request #172 from zonemaster/develop
Merge develop into master
2 parents 7d1b243 + 6b8f901 commit 4dac113

File tree

7 files changed

+149
-52
lines changed

7 files changed

+149
-52
lines changed

Changes

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

3+
3.2.0 2023-06-21 (public fix version)
4+
[Feature]
5+
- Expand DNAME support (#170)
6+
7+
[Fixes]
8+
- Ignore DNSKEY RRs with incalculable key sizes (#135)
9+
10+
311
3.1.0 2023-01-31 (public fix version)
412
[Feature]
513
- Includes the OPT RDATA from the edns_data function

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.1.0';
5+
our $VERSION = '3.2.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: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,36 @@ sub data {
2626
return $self->wireformat;
2727
}
2828

29+
sub answer {
30+
my ( $self ) = @_;
31+
32+
my @records = $self->answer_unfiltered;
33+
34+
for ( my $i = $#records ; $i >= 0 ; --$i ) {
35+
if ( $records[$i]->type() eq 'DNSKEY' && $records[$i]->keysize() == -1 ) {
36+
splice @records, $i, 1;
37+
}
38+
}
39+
40+
return @records;
41+
}
42+
43+
sub authority {
44+
my ( $self ) = @_;
45+
46+
my @records = $self->authority_unfiltered;
47+
48+
return @records;
49+
}
50+
51+
sub additional {
52+
my ( $self ) = @_;
53+
54+
my @records = $self->additional_unfiltered;
55+
56+
return @records;
57+
}
58+
2959
1;
3060

3161
=head1 NAME

lib/Zonemaster/LDNS/RR/DNAME.pm

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ A subclass of L<Zonemaster::LDNS::RR>, so it has all the methods of that class a
1717
1818
=head1 METHODS
1919
20-
No RDATA methods implemented yet.
20+
=over
2121
22-
=cut
22+
=item dname()
23+
24+
Returns the delegation name, i.e. the <target> field from the RDATA of a DNAME record.
25+
26+
=back

lib/Zonemaster/LDNS/RR/DNSKEY.pm

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,65 @@ use warnings;
55

66
use parent 'Zonemaster::LDNS::RR';
77

8+
sub keysize {
9+
my ( $self ) = @_;
10+
11+
my $algo = $self->algorithm;
12+
my $data = $self->keydata;
13+
14+
# RSA variants
15+
if ( $algo == 1 || $algo == 5 || $algo == 7 || $algo == 8 || $algo == 10 ) {
16+
17+
# Read first byte
18+
return -1
19+
if length $data < 1;
20+
my $byte = unpack( "c1", $data );
21+
22+
my $remaining;
23+
if ( $byte > 0 ) {
24+
$remaining = length( $data ) - 1 - $byte;
25+
}
26+
else {
27+
# Read bytes 1 and 2 as big-endian
28+
return -1
29+
if length $data < 3;
30+
my $short = unpack( "x1s>1", $data );
31+
32+
$remaining = length( $data ) - 3 - $short;
33+
}
34+
35+
if ( $remaining < 0 ) {
36+
return -1;
37+
}
38+
else {
39+
return 8 * $remaining;
40+
}
41+
}
42+
43+
# DSA variants
44+
elsif ( $algo == 3 || $algo == 6 ) {
45+
46+
# Read first byte (the T value)
47+
return -1
48+
if length $data < 1;
49+
return unpack( "c1", $data );
50+
}
51+
52+
# Diffie-Hellman
53+
elsif ( $algo == 2 ) {
54+
55+
# Read bytes 4 and 5 as big-endian
56+
return -1
57+
if length $data < 6;
58+
return unpack( "x4s>1", $data );
59+
}
60+
61+
# No idea what this is
62+
else {
63+
return 0;
64+
}
65+
}
66+
867
1;
968

1069
=head1 NAME
@@ -44,5 +103,6 @@ be available, depending on how you ldns library was compiled.
44103
45104
The size of the key stored in the record. For RSA variants, it's the length in bits of the prime number. For DSA variants, it's the key's "T" value
46105
(see RFC2536). For DH, it's the value of the "prime length" field (and probably useless, since DH keys can't have signature records).
106+
If there is insufficient data in the public key field to calculate the key size, C<-1> is returned.
47107
48108
=back

src/LDNS.xs

Lines changed: 24 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,7 @@ packet_timestamp(obj,...)
10641064
RETVAL
10651065

10661066
SV *
1067-
packet_answer(obj)
1067+
packet_answer_unfiltered(obj)
10681068
Zonemaster::LDNS::Packet obj;
10691069
PPCODE:
10701070
{
@@ -1092,7 +1092,7 @@ packet_answer(obj)
10921092
}
10931093

10941094
SV *
1095-
packet_authority(obj)
1095+
packet_authority_unfiltered(obj)
10961096
Zonemaster::LDNS::Packet obj;
10971097
PPCODE:
10981098
{
@@ -1120,7 +1120,7 @@ packet_authority(obj)
11201120
}
11211121

11221122
SV *
1123-
packet_additional(obj)
1123+
packet_additional_unfiltered(obj)
11241124
Zonemaster::LDNS::Packet obj;
11251125
PPCODE:
11261126
{
@@ -1930,50 +1930,6 @@ rr_ds_verify(obj,other)
19301930

19311931
MODULE = Zonemaster::LDNS PACKAGE = Zonemaster::LDNS::RR::DNSKEY PREFIX=rr_dnskey_
19321932

1933-
U32
1934-
rr_dnskey_keysize(obj)
1935-
Zonemaster::LDNS::RR::DNSKEY obj;
1936-
CODE:
1937-
{
1938-
U8 algorithm = D_U8(obj,2);
1939-
ldns_rdf *rdf = ldns_rr_rdf(obj,3);
1940-
uint8_t *data = ldns_rdf_data(rdf);
1941-
size_t total = ldns_rdf_size(rdf);
1942-
1943-
/* RSA variants */
1944-
if(algorithm==1||algorithm==5||algorithm==7||algorithm==8||algorithm==10)
1945-
{
1946-
size_t ex_len;
1947-
1948-
if(data[0] == 0)
1949-
{
1950-
ex_len = 3+(U16)data[1];
1951-
}
1952-
else
1953-
{
1954-
ex_len = 1+(U8)data[0];
1955-
}
1956-
RETVAL = 8*(total-ex_len);
1957-
}
1958-
/* DSA variants */
1959-
else if(algorithm==3||algorithm==6)
1960-
{
1961-
RETVAL = (U8)data[0]; /* First octet is T value */
1962-
}
1963-
/* Diffie-Hellman */
1964-
else if(algorithm==2)
1965-
{
1966-
RETVAL = (U16)data[4];
1967-
}
1968-
/* No idea what this is */
1969-
else
1970-
{
1971-
RETVAL = 0;
1972-
}
1973-
}
1974-
OUTPUT:
1975-
RETVAL
1976-
19771933
U16
19781934
rr_dnskey_flags(obj)
19791935
Zonemaster::LDNS::RR::DNSKEY obj;
@@ -2003,8 +1959,15 @@ rr_dnskey_keydata(obj)
20031959
Zonemaster::LDNS::RR::DNSKEY obj;
20041960
CODE:
20051961
{
2006-
ldns_rdf *rdf = ldns_rr_rdf(obj,3);
2007-
RETVAL = newSVpvn((char*)ldns_rdf_data(rdf), ldns_rdf_size(rdf));
1962+
if (ldns_rr_rd_count(obj)>3)
1963+
{
1964+
ldns_rdf *rdf = ldns_rr_rdf(obj,3);
1965+
RETVAL = newSVpvn((char*)ldns_rdf_data(rdf), ldns_rdf_size(rdf));
1966+
}
1967+
else
1968+
{
1969+
RETVAL = newSVpvn("",0);
1970+
}
20081971
}
20091972
OUTPUT:
20101973
RETVAL
@@ -2459,6 +2422,18 @@ rr_cname_cname(obj)
24592422
CLEANUP:
24602423
free(RETVAL);
24612424

2425+
MODULE = Zonemaster::LDNS PACKAGE = Zonemaster::LDNS::RR::DNAME PREFIX=rr_dname_
2426+
2427+
char *
2428+
rr_dname_dname(obj)
2429+
Zonemaster::LDNS::RR::DNAME obj;
2430+
CODE:
2431+
RETVAL = randomize_capitalization(D_STRING(obj,0));
2432+
OUTPUT:
2433+
RETVAL
2434+
CLEANUP:
2435+
free(RETVAL);
2436+
24622437
MODULE = Zonemaster::LDNS PACKAGE = Zonemaster::LDNS::RR::KEY PREFIX=rr_key_
24632438

24642439
U16

t/rr.t

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use Test::More;
22
use Test::Fatal;
33
use Devel::Peek;
44
use MIME::Base64;
5+
use Test::Differences;
56

67
BEGIN { use_ok( 'Zonemaster::LDNS' ) }
78

@@ -107,6 +108,19 @@ subtest 'DNSKEY' => sub {
107108
ok( $rr->algorithm == 8 );
108109
}
109110
}
111+
112+
my $data = decode_base64( "BleFgAABAAEAAAAADW5sYWdyaWN1bHR1cmUCbmwAAAEAAcAMADAAAQAAAAAABAEBAwg=");
113+
my $p = Zonemaster::LDNS::Packet->new_from_wireformat( $data );
114+
my ( $rr, @extra ) = $p->answer_unfiltered;
115+
eq_or_diff \@extra, [], "no extra RRs found";
116+
if ( !defined $rr ) {
117+
BAIL_OUT( "no RR found" );
118+
}
119+
is $rr->keydata, "", "we're able to extract the public key field even when it's empty";
120+
is $rr->keysize, -1, "insufficient data to calculate key size is reported as -1";
121+
122+
my ( @rrs ) = $p->answer;
123+
eq_or_diff \@rrs, [], "DNSKEY record with empty public key is filtered out by answer()";
110124
};
111125

112126
subtest 'RRSIG' => sub {
@@ -235,6 +249,12 @@ subtest 'SPF' => sub {
235249

236250
};
237251

252+
subtest 'DNAME' => sub {
253+
my $rr = Zonemaster::LDNS::RR->new( 'examplë.fake 3600 IN DNAME example.fake' );
254+
isa_ok( $rr, 'Zonemaster::LDNS::RR::DNAME' );
255+
is($rr->dname(), 'example.fake.');
256+
};
257+
238258
subtest 'croak when given malformed CAA records' => sub {
239259
my $will_croak = sub {
240260
# This will croak if LDNS.xs is compiled with -DUSE_ITHREADS

0 commit comments

Comments
 (0)