|
|
|
@ -13,65 +13,62 @@ use DBI; |
|
|
|
|
use strict; |
|
|
|
|
|
|
|
|
|
#plugin level variables are here since version 0.02 |
|
|
|
|
my($dsn,$mail_table,$rcpt_table,$user,$passwd,$mail_id); |
|
|
|
|
my($log_header); |
|
|
|
|
my($log_all_body,$log_deny_body,$body_table); |
|
|
|
|
my($dbh,$sth); |
|
|
|
|
|
|
|
|
|
sub register |
|
|
|
|
{my ($self,$qp) = (shift,shift); |
|
|
|
|
$self->log(LOGERROR,"Bad count of parameters in log2sql plugin.") if @_ % 2; |
|
|
|
|
my(%args) = @_; |
|
|
|
|
|
|
|
|
|
$self->register_hook("connect", "connect_handler"); |
|
|
|
|
$self->register_hook("mail", "mail_handler"); |
|
|
|
|
$self->register_hook("rcpt", "rcpt_handler"); |
|
|
|
|
$self->register_hook("data_post", "data_post_handler"); |
|
|
|
|
$self->register_hook("queue", "queue_handler"); |
|
|
|
|
|
|
|
|
|
$self->register_hook("deny", "deny_handler") if $args{D}; |
|
|
|
|
|
|
|
|
|
$self->register_hook("disconnect", "disconnect_handler"); |
|
|
|
|
|
|
|
|
|
$dsn = 'DBI'; |
|
|
|
|
$dsn .= ':'.($args{t} || 'mysql'); |
|
|
|
|
$dsn .= ':'.($args{d} || 'qpsmtpd'); |
|
|
|
|
$dsn .= ';host='.$args{h} if $args{h}; |
|
|
|
|
$dsn .= ';port='.$args{P} if $args{P}; |
|
|
|
|
$dsn .= ';'.$args{o} if $args{o}; |
|
|
|
|
|
|
|
|
|
$mail_table = $args{m} || 'messages'; |
|
|
|
|
$rcpt_table = $args{r} || 'rcpts'; |
|
|
|
|
|
|
|
|
|
$user = $args{u} || 'root'; |
|
|
|
|
$passwd = $args{p} || ''; |
|
|
|
|
|
|
|
|
|
$log_header = $args{H} || undef; |
|
|
|
|
|
|
|
|
|
$log_all_body = $args{B} || undef; |
|
|
|
|
$log_deny_body = $args{DB} || undef; |
|
|
|
|
$body_table = $args{b} || 'message_body'; |
|
|
|
|
}#end register |
|
|
|
|
my ($dsn,$mail_table,$rcpt_table,$user,$passwd,$mail_id); |
|
|
|
|
my ($log_header); |
|
|
|
|
my ($log_all_body,$log_deny_body,$body_table); |
|
|
|
|
my ($dbh,$sth); |
|
|
|
|
|
|
|
|
|
sub register { |
|
|
|
|
my ($self,$qp) = (shift,shift); |
|
|
|
|
$self->log(LOGERROR,"Bad count of parameters in log2sql plugin.") if @_ % 2; |
|
|
|
|
my (%args) = @_; |
|
|
|
|
|
|
|
|
|
$self->register_hook("connect", "connect_handler"); |
|
|
|
|
$self->register_hook("mail", "mail_handler"); |
|
|
|
|
$self->register_hook("rcpt", "rcpt_handler"); |
|
|
|
|
$self->register_hook("data_post", "data_post_handler"); |
|
|
|
|
$self->register_hook("queue", "queue_handler"); |
|
|
|
|
$self->register_hook("deny", "deny_handler") if $args{D}; |
|
|
|
|
$self->register_hook("disconnect", "disconnect_handler"); |
|
|
|
|
|
|
|
|
|
$dsn = 'DBI'; |
|
|
|
|
$dsn .= ':'.($args{t} || 'mysql'); |
|
|
|
|
$dsn .= ':'.($args{d} || 'qpsmtpd'); |
|
|
|
|
$dsn .= ';host='.$args{h} if $args{h}; |
|
|
|
|
$dsn .= ';port='.$args{P} if $args{P}; |
|
|
|
|
$dsn .= ';'.$args{o} if $args{o}; |
|
|
|
|
|
|
|
|
|
$mail_table = $args{m} || 'messages'; |
|
|
|
|
$rcpt_table = $args{r} || 'rcpts'; |
|
|
|
|
|
|
|
|
|
$user = $args{u} || 'root'; |
|
|
|
|
$passwd = $args{p} || ''; |
|
|
|
|
|
|
|
|
|
$log_header = $args{H} || undef; |
|
|
|
|
|
|
|
|
|
$log_all_body = $args{B} || undef; |
|
|
|
|
$log_deny_body = $args{DB} || undef; |
|
|
|
|
$body_table = $args{b} || 'message_body'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sub connect_handler |
|
|
|
|
{my ($self,$transaction) = @_; |
|
|
|
|
sub connect_handler { |
|
|
|
|
my ($self,$transaction) = @_; |
|
|
|
|
|
|
|
|
|
$self->log(LOGDEBUG,"DSN:$dsn"); |
|
|
|
|
$dbh = DBI->connect($dsn,$user,$passwd) |
|
|
|
|
|| $self->log(LOGERROR,DBI::errstr); |
|
|
|
|
$self->log(LOGDEBUG,"DSN:$dsn"); |
|
|
|
|
$dbh = DBI->connect($dsn,$user,$passwd) || $self->log(LOGERROR,DBI::errstr); |
|
|
|
|
|
|
|
|
|
# generate mail id |
|
|
|
|
$mail_id = $$.'.'.time.'.'.int(rand(10000)); |
|
|
|
|
# set note for other plugins |
|
|
|
|
$transaction->notes('log2sql_mail_id', $mail_id); |
|
|
|
|
# quote the mail_id for later use: |
|
|
|
|
$mail_id = $dbh->quote($mail_id); |
|
|
|
|
# generate mail id |
|
|
|
|
$mail_id = $$.'.'.time.'.'.int(rand(10000)); |
|
|
|
|
# set note for other plugins |
|
|
|
|
$transaction->notes('log2sql_mail_id', $mail_id); |
|
|
|
|
# quote the mail_id for later use: |
|
|
|
|
$mail_id = $dbh->quote($mail_id); |
|
|
|
|
|
|
|
|
|
my ($sec,$min,$hour,$day,$mon,$year) = localtime; |
|
|
|
|
$year += 1900; |
|
|
|
|
$mon += 1; |
|
|
|
|
my ($sec,$min,$hour,$day,$mon,$year) = localtime; |
|
|
|
|
$year += 1900; |
|
|
|
|
$mon += 1; |
|
|
|
|
|
|
|
|
|
my($statement) = "INSERT INTO ".$mail_table." (mail_id,". |
|
|
|
|
my ($statement) = "INSERT INTO ".$mail_table." (mail_id,". |
|
|
|
|
$mail_table.".date_day,". |
|
|
|
|
$mail_table.".date_time,". |
|
|
|
|
"remote_ip,remote_host,remote_info) ". |
|
|
|
@ -83,95 +80,93 @@ my($statement) = "INSERT INTO ".$mail_table." (mail_id,". |
|
|
|
|
$dbh->quote($self->qp->connection->remote_host).",". |
|
|
|
|
$dbh->quote($self->qp->connection->remote_info).")"; |
|
|
|
|
|
|
|
|
|
$self->log(LOGDEBUG,"connect_handler statement:".$statement); |
|
|
|
|
$self->log(LOGDEBUG,"connect_handler statement:".$statement); |
|
|
|
|
|
|
|
|
|
$dbh->do($statement) |
|
|
|
|
|| $self->log(LOGERROR,$dbh->errstr()); |
|
|
|
|
$dbh->do($statement) || $self->log(LOGERROR,$dbh->errstr()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return(DECLINED); |
|
|
|
|
return(DECLINED); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sub mail_handler |
|
|
|
|
{my ($self, $transaction, $sender) =@_; |
|
|
|
|
sub mail_handler { |
|
|
|
|
my ($self, $transaction, $sender) = @_; |
|
|
|
|
|
|
|
|
|
my($statement) = "UPDATE ".$mail_table." SET sender=". |
|
|
|
|
my ($statement) = "UPDATE ".$mail_table." SET sender=". |
|
|
|
|
$dbh->quote($sender->user.'@'.$sender->host). |
|
|
|
|
" WHERE mail_id=".$mail_id; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$self->log(LOGDEBUG,"mail_handler statement:".$statement); |
|
|
|
|
$self->log(LOGDEBUG,"mail_handler statement:".$statement); |
|
|
|
|
|
|
|
|
|
$dbh->do($statement) |
|
|
|
|
$dbh->do($statement) |
|
|
|
|
|| $self->log(LOGERROR,$dbh->errstr()); |
|
|
|
|
|
|
|
|
|
return(DECLINED); |
|
|
|
|
return(DECLINED); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sub rcpt_handler |
|
|
|
|
{my($self,$transaction,$recipient) = @_; |
|
|
|
|
sub rcpt_handler { |
|
|
|
|
my ($self,$transaction,$recipient) = @_; |
|
|
|
|
|
|
|
|
|
my($statement) = "INSERT INTO ".$rcpt_table." (mail_id,". |
|
|
|
|
my ($statement) = "INSERT INTO ".$rcpt_table." (mail_id,". |
|
|
|
|
"recipient) ". |
|
|
|
|
"VALUES(". |
|
|
|
|
$mail_id.",". |
|
|
|
|
$dbh->quote($recipient->user.'@'.$recipient->host).")"; |
|
|
|
|
|
|
|
|
|
$self->log(LOGDEBUG,"rcpt_handler statement:".$statement); |
|
|
|
|
$self->log(LOGDEBUG,"rcpt_handler statement:".$statement); |
|
|
|
|
|
|
|
|
|
$dbh->do($statement) |
|
|
|
|
|| $self->log(LOGERROR,$dbh->errstr()); |
|
|
|
|
$dbh->do($statement) || $self->log(LOGERROR,$dbh->errstr()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return(DECLINED); |
|
|
|
|
return(DECLINED); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sub data_post_handler |
|
|
|
|
{my($self,$transaction)=@_; |
|
|
|
|
my($header) = $transaction->header(); |
|
|
|
|
# In data_post handler the header is not actual, |
|
|
|
|
# but in queue handler somethimes there are problems with |
|
|
|
|
# header, sizes, subject logs (don't know why?!?!) |
|
|
|
|
sub data_post_handler{ |
|
|
|
|
my ($self,$transaction) = @_; |
|
|
|
|
my ($header) = $transaction->header(); |
|
|
|
|
# In data_post handler the header is not actual, |
|
|
|
|
# but in queue handler somethimes there are problems with |
|
|
|
|
# header, sizes, subject logs (don't know why?!?!) |
|
|
|
|
|
|
|
|
|
#'touch' this message :-)) |
|
|
|
|
$header->add("X-Sql-Log-ID",$mail_id); |
|
|
|
|
#'touch' this message :-)) |
|
|
|
|
$header->add("X-Sql-Log-ID",$mail_id); |
|
|
|
|
|
|
|
|
|
my $subject = scalar $header->get("Subject"); |
|
|
|
|
chomp($subject); |
|
|
|
|
# Only keep the first 255 chars to be sure it can be inserted in the table |
|
|
|
|
$subject= substr $subject, 0, 254 if (length($subject) > 254); |
|
|
|
|
my $subject = scalar $header->get("Subject"); |
|
|
|
|
chomp($subject); |
|
|
|
|
# Only keep the first 255 chars to be sure it can be inserted in the table |
|
|
|
|
$subject= substr $subject, 0, 254 if (length($subject) > 254); |
|
|
|
|
|
|
|
|
|
my($statement) = "UPDATE ".$mail_table." SET subject=". |
|
|
|
|
my ($statement) = "UPDATE ".$mail_table." SET subject=". |
|
|
|
|
$dbh->quote($subject). |
|
|
|
|
",header_size=".$dbh->quote(length($header->as_string())). |
|
|
|
|
",body_size=".$dbh->quote($transaction->data_size()). |
|
|
|
|
" WHERE mail_id=".$mail_id; |
|
|
|
|
|
|
|
|
|
$self->log(LOGDEBUG,"data_post_handler statement:".$statement); |
|
|
|
|
$self->log(LOGDEBUG,"data_post_handler statement:".$statement); |
|
|
|
|
|
|
|
|
|
$dbh->do($statement) |
|
|
|
|
$dbh->do($statement) |
|
|
|
|
|| $self->log(LOGERROR,$dbh->errstr()); |
|
|
|
|
|
|
|
|
|
#if $args{H} then log the message header in the main 'messages' table |
|
|
|
|
if ($log_header) |
|
|
|
|
{$statement = "UPDATE ".$mail_table." SET ". |
|
|
|
|
#if $args{H} then log the message header in the main 'messages' table |
|
|
|
|
if ($log_header){ |
|
|
|
|
$statement = "UPDATE ".$mail_table." SET ". |
|
|
|
|
"header=".$dbh->quote($header->as_string()). |
|
|
|
|
"WHERE mail_id=".$mail_id; |
|
|
|
|
$self->log(LOGDEBUG,"data_post_handler log header statement:".$statement); |
|
|
|
|
|
|
|
|
|
$dbh->do($statement) |
|
|
|
|
|| $self->log(LOGERROR,$dbh->errstr()); |
|
|
|
|
}#end log geader |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if args{B} then log message body in a separated table |
|
|
|
|
if ($log_all_body) |
|
|
|
|
{my(@body) = ($transaction->header()->as_string()); |
|
|
|
|
#if args{B} then log message body in a separated table |
|
|
|
|
if ($log_all_body) { |
|
|
|
|
my (@body) = ($transaction->header()->as_string()); |
|
|
|
|
|
|
|
|
|
$transaction->body_resetpos(); |
|
|
|
|
|
|
|
|
|
while(my $line = $transaction->body_getline()) |
|
|
|
|
{push(@body,$line); |
|
|
|
|
while(my $line = $transaction->body_getline()) { |
|
|
|
|
push(@body,$line); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$statement = "INSERT INTO ".$body_table." (mail_id,body)". |
|
|
|
@ -181,73 +176,71 @@ if ($log_all_body) |
|
|
|
|
$dbh->do($statement) |
|
|
|
|
|| $self->log(LOGERROR,$dbh->errstr()); |
|
|
|
|
|
|
|
|
|
}#end body log |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return(DECLINED); |
|
|
|
|
return(DECLINED); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sub queue_handler |
|
|
|
|
{my($self,$transaction) = @_; |
|
|
|
|
my($status) = $transaction->header->get('X-Spam-Status') or return (DECLINED); |
|
|
|
|
my($score) = ($status =~ m/hits=(\d+\.\d+)/)[0] || "0" ; |
|
|
|
|
sub queue_handler { |
|
|
|
|
my ($self,$transaction) = @_; |
|
|
|
|
my ($status) = $transaction->header->get('X-Spam-Status') or return (DECLINED); |
|
|
|
|
my ($score) = ($status =~ m/hits=(\d+\.\d+)/)[0] || "0" ; |
|
|
|
|
|
|
|
|
|
my($statement) = "UPDATE ".$mail_table." SET ". |
|
|
|
|
my ($statement) = "UPDATE ".$mail_table." SET ". |
|
|
|
|
"spam_status=".$dbh->quote($score). |
|
|
|
|
" WHERE mail_id=".$mail_id; |
|
|
|
|
|
|
|
|
|
$self->log(LOGDEBUG,"queue_handler statement:".$statement); |
|
|
|
|
$self->log(LOGDEBUG,"queue_handler statement:".$statement); |
|
|
|
|
|
|
|
|
|
$dbh->do($statement) |
|
|
|
|
$dbh->do($statement) |
|
|
|
|
|| $self->log(LOGERROR,$dbh->errstr()); |
|
|
|
|
|
|
|
|
|
return(DECLINED); |
|
|
|
|
return(DECLINED); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sub deny_handler |
|
|
|
|
{my($self,$transaction,$plugin,$code,$msg) = @_; |
|
|
|
|
sub deny_handler { |
|
|
|
|
my ($self,$transaction,$plugin,$code,$msg) = @_; |
|
|
|
|
|
|
|
|
|
my($statement) = "UPDATE ".$mail_table." SET ". |
|
|
|
|
my ($statement) = "UPDATE ".$mail_table." SET ". |
|
|
|
|
"deny='YES'". |
|
|
|
|
",deny_plugin=".$dbh->quote($plugin). |
|
|
|
|
",deny_code=".$dbh->quote($code). |
|
|
|
|
",deny_msg=".$dbh->quote($msg). |
|
|
|
|
" WHERE mail_id=".$mail_id; |
|
|
|
|
|
|
|
|
|
$self->log(LOGDEBUG,"deny_handler statement:".$statement); |
|
|
|
|
$self->log(LOGDEBUG,"deny_handler statement:".$statement); |
|
|
|
|
|
|
|
|
|
$dbh->do($statement) |
|
|
|
|
|| $self->log(LOGERROR,$dbh->errstr()); |
|
|
|
|
$dbh->do($statement) || $self->log(LOGERROR,$dbh->errstr()); |
|
|
|
|
|
|
|
|
|
#if configured to log the body of the denied messages |
|
|
|
|
if ($log_deny_body && ! $log_all_body) |
|
|
|
|
{my(@body) = ($transaction->header()->as_string()); |
|
|
|
|
#if configured to log the body of the denied messages |
|
|
|
|
if ($log_deny_body && ! $log_all_body) { |
|
|
|
|
my (@body) = ($transaction->header()->as_string()); |
|
|
|
|
|
|
|
|
|
$transaction->body_resetpos(); |
|
|
|
|
|
|
|
|
|
while(my $line = $transaction->body_getline()) |
|
|
|
|
{push(@body,$line); |
|
|
|
|
while (my $line = $transaction->body_getline()) { |
|
|
|
|
push(@body,$line); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$statement = "INSERT INTO ".$body_table." (mail_id,body)". |
|
|
|
|
" VALUES(".$mail_id.",".$dbh->quote(join('',@body)).")"; |
|
|
|
|
$self->log(LOGDEBUG,"data_post body log statement:".$statement); |
|
|
|
|
|
|
|
|
|
$dbh->do($statement) |
|
|
|
|
|| $self->log(LOGERROR,$dbh->errstr()); |
|
|
|
|
$self->log(LOGDEBUG,"data_post body log statement:".$statement); |
|
|
|
|
|
|
|
|
|
}#end body log |
|
|
|
|
$dbh->do($statement) || $self->log(LOGERROR,$dbh->errstr()); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return(DECLINED); |
|
|
|
|
return(DECLINED); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sub disconnect_handler |
|
|
|
|
{my($self,$transaction) = @_; |
|
|
|
|
sub disconnect_handler { |
|
|
|
|
my ($self,$transaction) = @_; |
|
|
|
|
|
|
|
|
|
$dbh->disconnect(); |
|
|
|
|
$dbh->disconnect(); |
|
|
|
|
|
|
|
|
|
return(DECLINED); |
|
|
|
|
return(DECLINED); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
=head1 NAME |
|
|
|
@ -293,12 +286,13 @@ Here are the CREATE statements for the tables. Assuming the 'messages' table is |
|
|
|
|
|
|
|
|
|
CREATE TABLE `messages` ( |
|
|
|
|
`mail_id` varchar(255) NOT NULL default '', |
|
|
|
|
`time` int(11) default '0', |
|
|
|
|
`date_day` date, |
|
|
|
|
`date_time` time, |
|
|
|
|
`remote_ip` varchar(255) default NULL, |
|
|
|
|
`remote_host` varchar(255) default NULL, |
|
|
|
|
`remote_info` varchar(255) default NULL, |
|
|
|
|
`sender` varchar(255) default NULL, |
|
|
|
|
`subject` text, |
|
|
|
|
`subject` varchar(255) default NULL, |
|
|
|
|
`header_size` int(11) default NULL, |
|
|
|
|
`body_size` int(11) default NULL, |
|
|
|
|
`spam_status` float default NULL, |
|
|
|
|