|
|
@@ -77,7 +77,13 @@ sub new { |
|
|
|
# Maximum email message size (including headers).
|
|
|
|
$self->{SNF_MaxTempFileSize} = 64 * 1024;
|
|
|
|
|
|
|
|
# Key for GBUdb maximum weight.
|
|
|
|
# Key for confidence in mail header inserted by SNFServer.
|
|
|
|
$self->{GBUdb_ConfidenceKey} = "c=";
|
|
|
|
|
|
|
|
# Key for probability in mail header inserted by SNFServer.
|
|
|
|
$self->{GBUdb_ProbabilityKey} = "p=";
|
|
|
|
|
|
|
|
# Key for GBUdb maximum weight in the configuration file.
|
|
|
|
$self->{GBUdb_MaxWeightKey} = "gbudb_max_weight";
|
|
|
|
|
|
|
|
# Key for SNFServer code in configuration file.
|
|
|
@@ -111,11 +117,13 @@ sub new { |
|
|
|
|
|
|
|
sub have_shortcircuited {
|
|
|
|
|
|
|
|
my ($self, $permsgstatus) = @_;
|
|
|
|
my ($self, $options) = @_;
|
|
|
|
|
|
|
|
if (defined($options->{permsgstatus}->{shortCircuit})) {
|
|
|
|
|
|
|
|
# print "************************************\n";
|
|
|
|
# print "****have_shortcircuited returning 0\n";
|
|
|
|
# print "************************************\n";
|
|
|
|
return $options->{permsgstatus}->{shortCircuit};
|
|
|
|
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
@@ -155,14 +163,39 @@ sub parse_config { |
|
|
|
# Relationship between SNFServer code and SA score delta.
|
|
|
|
my $snf = $self->parse_snf_sa_mapping($options);
|
|
|
|
if (defined($snf)) {
|
|
|
|
my @codes = @{$snf->{snfCode}};
|
|
|
|
print "snf->{snfCode}: @codes\n";
|
|
|
|
print "snf->{deltaScore}: $snf->{deltaScore}\n";
|
|
|
|
print "snf->{shortCircuit}: $snf->{shortCircuit}\n";
|
|
|
|
my @snfCode = @{$snf->{snfCode}};
|
|
|
|
#print "snf->{snfCode}: @snfCode\n"; # DEBUG.
|
|
|
|
#print "snf->{deltaScore}: $snf->{deltaScore}\n"; # DEBUG.
|
|
|
|
#print "snf->{shortCircuit}: $snf->{shortCircuit}\n"; # DEBUG.
|
|
|
|
|
|
|
|
# Save configuration.
|
|
|
|
foreach my $i (@{$snf->{snfCode}}) {
|
|
|
|
|
|
|
|
# Create (or update) an element in the mapping array
|
|
|
|
# that snfSaMapping is a reference to.
|
|
|
|
$options->{conf}->{snfSaMapping}->[$i] = {
|
|
|
|
deltaScore => $snf->{deltaScore},
|
|
|
|
shortCircuit => $snf->{shortCircuit}
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
# DEBUG.
|
|
|
|
#for (my $i = 0; $i < @{$options->{conf}->{snfSaMapping}}; $i++) {
|
|
|
|
# if (! defined($options->{conf}->{snfSaMapping}->[$i])) {
|
|
|
|
# print "No configuration for SNFServer code $i\n";
|
|
|
|
# next;
|
|
|
|
# }
|
|
|
|
# print "SNFServer code: $i, " .
|
|
|
|
# "deltaScore: " .
|
|
|
|
# "$options->{conf}->{snfSaMapping}->[$i]->{deltaScore}, " .
|
|
|
|
# "shortCircuit: " .
|
|
|
|
# "$options->{conf}->{snfSaMapping}->[$i]->{shortCircuit}\n";
|
|
|
|
#}
|
|
|
|
# END OF DEBUG.
|
|
|
|
|
|
|
|
# Successfully parsed.
|
|
|
|
$self->inhibit_further_callbacks();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -178,7 +211,7 @@ sub parse_config { |
|
|
|
#
|
|
|
|
# $line--String containing the snf_result line without the first word.
|
|
|
|
#
|
|
|
|
# Returns has reference with the following fields (if no error)--
|
|
|
|
# Returns a reference with the following fields (if no error)--
|
|
|
|
#
|
|
|
|
# snfCode--Array of SNFServer result codes that this configuration
|
|
|
|
# line specifies.
|
|
|
@@ -382,7 +415,6 @@ sub snf4sa_sacheck { |
|
|
|
|
|
|
|
my ($self, $permsgstatus, $fulltext) = @_;
|
|
|
|
|
|
|
|
my $testscore = 0;
|
|
|
|
my $response ='';
|
|
|
|
my $exitvalue;
|
|
|
|
|
|
|
@@ -419,23 +451,7 @@ sub snf4sa_sacheck { |
|
|
|
# xci_scan connects to SNFServer with XCI to scan the message
|
|
|
|
my $SNF_XCI_Return = $self->xci_scan( $filename );
|
|
|
|
|
|
|
|
#print "header:\n\n$SNF_XCI_Return->{header}"; # DEBUG
|
|
|
|
#print "\nEnd of header\n\n"; # DEBUG
|
|
|
|
|
|
|
|
# Initialize the change in the SA score.
|
|
|
|
my $deltaScore = 0.0;
|
|
|
|
|
|
|
|
# Perform GBUdb processing.
|
|
|
|
if (defined($permsgstatus->{main}->{conf}->{gbuDbMaxWeight})) {
|
|
|
|
|
|
|
|
#print "gbudbMaxWeight: $permsgstatus->{main}->{conf}->{gbuDbMaxWeight}\n\n"; # DEBUG.
|
|
|
|
|
|
|
|
# Calculate the contribution to the scrore from the GBUdb results.
|
|
|
|
$deltaScore +=
|
|
|
|
$self->calc_GBUdb($SNF_XCI_Return->{header},
|
|
|
|
$permsgstatus->{main}->{conf}->{gbuDbMaxWeight});
|
|
|
|
|
|
|
|
}
|
|
|
|
#print "header:\n\n$SNF_XCI_Return->{header}\n\n"; # DEBUG
|
|
|
|
|
|
|
|
# Remove the temp file, we are done with it.
|
|
|
|
unlink($filename);
|
|
|
@@ -459,16 +475,43 @@ sub snf4sa_sacheck { |
|
|
|
$rcx = 'Unknown' unless $rcx;
|
|
|
|
my $rch = $SNF_XCI_Return->{"header"}; # the SNF header(s)
|
|
|
|
|
|
|
|
# Result code of 0 indicates non-spam. Any other value indicates
|
|
|
|
# spam.
|
|
|
|
if ($rc >= 1) {
|
|
|
|
$testscore=1;
|
|
|
|
} else {
|
|
|
|
$testscore=0;
|
|
|
|
# Initialize the change in the SA score.
|
|
|
|
my $deltaScore = 0.0;
|
|
|
|
|
|
|
|
# Add the score from the SNFServer return.
|
|
|
|
if (defined($permsgstatus->{main}->{conf}->{snfSaMapping}->[$rc])) {
|
|
|
|
|
|
|
|
$deltaScore +=
|
|
|
|
$permsgstatus->{main}->{conf}->{snfSaMapping}->[$rc]->{deltaScore};
|
|
|
|
|
|
|
|
$permsgstatus->{shortCircuit} =
|
|
|
|
$permsgstatus->{main}->{conf}->{snfSaMapping}->[$rc]->{shortCircuit};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
# Add the header.
|
|
|
|
# Perform GBUdb processing.
|
|
|
|
if (defined($permsgstatus->{main}->{conf}->{gbuDbMaxWeight})) {
|
|
|
|
|
|
|
|
#print "gbudbMaxWeight: $permsgstatus->{main}->{conf}->{gbuDbMaxWeight}\n\n"; # DEBUG.
|
|
|
|
|
|
|
|
# Calculate the contribution to the scrore from the GBUdb results.
|
|
|
|
$deltaScore +=
|
|
|
|
$self->calc_GBUdb($SNF_XCI_Return->{header},
|
|
|
|
$permsgstatus->{main}->{conf}->{gbuDbMaxWeight});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
# Add the headers.
|
|
|
|
$permsgstatus->set_tag("SNFRESULTTAG", "$rc ($rcx)");
|
|
|
|
$permsgstatus->set_tag("SNFMESSAGESNIFFERSCANRESULT",
|
|
|
|
$self->extract_header_body($SNF_XCI_Return->{header},
|
|
|
|
"X-MessageSniffer-Scan-Result"));
|
|
|
|
$permsgstatus->set_tag("SNFMESSAGESNIFFERRULES",
|
|
|
|
$self->extract_header_body($SNF_XCI_Return->{header},
|
|
|
|
"X-MessageSniffer-Rules"));
|
|
|
|
$permsgstatus->set_tag("SNFGBUDBANALYSIS",
|
|
|
|
$self->extract_header_body($SNF_XCI_Return->{header},
|
|
|
|
"X-GBUdb-Analysis"));
|
|
|
|
|
|
|
|
# Submit the score.
|
|
|
|
if ($deltaScore) {
|
|
|
@@ -487,6 +530,16 @@ sub snf4sa_sacheck { |
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
# Calculate the contribution of the GBUdb scan to the SA score.
|
|
|
|
#
|
|
|
|
# Input--
|
|
|
|
#
|
|
|
|
# $headers--String containing the headers.
|
|
|
|
#
|
|
|
|
# $weight--Weight used to calculate the contribution.
|
|
|
|
#
|
|
|
|
# Returns the contribution to the SA score (float).
|
|
|
|
#
|
|
|
|
sub calc_GBUdb
|
|
|
|
{
|
|
|
|
my ( $self, $headers, $weight ) = @_;
|
|
|
@@ -502,16 +555,16 @@ sub calc_GBUdb |
|
|
|
if ($line =~ /^X-GBUdb-Analysis:/) {
|
|
|
|
|
|
|
|
# GBUdb analysis was done. Extract the values.
|
|
|
|
my $ind0 = index($line, "c=");
|
|
|
|
my $ind0 = index($line, $self->{GBUdb_ConfidenceKey});
|
|
|
|
my $ind1 = index($line, " ", $ind0 + 2);
|
|
|
|
if (-1 == $ind0) {
|
|
|
|
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
my $c = 1.0 * substr($line, $ind0 + 2, $ind1 - $ind0 - 2);
|
|
|
|
print "calc_GBUdb. line: $line\n"; # DEBUG
|
|
|
|
print "calc_GBUdb. c: $c, ind0: $ind0, ind1: $ind1\n"; # DEBUG
|
|
|
|
$ind0 = index($line, "p=");
|
|
|
|
#print "calc_GBUdb. line: $line\n"; # DEBUG
|
|
|
|
#print "calc_GBUdb. c: $c, ind0: $ind0, ind1: $ind1\n"; # DEBUG
|
|
|
|
$ind0 = index($line, $self->{GBUdb_ProbabilityKey});
|
|
|
|
$ind1 = index($line, " ", $ind0 + 2);
|
|
|
|
if (-1 == $ind0) {
|
|
|
|
|
|
|
@@ -519,7 +572,7 @@ sub calc_GBUdb |
|
|
|
}
|
|
|
|
my $p = 1.0 * substr($line, $ind0 + 2, $ind1 - $ind0 - 2);
|
|
|
|
|
|
|
|
print "calc_GBUdb. p: $p, ind0: $ind0, ind1: $ind1\n"; # DEBUG
|
|
|
|
#print "calc_GBUdb. p: $p, ind0: $ind0, ind1: $ind1\n"; # DEBUG
|
|
|
|
|
|
|
|
# Calculate and return the score.
|
|
|
|
my $score = ($p * $c);
|
|
|
@@ -527,16 +580,36 @@ sub calc_GBUdb |
|
|
|
if ($p < 0.0) {
|
|
|
|
$score *= -1.0;
|
|
|
|
}
|
|
|
|
print "calc_GBUdb. score: $score\n"; # DEBUG
|
|
|
|
#print "calc_GBUdb. score: $score\n"; # DEBUG
|
|
|
|
return $score;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub abort
|
|
|
|
# Extract the specified header body from a string containing all the
|
|
|
|
# headers.
|
|
|
|
#
|
|
|
|
# Input--
|
|
|
|
#
|
|
|
|
# $headers--String containing the headers.
|
|
|
|
#
|
|
|
|
# $head--String containing the head of the header to extract.
|
|
|
|
#
|
|
|
|
# Returns the body of the header.
|
|
|
|
#
|
|
|
|
sub extract_header_body
|
|
|
|
{
|
|
|
|
my ( $self, $message ) = @_;
|
|
|
|
my ( $self, $headers, $head ) = @_;
|
|
|
|
my $body = "";
|
|
|
|
if ($headers =~ /$head:(.*)/s) {
|
|
|
|
|
|
|
|
my $temp = $1;
|
|
|
|
$temp =~ /(.*)\nX-(.*)/s;
|
|
|
|
$body = $1;
|
|
|
|
|
|
|
|
}
|
|
|
|
return $body;
|
|
|
|
}
|
|
|
|
|
|
|
|
# xci_scan( $file )
|