View | Details | Raw Unified | Return to bug 6490
Collapse All | Expand All

(-)lib/Mail/SpamAssassin/Plugin/SPF.pm (+69 lines)
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

Return to bug 6490