Mail-SpamAssassin

 view release on metacpan or  search on metacpan

lib/Mail/SpamAssassin/GeoDB.pm  view on Meta::CPAN

    return "IP::Country::DB_File country: ".localtime($_[0]->{db}->{country}->db_time());
  };

  # country();
  $db->{country} and $dbapi->{country} = $dbapi->{country_v6} = sub {
    my $res = {};
    my $country;
    if ($_[1] =~ IS_IPV4_ADDRESS) {
      $country = $_[0]->{db}->{country}->inet_atocc($_[1]);
    } else {
      $country = $_[0]->{db}->{country}->inet6_atocc($_[1]);
    }
    if (!defined $country) {
      dbg("geodb: IP::Country::DB_File country query failed for $_[1]");
      return $res;
    };
    $res->{country} = $country || 'XX';
    $res->{continent} = $country_to_continent{$country} || 'XX';
    return $res;
  };

sa-update.raw  view on Meta::CPAN

    }
  }
}

# These are the non-standard required modules
use Net::DNS;
use Archive::Tar 1.23;
use IO::Zlib 1.04;
use Mail::SpamAssassin::Logger qw(:DEFAULT info log_message);

our ($have_lwp, $io_socket_module_name, $have_inet4, $use_inet4, $have_inet6, $use_inet6, $have_sha256, $have_sha512);

BEGIN {
  # Deal with optional modules

  eval { require Digest::SHA; Digest::SHA->import(qw(sha256_hex sha512_hex)); 1 } and do { $have_sha256=1; $have_sha512=1 }
  or die "Unable to verify file hashes! You must install a modern version of Digest::SHA.";
  
    $have_lwp = eval {
    require LWP::UserAgent;
    require LWP::Protocol::https;

sa-update.raw  view on Meta::CPAN

  }

  $have_inet4 =  # can we create a PF_INET socket?
    defined $io_socket_module_name && eval {
      my $sock =
        $io_socket_module_name->new(LocalAddr => '0.0.0.0', Proto => 'tcp');
      $sock->close or die "error closing socket: $!"  if $sock;
      $sock ? 1 : undef;
    };

  $have_inet6 =  # can we create a PF_INET6 socket?
    defined $io_socket_module_name &&
    $io_socket_module_name ne 'IO::Socket::INET' &&
    eval {
      my $sock =
        $io_socket_module_name->new(LocalAddr => '::', Proto => 'tcp');
      $sock->close or die "error closing socket: $!"  if $sock;
      $sock ? 1 : undef;
    };
}

sa-update.raw  view on Meta::CPAN

  'channel=s'				=> $opt{'channel'},

  'install=s'                           => \$opt{'install'},
  'import=s'			        => \$opt{'import'},
  'gpgkeyfile=s'			=> \$opt{'gpgkeyfile'},
  'channelfile=s'			=> \$opt{'channelfile'},
  'updatedir=s'				=> \$opt{'updatedir'},
  'gpg!'				=> \$GPG_ENABLED,

  '4'                                   => sub { $opt{'force_pf'} = 'inet' },
  '6'                                   => sub { $opt{'force_pf'} = 'inet6' },

  # backward compatibility
  'usegpg'				=> \$GPG_ENABLED,

) or print_usage_and_exit();

if ( defined $opt{'help'} ) {               
  print_usage_and_exit("For more information read the sa-update man page.\n", 0);
} 
if ( defined $opt{'version'} ) {            

sa-update.raw  view on Meta::CPAN

}

if ( $opt{'allowplugins'} && !$opt{'reallyallowplugins'} ) {
  warn "Security warning: dangerous option --allowplugins used:\n".
       "- there should never be need to use this option, see man sa-update(1)\n".
       "- specify --reallyallowplugins to allow activating plugins\n";
  exit 2;
}

$use_inet4 = $have_inet4 && ( !$opt{'force_pf'} || $opt{'force_pf'} eq 'inet' );
$use_inet6 = $have_inet6 && ( !$opt{'force_pf'} || $opt{'force_pf'} eq 'inet6' );

if ( $opt{'force_pf'} && $opt{'force_pf'} eq 'inet' && !$have_inet4 ) {
  warn "Option -4 specified but support for the ".
       "INET protocol family is not available.\n";
}
if ( $opt{'force_pf'} && $opt{'force_pf'} eq 'inet6' && !$have_inet6 ) {
  warn "Option -6 specified but support for the ".
       "INET6 protocol family is not available.\n";
}

if ( defined $opt{'httputil'} && $opt{'httputil'} !~ /^(curl|wget|fetch|lwp)$/ ) {
  warn "Invalid parameter for --httputil, curl|wget|fetch|lwp wanted\n";
}

if ( defined $opt{'score-multiplier'} && $opt{'score-multiplier'} !~ /^\d+(?:\.\d+)?$/ ) {
  die "Invalid parameter for --score-multiplier, integer or float expected.\n";

sa-update.raw  view on Meta::CPAN

  if ($instfile) {
    dbg("channel: using --install files $instfile\{,.asc,.sha512,.sha256\}");
    $content = read_install_file($instfile);
    if ( -f "$instfile.sha512" ) { $SHA512 = read_install_file($instfile.".sha512"); }
    if ( -f "$instfile.sha256" ) { $SHA256 = read_install_file($instfile.".sha256"); }
    $GPG = read_install_file($instfile.".asc") if $GPG_ENABLED;

  } else {  # not an install file, obtain fresh rules from network
    dbg("channel: protocol family available: %s%s",
        join(',', $have_inet4 ? 'inet'  : (),
                  $have_inet6 ? 'inet6' : ()),
        $opt{'force_pf'} ? '; force '.$opt{'force_pf'} : '' );

    # test if the MIRRORED.BY file for this channel exists,
    # is nonempty, and is reasonably fresh

    my(@mirr_stat_list) = stat($mirby_path);
    if (!@mirr_stat_list) {
      if ($! == ENOENT) {
        dbg("channel: no mirror file %s, will fetch it", $mirby_path);
      } else {

sa-update.raw  view on Meta::CPAN

      unlink($path_content);
      unlink($path_sha512);
      unlink($path_sha256);
      unlink($path_asc);

      my $sleep_sec = 2;

      if (!check_mirror_af($mirror)) {
        my @my_af;
        push(@my_af, "IPv4") if $use_inet4;
        push(@my_af, "IPv6") if $use_inet6;
        push(@my_af, "no IP service") if !@my_af;
        dbg("reject mirror %s: no common address family (%s), %s",
            $mirror, join(" ", @my_af),
            %mirrors ? "sleeping $sleep_sec sec and trying next" : 'no mirrors left');
        sleep($sleep_sec) if %mirrors;
        next;
      }

      dbg("channel: selected mirror $mirror");

sa-update.raw  view on Meta::CPAN

    printf("DNS %s query %s failed: %s\n", $rr_type, $query, $res->errorstring)
      if $opt{'verbose'} && $opt{'verbose'} > 1;
  }

  return @result;
}

##############################################################################

sub init_lwp {
  if ($have_inet6 &&
      (!$opt{'force_pf'} || $opt{'force_pf'} eq 'inet6') &&
      ($io_socket_module_name eq 'IO::Socket::IP' ||
       $io_socket_module_name eq 'IO::Socket::INET6') )
  {
    # LWP module has no support for IPv6.  Use hotpatching,
    # copying IO::Socket::IP or IO::Socket::INET6 to IO::Socket::INET.
    # 'Borrowed' from Net::INET6Glue::INET_is_INET6 :

    printf("http: (lwp) hotpatching IO::Socket::INET by module %s\n",
           $io_socket_module_name) if $opt{'verbose'};
    my $io_socket_module_hash_name = $io_socket_module_name . '::';

sa-update.raw  view on Meta::CPAN

  $ua->agent("sa-update/$VERSION/$SAVersion");
  $ua->timeout(60);      # a good long timeout; 10 is too short for Coral!
  $ua->env_proxy;

# if ($opt{'force_pf'}) {
#   # No longer needed and can be harmful as we don't know which address family
#   # will be picked by the IO::Socket::* module in case of multihomed servers.
#   # The IO::Socket::IP should choose the right protocol family automatically.
#   if ($have_inet4 && $opt{'force_pf'} eq 'inet') {
#     $ua->local_address('0.0.0.0');
#   } elsif ($have_inet6 && $opt{'force_pf'} eq 'inet6') {
#     $ua->local_address('::');
#   }
# }

  return $ua;
}

# Do a GET request via HTTP for a certain URL
# Use the optional time_t value to do an IMS GET
sub http_get_lwp {

sa-update.raw  view on Meta::CPAN

    }
    $out_fh->close or die "Error closing file $out_fname: $!";
    return ($out_fname, 1);
  } else {
    die "http: no downloading tool available";
  }

  # only reached if invoking an external program is needed (not lwp)
  if ($opt{'force_pf'}) {
    if    ($opt{'force_pf'} eq 'inet')  { push(@args, '-4') }
    elsif ($opt{'force_pf'} eq 'inet6') { push(@args, '-6') }
  }
  push(@args, '--', untaint_var($url));
  dbg("http: %s", join(' ',$cmd,@args));

  # avoid a system() call, use fork/exec to make sure we avoid invoking a shell
  my $pid;
  eval {
    # use eval, the fork() sometimes signals an error
    # instead of returning a failure status
    $pid = fork(); 1;

sa-update.raw  view on Meta::CPAN

    my $scheme = lc($1);
    # No DNS check needed for proxied connections (caveat: no_proxy is not checked)
    my $http_proxy = (defined $ENV{"http_proxy"} && $ENV{"http_proxy"} =~ /\S/) ||
                     (defined $ENV{"HTTP_PROXY"} && $ENV{"HTTP_PROXY"} =~ /\S/);
    my $https_proxy = (defined $ENV{"https_proxy"} && $ENV{"https_proxy"} =~ /\S/) ||
                      (defined $ENV{"HTTPS_PROXY"} && $ENV{"HTTPS_PROXY"} =~ /\S/);
    return 1 if $scheme eq "http" && $http_proxy;
    return 1 if $scheme eq "https" && $https_proxy;
    # No DNS check needed for IPv4 or IPv6 address literal
    return 1 if $use_inet4 && $mirror =~ m{^\d+\.\d+\.\d+\.\d+(?:[:/]|$)};
    return 1 if $use_inet6 && $mirror =~ m{^\[};
    $mirror =~ s{[:/].*}{}s;  # strip all starting from :port or /path
    return 1 if $use_inet4 && do_dns_query($mirror, "A");
    return 1 if $use_inet6 && do_dns_query($mirror, "AAAA");
    return 0;
}

##############################################################################

sub print_version {
  printf("sa-update version %s\n  running on Perl version %s\n", $VERSION, 
         join(".", map( 0+($_||0), ( $] =~ /(\d)\.(\d{3})(\d{3})?/ ))));
}

sa-update.raw  view on Meta::CPAN

  --score-multiplier x.x  Adjust all scores from update channel, multiply
                          with given value (integer or float).
  --score-limit x.x       Adjust all scores from update channel, limit
                          to given value (integer or float). Limiting
                          is done after possible multiply operation.
  -D, --debug [area=n,...]  Print debugging messages
  -v, --verbose           Be verbose, like print updated channel names;
                          For more verbosity specify multiple times
  -V, --version           Print version
  -h, --help              Print usage message
  -4                      Force using the inet protocol (IPv4), not inet6
  -6                      Force using the inet6 protocol (IPv6), not inet

=head1 DESCRIPTION

sa-update automates the process of downloading and installing new rules and
configuration, based on channels.  The default channel is
I<updates.spamassassin.org>, which has updated rules since the previous
release.

NOTE: channel names are domain names, but DO NOT typically have any DNS
records other than (maybe) NS records. There is a tree of records below that

spamd/spamd.raw  view on Meta::CPAN

# This is disabled during the "make install" process.
BEGIN {
  if ( -e '../blib/lib/Mail/SpamAssassin.pm' ) {    # REMOVEFORINST
    unshift ( @INC, '../blib/lib' );                # REMOVEFORINST
  } else {                                          # REMOVEFORINST
    unshift ( @INC, '../lib' );                     # REMOVEFORINST
  }                                                 # REMOVEFORINST
}

our ($have_getaddrinfo_in_core, $have_getaddrinfo_legacy, $io_socket_module_name,
     $have_inet4, $have_inet6, $ai_addrconfig_flag);

# don't force requirement on IO::Socket::IP or IO::Socket::INET6
BEGIN {
  require Socket;
  $have_getaddrinfo_in_core = eval {
    # The Socket module (1.94) bundled with Perl 5.14.* provides
    # new affordances for IPv6, including implementations of the
    # Socket::getaddrinfo() and Socket::getnameinfo() functions,
    # along with related constants and a handful of new functions.
    # Perl 5.16.0 upgrades the core Socket module to version 2.001.

spamd/spamd.raw  view on Meta::CPAN

  }

  $have_inet4 =  # can we create a PF_INET socket?
    defined $io_socket_module_name && eval {  
      my $sock =
        $io_socket_module_name->new(LocalAddr => '0.0.0.0', Proto => 'tcp');
      $sock->close or die "error closing socket: $!"  if $sock;
      $sock ? 1 : undef;
    };

  $have_inet6 =  # can we create a PF_INET6 socket?
    defined $io_socket_module_name &&
    $io_socket_module_name ne 'IO::Socket::INET' &&
    eval {
      my $sock =
        $io_socket_module_name->new(LocalAddr => '::', Proto => 'tcp');
      $sock->close or die "error closing socket: $!"  if $sock;
      $sock ? 1 : undef;
    };

}

spamd/spamd.raw  view on Meta::CPAN


# ---------------------------------------------------------------------------
# Server (listening) socket setup for the various supported types

dbg("spamd: socket module of choice: %s %s, Socket %s".
    ", %s PF_INET, %s PF_INET6, %s, AI_ADDRCONFIG %s",
    $io_socket_module_name,
    $io_socket_module_name->VERSION,
    Socket->VERSION,
    $have_inet4 ? 'have' : 'no',
    $have_inet6 ? 'have' : 'no',
    $have_getaddrinfo_in_core ? 'using Socket::getaddrinfo'
    : $have_getaddrinfo_legacy ? 'using legacy Socket6::getaddrinfo'
    : 'no getaddrinfo, using gethostbyname, IPv4-only',
    $ai_addrconfig_flag ? "is supported" : "not supported",
);

my $have_ssl_module;
my @listen_sockets;  # list of hashrefs, contains info on all listen sockets
my $server_select_mask;

spamd/spamd.raw  view on Meta::CPAN

  push(@listen_sockets, { specs => $socket_specs,
                          path => $path,
                          socket => $server_unix,
                          fd => $server_unix->fileno })  if $server_unix;
  1;
}

sub server_sock_setup_inet {
  my($socket_specs, $addr, $port, $ssl) = @_;

  $have_inet4 || $have_inet6
    or warn "spamd: neither the PF_INET (IPv4) nor the PF_INET6 (IPv6) ".
            "protocol families seem to be available, pushing our luck anyway\n";

  my $ai_family = &AF_UNSPEC;  # defaults to any address family (i.e. both)
  if      ($have_inet6 && (!$have_inet4 || $opt{'force_ipv6'})) {
    $ai_family = &AF_INET6;
  } elsif ($have_inet4 && (!$have_inet6 || $opt{'force_ipv4'})) {
    $ai_family = &AF_INET;
  }
  my($error, @addresses);
  if (!defined $addr || lc $addr eq 'localhost') {  # loopback interface
    push(@addresses, '::1')
      if $ai_family == &AF_UNSPEC || $ai_family == &AF_INET6;
    push(@addresses, '127.0.0.1')
      if $ai_family == &AF_UNSPEC || $ai_family == &AF_INET;
  } elsif ($addr eq '*' || $addr eq '') {  # any address
    push(@addresses, '::')

t/SATest.pm  view on Meta::CPAN

use File::Temp qw(tempdir);

use Test::Builder ();
use Test::More    ();

use POSIX qw(WIFEXITED WIFSIGNALED WIFSTOPPED WEXITSTATUS WTERMSIG WSTOPSIG);

use vars qw($RUNNING_ON_WINDOWS $SSL_AVAILABLE
            $SKIP_SPAMD_TESTS $SKIP_SPAMC_TESTS $NO_SPAMC_EXE
            $SKIP_SETUID_NOBODY_TESTS $SKIP_DNSBL_TESTS
            $have_inet4 $have_inet6 $spamdhost $spamdport
            $workdir $siterules $localrules $userrules $userstate
            $keep_workdir $mainpid $spamd_pidfile);

my $sa_code_dir;
BEGIN {
  require Exporter;
  use vars qw(@ISA @EXPORT @EXPORT_OK);
  @ISA = qw(Exporter);

  @EXPORT = qw($have_inet4 $have_inet6 $spamdhost $spamdport);

  # No spamd test in Windows unless env override says user figured out a way
  # If you want to know why these are vars and no constants, read this thread:
  #   <http://www.mail-archive.com/dev%40perl.apache.org/msg05466.html>
  #  -- mss, 2004-01-13
  $RUNNING_ON_WINDOWS = ($^O =~ /^(mswin|dos|os2)/oi);
  $SKIP_SPAMD_TESTS =
        $RUNNING_ON_WINDOWS ||
        ( $ENV{'SPAMD_HOST'} && !($ENV{'SPAMD_HOST'} eq '127.0.0.1' ||
                                  $ENV{'SPAMD_HOST'} eq '::1' ||

t/SATest.pm  view on Meta::CPAN

  $SKIP_SETUID_NOBODY_TESTS = 0;
  $SKIP_DNSBL_TESTS = 0;

  $have_inet4 = eval {
    require IO::Socket::INET;
    my $sock = IO::Socket::INET->new(LocalAddr => '127.0.0.1', Proto => 'udp');
    $sock->close or die "error closing inet socket: $!"  if $sock;
    $sock ? 1 : undef;
  };

  $have_inet6 = eval {
    require IO::Socket::INET6;
    my $sock = IO::Socket::INET6->new(LocalAddr => '::1', Proto => 'udp');
    $sock->close or die "error closing inet6 socket: $!"  if $sock;
    $sock ? 1 : undef;
  };

  # Clean PATH so taint doesn't complain
  if (!$RUNNING_ON_WINDOWS) {
    $ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';
    # Remove tainted envs, at least ENV used in FreeBSD
    delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
  } else {
    # Windows might need non-system directories in PATH to run a Perl installation

t/SATest.pm  view on Meta::CPAN

  $salearn ||= "$perl_cmd ../sa-learn.raw";

  $saawl = $ENV{'SAAWL_SCRIPT'};
  $saawl ||= "$perl_cmd ../sa-awl";

  $sacheckspamd = $ENV{'SACHECKSPAMD_SCRIPT'};
  $sacheckspamd ||= "$perl_cmd ../sa-check_spamd";

  $spamdlocalhost = $ENV{'SPAMD_LOCALHOST'};
  if (!$spamdlocalhost) {
    $spamdlocalhost = $have_inet4 || !$have_inet6 ? '127.0.0.1' : '::1';
  }
  $spamdhost = $ENV{'SPAMD_HOST'};
  $spamdhost ||= $spamdlocalhost;

  # optimisation -- don't setup spamd test parameters unless we're
  # not skipping all spamd tests and this particular test is called
  # called "spamd_something" or "spamc_foo"
  # We still run spamc tests when there is an external SPAMD_HOST, but don't have to set up the spamd parameters for it
  if ($tname !~ /spam[cd]/) {
    $TEST_DOES_NOT_RUN_SPAMC_OR_D = 1;

t/dnsbl_subtests.t  view on Meta::CPAN


use Mail::SpamAssassin;

# Bug 5761 (no 127.0.0.1 in jail, use SPAMD_LOCALHOST if specified)
my $dns_server_localaddr = $ENV{'SPAMD_LOCALHOST'};
if (!$dns_server_localaddr) {
  $dns_server_localaddr = $have_inet4 ? '127.0.0.1' : '::1';
}

my $use_inet4 =
  !$have_inet6 ||
  ($have_inet4 && $dns_server_localaddr =~ /^\d+\.\d+\.\d+\.\d+\z/);

sub find_free_port($);  # prototype
my($dns_server_localport, $sock_udp, $sock_tcp) =
  find_free_port($dns_server_localaddr);

$dns_server_localport  or die "Failed to obtain a free port number";

printf("Using %s [%s]:%s for a spawned test DNS server\n",
       $use_inet4 ? 'inet' : 'inet6',
       $dns_server_localaddr, $dns_server_localport);

# test zone names (lowercase!)
my $z  = 'sa1-dbl-test.spamassassin.org';
my $z2 = 'sa2-dbl-test.spamassassin.org';

my $local_conf = <<"EOD";
  use_bayes 0
  use_razor2 0
  use_pyzor 0

t/dnsbl_subtests.t  view on Meta::CPAN

    $port = 11001 + int(rand(65536-11001));
    my %args = (LocalAddr => $addr, LocalPort => $port);
    $sock_udp = $use_inet4 ? IO::Socket::INET->new(%args, Proto => 'udp')
                           : IO::Socket::INET6->new(%args, Proto => 'udp');
    $sock_udp || $! == EADDRINUSE || $! == EACCES
      or printf("Error creating UDP socket [%s]:%s: %s\n", $addr, $port, $!);
    $sock_tcp = $use_inet4 ? IO::Socket::INET->new(%args, Proto => 'tcp')
                           : IO::Socket::INET6->new(%args, Proto => 'tcp');
    $sock_tcp || $! == EADDRINUSE || $! == EACCES
      or printf("Error creating %s TCP socket [%s]:%s: %s\n",
                $use_inet4 ? 'inet' : 'inet6', $addr, $port, $!);
    last if $sock_tcp && $sock_udp;
  }
  undef $port if !$sock_tcp || !$sock_udp;
  return ($port, $sock_udp, $sock_tcp);
}

# ---------------------------------------------------------------------------

my $spamassassin_obj;

t/spamd_protocol_10.t  view on Meta::CPAN

  clear_pattern_counters();
}

stop_spamd();
exit;


sub run_symbols {
  my($data, $proto10) = @_;
  my $use_inet4 =
    !$have_inet6 ||
    ($have_inet4 && $spamdhost =~ /^\d+\.\d+\.\d+\.\d+\z/);
  my %args = ( PeerAddr => $spamdhost,
               PeerPort => $spamdport,
               Proto    => "tcp",
               Type     => SOCK_STREAM
             );
  $socket = $use_inet4 ? IO::Socket::INET->new(%args)
                       : IO::Socket::INET6->new(%args);
  unless ($socket) {
    warn("FAILED - Couldn't Connect to SpamCheck Host\n");



( run in 0.266 second using v1.01-cache-2.11-cpan-87723dcf8b7 )