Lines 56-65
Link Here
|
56 |
|
56 |
|
57 |
$self->register_eval_rule ("check_for_spf_pass"); |
57 |
$self->register_eval_rule ("check_for_spf_pass"); |
58 |
$self->register_eval_rule ("check_for_spf_neutral"); |
58 |
$self->register_eval_rule ("check_for_spf_neutral"); |
|
|
59 |
$self->register_eval_rule ("check_for_spf_none"); |
59 |
$self->register_eval_rule ("check_for_spf_fail"); |
60 |
$self->register_eval_rule ("check_for_spf_fail"); |
60 |
$self->register_eval_rule ("check_for_spf_softfail"); |
61 |
$self->register_eval_rule ("check_for_spf_softfail"); |
61 |
$self->register_eval_rule ("check_for_spf_helo_pass"); |
62 |
$self->register_eval_rule ("check_for_spf_helo_pass"); |
62 |
$self->register_eval_rule ("check_for_spf_helo_neutral"); |
63 |
$self->register_eval_rule ("check_for_spf_helo_neutral"); |
|
|
64 |
$self->register_eval_rule ("check_for_spf_helo_none"); |
63 |
$self->register_eval_rule ("check_for_spf_helo_fail"); |
65 |
$self->register_eval_rule ("check_for_spf_helo_fail"); |
64 |
$self->register_eval_rule ("check_for_spf_helo_softfail"); |
66 |
$self->register_eval_rule ("check_for_spf_helo_softfail"); |
65 |
$self->register_eval_rule ("check_for_spf_whitelist_from"); |
67 |
$self->register_eval_rule ("check_for_spf_whitelist_from"); |
Lines 233-238
Link Here
|
233 |
$scanner->{spf_neutral}; |
235 |
$scanner->{spf_neutral}; |
234 |
} |
236 |
} |
235 |
|
237 |
|
|
|
238 |
sub check_for_spf_none { |
239 |
my ($self, $scanner) = @_; |
240 |
$self->_check_spf ($scanner, 0) unless $scanner->{spf_checked}; |
241 |
$scanner->{spf_none}; |
242 |
} |
243 |
|
236 |
sub check_for_spf_fail { |
244 |
sub check_for_spf_fail { |
237 |
my ($self, $scanner) = @_; |
245 |
my ($self, $scanner) = @_; |
238 |
$self->_check_spf ($scanner, 0) unless $scanner->{spf_checked}; |
246 |
$self->_check_spf ($scanner, 0) unless $scanner->{spf_checked}; |
Lines 260-265
Link Here
|
260 |
$scanner->{spf_helo_neutral}; |
268 |
$scanner->{spf_helo_neutral}; |
261 |
} |
269 |
} |
262 |
|
270 |
|
|
|
271 |
sub check_for_spf_helo_none { |
272 |
my ($self, $scanner) = @_; |
273 |
$self->_check_spf ($scanner, 1) unless $scanner->{spf_helo_checked}; |
274 |
$scanner->{spf_helo_none}; |
275 |
} |
276 |
|
263 |
sub check_for_spf_helo_fail { |
277 |
sub check_for_spf_helo_fail { |
264 |
my ($self, $scanner) = @_; |
278 |
my ($self, $scanner) = @_; |
265 |
$self->_check_spf ($scanner, 1) unless $scanner->{spf_helo_checked}; |
279 |
$self->_check_spf ($scanner, 1) unless $scanner->{spf_helo_checked}; |
Lines 318-323
Link Here
|
318 |
} |
332 |
} |
319 |
|
333 |
|
320 |
foreach my $hdr (@internal_hdrs) { |
334 |
foreach my $hdr (@internal_hdrs) { |
|
|
335 |
local($1,$2); |
321 |
if ($hdr =~ /^received-spf:/i) { |
336 |
if ($hdr =~ /^received-spf:/i) { |
322 |
dbg("spf: found a Received-SPF header added by an internal host: $hdr"); |
337 |
dbg("spf: found a Received-SPF header added by an internal host: $hdr"); |
323 |
|
338 |
|
Lines 361-366
Link Here
|
361 |
$scanner->{"spf_${identity}checked"} = 1; |
376 |
$scanner->{"spf_${identity}checked"} = 1; |
362 |
$scanner->{"spf_${identity}pass"} = 0; |
377 |
$scanner->{"spf_${identity}pass"} = 0; |
363 |
$scanner->{"spf_${identity}neutral"} = 0; |
378 |
$scanner->{"spf_${identity}neutral"} = 0; |
|
|
379 |
$scanner->{"spf_${identity}none"} = 0; |
364 |
$scanner->{"spf_${identity}fail"} = 0; |
380 |
$scanner->{"spf_${identity}fail"} = 0; |
365 |
$scanner->{"spf_${identity}softfail"} = 0; |
381 |
$scanner->{"spf_${identity}softfail"} = 0; |
366 |
$scanner->{"spf_${identity}failure_comment"} = undef; |
382 |
$scanner->{"spf_${identity}failure_comment"} = undef; |
Lines 376-381
Link Here
|
376 |
} else { |
392 |
} else { |
377 |
dbg("spf: could not parse result from existing Received-SPF header"); |
393 |
dbg("spf: could not parse result from existing Received-SPF header"); |
378 |
} |
394 |
} |
|
|
395 |
|
396 |
} elsif ($hdr =~ /^Authentication-Results:.*;\s*SPF\s*=\s*([^;]*)/i) { |
397 |
dbg("spf: found an Authentication-Results header added by an internal host: $hdr"); |
398 |
|
399 |
# RFC 5451 header parser - added by D. Stussy 2010-09-09: |
400 |
# Authentication-Results: mail.example.com; SPF=none smtp.mailfrom=example.org (comment) |
401 |
|
402 |
my $tmphdr = $1; |
403 |
if ($tmphdr =~ /^(pass|neutral|(?:hard|soft)?fail|none)(?:[^;]*?\bsmtp\.(\S+)\s*=[^;]+)?/i) { |
404 |
my $result = lc($1); |
405 |
$result = 'fail' if $result eq 'hardfail'; # RFC5451 permits this |
406 |
|
407 |
my $identity = ''; # we assume it's a mfrom check if we can't tell otherwise |
408 |
if (defined $2) { |
409 |
$identity = lc($2); |
410 |
if ($identity eq 'mfrom' || $identity eq 'mailfrom') { |
411 |
next if $scanner->{spf_checked}; |
412 |
$identity = ''; |
413 |
} elsif ($identity eq 'helo') { |
414 |
next if $scanner->{spf_helo_checked}; |
415 |
$identity = 'helo_'; |
416 |
} else { |
417 |
dbg("spf: found unknown identity value, cannot use: $identity"); |
418 |
next; # try the next Authentication-Results header, if any |
419 |
} |
420 |
} else { |
421 |
next if $scanner->{spf_checked}; |
422 |
} |
423 |
|
424 |
# we'd set these if we actually did the check |
425 |
$scanner->{"spf_${identity}checked"} = 1; |
426 |
$scanner->{"spf_${identity}pass"} = 0; |
427 |
$scanner->{"spf_${identity}neutral"} = 0; |
428 |
$scanner->{"spf_${identity}none"} = 0; |
429 |
$scanner->{"spf_${identity}fail"} = 0; |
430 |
$scanner->{"spf_${identity}softfail"} = 0; |
431 |
$scanner->{"spf_${identity}failure_comment"} = undef; |
432 |
|
433 |
# and the result |
434 |
$scanner->{"spf_${identity}${result}"} = 1; |
435 |
dbg("spf: re-using %s result from Authentication-Results header: %s", |
436 |
($identity ? 'helo' : 'mfrom'), $result); |
437 |
|
438 |
# if we've got *both* the mfrom and helo results we're done |
439 |
return if ($scanner->{spf_checked} && $scanner->{spf_helo_checked}); |
440 |
|
441 |
} else { |
442 |
dbg("spf: could not parse result from existing Authentication-Results header"); |
443 |
} |
379 |
} |
444 |
} |
380 |
} |
445 |
} |
381 |
# we can return if we've found the one we're being asked to get |
446 |
# we can return if we've found the one we're being asked to get |
Lines 454-459
Link Here
|
454 |
$scanner->{spf_helo_checked} = 1; |
519 |
$scanner->{spf_helo_checked} = 1; |
455 |
$scanner->{spf_helo_pass} = 0; |
520 |
$scanner->{spf_helo_pass} = 0; |
456 |
$scanner->{spf_helo_neutral} = 0; |
521 |
$scanner->{spf_helo_neutral} = 0; |
|
|
522 |
$scanner->{spf_helo_none} = 0; |
457 |
$scanner->{spf_helo_fail} = 0; |
523 |
$scanner->{spf_helo_fail} = 0; |
458 |
$scanner->{spf_helo_softfail} = 0; |
524 |
$scanner->{spf_helo_softfail} = 0; |
459 |
$scanner->{spf_helo_failure_comment} = undef; |
525 |
$scanner->{spf_helo_failure_comment} = undef; |
Lines 462-467
Link Here
|
462 |
$scanner->{spf_checked} = 1; |
528 |
$scanner->{spf_checked} = 1; |
463 |
$scanner->{spf_pass} = 0; |
529 |
$scanner->{spf_pass} = 0; |
464 |
$scanner->{spf_neutral} = 0; |
530 |
$scanner->{spf_neutral} = 0; |
|
|
531 |
$scanner->{spf_none} = 0; |
465 |
$scanner->{spf_fail} = 0; |
532 |
$scanner->{spf_fail} = 0; |
466 |
$scanner->{spf_softfail} = 0; |
533 |
$scanner->{spf_softfail} = 0; |
467 |
$scanner->{spf_failure_comment} = undef; |
534 |
$scanner->{spf_failure_comment} = undef; |
Lines 607-612
Link Here
|
607 |
if ($ishelo) { |
674 |
if ($ishelo) { |
608 |
if ($result eq 'pass') { $scanner->{spf_helo_pass} = 1; } |
675 |
if ($result eq 'pass') { $scanner->{spf_helo_pass} = 1; } |
609 |
elsif ($result eq 'neutral') { $scanner->{spf_helo_neutral} = 1; } |
676 |
elsif ($result eq 'neutral') { $scanner->{spf_helo_neutral} = 1; } |
|
|
677 |
elsif ($result eq 'none') { $scanner->{spf_helo_none} = 1; } |
610 |
elsif ($result eq 'fail') { $scanner->{spf_helo_fail} = 1; } |
678 |
elsif ($result eq 'fail') { $scanner->{spf_helo_fail} = 1; } |
611 |
elsif ($result eq 'softfail') { $scanner->{spf_helo_softfail} = 1; } |
679 |
elsif ($result eq 'softfail') { $scanner->{spf_helo_softfail} = 1; } |
612 |
|
680 |
|
Lines 616-621
Link Here
|
616 |
} else { |
684 |
} else { |
617 |
if ($result eq 'pass') { $scanner->{spf_pass} = 1; } |
685 |
if ($result eq 'pass') { $scanner->{spf_pass} = 1; } |
618 |
elsif ($result eq 'neutral') { $scanner->{spf_neutral} = 1; } |
686 |
elsif ($result eq 'neutral') { $scanner->{spf_neutral} = 1; } |
|
|
687 |
elsif ($result eq 'none') { $scanner->{spf_none} = 1; } |
619 |
elsif ($result eq 'fail') { $scanner->{spf_fail} = 1; } |
688 |
elsif ($result eq 'fail') { $scanner->{spf_fail} = 1; } |
620 |
elsif ($result eq 'softfail') { $scanner->{spf_softfail} = 1; } |
689 |
elsif ($result eq 'softfail') { $scanner->{spf_softfail} = 1; } |
621 |
|
690 |
|