diff --git a/Changes b/Changes index ac518db..f46cf49 100644 --- a/Changes +++ b/Changes @@ -1,4 +1,8 @@ 0.3x + The ill-named $transaction->body_size() is depreceated now, use + $transaction->data_size() instead. Check your logs for LOGWARN messages + about "body_size" and fix your plugins. (Hanno Hecker) + Instead of failing with cryptic message, ignore lines in config/plugins for uninstalled plugins. (John Peacock) diff --git a/lib/Qpsmtpd/Transaction.pm b/lib/Qpsmtpd/Transaction.pm index ea1d41c..6cfaed4 100644 --- a/lib/Qpsmtpd/Transaction.pm +++ b/lib/Qpsmtpd/Transaction.pm @@ -141,10 +141,23 @@ sub body_write { } } -sub body_size { +sub body_size { # depreceated, use data_size() instead + my $self = shift; + $self->log(LOGWARN, "WARNING: body_size() is depreceated, use data_size() instead"); + $self->{_body_size} || 0; +} + +sub data_size { shift->{_body_size} || 0; } +sub body_length { + my $self = shift; + $self->{_body_size} or return 0; + $self->{_header_size} or return 0; + return $self->{_body_size} - $self->{_header_size}; +} + sub body_resetpos { my $self = shift; @@ -190,6 +203,10 @@ sub body_as_string { return $str; } +sub body_fh { + return shift->{_body_file}; +} + sub DESTROY { my $self = shift; # would we save some disk flushing if we unlinked the file before @@ -294,6 +311,11 @@ use the notes field in the C object instead. Returns the temporary filename used to store the message contents; useful for virus scanners so that an additional copy doesn't need to be made. +Calling C also forces spooling to disk. A message is not +spooled to disk if it's size is smaller than +I<$self-Econfig("size_threshold")>, default threshold is 0, the sample +config file sets this to 10000. + =head2 body_write( $data ) Write data to the end of the email. @@ -302,7 +324,26 @@ C<$data> can be either a plain scalar, or a reference to a scalar. =head2 body_size( ) -Get the current size of the email. +B, Use I instead. + +=head2 data_size( ) + +Get the current size of the email. Note that this is not the size of the +message that will be queued, it is the size of what the client sent after +the C command. If you need the size that will be queued, use + + my $msg_len = length($transaction->header->as_string) + + $transaction->body_length; + +The line above is of course only valid in I, as other plugins +may add headers and qpsmtpd will add it's I header. + +=head2 body_length( ) + +Get the current length of the body of the email. This length includes the +empty line between the headers and the body. Until the client has sent +some data of the body of the message (i.e. headers are finished and client +sent the empty line) this will return 0. =head2 body_resetpos( ) @@ -316,6 +357,12 @@ file pointer. Returns a single line of data from the body of the email. +=head2 body_fh( ) + +Returns the file handle to the temporary file of the email. This will return +undef if the file is not opened (yet). In I or later you can +force spooling to disk by calling I<$transaction-Ebody_filename>. + =head1 SEE ALSO L, L, L diff --git a/plugins/check_basicheaders b/plugins/check_basicheaders index 5efa438..8f90dbd 100644 --- a/plugins/check_basicheaders +++ b/plugins/check_basicheaders @@ -44,7 +44,7 @@ sub hook_data_post { my ($self, $transaction) = @_; return (DENY, "You have to send some data first") - if $transaction->body_size == 0; + if $transaction->data_size == 0; return (DENY, "Mail with no From header not accepted here") unless $transaction->header->get('From'); diff --git a/plugins/spamassassin b/plugins/spamassassin index 0f3686a..5b62153 100644 --- a/plugins/spamassassin +++ b/plugins/spamassassin @@ -96,7 +96,7 @@ sub hook_data_post { # check_spam my ($self, $transaction) = @_; $self->log(LOGDEBUG, "check_spam"); - return (DECLINED) if $transaction->body_size > 500_000; + return (DECLINED) if $transaction->data_size > 500_000; my $leave_old_headers = lc($self->{_args}->{leave_old_headers}) || 'rename'; diff --git a/plugins/virus/bitdefender b/plugins/virus/bitdefender index b29d50c..57eb974 100644 --- a/plugins/virus/bitdefender +++ b/plugins/virus/bitdefender @@ -80,10 +80,10 @@ sub register { sub hook_data_post { my ( $self, $transaction ) = @_; - if ( $transaction->body_size > $self->{"_bitd"}->{"max_size"} ) { + if ( $transaction->data_size > $self->{"_bitd"}->{"max_size"} ) { $self->log( LOGWARN, 'Mail too large to scan (' - . $transaction->body_size . " vs " + . $transaction->data_size . " vs " . $self->{"_bitd"}->{"max_size"} . ")" ); return (DECLINED); diff --git a/plugins/virus/clamav b/plugins/virus/clamav index b16d1cb..24ad7b0 100644 --- a/plugins/virus/clamav +++ b/plugins/virus/clamav @@ -164,9 +164,9 @@ sub register { sub hook_data_post { my ($self, $transaction) = @_; - if ($transaction->body_size > $self->{_max_size}) { + if ($transaction->data_size > $self->{_max_size}) { $self->log(LOGWARN, 'Mail too large to scan ('. - $transaction->body_size . " vs $self->{_max_size})" ); + $transaction->data_size . " vs $self->{_max_size})" ); return (DECLINED); } diff --git a/plugins/virus/clamdscan b/plugins/virus/clamdscan index 80a49d3..36f647d 100644 --- a/plugins/virus/clamdscan +++ b/plugins/virus/clamdscan @@ -107,8 +107,8 @@ sub hook_data_post { my ( $self, $transaction ) = @_; $DB::single = 1; - if ( $transaction->body_size > $self->{"_clamd"}->{"max_size"} * 1024 ) { - $self->log( LOGNOTICE, "Declining due to body_size" ); + if ( $transaction->data_size > $self->{"_clamd"}->{"max_size"} * 1024 ) { + $self->log( LOGNOTICE, "Declining due to data_size" ); return (DECLINED); } diff --git a/plugins/virus/klez_filter b/plugins/virus/klez_filter index 4c6b9b8..620de98 100644 --- a/plugins/virus/klez_filter +++ b/plugins/virus/klez_filter @@ -4,9 +4,9 @@ sub hook_data_post { # klez files are always sorta big .. how big? Dunno. return (DECLINED) - if $transaction->body_size < 60_000; + if $transaction->data_size < 60_000; # 220k was too little, so let's just disable the "big size check" - # or $transaction->body_size > 1_000_000; + # or $transaction->data_size > 1_000_000; # maybe it would be worthwhile to add a check for # Content-Type: multipart/alternative; here? diff --git a/plugins/virus/sophie b/plugins/virus/sophie index 6850590..0b35d32 100644 --- a/plugins/virus/sophie +++ b/plugins/virus/sophie @@ -16,8 +16,8 @@ sub hook_data_post { my ( $self, $transaction ) = @_; $DB::single = 1; - if ( $transaction->body_size > $self->{"_sophie"}->{"max_size"} * 1024 ) { - $self->log( LOGNOTICE, "Declining due to body_size" ); + if ( $transaction->data_size > $self->{"_sophie"}->{"max_size"} * 1024 ) { + $self->log( LOGNOTICE, "Declining due to data_size" ); return (DECLINED); } diff --git a/plugins/virus/uvscan b/plugins/virus/uvscan index 55447ed..bfe3345 100644 --- a/plugins/virus/uvscan +++ b/plugins/virus/uvscan @@ -55,7 +55,7 @@ sub hook_data_post { my ($self, $transaction) = @_; return (DECLINED) - if $transaction->body_size > 250_000; + if $transaction->data_size > 250_000; # Ignore non-multipart emails my $content_type = $transaction->header->get('Content-Type');