home *** CD-ROM | disk | FTP | other *** search
/ ftp.f-secure.com / 2014.06.ftp.f-secure.com.tar / ftp.f-secure.com / support / hotfix / fsis / IS-SpamControl.fsfix / iufssc / lib / FS / PhishBLPlugin.pm < prev   
Text File  |  2006-11-29  |  4KB  |  188 lines

  1. #!/usr/bin/perl
  2. #
  3. # $Id: PhishBLPlugin.pm 4094 2006-11-02 12:25:37Z eriker $
  4.  
  5. use strict;
  6. use warnings;
  7.  
  8. package FS::PhishBLPlugin;
  9.  
  10. =head1 NAME
  11.  
  12. FS::PhishBLPlugin - F-Secure SpamAssassin 3.x anti-phishing plugin 
  13.  
  14. =head1 SYNOPSYS
  15.  
  16.   # Add to rules/init.pre or rules/v3xx.pre
  17.  
  18.   loadplugin FS::PhishBLPlugin
  19.  
  20.   # Add to any rules/*.cf file
  21.  
  22.   phish_enabled        0
  23.   phish_salt           <salt-code>
  24.   phish_lookup_url     http://<f-secure-lookup-url-example>/phish-<SLAKjlaskd>/
  25.  
  26.  
  27. =head1 DESCRIPTION
  28.  
  29. This module interfaces spamassassin 3.x (tested with 3.1) to
  30. the F-Secure phishing URL blocklist.
  31.  
  32. =cut
  33.  
  34. use Mail::SpamAssassin::Plugin;
  35. use Mail::SpamAssassin::Util;
  36. use Mail::SpamAssassin::Logger qw//;
  37. use FS::Logger;
  38. BEGIN {
  39.     FS::Logger::set_logger(\&Mail::SpamAssassin::Logger::_log);
  40. }
  41. our $FS_Logger_facility = "pheed";
  42.  
  43. use File::Spec;
  44.  
  45. use bytes;
  46. use FS::PhishBL;
  47.  
  48. use vars qw(@ISA);
  49. @ISA = qw(Mail::SpamAssassin::Plugin);
  50.  
  51. # number of seconds to back off lookups after an error
  52. my $LOOKUP_TEST_RETRY_INTERVAL = 5*60;
  53.  
  54. my $prev_enabled = 0;         # just for logging
  55. my $prev_dns_available = "";  # just for logging
  56.  
  57. # constructor
  58. sub new {
  59.     my $class = shift;
  60.     my $samain = shift;
  61.  
  62.     debug(">>PhishBLPlugin::new()");
  63.     # some boilerplate...
  64.     $class = ref($class) || $class;
  65.     my $self = $class->SUPER::new($samain);
  66.     bless ($self, $class);
  67.  
  68.     return $self;
  69. }
  70.  
  71. sub check_post_learn {
  72.     goto &check_phishbl;
  73. }
  74.  
  75. sub check_phishbl {
  76.     my ($self, $options) = @_;
  77.     my $msg = $options->{permsgstatus};
  78.  
  79.     # set initial classification result
  80.     $msg->{fs_phishblplugin} = {};
  81.  
  82.     my $conf = $msg->{main}{conf}{phish};
  83.     # no: unconditionally disabled
  84.     return 0 if $conf->{enabled} == 0;
  85.     # when_dns: disabled if dns is not available
  86.     return 0 if    $conf->{enabled} == 1 && !$msg->is_dns_available();
  87.  
  88.     $self->{src} ||= FS::PhishBL->new($conf);
  89.  
  90.     if (time() < $conf->{lookup_test_deadline}) {
  91.         debug "skipping lookup query temporarily because of earlier failure";
  92.         return 0;
  93.     }
  94.  
  95.     my %duplicate;
  96.     my %classification = ();
  97.     
  98.     eval {
  99.     foreach my $uri ($msg->get_uri_list()) {
  100.         next if $duplicate{$uri}++;
  101.         my $classes = $self->{src}->is_phish($uri);
  102.         while (my ($k, $v) = each %$classes) {
  103.             # store only if this is higer score than
  104.             # existing one for this class
  105.             my $current = $classification{$k} || 0; 
  106.             $classification{$k} = $v if
  107.             !exists $classification{$k} ||
  108.             $current < $v;
  109.         }
  110.     }
  111.     };
  112.     if ($@) {
  113.         info "lookup failed: " . $@->status_line;
  114.         info "disabling lookups for $LOOKUP_TEST_RETRY_INTERVAL seconds";
  115.         $conf->{lookup_test_deadline} = time() + $LOOKUP_TEST_RETRY_INTERVAL;
  116.     }
  117.  
  118.     # set classification result
  119.     $msg->{fs_phishblplugin} = \%classification;
  120.     return %classification ? 1 : 0;
  121. }
  122.  
  123. sub parse_config {
  124.     my ($self, $opts) = @_;
  125.     my $key = $opts->{key};
  126.     my $value = $opts->{value};
  127.  
  128.     # map configuration file keys -> keys of our config hash ref
  129.     my %phish_config = (
  130.     phish_enabled         => "enabled",
  131.     phish_salt            => "salt",
  132.     phish_lookup_url      => "query_url",
  133.     );
  134.  
  135.     if (exists $phish_config{$key}) {
  136.     debug "$key = $value";
  137.     $key = $phish_config{$key};
  138.     if ($key eq "enabled") {
  139.         # normalize value to 0, 1 or 2
  140.         $value = $value eq "yes" ? 2 : $value eq "when_dns" ? 1 : 0;
  141.     }
  142.     $opts->{conf}{phish}{$key} = $value;
  143.     $self->inhibit_further_callbacks();
  144.     return 1;
  145.     }
  146.     my %common_config = (
  147.     http_proxy  => "proxy",
  148.     );
  149.     if (exists $common_config{$key}) {
  150.     debug "$key = $value";
  151.     $opts->{conf}{phish}{$common_config{$key}} = $value;
  152.     return 1;
  153.     }
  154.  
  155.     return 0;
  156. }
  157.  
  158. sub finish_parsing_end {
  159.     my ($self) = @_;
  160.  
  161.     my $conf = $self->{main}{conf}{phish};
  162.     if ($prev_enabled != $conf->{enabled}) {
  163.     $prev_enabled = $conf->{enabled};
  164.     info "Enabled: " . ("no", "when_dns", "yes")[$prev_enabled];
  165.     }
  166.     if ($prev_dns_available ne $self->{main}{conf}{dns_available}) {
  167.     $prev_dns_available = $self->{main}{conf}{dns_available};
  168.     info("dns_available $self->{main}{conf}{dns_available}");
  169.     }
  170.  
  171.     $conf->{lookup_test_deadline} = 0;
  172.  
  173.     if ($self->{src}) {
  174.     debug "Refreshing settings";
  175.     $self->{src}->refresh_settings($conf);
  176.     } else {
  177.     debug "Not yet refreshing settings";
  178.     }
  179. }
  180.  
  181. =head1 COPYRIGHT
  182.  
  183. Copyright (C) 2006 F-Secure Corp, all rights reserved
  184.  
  185. =cut
  186.  
  187. 1;
  188.