NAME
Mail::SPF::Query - query Sender Permitted From for an IP,email,helo
SYNOPSIS
my $query = new Mail::SPF::Query (ip => "127.0.0.1", sender=>'foo@example.com', helo=>"somehost.example.com");
my ($result, $smtp_comment, $header_comment) = $query->result();
my ($guess, $smtp_guess, $header_guess) = $query->best_guess();
if ($result eq "pass") { ... } # domain is not forged
elsif ($result eq "fail") { ... } # domain is forged
else { # domain has not implemented SPF
if ($guess eq "pass") { ... } # result based on $guess_mechs
elsif ($guess eq "fail") { ... } # result based on $guess_mechs
else { ... } #
}
The default $guess_mechs is "a/24 mx/24 ptr
exists:%{p}.wl.trusted-forwarder.org
exists:%{ir}.wl.trusted-forwarder.org".
ABSTRACT
The SPF protocol relies on sender domains to publish a DNS whitelist of their designated outbound mailers. Given an envelope sender, Mail::SPF::Query determines the legitimacy of an SMTP client IP.
METHODS
Mail::SPF::Query->new()
my $query = eval { new Mail::SPF::Query (ip =>"127.0.0.1",
sender=>'foo@example.com',
helo =>"host.example.com") };
optional parameters:
guess_mechs => "a/24 mx/24 ptr exists:%{p}.wl.trusted-forwarder.org",
debug => 1, debuglog => sub { print STDERR "@_\n" },
max_lookup_count => 20, # total number of SPF include/redirect queries
myhostname => "foo.example.com", # prepended to header_comment
if ($@) { warn "bad input to Mail::SPF::Query: $@" }
Set debug=>1
to watch the queries happen.
$query->result()
my ($result, $smtp_comment, $header_comment) = $query->result();
$result
will be one of pass
, fail
, unknown
, or error
.
pass
means the client IP is a designated mailer for the sender. The mail should be accepted subject to local policy regarding the sender.
fail
means the client IP is not a designated mailer, and the sender wants you to reject the transaction for fear of forgery.
unknown
means the domain either does not publish SPF data or has a configuration error in the published data.
error
means the DNS lookup encountered a temporary error during processing.
Results are cached internally for a default of 120 seconds. You can call ->result()
repeatedly; subsequent lookups won't hit your DNS.
The smtp_comment should be displayed to the SMTP client.
The header_comment goes into a Received-SPF header.
$query->best_guess()
my ($result, $smtp_comment, $header_comment) = $query->best_guess();
When a domain does not publish SPF records, this library can produce an educated guess anyway.
It pretends the domain defined A, MX, and PTR mechanisms, plus a few others. The default set of directives is
"a/24 mx/24 pt rexists:%{p}.wl.trusted-forwarder.org exists:%{ir}.wl.trusted-forwarder.org"
That default set will return either "pass" or "unknown".
$query->debuglog()
Subclasses may override this with their own debug logger.
I recommend Log::Dispatch.
Alternatively, pass the C<new()> constructor a
C<debuglog => sub { ... }> callback, and we'll pass
debugging lines to that.
EXPORT
None by default.
AUTHOR
Meng Weng Wong, <mengwong+spf@pobox.com>
SEE ALSO
http://spf.pobox.com/