From owner-freebsd-ports-bugs@FreeBSD.ORG Tue May 24 18:00:21 2011 Return-Path: Delivered-To: freebsd-ports-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B59E5106567F for ; Tue, 24 May 2011 18:00:21 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 9135A8FC1C for ; Tue, 24 May 2011 18:00:21 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id p4OI0L2W085616 for ; Tue, 24 May 2011 18:00:21 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id p4OI0LjM085614; Tue, 24 May 2011 18:00:21 GMT (envelope-from gnats) Date: Tue, 24 May 2011 18:00:21 GMT Message-Id: <201105241800.p4OI0LjM085614@freefall.freebsd.org> To: freebsd-ports-bugs@FreeBSD.org From: Koen Martens Cc: Subject: Re: ports/157107: conflict between mail/p5-Mail-SPF and mail/libspf2 X-BeenThere: freebsd-ports-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Koen Martens List-Id: Ports bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 May 2011 18:00:21 -0000 The following reply was made to PR ports/157107; it has been noted by GNATS. From: Koen Martens To: bug-followup@FreeBSD.ORG Cc: Subject: Re: ports/157107: conflict between mail/p5-Mail-SPF and mail/libspf2 Date: Tue, 24 May 2011 19:58:20 +0200 --r5Pyd7+fXNt84Ff3 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline This patch should fix it. On Tue, May 17, 2011 at 09:10:24AM +0000, Edwin Groothuis wrote: > Maintainer of mail/p5-Mail-SPF, > > Please note that PR ports/157107 has just been submitted. > > If it contains a patch for an upgrade, an enhancement or a bug fix > you agree on, reply to this email stating that you approve the patch > and a committer will take care of it. > > The full text of the PR can be found at: > http://www.freebsd.org/cgi/query-pr.cgi?pr=ports/157107 > > -- > Edwin Groothuis via the GNATS Auto Assign Tool > edwin@FreeBSD.org > > -- http://www.sonologic.nl/ http://koenmartens.nl/ https://www.revspace.nl/ http://hxxfoundation.com/ --r5Pyd7+fXNt84Ff3 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="p5-Mail-SPF.patch" diff -Naur p5-Mail-SPF.dist/Makefile p5-Mail-SPF/Makefile --- p5-Mail-SPF.dist/Makefile 2009-11-15 10:07:11.000000000 +0100 +++ p5-Mail-SPF/Makefile 2011-05-24 19:52:00.000000000 +0200 @@ -15,6 +15,9 @@ MAINTAINER= gmc@sonologic.nl COMMENT= Reference implementation of the RFC 4408 SPF protocol +OPTIONS= SPFQUERY "Install spfquery command-line tool" on \ + SPFQUERY_SUFFIX "Add .pl suffix to spfquery" off + RUN_DEPENDS= p5-Net-DNS-Resolver-Programmable>=0.002.1:${PORTSDIR}/dns/p5-Net-DNS-Resolver-Programmable \ p5-Net-DNS>=0.58:${PORTSDIR}/dns/p5-Net-DNS \ p5-version>0:${PORTSDIR}/devel/p5-version \ @@ -28,7 +31,6 @@ PERL_MODBUILD= 5.6.0+ CONFIGURE_ARGS= --install_path sbin=${PREFIX}/sbin -MAN1= spfquery.1 MAN3= Mail::SPF.3 Mail::SPF::Mech::PTR.3 Mail::SPF::Mech.3 \ Mail::SPF::SenderIPAddrMech.3 Mail::SPF::MacroString.3 \ Mail::SPF::Mech::IP4.3 Mail::SPF::Mech::A.3 \ @@ -45,6 +47,24 @@ DOCSDIR= ${PREFIX}/share/doc/p5-Mail-SPF DOCS= CHANGES INSTALL LICENSE README TODO +.if defined(WITH_SPFQUERY) +PLIST_SUB+= SPFQUERY="" + +.if defined(WITH_SPFQUERY_SUFFIX) +PLIST_SUB+= SPFQUERY_SUFFIX=".pl" +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-spfquery-suffix +MAN1+= spfquery.pl.1 +.else +PLIST_SUB+= SPFQUERY_SUFFIX="" +MAN1+= spfquery.1 +CONFLICTS+= libspf2* +.endif + +.else +PLIST_SUB+= SPFQUERY="@comment " +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-no-spfquery +.endif + post-install: .if !defined(NOPORTDOCS) @${MKDIR} ${DOCSDIR} diff -Naur p5-Mail-SPF.dist/files/extra-patch-no-spfquery p5-Mail-SPF/files/extra-patch-no-spfquery --- p5-Mail-SPF.dist/files/extra-patch-no-spfquery 1970-01-01 01:00:00.000000000 +0100 +++ p5-Mail-SPF/files/extra-patch-no-spfquery 2011-05-24 19:30:10.000000000 +0200 @@ -0,0 +1,33 @@ +diff -Naur orig/Build.PL Build.PL +--- orig/Build.PL 2009-10-31 23:16:14.000000000 +0100 ++++ Build.PL 2011-05-24 19:27:19.000000000 +0200 +@@ -66,7 +66,6 @@ + => 'v0.002.1', + }, + script_files => [ +- 'bin/spfquery' + ], + install_path => { + 'sbin' => '/usr/sbin' +diff -Naur orig/MANIFEST MANIFEST +--- orig/MANIFEST 2009-10-31 23:16:14.000000000 +0100 ++++ MANIFEST 2011-05-24 19:26:56.000000000 +0200 +@@ -1,4 +1,3 @@ +-bin/spfquery + Build.PL + CHANGES + debian/changelog +diff -Naur orig/README README +--- orig/README 2009-10-31 23:16:14.000000000 +0100 ++++ README 2011-05-24 19:27:05.000000000 +0200 +@@ -12,9 +12,8 @@ + This release of Mail::SPF fully conforms to RFC 4408 and passes the 2008.08 + release of the official test-suite . + +-The Mail::SPF source package includes the following additional tools: ++The Mail::SPF source package includes the following additional tool: + +- * spfquery: A command-line tool for performing SPF checks. + * spfd: A daemon for services that perform SPF checks frequently. + + Mail::SPF is not your mother! diff -Naur p5-Mail-SPF.dist/files/extra-patch-spfquery-suffix p5-Mail-SPF/files/extra-patch-spfquery-suffix --- p5-Mail-SPF.dist/files/extra-patch-spfquery-suffix 1970-01-01 01:00:00.000000000 +0100 +++ p5-Mail-SPF/files/extra-patch-spfquery-suffix 2011-05-24 19:41:56.000000000 +0200 @@ -0,0 +1,1505 @@ +diff -Naur orig/Build.PL Build.PL +--- orig/Build.PL 2009-10-31 23:16:14.000000000 +0100 ++++ Build.PL 2011-05-24 19:40:10.000000000 +0200 +@@ -66,7 +66,7 @@ + => 'v0.002.1', + }, + script_files => [ +- 'bin/spfquery' ++ 'bin/spfquery.pl' + ], + install_path => { + 'sbin' => '/usr/sbin' +diff -Naur orig/MANIFEST MANIFEST +--- orig/MANIFEST 2009-10-31 23:16:14.000000000 +0100 ++++ MANIFEST 2011-05-24 19:40:36.000000000 +0200 +@@ -1,4 +1,4 @@ +-bin/spfquery ++bin/spfquery.pl + Build.PL + CHANGES + debian/changelog +diff -Naur orig/README README +--- orig/README 2009-10-31 23:16:14.000000000 +0100 ++++ README 2011-05-24 19:40:54.000000000 +0200 +@@ -14,8 +14,8 @@ + + The Mail::SPF source package includes the following additional tools: + +- * spfquery: A command-line tool for performing SPF checks. +- * spfd: A daemon for services that perform SPF checks frequently. ++ * spfquery.pl: A command-line tool for performing SPF checks. ++ * spfd: A daemon for services that perform SPF checks frequently. + + Mail::SPF is not your mother! + ----------------------------- +diff -Naur orig/bin/spfquery bin/spfquery +--- orig/bin/spfquery 2009-10-31 23:16:14.000000000 +0100 ++++ bin/spfquery 1970-01-01 01:00:00.000000000 +0100 +@@ -1,731 +0,0 @@ +-#!/usr/bin/perl +- +-# +-# spfquery: Command-line tool for performing SPF queries +-# +-# (C) 2005-2008 Julian Mehnle +-# 2004 Wayne Schlitt +-# $Id: spfquery 138 2006-01-22 18:00:34Z julian $ +-# +-############################################################################## +- +-=head1 NAME +- +-spfquery - (Mail::SPF) - Checks if a given set of e-mail parameters matches a +-domain's SPF policy +- +-=head1 VERSION +- +-2.501 +- +-=head1 SYNOPSIS +- +-=over +- +-=item B +- +-B [B<--versions>|B<-v> B<1>|B<2>|B<1,2>] [B<--scope>|B<-s> B|B|B] +-B<--identity>|B<--id> I B<--ip-address>|B<--ip> I +-[B<--helo-identity>|B<--helo-id> I] [I] +- +-B [B<--versions>|B<-v> B<1>|B<2>|B<1,2>] [B<--scope>|B<-s> B|B|B] +-B<--file>|B<-f> I|B<-> [I] +- +-=item B +- +-B B<--helo> I B<--ip-address>|B<--ip> I [I] +- +-B B<--mfrom> I B<--ip-address>|B<--ip> I +-[B<--helo> I] [I] +- +-B B<--pra> I B<--ip-address>|B<--ip> I [I] +- +-=item B +- +-B B<--version>|B<-V> +- +-B B<--help> +- +-=back +- +-=head1 DESCRIPTION +- +-B checks if a given set of e-mail parameters (e.g., the SMTP sender's +-IP address) matches the responsible domain's Sender Policy Framework (SPF) +-policy. For more information on SPF see L. +- +-=head2 Preferred Usage +- +-The following usage forms are preferred over the L +-used by older B versions: +- +-The B<--identity> form checks if the given I is an authorized SMTP +-sender for the given C hostname, C envelope sender e-mail address, +-or C (so-called purported resonsible address) e-mail address, depending +-on the value of the B<--scope> option (which defaults to B if omitted). +- +-The B<--file> form reads "I I [I]" tuples +-from the file with the specified I, or from standard input if +-I is B<->, and checks them against the specified scope (B by +-default). +- +-Both forms support an optional B<--versions> option, which specifies a +-comma-separated list of the SPF version numbers of SPF records that may be +-used. B<1> means that C records should be used. B<2> means that +-C records should be used. Defaults to B<1,2>, i.e., uses any SPF +-records that are available. Records of a higher version are preferred. +- +-=head2 Legacy Usage +- +-B versions before 2.500 featured the following usage forms, which are +-discouraged but still supported for L: +- +-The B<--helo> form checks if the given I is an authorized SMTP +-sender for the C hostname given as the I (so-called C +-check). +- +-The B<--mfrom> form checks if the given I is an authorized SMTP +-sender for the envelope sender email-address (or domain) given as the +-I (so-called C check). If a domain is given instead of an +-e-mail address, C will be substituted for the localpart. +- +-The B<--pra> form checks if the given I is an authorized SMTP +-sender for the PRA (Purported Responsible Address) e-mail address given as the +-identity. +- +-=head2 Other Usage +- +-The B<--version> form prints version information of spfquery. The B<--help> +-form prints usage information for spfquery. +- +-=head1 OPTIONS +- +-=head2 Standard Options +- +-The preferred and legacy forms optionally take any of the following +-I: +- +-=over +- +-=item B<--default-explanation> I +- +-=item B<--def-exp> I +- +-Use the specified I as the default explanation if the authority domain +-does not specify an explanation string of its own. +- +-=item B<--hostname> I +- +-Use I as the host name of the local system instead of auto-detecting +-it. +- +-=item B<--keep-comments> +- +-=item B<--no-keep-comments> +- +-Do (not) print any comments found when reading from a file or from standard +-input. +- +-=item B<--sanitize> (currently ignored) +- +-=item B<--no-sanitize> (currently ignored) +- +-Do (not) sanitize the output by condensing consecutive white-space into a +-single space and replacing non-printable characters with question marks. +-Enabled by default. +- +-=item B<--debug> (currently ignored) +- +-Print out debug information. +- +-=back +- +-=head2 Black Magic Options +- +-Several options that were supported by earlier versions of B are +-considered black magic (i.e. potentially dangerous for the innocent user) and +-are thus disabled by default. If the L> Perl module +-is installed, they may be enabled by specifying B<--enable-black-magic>. +- +-=over +- +-=item B<--max-dns-interactive-terms> I +- +-Evaluate a maximum of I DNS-interactive mechanisms and modifiers per SPF +-check. Defaults to B<10>. Do I override the default unless you know what +-you are doing! +- +-=item B<--max-name-lookups-per-term> I +- +-Perform a maximum of I DNS name look-ups per mechanism or modifier. +-Defaults to B<10>. Do I override the default unless you know what you are +-doing! +- +-=item B<--authorize-mxes-for> I|IB<,>... +- +-Consider all the MXes of the comma-separated list of Ies and +-Is as inherently authorized. +- +-=item B<--tfwl> +- +-Perform C accreditation checking. +- +-=item B<--guess> I +- +-Use I as a default record if no SPF record is found. +- +-=item B<--local> I +- +-Process I as local policy before resorting to a default result +-(the implicit or explicit C mechanism at the end of the domain's SPF +-record). For example, this could be used for white-listing one's secondary +-MXes: C. +- +-=item B<--override> IB<=>I +- +-=item B<--fallback> IB<=>I +- +-Set overrides and fallbacks. Each option can be specified multiple times. For +-example: +- +- --override example.org='v=spf1 -all' +- --override '*.example.net'='v=spf1 a mx -all' +- --fallback example.com='v=spf1 -all' +- +-=back +- +-=head1 RESULT CODES +- +-=over 12 +- +-=item B +- +-The specified IP address is an authorized SMTP sender for the identity. +- +-=item B +- +-The specified IP address is not an authorized SMTP sender for the identity. +- +-=item B +- +-The specified IP address is not an authorized SMTP sender for the identity, +-however the authority domain is still testing out its SPF policy. +- +-=item B +- +-The identity's authority domain makes no assertion about the status of the IP +-address. +- +-=item B +- +-A permanent error occurred while evaluating the authority domain's policy +-(e.g., a syntax error in the SPF record). Manual intervention is required +-from the authority domain. +- +-=item B +- +-A temporary error occurred while evaluating the authority domain's policy +-(e.g., a DNS error). Try again later. +- +-=item B +- +-There is no applicable SPF policy for the identity domain. +- +-=back +- +-=head1 EXIT CODES +- +- Result | Exit code +- -----------+----------- +- pass | 0 +- fail | 1 +- softfail | 2 +- neutral | 3 +- permerror | 4 +- temperror | 5 +- none | 6 +- +-=head1 EXAMPLES +- +- spfquery --scope mfrom --id user@example.com --ip 1.2.3.4 +- spfquery --file test_data +- echo "127.0.0.1 user@example.com helohost.example.com" | spfquery -f - +- +-=head1 COMPATIBILITY +- +-B has undergone the following interface changes compared to earlier +-versions: +- +-=over +- +-=item B<2.500> +- +-=over +- +-=item * +- +-A new preferred usage style for performing individual SPF checks has been +-introduced. The new style accepts a unified B<--identity> option and an +-optional B<--scope> option that specifies the type (scope) of the identity. In +-contrast, the legacy usage style requires a separate usage form for every +-supported scope. See L and L for details. +- +-=item * +- +-The former C and C result codes have been renamed to C +-and C, respectively, in order to comply with RFC 4408 terminology. +- +-=item * +- +-SPF checks with an empty identity are no longer supported. In the case of an +-empty C SMTP transaction parameter, perform a check with the C +-scope directly. +- +-=item * +- +-The B<--debug> and B<--(no-)sanitize> options are currently ignored by this +-version of B. They will again be supported in the future. +- +-=item * +- +-Several features that were supported by earlier versions of B are +-considered black magic and thus are now disabled by default. See L. +- +-=item * +- +-Several option names have been deprecated. This is a list of them and their +-preferred synonyms: +- +- Deprecated options | Preferred options +- ---------------------+----------------------------- +- --sender, -s | --mfrom +- --ipv4, -i | --ip-address, --ip +- --name | --hostname +- --max-lookup-count, | --max-dns-interactive-terms +- --max-lookup | +- --rcpt-to, -r | --authorize-mxes-for +- --trusted | --tfwl +- +-=back +- +-=back +- +-=head1 SEE ALSO +- +-L, L +- +-L +- +-=head1 AUTHORS +- +-This version of B is a complete rewrite by Julian Mehnle +-, based on an earlier version written by Meng Weng Wong +- and Wayne Schlitt . +- +-=cut +- +-our $VERSION = '2.501'; +- +-use warnings; +-use strict; +- +-use IO::File; +-use Getopt::Long qw(:config gnu_compat no_ignore_case); +-use Error ':try'; +-use Mail::SPF; +- +-use constant TRUE => (0 == 0); +-use constant FALSE => not TRUE; +- +-use constant exit_codes_by_result_code => { +- pass => 0, +- fail => 1, +- softfail => 2, +- neutral => 3, +- permerror => 4, +- temperror => 5, +- none => 6 +-}; +- +-# Helper Functions +-############################################################################## +- +-sub usage { +- STDERR->printf(<<'EOT'); +-Preferred Usage: +- spfquery [--versions|-v 1|2|1,2] [--scope|-s helo|mfrom|pra] +- --identity|--id --ip-address|--ip +- [--helo-identity|--helo-id ] [OPTIONS] +- spfquery [--versions|-v 1|2|1,2] [--scope|-s helo|mfrom|pra] +- --file|-f |- [OPTIONS] +- +-Legacy Usage: +- spfquery --helo --ip-address|--ip [OPTIONS] +- spfquery --mfrom --ip-address|--ip +- [--helo ] [OPTIONS] +- spfquery --pra --ip-address|--ip [OPTIONS] +- +-Other Usage: +- spfquery --version|-V +- +-See `spfquery --help` for more information. +-EOT +- return; +-} +- +-sub help { +- print(<<'EOT'); +-Preferred Usage: +- spfquery [--versions|-v 1|2|1,2] [--scope|-s helo|mfrom|pra] +- --identity|--id --ip-address|--ip +- [--helo-identity|--helo-id ] [OPTIONS] +- spfquery [--versions|-v 1|2|1,2] [--scope|-s helo|mfrom|pra] +- --file|-f |- [OPTIONS] +- +-Legacy Usage: +- spfquery --helo --ip-address|--ip [OPTIONS] +- spfquery --mfrom --ip-address|--ip +- [--helo ] [OPTIONS] +- spfquery --pra --ip-address|--ip [OPTIONS] +- +-Other Usage: +- spfquery --version|-V +- +-spfquery performs SPF checks based on the command-line arguments or data given +-in a file or on standard input. +- +-Only the preferred and other usage forms are explained here. See the +-spfquery(1) man-page for an explanation of the legacy usage forms. +- +-The "--identity" form checks if the given is an authorized SMTP +-sender for the given "helo" hostname, "mfrom" envelope sender e-mail address, +-or "pra" (purported resonsible address) e-mail address, depending on the value +-of the "--scope" option (which defaults to "mfrom" if omitted). +- +-The "--file" form reads " []" tuples from +-the file with the specified , or from standard input if is +-"-", and checks them against the specified scope ("mfrom" by default). +- +-The "--version" form prints version information of spfquery. +- +-Valid OPTIONS (and their defaults) are: +- --default-explanation +- Default explanation string to use (sensible default). +- --hostname +- The name of the system doing the SPF checking (local +- system's configured hostname). +- --keep-comments Print comments found when reading from a file. +- --no-sanitize Do not clean up invalid characters in output. +- --debug Output debugging information. +- +-Black-magic OPTIONS are: +- --max-dns-interactive-terms +- Maximum number of DNS-interactive mechanisms and +- modifiers (10). +- --max-name-lookups-per-term +- Maximum number of DNS name look-ups per mechanism or +- modifier (10). +- --authorize-mxes-for |,... +- A comma-separated list of e-mail addresses and domains +- whose MXes will be considered inherently authorized. +- --tfwl Check trusted-forwarder.org white-list. +- --guess Default checks if no SPF record is found. +- --local Local policy to process before default result. +- --override = +- --fallback = +- Set override and fallback SPF records for domains. +- +-Examples: +- spfquery --scope mfrom --id user@example.com --ip 1.2.3.4 +- spfquery --file test_data +- echo "127.0.0.1 user@example.com helohost.example.com" | spfquery -f - +-EOT +- return; +-} +- +-sub deprecated_option { +- my ($old_option, $new_option, $options) = @_; +- return FALSE if not exists($options->{$old_option}); +- STDERR->print( +- "Warning: '$old_option' option is deprecated" . +- ($new_option ? "; use '$new_option' instead" : '') . +- ".\n" +- ); +- $options->{$new_option} = delete($options->{$old_option}); +- return TRUE; +-} +- +-sub unsupported_option { +- my ($option_name, $options) = @_; +- return FALSE if not exists($options->{$option_name}); +- STDERR->print("Error: '$option_name' option is no longer supported.\n"); +- return TRUE; +-} +- +-sub black_magic_option { +- my ($option_name, $options) = @_; +- return FALSE if not exists($options->{$option_name}); +- STDERR->print("Error: '$option_name' option is black magic! Do not use it!\n"); +- return TRUE; +-} +- +-# Command-line Option Handling +-############################################################################## +- +-my $options = {}; +-my $getopt_result = GetOptions( +- $options, +- +- 'file|f=s', +- +- 'versions|v=s', +- 'scope=s', +- 's=s', # Special handling for ambiguous 's' option (formerly a synonym +- # for 'sender', now preferredly a synonym for 'scope'). +- 'identity|id=s', +- 'ip-address|ip=s', +- 'helo-identity|helo-id=s', +- +- # Legacy/shortcut options: +- 'mfrom|mail-from|m=s', +- 'helo|h=s', +- +- 'default-explanation|def-exp=s', +- 'hostname=s', +- +- 'keep-comments!', +- 'debug!', # TODO Implement! +- 'sanitize!', # TODO Implement! +- +- # Black Magic options: +- 'enable-black-magic!', +- 'max-dns-interactive-terms=i', +- 'max-name-lookups-per-term=i', +- 'authorize-mxes-for=s', +- # TODO implement! +- 'tfwl!', # TODO Implement! +- 'guess=s', # TODO Implement! +- 'local=s', # TODO Implement! +- 'override=s%', # TODO Implement! +- 'fallback=s%', # TODO Implement! +- +- # Meta actions: +- 'version|V!', +- 'help!', +- +- # Deprecated options: +- 'sender=s', # Now 'scope'/'identity' or 'mfrom' +- 'ipv4=s', # Now 'ip-address' +- 'i=s', # Now 'ip-address' +- 'name=s', # Now 'hostname' +- 'max-lookup-count=i', +- 'max-lookup=i', # Now 'max-dns-interactive-terms' +- 'rcpt-to=s', # Now 'authorize-mxes-for' +- 'r=s', # Now 'authorize-mxes-for' +- 'trusted!' # Now 'tfwl' +-); +- +-if (not $getopt_result) { +- usage(); +- exit(255); +-} +- +-if ($options->{help}) { +- help(); +- exit(0); +-} +- +-if ($options->{version}) { +- print("spfquery version $VERSION (using Mail::SPF)\n"); +- exit(0); +-} +- +-deprecated_option('sender', 'mfrom', $options); +-deprecated_option('ipv4', 'ip-address', $options); +-deprecated_option('i', 'ip-address', $options); +-deprecated_option('name', 'hostname', $options); +-deprecated_option('max-lookup-count', 'max-dns-interactive-terms', $options); +-deprecated_option('max-lookup', 'max-dns-interactive-terms', $options); +-deprecated_option('rcpt-to', 'authorize-mxes-for', $options); +-deprecated_option('r', 'authorize-mxes-for', $options); +-deprecated_option('trusted', 'tfwl', $options); +- +-if ($options->{'enable-black-magic'}) { +- if (not defined(eval('require Mail::SPF::BlackMagic'))) { +- STDERR->print("Error: Cannot enable black magic. Unable to load Mail::SPF::BlackMagic.\n"); +- exit(255); +- } +- # else: Black magic enabled! +-} +-elsif ( +- black_magic_option('max-dns-interactive-terms', $options) or +- black_magic_option('max-name-lookups-per-term', $options) or +- black_magic_option('rcpt-to', $options) or +- black_magic_option('trusted', $options) or +- black_magic_option('guess', $options) or +- black_magic_option('local', $options) or +- black_magic_option('override', $options) or +- black_magic_option('fallback', $options) +-) { +- exit(255); +-} +- +-my @versions = split(',', $options->{versions} || ''); +-my $scope = $options->{scope}; +-my $identity = $options->{identity}; +-my $ip_address = $options->{'ip-address'}; +-my $helo_identity = $options->{'helo-identity'}; +- +-# Heuristic for distinguishing between 's(cope)' and 's(ender)': +-if (defined(my $s = $options->{s})) { +- if ( +- not defined($scope) and # No explicit 'scope' option has been specified, and +- $s !~ /[@.]/ # 's' option contains neither an '@' nor a dot, +- # so it cannot be an e-mail address or a domain. +- ) { +- # Thus it must be meant as the 'scope' option: +- $scope = $s; +- } +- else { +- # Else, it must be meant as the deprecated 'sender' option: +- $options->{mfrom} = $s; +- } +-} +- +-# Heuristic for when explicit 'scope'/'s(cope)' option is absent: +-if (not defined($scope)) { +- if (defined($identity) or defined($options->{file})) { +- # Identity has been specified, or input will be read from file: +- # apply the 'scope' option default: +- $scope = 'mfrom'; +- } +- elsif (defined($options->{helo})) { +- $scope = 'helo'; +- $identity = $options->{helo}; +- } +- elsif (defined($options->{mfrom})) { +- $scope = 'mfrom'; +- $identity = $options->{mfrom}; +- $helo_identity ||= $options->{helo}; +- } +- elsif (defined($options->{pra})) { +- $scope = 'pra'; +- $identity = $options->{pra}; +- } +-} +- +-my $default_explanation = $options->{'default-explanation'}; +-my $hostname = $options->{hostname}; +- +-if ( +- not defined($scope) or +- not (defined($identity) xor defined($options->{file})) +-) { +- usage(); +- exit(255); +-} +- +-if (defined($identity) and $identity eq '') { +- STDERR->print("Error: Empty identities are not supported. See spfquery(1).\n"); +- exit(255); +-} +- +-# Process the SPF Request(s) +-############################################################################## +- +-try { +- my $spf_server = Mail::SPF::Server->new( +- default_authority_explanation +- => $default_explanation, +- hostname => $hostname, +- # debug => $options->{debug}, +- # sanitize => $options->{sanitize}, +- +- # Black Magic: +- ( +- exists($options->{'max-dns-interactive-terms'}) ? +- (max_dns_interactive_terms => $options->{'max-dns-interactive-terms'} || undef) +- : () +- ), +- ( +- exists($options->{'max-name-lookups-per-term'}) ? +- (max_name_lookups_per_term => $options->{'max-name-lookups-per-term'} || undef) +- : () +- ) +- # rcpt_to => $options->{'rcpt-to'}, +- # trusted => $options->{trusted}, +- # guess => $options->{guess}, +- # local => $options->{local}, +- # override => $options->{override}, +- # fallback => $options->{fallback}, +- ); +- +- my $exit_code; +- +- if (not defined($options->{file})) { +- # Single request: +- my $result_code = do_process( +- $spf_server, +- versions => @versions ? [@versions] : undef, +- scope => $scope, +- identity => $identity, +- ip_address => $ip_address, +- helo_identity => $helo_identity +- ); +- $exit_code = exit_codes_by_result_code->{$result_code}; +- } +- else { +- # File request: +- my $file = $options->{file} eq '-' ? \*STDIN : IO::File->new($options->{file}) +- or die("Could not open: $options->{file}\n"); +- while (<$file>) { +- chomp; +- s/^\s*//; +- next if /^$/; +- if (/^#/) { +- print("$_\n") if $options->{'keep-comments'}; +- next; +- } +- ($ip_address, $identity, $helo_identity) = split; +- my $result_code = do_process( +- $spf_server, +- versions => @versions ? [@versions] : undef, +- scope => $scope, +- identity => $identity, +- ip_address => $ip_address, +- helo_identity => $helo_identity +- ); +- $exit_code ||= exit_codes_by_result_code->{$result_code}; +- } +- } +- +- exit($exit_code); +-} +-catch Mail::SPF::Exception with { +- my ($e) = @_; +- STDERR->printf("Error: %s.\n", $e->text); +- exit(255); +-}; +- +- +-# Helper Function +-############################################################################## +- +-sub do_process { +- my ($spf_server, %request_options) = @_; +- my $request = Mail::SPF::Request->new(%request_options); +- my $result = $spf_server->process($request); +- printf( +- "%s\n%s\n%s\n%s\n", +- $result->code, +- ( +- $result->can('authority_explanation') ? +- $result->authority_explanation +- : $result->local_explanation +- ), +- $result->local_explanation, +- $result->received_spf_header +- ); +- return $result->code; +-} +diff -Naur orig/bin/spfquery.pl bin/spfquery.pl +--- orig/bin/spfquery.pl 1970-01-01 01:00:00.000000000 +0100 ++++ bin/spfquery.pl 2009-10-31 23:16:14.000000000 +0100 +@@ -0,0 +1,731 @@ ++#!/usr/bin/perl ++ ++# ++# spfquery: Command-line tool for performing SPF queries ++# ++# (C) 2005-2008 Julian Mehnle ++# 2004 Wayne Schlitt ++# $Id: spfquery 138 2006-01-22 18:00:34Z julian $ ++# ++############################################################################## ++ ++=head1 NAME ++ ++spfquery - (Mail::SPF) - Checks if a given set of e-mail parameters matches a ++domain's SPF policy ++ ++=head1 VERSION ++ ++2.501 ++ ++=head1 SYNOPSIS ++ ++=over ++ ++=item B ++ ++B [B<--versions>|B<-v> B<1>|B<2>|B<1,2>] [B<--scope>|B<-s> B|B|B] ++B<--identity>|B<--id> I B<--ip-address>|B<--ip> I ++[B<--helo-identity>|B<--helo-id> I] [I] ++ ++B [B<--versions>|B<-v> B<1>|B<2>|B<1,2>] [B<--scope>|B<-s> B|B|B] ++B<--file>|B<-f> I|B<-> [I] ++ ++=item B ++ ++B B<--helo> I B<--ip-address>|B<--ip> I [I] ++ ++B B<--mfrom> I B<--ip-address>|B<--ip> I ++[B<--helo> I] [I] ++ ++B B<--pra> I B<--ip-address>|B<--ip> I [I] ++ ++=item B ++ ++B B<--version>|B<-V> ++ ++B B<--help> ++ ++=back ++ ++=head1 DESCRIPTION ++ ++B checks if a given set of e-mail parameters (e.g., the SMTP sender's ++IP address) matches the responsible domain's Sender Policy Framework (SPF) ++policy. For more information on SPF see L. ++ ++=head2 Preferred Usage ++ ++The following usage forms are preferred over the L ++used by older B versions: ++ ++The B<--identity> form checks if the given I is an authorized SMTP ++sender for the given C hostname, C envelope sender e-mail address, ++or C (so-called purported resonsible address) e-mail address, depending ++on the value of the B<--scope> option (which defaults to B if omitted). ++ ++The B<--file> form reads "I I [I]" tuples ++from the file with the specified I, or from standard input if ++I is B<->, and checks them against the specified scope (B by ++default). ++ ++Both forms support an optional B<--versions> option, which specifies a ++comma-separated list of the SPF version numbers of SPF records that may be ++used. B<1> means that C records should be used. B<2> means that ++C records should be used. Defaults to B<1,2>, i.e., uses any SPF ++records that are available. Records of a higher version are preferred. ++ ++=head2 Legacy Usage ++ ++B versions before 2.500 featured the following usage forms, which are ++discouraged but still supported for L: ++ ++The B<--helo> form checks if the given I is an authorized SMTP ++sender for the C hostname given as the I (so-called C ++check). ++ ++The B<--mfrom> form checks if the given I is an authorized SMTP ++sender for the envelope sender email-address (or domain) given as the ++I (so-called C check). If a domain is given instead of an ++e-mail address, C will be substituted for the localpart. ++ ++The B<--pra> form checks if the given I is an authorized SMTP ++sender for the PRA (Purported Responsible Address) e-mail address given as the ++identity. ++ ++=head2 Other Usage ++ ++The B<--version> form prints version information of spfquery. The B<--help> ++form prints usage information for spfquery. ++ ++=head1 OPTIONS ++ ++=head2 Standard Options ++ ++The preferred and legacy forms optionally take any of the following ++I: ++ ++=over ++ ++=item B<--default-explanation> I ++ ++=item B<--def-exp> I ++ ++Use the specified I as the default explanation if the authority domain ++does not specify an explanation string of its own. ++ ++=item B<--hostname> I ++ ++Use I as the host name of the local system instead of auto-detecting ++it. ++ ++=item B<--keep-comments> ++ ++=item B<--no-keep-comments> ++ ++Do (not) print any comments found when reading from a file or from standard ++input. ++ ++=item B<--sanitize> (currently ignored) ++ ++=item B<--no-sanitize> (currently ignored) ++ ++Do (not) sanitize the output by condensing consecutive white-space into a ++single space and replacing non-printable characters with question marks. ++Enabled by default. ++ ++=item B<--debug> (currently ignored) ++ ++Print out debug information. ++ ++=back ++ ++=head2 Black Magic Options ++ ++Several options that were supported by earlier versions of B are ++considered black magic (i.e. potentially dangerous for the innocent user) and ++are thus disabled by default. If the L> Perl module ++is installed, they may be enabled by specifying B<--enable-black-magic>. ++ ++=over ++ ++=item B<--max-dns-interactive-terms> I ++ ++Evaluate a maximum of I DNS-interactive mechanisms and modifiers per SPF ++check. Defaults to B<10>. Do I override the default unless you know what ++you are doing! ++ ++=item B<--max-name-lookups-per-term> I ++ ++Perform a maximum of I DNS name look-ups per mechanism or modifier. ++Defaults to B<10>. Do I override the default unless you know what you are ++doing! ++ ++=item B<--authorize-mxes-for> I|IB<,>... ++ ++Consider all the MXes of the comma-separated list of Ies and ++Is as inherently authorized. ++ ++=item B<--tfwl> ++ ++Perform C accreditation checking. ++ ++=item B<--guess> I ++ ++Use I as a default record if no SPF record is found. ++ ++=item B<--local> I ++ ++Process I as local policy before resorting to a default result ++(the implicit or explicit C mechanism at the end of the domain's SPF ++record). For example, this could be used for white-listing one's secondary ++MXes: C. ++ ++=item B<--override> IB<=>I ++ ++=item B<--fallback> IB<=>I ++ ++Set overrides and fallbacks. Each option can be specified multiple times. For ++example: ++ ++ --override example.org='v=spf1 -all' ++ --override '*.example.net'='v=spf1 a mx -all' ++ --fallback example.com='v=spf1 -all' ++ ++=back ++ ++=head1 RESULT CODES ++ ++=over 12 ++ ++=item B ++ ++The specified IP address is an authorized SMTP sender for the identity. ++ ++=item B ++ ++The specified IP address is not an authorized SMTP sender for the identity. ++ ++=item B ++ ++The specified IP address is not an authorized SMTP sender for the identity, ++however the authority domain is still testing out its SPF policy. ++ ++=item B ++ ++The identity's authority domain makes no assertion about the status of the IP ++address. ++ ++=item B ++ ++A permanent error occurred while evaluating the authority domain's policy ++(e.g., a syntax error in the SPF record). Manual intervention is required ++from the authority domain. ++ ++=item B ++ ++A temporary error occurred while evaluating the authority domain's policy ++(e.g., a DNS error). Try again later. ++ ++=item B ++ ++There is no applicable SPF policy for the identity domain. ++ ++=back ++ ++=head1 EXIT CODES ++ ++ Result | Exit code ++ -----------+----------- ++ pass | 0 ++ fail | 1 ++ softfail | 2 ++ neutral | 3 ++ permerror | 4 ++ temperror | 5 ++ none | 6 ++ ++=head1 EXAMPLES ++ ++ spfquery --scope mfrom --id user@example.com --ip 1.2.3.4 ++ spfquery --file test_data ++ echo "127.0.0.1 user@example.com helohost.example.com" | spfquery -f - ++ ++=head1 COMPATIBILITY ++ ++B has undergone the following interface changes compared to earlier ++versions: ++ ++=over ++ ++=item B<2.500> ++ ++=over ++ ++=item * ++ ++A new preferred usage style for performing individual SPF checks has been ++introduced. The new style accepts a unified B<--identity> option and an ++optional B<--scope> option that specifies the type (scope) of the identity. In ++contrast, the legacy usage style requires a separate usage form for every ++supported scope. See L and L for details. ++ ++=item * ++ ++The former C and C result codes have been renamed to C ++and C, respectively, in order to comply with RFC 4408 terminology. ++ ++=item * ++ ++SPF checks with an empty identity are no longer supported. In the case of an ++empty C SMTP transaction parameter, perform a check with the C ++scope directly. ++ ++=item * ++ ++The B<--debug> and B<--(no-)sanitize> options are currently ignored by this ++version of B. They will again be supported in the future. ++ ++=item * ++ ++Several features that were supported by earlier versions of B are ++considered black magic and thus are now disabled by default. See L. ++ ++=item * ++ ++Several option names have been deprecated. This is a list of them and their ++preferred synonyms: ++ ++ Deprecated options | Preferred options ++ ---------------------+----------------------------- ++ --sender, -s | --mfrom ++ --ipv4, -i | --ip-address, --ip ++ --name | --hostname ++ --max-lookup-count, | --max-dns-interactive-terms ++ --max-lookup | ++ --rcpt-to, -r | --authorize-mxes-for ++ --trusted | --tfwl ++ ++=back ++ ++=back ++ ++=head1 SEE ALSO ++ ++L, L ++ ++L ++ ++=head1 AUTHORS ++ ++This version of B is a complete rewrite by Julian Mehnle ++, based on an earlier version written by Meng Weng Wong ++ and Wayne Schlitt . ++ ++=cut ++ ++our $VERSION = '2.501'; ++ ++use warnings; ++use strict; ++ ++use IO::File; ++use Getopt::Long qw(:config gnu_compat no_ignore_case); ++use Error ':try'; ++use Mail::SPF; ++ ++use constant TRUE => (0 == 0); ++use constant FALSE => not TRUE; ++ ++use constant exit_codes_by_result_code => { ++ pass => 0, ++ fail => 1, ++ softfail => 2, ++ neutral => 3, ++ permerror => 4, ++ temperror => 5, ++ none => 6 ++}; ++ ++# Helper Functions ++############################################################################## ++ ++sub usage { ++ STDERR->printf(<<'EOT'); ++Preferred Usage: ++ spfquery [--versions|-v 1|2|1,2] [--scope|-s helo|mfrom|pra] ++ --identity|--id --ip-address|--ip ++ [--helo-identity|--helo-id ] [OPTIONS] ++ spfquery [--versions|-v 1|2|1,2] [--scope|-s helo|mfrom|pra] ++ --file|-f |- [OPTIONS] ++ ++Legacy Usage: ++ spfquery --helo --ip-address|--ip [OPTIONS] ++ spfquery --mfrom --ip-address|--ip ++ [--helo ] [OPTIONS] ++ spfquery --pra --ip-address|--ip [OPTIONS] ++ ++Other Usage: ++ spfquery --version|-V ++ ++See `spfquery --help` for more information. ++EOT ++ return; ++} ++ ++sub help { ++ print(<<'EOT'); ++Preferred Usage: ++ spfquery [--versions|-v 1|2|1,2] [--scope|-s helo|mfrom|pra] ++ --identity|--id --ip-address|--ip ++ [--helo-identity|--helo-id ] [OPTIONS] ++ spfquery [--versions|-v 1|2|1,2] [--scope|-s helo|mfrom|pra] ++ --file|-f |- [OPTIONS] ++ ++Legacy Usage: ++ spfquery --helo --ip-address|--ip [OPTIONS] ++ spfquery --mfrom --ip-address|--ip ++ [--helo ] [OPTIONS] ++ spfquery --pra --ip-address|--ip [OPTIONS] ++ ++Other Usage: ++ spfquery --version|-V ++ ++spfquery performs SPF checks based on the command-line arguments or data given ++in a file or on standard input. ++ ++Only the preferred and other usage forms are explained here. See the ++spfquery(1) man-page for an explanation of the legacy usage forms. ++ ++The "--identity" form checks if the given is an authorized SMTP ++sender for the given "helo" hostname, "mfrom" envelope sender e-mail address, ++or "pra" (purported resonsible address) e-mail address, depending on the value ++of the "--scope" option (which defaults to "mfrom" if omitted). ++ ++The "--file" form reads " []" tuples from ++the file with the specified , or from standard input if is ++"-", and checks them against the specified scope ("mfrom" by default). ++ ++The "--version" form prints version information of spfquery. ++ ++Valid OPTIONS (and their defaults) are: ++ --default-explanation ++ Default explanation string to use (sensible default). ++ --hostname ++ The name of the system doing the SPF checking (local ++ system's configured hostname). ++ --keep-comments Print comments found when reading from a file. ++ --no-sanitize Do not clean up invalid characters in output. ++ --debug Output debugging information. ++ ++Black-magic OPTIONS are: ++ --max-dns-interactive-terms ++ Maximum number of DNS-interactive mechanisms and ++ modifiers (10). ++ --max-name-lookups-per-term ++ Maximum number of DNS name look-ups per mechanism or ++ modifier (10). ++ --authorize-mxes-for |,... ++ A comma-separated list of e-mail addresses and domains ++ whose MXes will be considered inherently authorized. ++ --tfwl Check trusted-forwarder.org white-list. ++ --guess Default checks if no SPF record is found. ++ --local Local policy to process before default result. ++ --override = ++ --fallback = ++ Set override and fallback SPF records for domains. ++ ++Examples: ++ spfquery --scope mfrom --id user@example.com --ip 1.2.3.4 ++ spfquery --file test_data ++ echo "127.0.0.1 user@example.com helohost.example.com" | spfquery -f - ++EOT ++ return; ++} ++ ++sub deprecated_option { ++ my ($old_option, $new_option, $options) = @_; ++ return FALSE if not exists($options->{$old_option}); ++ STDERR->print( ++ "Warning: '$old_option' option is deprecated" . ++ ($new_option ? "; use '$new_option' instead" : '') . ++ ".\n" ++ ); ++ $options->{$new_option} = delete($options->{$old_option}); ++ return TRUE; ++} ++ ++sub unsupported_option { ++ my ($option_name, $options) = @_; ++ return FALSE if not exists($options->{$option_name}); ++ STDERR->print("Error: '$option_name' option is no longer supported.\n"); ++ return TRUE; ++} ++ ++sub black_magic_option { ++ my ($option_name, $options) = @_; ++ return FALSE if not exists($options->{$option_name}); ++ STDERR->print("Error: '$option_name' option is black magic! Do not use it!\n"); ++ return TRUE; ++} ++ ++# Command-line Option Handling ++############################################################################## ++ ++my $options = {}; ++my $getopt_result = GetOptions( ++ $options, ++ ++ 'file|f=s', ++ ++ 'versions|v=s', ++ 'scope=s', ++ 's=s', # Special handling for ambiguous 's' option (formerly a synonym ++ # for 'sender', now preferredly a synonym for 'scope'). ++ 'identity|id=s', ++ 'ip-address|ip=s', ++ 'helo-identity|helo-id=s', ++ ++ # Legacy/shortcut options: ++ 'mfrom|mail-from|m=s', ++ 'helo|h=s', ++ ++ 'default-explanation|def-exp=s', ++ 'hostname=s', ++ ++ 'keep-comments!', ++ 'debug!', # TODO Implement! ++ 'sanitize!', # TODO Implement! ++ ++ # Black Magic options: ++ 'enable-black-magic!', ++ 'max-dns-interactive-terms=i', ++ 'max-name-lookups-per-term=i', ++ 'authorize-mxes-for=s', ++ # TODO implement! ++ 'tfwl!', # TODO Implement! ++ 'guess=s', # TODO Implement! ++ 'local=s', # TODO Implement! ++ 'override=s%', # TODO Implement! ++ 'fallback=s%', # TODO Implement! ++ ++ # Meta actions: ++ 'version|V!', ++ 'help!', ++ ++ # Deprecated options: ++ 'sender=s', # Now 'scope'/'identity' or 'mfrom' ++ 'ipv4=s', # Now 'ip-address' ++ 'i=s', # Now 'ip-address' ++ 'name=s', # Now 'hostname' ++ 'max-lookup-count=i', ++ 'max-lookup=i', # Now 'max-dns-interactive-terms' ++ 'rcpt-to=s', # Now 'authorize-mxes-for' ++ 'r=s', # Now 'authorize-mxes-for' ++ 'trusted!' # Now 'tfwl' ++); ++ ++if (not $getopt_result) { ++ usage(); ++ exit(255); ++} ++ ++if ($options->{help}) { ++ help(); ++ exit(0); ++} ++ ++if ($options->{version}) { ++ print("spfquery version $VERSION (using Mail::SPF)\n"); ++ exit(0); ++} ++ ++deprecated_option('sender', 'mfrom', $options); ++deprecated_option('ipv4', 'ip-address', $options); ++deprecated_option('i', 'ip-address', $options); ++deprecated_option('name', 'hostname', $options); ++deprecated_option('max-lookup-count', 'max-dns-interactive-terms', $options); ++deprecated_option('max-lookup', 'max-dns-interactive-terms', $options); ++deprecated_option('rcpt-to', 'authorize-mxes-for', $options); ++deprecated_option('r', 'authorize-mxes-for', $options); ++deprecated_option('trusted', 'tfwl', $options); ++ ++if ($options->{'enable-black-magic'}) { ++ if (not defined(eval('require Mail::SPF::BlackMagic'))) { ++ STDERR->print("Error: Cannot enable black magic. Unable to load Mail::SPF::BlackMagic.\n"); ++ exit(255); ++ } ++ # else: Black magic enabled! ++} ++elsif ( ++ black_magic_option('max-dns-interactive-terms', $options) or ++ black_magic_option('max-name-lookups-per-term', $options) or ++ black_magic_option('rcpt-to', $options) or ++ black_magic_option('trusted', $options) or ++ black_magic_option('guess', $options) or ++ black_magic_option('local', $options) or ++ black_magic_option('override', $options) or ++ black_magic_option('fallback', $options) ++) { ++ exit(255); ++} ++ ++my @versions = split(',', $options->{versions} || ''); ++my $scope = $options->{scope}; ++my $identity = $options->{identity}; ++my $ip_address = $options->{'ip-address'}; ++my $helo_identity = $options->{'helo-identity'}; ++ ++# Heuristic for distinguishing between 's(cope)' and 's(ender)': ++if (defined(my $s = $options->{s})) { ++ if ( ++ not defined($scope) and # No explicit 'scope' option has been specified, and ++ $s !~ /[@.]/ # 's' option contains neither an '@' nor a dot, ++ # so it cannot be an e-mail address or a domain. ++ ) { ++ # Thus it must be meant as the 'scope' option: ++ $scope = $s; ++ } ++ else { ++ # Else, it must be meant as the deprecated 'sender' option: ++ $options->{mfrom} = $s; ++ } ++} ++ ++# Heuristic for when explicit 'scope'/'s(cope)' option is absent: ++if (not defined($scope)) { ++ if (defined($identity) or defined($options->{file})) { ++ # Identity has been specified, or input will be read from file: ++ # apply the 'scope' option default: ++ $scope = 'mfrom'; ++ } ++ elsif (defined($options->{helo})) { ++ $scope = 'helo'; ++ $identity = $options->{helo}; ++ } ++ elsif (defined($options->{mfrom})) { ++ $scope = 'mfrom'; ++ $identity = $options->{mfrom}; ++ $helo_identity ||= $options->{helo}; ++ } ++ elsif (defined($options->{pra})) { ++ $scope = 'pra'; ++ $identity = $options->{pra}; ++ } ++} ++ ++my $default_explanation = $options->{'default-explanation'}; ++my $hostname = $options->{hostname}; ++ ++if ( ++ not defined($scope) or ++ not (defined($identity) xor defined($options->{file})) ++) { ++ usage(); ++ exit(255); ++} ++ ++if (defined($identity) and $identity eq '') { ++ STDERR->print("Error: Empty identities are not supported. See spfquery(1).\n"); ++ exit(255); ++} ++ ++# Process the SPF Request(s) ++############################################################################## ++ ++try { ++ my $spf_server = Mail::SPF::Server->new( ++ default_authority_explanation ++ => $default_explanation, ++ hostname => $hostname, ++ # debug => $options->{debug}, ++ # sanitize => $options->{sanitize}, ++ ++ # Black Magic: ++ ( ++ exists($options->{'max-dns-interactive-terms'}) ? ++ (max_dns_interactive_terms => $options->{'max-dns-interactive-terms'} || undef) ++ : () ++ ), ++ ( ++ exists($options->{'max-name-lookups-per-term'}) ? ++ (max_name_lookups_per_term => $options->{'max-name-lookups-per-term'} || undef) ++ : () ++ ) ++ # rcpt_to => $options->{'rcpt-to'}, ++ # trusted => $options->{trusted}, ++ # guess => $options->{guess}, ++ # local => $options->{local}, ++ # override => $options->{override}, ++ # fallback => $options->{fallback}, ++ ); ++ ++ my $exit_code; ++ ++ if (not defined($options->{file})) { ++ # Single request: ++ my $result_code = do_process( ++ $spf_server, ++ versions => @versions ? [@versions] : undef, ++ scope => $scope, ++ identity => $identity, ++ ip_address => $ip_address, ++ helo_identity => $helo_identity ++ ); ++ $exit_code = exit_codes_by_result_code->{$result_code}; ++ } ++ else { ++ # File request: ++ my $file = $options->{file} eq '-' ? \*STDIN : IO::File->new($options->{file}) ++ or die("Could not open: $options->{file}\n"); ++ while (<$file>) { ++ chomp; ++ s/^\s*//; ++ next if /^$/; ++ if (/^#/) { ++ print("$_\n") if $options->{'keep-comments'}; ++ next; ++ } ++ ($ip_address, $identity, $helo_identity) = split; ++ my $result_code = do_process( ++ $spf_server, ++ versions => @versions ? [@versions] : undef, ++ scope => $scope, ++ identity => $identity, ++ ip_address => $ip_address, ++ helo_identity => $helo_identity ++ ); ++ $exit_code ||= exit_codes_by_result_code->{$result_code}; ++ } ++ } ++ ++ exit($exit_code); ++} ++catch Mail::SPF::Exception with { ++ my ($e) = @_; ++ STDERR->printf("Error: %s.\n", $e->text); ++ exit(255); ++}; ++ ++ ++# Helper Function ++############################################################################## ++ ++sub do_process { ++ my ($spf_server, %request_options) = @_; ++ my $request = Mail::SPF::Request->new(%request_options); ++ my $result = $spf_server->process($request); ++ printf( ++ "%s\n%s\n%s\n%s\n", ++ $result->code, ++ ( ++ $result->can('authority_explanation') ? ++ $result->authority_explanation ++ : $result->local_explanation ++ ), ++ $result->local_explanation, ++ $result->received_spf_header ++ ); ++ return $result->code; ++} diff -Naur p5-Mail-SPF.dist/pkg-plist p5-Mail-SPF/pkg-plist --- p5-Mail-SPF.dist/pkg-plist 2008-02-22 22:40:33.000000000 +0100 +++ p5-Mail-SPF/pkg-plist 2011-05-24 19:42:51.000000000 +0200 @@ -1,4 +1,4 @@ -bin/spfquery +%%SPFQUERY%%bin/spfquery%%SPFQUERY_SUFFIX%% sbin/spfd %%SITE_PERL%%/Mail/SPF.pm %%SITE_PERL%%/Mail/SPF/MacroString.pm --r5Pyd7+fXNt84Ff3--