diff --git a/plugins/tls b/plugins/tls index ca456b8..4a3d00f 100644 --- a/plugins/tls +++ b/plugins/tls @@ -93,6 +93,33 @@ sub hook_unrecognized_command { # OK, now we setup TLS $self->qp->respond (220, "Go ahead with TLS"); + unless ( _convert_to_ssl($self) ) { + # SSL setup failed. Now we must respond to every command with 5XX + warn("TLS failed: $@\n"); + $transaction->notes('ssl_failed', 1); + return DENY, "TLS Negotiation Failed"; + } + + $self->log(LOGWARN, "TLS setup returning"); + return DONE; +} + +sub hook_connect { + my ($self, $transaction) = @_; + + my $local_port = $self->qp->connection->local_port; + return DECLINED unless $local_port == 465; # SMTPS + + unless ( _convert_to_ssl($self) ) { + return (DENY_DISCONNECT, "Cannot establish SSL session"); + } + $self->log(LOGWARN, "Connected via SMTPS"); + return DECLINED; +} + +sub _convert_to_ssl { + my ($self) = @_; + eval { my $tlssocket = IO::Socket::SSL->new_from_fd( fileno(STDIN), '+>', @@ -112,14 +139,11 @@ sub hook_unrecognized_command { $self->connection->notes('tls_enabled', 1); }; if ($@) { - # SSL setup failed. Now we must respond to every command with 5XX - warn("TLS failed: $@\n"); - $transaction->notes('ssl_failed', 1); - return DENY, "TLS Negotiation Failed"; + return 0; + } + else { + return 1; } - - $self->log(LOGWARN, "TLS setup returning"); - return DONE; } sub can_do_tls { diff --git a/qpsmtpd-forkserver b/qpsmtpd-forkserver index 8eb2be6..f2cfb4a 100755 --- a/qpsmtpd-forkserver +++ b/qpsmtpd-forkserver @@ -56,8 +56,8 @@ GetOptions('h|help' => \&usage, if ($PORT =~ /^(\d+)$/) { $PORT = $1 } else { &usage } @LOCALADDR = ( '0.0.0.0' ) if !@LOCALADDR; for (0..$#LOCALADDR) { - if ($LOCALADDR[$_] =~ /^([\d\w\-.]+)$/) { - $LOCALADDR[$_] = $1; + if ($LOCALADDR[$_] =~ /^([\d\w\-.]+)(?::(\d+))?$/) { + $LOCALADDR[$_] = { 'addr' => $1, 'port' => $2 || $PORT }; } else { &usage; } @@ -94,13 +94,13 @@ my $select = new IO::Select; # establish SERVER socket(s), bind and listen. for my $listen_addr (@LOCALADDR) { - my $server = IO::Socket::INET->new(LocalPort => $PORT, - LocalAddr => $listen_addr, + my $server = IO::Socket::INET->new(LocalPort => $listen_addr->{'port'}, + LocalAddr => $listen_addr->{'addr'}, Proto => 'tcp', Reuse => 1, Blocking => 0, Listen => SOMAXCONN ) - or die "Creating TCP socket $listen_addr:$PORT: $!\n"; + or die "Creating TCP socket $listen_addr->{'addr'}:$listen_addr->{'port'}: $!\n"; IO::Handle::blocking($server, 0); $select->add($server); } @@ -149,7 +149,9 @@ $> = $quid; $qpsmtpd->load_plugins; -::log(LOGINFO,"Listening on port $PORT"); +foreach my $local_addr ( @LOCALADDR ) { + ::log(LOGINFO,"Listening on $local_addr->{'addr'}:$local_addr->{'port'}"); +} ::log(LOGINFO, 'Running as user '. (getpwuid($>) || $>) . ', group '.