diff --git a/plugins/tls b/plugins/tls index 4a3d00fe..4ff9d559 100644 --- a/plugins/tls +++ b/plugins/tls @@ -12,7 +12,15 @@ tls - plugin to support STARTTLS =head1 DESCRIPTION -This plugin implements basic TLS support. +This plugin implements basic TLS support. It can also be used to support +port 465 (SMTP over SSL), but only with qpsmtpd-forkserver. In this case, +be sure to load plugins/tls before any other connect plugins and start +qpsmtpd like this: + + qpsmtpd-forkserver --port 25 --port 465 + +You can also specify multiple --listen-address options as well; see the help +for qpsmtpd-forkserver for more details. If TLS is successfully negotiated then the C field in the Connection notes is set. If you wish to make TLS mandatory you should check diff --git a/qpsmtpd-forkserver b/qpsmtpd-forkserver index f2cfb4a9..b8362556 100755 --- a/qpsmtpd-forkserver +++ b/qpsmtpd-forkserver @@ -19,7 +19,7 @@ $| = 1; # Configuration my $MAXCONN = 15; # max simultaneous connections -my $PORT = 2525; # port number +my @PORT; # port number(s) my @LOCALADDR; # ip address(es) to bind to my $USER = 'smtpd'; # user to suid to my $MAXCONNIP = 5; # max simultaneous connections from one IP @@ -31,8 +31,9 @@ sub usage { usage: qpsmtpd-forkserver [ options ] -l, --listen-address addr : listen on specific address(es); can be specified multiple times for multiple bindings. Default is - 0.0.0.0 (all interfaces). - -p, --port P : listen on a specific port; default 2525 + 0.0.0.0 (all interfaces). + -p, --port P : listen on a specific port; default 2525; can be + specified multiple times for multiple bindings. -c, --limit-connections N : limit concurrent connections to N; default 15 -u, --user U : run as a particular user (default 'smtpd') -m, --max-from-ip M : limit connections from a single IP; default 5 @@ -46,22 +47,36 @@ GetOptions('h|help' => \&usage, 'l|listen-address=s' => \@LOCALADDR, 'c|limit-connections=i' => \$MAXCONN, 'm|max-from-ip=i' => \$MAXCONNIP, - 'p|port=i' => \$PORT, + 'p|port=s' => \@PORT, 'u|user=s' => \$USER, 'pid-file=s' => \$PID_FILE, 'd|detach' => \$DETACH, - ) || &usage; + ) || &usage; # detaint the commandline -if ($PORT =~ /^(\d+)$/) { $PORT = $1 } else { &usage } @LOCALADDR = ( '0.0.0.0' ) if !@LOCALADDR; +@PORT = ( 2525 ) if !@PORT; + +my @LISTENADDR; for (0..$#LOCALADDR) { if ($LOCALADDR[$_] =~ /^([\d\w\-.]+)(?::(\d+))?$/) { - $LOCALADDR[$_] = { 'addr' => $1, 'port' => $2 || $PORT }; + if ( defined $2 ) { + push @LISTENADDR, { 'addr' => $1, 'port' => $2 }; + } else { + my $addr = $1; + for (0..$#PORT) { + if ( $PORT[$_] =~ /^(\d+)$/ ) { + push @LISTENADDR, { 'addr' => $addr, 'port' => $1 }; + } else { + &usage; + } + } + } } else { &usage; } } + if ($USER =~ /^([\w\-]+)$/) { $USER = $1 } else { &usage } if ($MAXCONN =~ /^(\d+)$/) { $MAXCONN = $1 } else { &usage } @@ -93,7 +108,7 @@ $SIG{TERM} = \&HUNTSMAN; my $select = new IO::Select; # establish SERVER socket(s), bind and listen. -for my $listen_addr (@LOCALADDR) { +for my $listen_addr (@LISTENADDR) { my $server = IO::Socket::INET->new(LocalPort => $listen_addr->{'port'}, LocalAddr => $listen_addr->{'addr'}, Proto => 'tcp', @@ -137,7 +152,7 @@ my $groups = "$qgid $qgid"; while (my ($name,$passwd,$gid,$members) = getgrent()) { my @m = split(/ /, $members); if (grep {$_ eq $USER} @m) { - $groups .= " $gid"; + $groups .= " $gid"; } } $) = $groups; @@ -149,13 +164,13 @@ $> = $quid; $qpsmtpd->load_plugins; -foreach my $local_addr ( @LOCALADDR ) { - ::log(LOGINFO,"Listening on $local_addr->{'addr'}:$local_addr->{'port'}"); +foreach my $listen_addr ( @LISTENADDR ) { + ::log(LOGINFO,"Listening on $listen_addr->{'addr'}:$listen_addr->{'port'}"); } ::log(LOGINFO, 'Running as user '. - (getpwuid($>) || $>) . - ', group '. - (getgrgid($)) || $))); + (getpwuid($>) || $>) . + ', group '. + (getgrgid($)) || $))); if ($DETACH) { open STDIN, '/dev/null' or die "/dev/null: $!"; @@ -225,8 +240,8 @@ while (1) { my $pid = safe_fork(); if ($pid) { # parent - $childstatus{$pid} = $iaddr; # add to table - # $childstatus{$pid} = 1; # add to table + $childstatus{$pid} = $iaddr; # add to table + # $childstatus{$pid} = 1; # add to table $running++; close($client); next;