data_post hook
spamassassin plugin git-svn-id: https://svn.perl.org/qpsmtpd/branches/v010@38 958fd67b-6ff1-0310-b445-bb7760255be9
This commit is contained in:
parent
e561b69696
commit
8ce8427bf9
@ -5,3 +5,5 @@ dnsbl
|
||||
|
||||
# this plugin needs to run after all other "rcpt" plugins
|
||||
check_relay
|
||||
|
||||
spamassassin
|
@ -335,7 +335,8 @@ sub data {
|
||||
#. ..
|
||||
}
|
||||
|
||||
$buffer .= $_;
|
||||
$self->transaction->body_write($_);
|
||||
|
||||
$size += length $_;
|
||||
}
|
||||
$self->log(5, "size is at $size\n") unless ($i % 300);
|
||||
@ -346,27 +347,27 @@ sub data {
|
||||
$self->log(6, "max_size: $max_size / size: $size");
|
||||
|
||||
$self->transaction->header($header);
|
||||
$self->transaction->body(\$buffer);
|
||||
|
||||
# if we get here without seeing a terminator, the connection is
|
||||
# probably dead.
|
||||
$self->respond(451, "Incomplete DATA"), return 1 unless $complete;
|
||||
|
||||
#
|
||||
# FIXME - Call plugins to work on the body here
|
||||
#
|
||||
|
||||
$self->respond(550, $self->transaction->blocked),return 1 if ($self->transaction->blocked);
|
||||
|
||||
$self->respond(552, "Message too big!"),return 1 if $max_size and $size > $max_size;
|
||||
|
||||
return $self->queue($self->transaction);
|
||||
my ($rc, $msg) = $self->run_hooks("data_post");
|
||||
if ($rc != DONE) {
|
||||
warn "QPSM100";
|
||||
return $self->queue($self->transaction);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub queue {
|
||||
my ($self, $transaction) = @_;
|
||||
|
||||
warn "QPSM2000";
|
||||
|
||||
# these bits inspired by Peter Samuels "qmail-queue wrapper"
|
||||
pipe(MESSAGE_READER, MESSAGE_WRITER) or fault("Could not create message pipe"), exit;
|
||||
pipe(ENVELOPE_READER, ENVELOPE_WRITER) or fault("Could not create envelope pipe"), exit;
|
||||
@ -391,7 +392,10 @@ sub queue {
|
||||
print MESSAGE_WRITER "X-smtpd: qpsmtpd/",$self->version,", http://develooper.com/code/qpsmtpd/\n";
|
||||
|
||||
$transaction->header->print(\*MESSAGE_WRITER);
|
||||
print MESSAGE_WRITER ${$transaction->body};
|
||||
$transaction->body_resetpos;
|
||||
while (my $line = $transaction->body_getline) {
|
||||
print MESSAGE_WRITER $line;
|
||||
}
|
||||
close MESSAGE_WRITER;
|
||||
|
||||
my @rcpt = map { "T" . $_->address } $transaction->recipients;
|
||||
|
@ -1,5 +1,10 @@
|
||||
package Qpsmtpd::Transaction;
|
||||
use strict;
|
||||
use IO::File qw(O_RDWR O_CREAT);
|
||||
|
||||
# For unique filenames. We write to a local tmp dir so we don't need
|
||||
# to make them unpredictable.
|
||||
my $transaction_counter = 0;
|
||||
|
||||
sub new { start(@_) }
|
||||
|
||||
@ -33,11 +38,11 @@ sub header {
|
||||
$self->{_header};
|
||||
}
|
||||
|
||||
sub body {
|
||||
my $self = shift;
|
||||
@_ and $self->{_body} = shift;
|
||||
$self->{_body};
|
||||
}
|
||||
#sub body {
|
||||
# my $self = shift;
|
||||
# @_ and $self->{_body} = shift;
|
||||
# $self->{_body};
|
||||
#}
|
||||
|
||||
sub blocked {
|
||||
my $self = shift;
|
||||
@ -52,10 +57,45 @@ sub notes {
|
||||
$self->{_notes}->{$key};
|
||||
}
|
||||
|
||||
#sub add_header_line {
|
||||
#}
|
||||
sub add_header_line {
|
||||
my $self = shift;
|
||||
$self->{_header} .= shift;
|
||||
}
|
||||
|
||||
#sub add_body_line {
|
||||
#}
|
||||
sub body_write {
|
||||
my $self = shift;
|
||||
my $data = shift;
|
||||
#$self->{_body} .= shift;
|
||||
unless ($self->{_body_file}) {
|
||||
-d "tmp" or mkdir("tmp", 0700) or die "Could not create dir tmp: $!";
|
||||
$self->{_filename} = "/home/smtpd/qpsmtpd/tmp/" . join(":", time, $$, $transaction_counter++);
|
||||
$self->{_body_file} = IO::File->new($self->{_filename}, O_RDWR|O_CREAT)
|
||||
or die "Could not open file $self->{_filename} - $! "; # . $self->{_body_file}->error;
|
||||
}
|
||||
# go to the end of the file
|
||||
seek($self->{_body_file},0,2)
|
||||
unless $self->{_body_file_writing};
|
||||
$self->{_body_file_writing} = 1;
|
||||
$self->{_body_file}->print(ref $data eq "SCALAR" ? $$data : $data);
|
||||
}
|
||||
|
||||
sub body_resetpos {
|
||||
my $self = shift;
|
||||
return unless $self->{_body_file};
|
||||
seek($self->{_body_file}, 0,0);
|
||||
$self->{_body_file_writing} = 0;
|
||||
1;
|
||||
}
|
||||
|
||||
sub body_getline {
|
||||
my $self = shift;
|
||||
return unless $self->{_body_file};
|
||||
seek($self->{_body_file}, 0,0)
|
||||
if $self->{_body_file_writing};
|
||||
$self->{_body_file_writing} = 0;
|
||||
my $line = $self->{_body_file}->getline;
|
||||
return $line;
|
||||
|
||||
}
|
||||
|
||||
1;
|
||||
|
55
plugins/spamassassin
Normal file
55
plugins/spamassassin
Normal file
@ -0,0 +1,55 @@
|
||||
use Socket qw(:DEFAULT :crlf);
|
||||
use IO::Handle;
|
||||
|
||||
sub register {
|
||||
my ($self, $qp) = @_;
|
||||
$self->register_hook("data_post", "check_spam");
|
||||
}
|
||||
|
||||
#my $rv = check_spam();
|
||||
#die "failure!" unless defined $rv;
|
||||
#print "rv: $rv\n";
|
||||
|
||||
sub check_spam {
|
||||
my ($self, $transaction) = @_;
|
||||
|
||||
my $remote = 'localhost';
|
||||
my $port = 783;
|
||||
if ($port =~ /\D/) { $port = getservbyname($port, 'tcp') }
|
||||
die "No port" unless $port;
|
||||
my $iaddr = inet_aton($remote) || die "no host: $remote";
|
||||
my $paddr = sockaddr_in($port, $iaddr);
|
||||
|
||||
my $proto = getprotobyname('tcp');
|
||||
socket(SPAMD, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
|
||||
connect(SPAMD, $paddr) || warn "SA: connect: $!", return undef;
|
||||
|
||||
SPAMD->autoflush(1);
|
||||
|
||||
$transaction->body_resetpos;
|
||||
|
||||
print SPAMD "REPORT SPAMC/1.0" . CRLF;
|
||||
# or CHECK or REPORT or SYMBOLS
|
||||
|
||||
while (my $line = $transaction->body_getline) {
|
||||
chomp $line;
|
||||
print SPAMD $line, CRLF;
|
||||
}
|
||||
print SPAMD CRLF;
|
||||
shutdown(SPAMD, 1);
|
||||
my $line0 = <SPAMD>; # get the first protocol lines out
|
||||
if ($line0) {
|
||||
$transaction->header->add("X-Spam-Check-By", $self->qp->config('me'));
|
||||
}
|
||||
while (<SPAMD>) {
|
||||
warn "GOT FROM SPAMD1: $_";
|
||||
next unless m/\S/;
|
||||
s/\r?\n$/\n/;
|
||||
my @h = split /: /, $_, 2;
|
||||
|
||||
$transaction->header->add(@h);
|
||||
last if $h[0] eq "Spam" and $h[1] =~ m/^False/;
|
||||
|
||||
}
|
||||
return (OK);
|
||||
}
|
Loading…
Reference in New Issue
Block a user