diff --git a/README.plugins b/README.plugins index ddaf057..1fe37a0 100644 --- a/README.plugins +++ b/README.plugins @@ -232,6 +232,24 @@ in - if we're in a connection, store things in the connection notes instead. +=head2 received_line + +If you wish to provide your own Received header line, do it here. + +The hook is passed the following extra parameters (beyond $self and $transaction): + + - $smtp - the SMTP type used (e.g. "SMTP" or "ESMTP"). + - $auth - the Auth header additionals. + - $sslinfo - information about SSL for the header. + +You're free to use or discard any of the above. + +Allowed return codes: + + OK, $string - use this string for the Received header. + Anything Else - use the standard Received header. + + =head1 Include Files diff --git a/lib/Qpsmtpd/Plugin.pm b/lib/Qpsmtpd/Plugin.pm index b6357be..fcc85a6 100644 --- a/lib/Qpsmtpd/Plugin.pm +++ b/lib/Qpsmtpd/Plugin.pm @@ -9,7 +9,7 @@ our @hooks = qw( rcpt_parse rcpt_pre rcpt mail_parse mail mail_pre data data_post queue_pre queue queue_post quit reset_transaction disconnect post-connection - unrecognized_command deny ok + unrecognized_command deny ok received_line ); our %hooks = map { $_ => 1 } @hooks; diff --git a/lib/Qpsmtpd/PollServer.pm b/lib/Qpsmtpd/PollServer.pm index 8ba24bf..549981c 100644 --- a/lib/Qpsmtpd/PollServer.pm +++ b/lib/Qpsmtpd/PollServer.pm @@ -308,16 +308,24 @@ sub end_of_data { $self->transaction->header($header); } - # only true if client authenticated - if ( $self->authenticated == OK ) { - $header->add("X-Qpsmtpd-Auth","True"); + my $smtp = $self->connection->hello eq "ehlo" ? "ESMTP" : "SMTP"; + my $esmtp = substr($smtp,0,1) eq "E"; + my $authheader; + my $sslheader; + + if (defined $self->connection->notes('tls_enabled') + and $self->connection->notes('tls_enabled')) + { + $smtp .= "S" if $esmtp; # RFC3848 + $sslheader = "(".$self->connection->notes('tls_socket')->get_cipher()." encrypted) "; } - $header->add("Received", "from ".$self->connection->remote_info - ." (HELO ".$self->connection->hello_host . ") (".$self->connection->remote_ip - . ")\n by ".$self->config('me')." (qpsmtpd/".$self->version - .") with $smtp; ". (strftime('%a, %d %b %Y %H:%M:%S %z', localtime)), - 0); + if (defined $self->{_auth} and $self->{_auth} == OK) { + $smtp .= "A" if $esmtp; # RFC3848 + $authheader = "(smtp-auth username $self->{_auth_user}, mechanism $self->{_auth_mechanism})\n"; + } + + $header->add("Received", $self->received_line($smtp, $authheader, $sslheader), 0); return $self->respond(552, "Message too big!") if $self->{max_size} and $self->{data_size} > $self->{max_size}; diff --git a/lib/Qpsmtpd/SMTP.pm b/lib/Qpsmtpd/SMTP.pm index 6837043..e10327d 100644 --- a/lib/Qpsmtpd/SMTP.pm +++ b/lib/Qpsmtpd/SMTP.pm @@ -673,11 +673,7 @@ sub data_respond { $authheader = "(smtp-auth username $self->{_auth_user}, mechanism $self->{_auth_mechanism})\n"; } - $header->add("Received", "from ".$self->connection->remote_info - ." (HELO ".$self->connection->hello_host . ") (".$self->connection->remote_ip - . ")\n $authheader by ".$self->config('me')." (qpsmtpd/".$self->version - .") with $sslheader$smtp; ". (strftime('%a, %d %b %Y %H:%M:%S %z', localtime)), - 0); + $header->add("Received", $self->received_line($smtp, $authheader, $sslheader), 0); # if we get here without seeing a terminator, the connection is # probably dead. @@ -697,6 +693,23 @@ sub data_respond { $self->run_hooks("data_post"); } +sub received_line { + my ($self, $smtp, $authheader, $sslheader) = @_; + my ($rc, $received) = $self->run_hooks("received_line", $smtp, $authheader, $sslheader); + if ($rc == YIELD) { + die "YIELD not supported for received_line hook"; + } + elsif ($rc == OK) { + return $received; + } + else { # assume $rc == DECLINED + return "from ".$self->connection->remote_info + ." (HELO ".$self->connection->hello_host . ") (".$self->connection->remote_ip + . ")\n $authheader by ".$self->config('me')." (qpsmtpd/".$self->version + .") with $sslheader$smtp; ". (strftime('%a, %d %b %Y %H:%M:%S %z', localtime)) + } +} + sub data_post_respond { my ($self, $rc, $msg, $args) = @_; if ($rc == DONE) {