diff --git a/Changes b/Changes index 8247ed4..250d3a8 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,9 @@ 0.33 + Add SSL encryption method to header to mirror other qmail/SSL patches. + Add tls_before_auth to suppress AUTH unless TLS has already been + established (Robin Johnson). + Fix "help" command when there's no "smtpgreeting" configured (the default) (Thanks to Thomas Ogrisegg) diff --git a/README b/README index 53c3fc9..0e2979d 100644 --- a/README +++ b/README @@ -176,6 +176,11 @@ smtpd uses during the data transactions. If this file doesnt exist, it will default to use $ENV{HOME}/tmp/. This directory should be set with a mode of 700 and owned by the smtpd user. +=item tls_before_auth + +If this file contains anything except a 0 on the first noncomment line, then +AUTH will not be offered unless TLS/SSL are in place, either with STARTTLS, +or SMTP-SSL on port 465. =item everything (?) that qmail-smtpd supports. diff --git a/config.sample/tls_before_auth b/config.sample/tls_before_auth new file mode 100644 index 0000000..d9084c2 --- /dev/null +++ b/config.sample/tls_before_auth @@ -0,0 +1,2 @@ +# change the next line to 0 if you want to offer AUTH without TLS +1 diff --git a/lib/Qpsmtpd/SMTP.pm b/lib/Qpsmtpd/SMTP.pm index 577d7bf..cdace58 100644 --- a/lib/Qpsmtpd/SMTP.pm +++ b/lib/Qpsmtpd/SMTP.pm @@ -219,7 +219,9 @@ HOOK: foreach my $hook ( keys %{$self->{hooks}} ) { } } - if ( %auth_mechanisms ) { + # Check if we should only offer AUTH after TLS is completed + my $tls_before_auth = ($self->config('tls_before_auth') ? ($self->config('tls_before_auth'))[0] && $self->transaction->notes('tls_enabled') : 0); + if ( %auth_mechanisms && !$tls_before_auth) { push @capabilities, 'AUTH '.join(" ",keys(%auth_mechanisms)); $self->{_commands}->{'auth'} = ""; } @@ -248,6 +250,9 @@ sub auth { and $self->{_auth} == OK ); return $self->respond( 503, "AUTH not defined for HELO" ) if ( $self->connection->hello eq "helo" ); + return $self->respond( 503, "SSL/TLS required before AUTH" ) + if ( ($self->config('tls_before_auth'))[0] + and $self->transaction->notes('tls_enabled') ); return $self->{_auth} = Qpsmtpd::Auth::SASL( $self, $arg, @stuff ); } @@ -584,13 +589,15 @@ sub data { $self->transaction->header($header); my $smtp = $self->connection->hello eq "ehlo" ? "ESMTP" : "SMTP"; + my $sslheader = (defined $self->connection->notes('tls_enabled') and $self->connection->notes('tls_enabled')) ? + "(".$self->connection->notes('tls_socket')->get_cipher()." encrypted) " : ""; my $authheader = (defined $self->{_auth} and $self->{_auth} == OK) ? "(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 $smtp; ". (strftime('%a, %d %b %Y %H:%M:%S %z', localtime)), + .") with $sslheader$smtp; ". (strftime('%a, %d %b %Y %H:%M:%S %z', localtime)), 0); # if we get here without seeing a terminator, the connection is