From b3a6ebddcae7d585798499e2268c272e60937da4 Mon Sep 17 00:00:00 2001 From: Marc Bradshaw Date: Mon, 13 Nov 2023 00:25:32 +0000 Subject: [PATCH 1/3] Apply patch from RT#149825 Fixes char_str_list is not a valid sub in new Net::DNS Thanks to GBECHIS@cpan.org --- lib/Mail/SPF/Mod/Exp.pm | 21 +++++++++++++++++++-- lib/Mail/SPF/Server.pm | 12 +++++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/lib/Mail/SPF/Mod/Exp.pm b/lib/Mail/SPF/Mod/Exp.pm index 50ca729..d11f089 100644 --- a/lib/Mail/SPF/Mod/Exp.pm +++ b/lib/Mail/SPF/Mod/Exp.pm @@ -19,6 +19,8 @@ Mail::SPF::Mod::Exp - SPF record C modifier class use warnings; use strict; +use Net::DNS; + use Mail::SPF::Mod; use base 'Mail::SPF::GlobalMod'; @@ -145,12 +147,27 @@ sub process { @txt_rrs == 1 or $server->throw_result('permerror', $request, "Redundant authority explanation strings found at domain '$exp_domain'"); # RFC 4408, 6.2/4 - my $explanation = Mail::SPF::MacroString->new( + + my $explanation; + # join with no intervening spaces, RFC 6376 + if ( Net::DNS->VERSION >= 0.69 ) { + # must call txtdata() in a list context + $explanation = Mail::SPF::MacroString->new( + text => join('', $txt_rrs[0]->txtdata), + server => $server, + request => $request, + is_explanation => TRUE + ); + } else { + # char_str_list method is 'historical' + $explanation = Mail::SPF::MacroString->new( text => join('', $txt_rrs[0]->char_str_list), server => $server, request => $request, is_explanation => TRUE - ); + ); + } + $request->state('authority_explanation', $explanation); } # Ignore DNS and other errors: diff --git a/lib/Mail/SPF/Server.pm b/lib/Mail/SPF/Server.pm index 8c360a5..16951fe 100644 --- a/lib/Mail/SPF/Server.pm +++ b/lib/Mail/SPF/Server.pm @@ -22,6 +22,7 @@ use strict; use base 'Mail::SPF::Base'; use Error ':try'; +use Net::DNS; use Net::DNS::Resolver; use Mail::SPF::MacroString; @@ -510,10 +511,19 @@ sub get_acceptable_records_from_packet { # (This may be too simplistic for future revisions of SPF.) my @records; + foreach my $rr ($packet->answer) { next if $rr->type ne $rr_type; # Ignore RRs of unexpected type. - my $text = join('', $rr->char_str_list); + my $text; + # join with no intervening spaces, RFC 6376 + if ( Net::DNS->VERSION >= 0.69 ) { + # must call txtdata() in a list context + $text = join '', $rr->txtdata; + } else { + # char_str_list method is 'historical' + $text = join('', $rr->char_str_list); + } my $record; # Try to parse RR as each of the requested record versions, From 43c5898a4d86481adcd3a8d2d9ff71d6089ace9e Mon Sep 17 00:00:00 2001 From: Marc Bradshaw Date: Mon, 13 Nov 2023 01:21:22 +0000 Subject: [PATCH 2/3] This is a combination of 2 commits. Reimplement as a ternary using the can method This avoids the hard coded version string and will use txtdata whenever it is available --- lib/Mail/SPF/Mod/Exp.pm | 30 ++++++++++++------------------ lib/Mail/SPF/Server.pm | 14 ++++++-------- 2 files changed, 18 insertions(+), 26 deletions(-) diff --git a/lib/Mail/SPF/Mod/Exp.pm b/lib/Mail/SPF/Mod/Exp.pm index d11f089..918aa46 100644 --- a/lib/Mail/SPF/Mod/Exp.pm +++ b/lib/Mail/SPF/Mod/Exp.pm @@ -148,25 +148,19 @@ sub process { or $server->throw_result('permerror', $request, "Redundant authority explanation strings found at domain '$exp_domain'"); # RFC 4408, 6.2/4 - my $explanation; + # char_str_list method is 'historical', use as a fallback for Net::DNS prior to 0.69 + # where txtdata is not available. # join with no intervening spaces, RFC 6376 - if ( Net::DNS->VERSION >= 0.69 ) { - # must call txtdata() in a list context - $explanation = Mail::SPF::MacroString->new( - text => join('', $txt_rrs[0]->txtdata), - server => $server, - request => $request, - is_explanation => TRUE - ); - } else { - # char_str_list method is 'historical' - $explanation = Mail::SPF::MacroString->new( - text => join('', $txt_rrs[0]->char_str_list), - server => $server, - request => $request, - is_explanation => TRUE - ); - } + # must call txtdata() in a list context + my $text = $txt_rrs[0]->can('txtdata') + ? join('', $txt_rrs[0]->txtdata) + : join('', $txt_rrs[0]->char_str_list); + my $explanation = Mail::SPF::MacroString->new( + text => $text, + server => $server, + request => $request, + is_explanation => TRUE + ); $request->state('authority_explanation', $explanation); } diff --git a/lib/Mail/SPF/Server.pm b/lib/Mail/SPF/Server.pm index 16951fe..25116ef 100644 --- a/lib/Mail/SPF/Server.pm +++ b/lib/Mail/SPF/Server.pm @@ -515,15 +515,13 @@ sub get_acceptable_records_from_packet { foreach my $rr ($packet->answer) { next if $rr->type ne $rr_type; # Ignore RRs of unexpected type. - my $text; + # char_str_list method is 'historical', use as a fallback for Net::DNS prior to 0.69 + # where txtdata is not available. # join with no intervening spaces, RFC 6376 - if ( Net::DNS->VERSION >= 0.69 ) { - # must call txtdata() in a list context - $text = join '', $rr->txtdata; - } else { - # char_str_list method is 'historical' - $text = join('', $rr->char_str_list); - } + # must call txtdata() in a list context + my $text = $rr->can('txtdata') + ? join('', $rr->txtdata) + : join('', $rr->char_str_list); my $record; # Try to parse RR as each of the requested record versions, From 146a76609c934823f68cbc5a5601b5a652fb9d35 Mon Sep 17 00:00:00 2001 From: Marc Bradshaw Date: Mon, 13 Nov 2023 01:24:41 +0000 Subject: [PATCH 3/3] No longer need explicit Net::DNS import --- lib/Mail/SPF/Mod/Exp.pm | 2 -- lib/Mail/SPF/Server.pm | 1 - 2 files changed, 3 deletions(-) diff --git a/lib/Mail/SPF/Mod/Exp.pm b/lib/Mail/SPF/Mod/Exp.pm index 918aa46..21ce984 100644 --- a/lib/Mail/SPF/Mod/Exp.pm +++ b/lib/Mail/SPF/Mod/Exp.pm @@ -19,8 +19,6 @@ Mail::SPF::Mod::Exp - SPF record C modifier class use warnings; use strict; -use Net::DNS; - use Mail::SPF::Mod; use base 'Mail::SPF::GlobalMod'; diff --git a/lib/Mail/SPF/Server.pm b/lib/Mail/SPF/Server.pm index 25116ef..e1a6b03 100644 --- a/lib/Mail/SPF/Server.pm +++ b/lib/Mail/SPF/Server.pm @@ -22,7 +22,6 @@ use strict; use base 'Mail::SPF::Base'; use Error ':try'; -use Net::DNS; use Net::DNS::Resolver; use Mail::SPF::MacroString;