diff --git a/mailboxes/boxes-lib.pl b/mailboxes/boxes-lib.pl
index 6e4a4a5be..9b1d97d2c 100755
--- a/mailboxes/boxes-lib.pl
+++ b/mailboxes/boxes-lib.pl
@@ -871,7 +871,7 @@ local $lnum = 0;
$sm ||= $config{'send_mode'};
local $eol = $nocr || !$sm ? "\n" : "\r\n";
$ssl = $config{'smtp_ssl'} if ($ssl eq '');
-local $defport = $ssl ? 465 : 25;
+local $defport = $ssl == 1 ? 465 : 25;
$port ||= $config{'smtp_port'} || $defport;
my %header;
foreach my $head (@{$mail->{'headers'}}) {
@@ -920,19 +920,9 @@ if ($file) {
elsif ($sm) {
# Connect to SMTP server
&open_socket($sm, $port, $h->{'fh'});
- if ($ssl) {
- # Switch to SSL mode
- eval "use Net::SSLeay";
- $@ && &error($text{'link_essl'});
- eval "Net::SSLeay::SSLeay_add_ssl_algorithms()";
- eval "Net::SSLeay::load_error_strings()";
- $h->{'ssl_ctx'} = Net::SSLeay::CTX_new() ||
- &error("Failed to create SSL context");
- $h->{'ssl_con'} = Net::SSLeay::new($h->{'ssl_ctx'}) ||
- &error("Failed to create SSL connection");
- Net::SSLeay::set_fd($h->{'ssl_con'}, fileno($h->{'fh'}));
- Net::SSLeay::connect($h->{'ssl_con'}) ||
- &error("SSL connect() failed");
+ if ($ssl == 1) {
+ # Start using SSL mode right away
+ &switch_smtp_to_ssl($h);
}
&smtp_command($h, undef, 0);
@@ -944,6 +934,17 @@ elsif ($sm) {
&smtp_command($h, "helo $helo\r\n", 0);
}
+ if ($ssl == 2) {
+ # Switch to SSL with STARTTLS, if possible
+ my $rv = &smtp_command($h, "starttls\r\n", 1);
+ if ($rv =~ /^2\d+/) {
+ &switch_smtp_to_ssl($h);
+ }
+ else {
+ $ssl = 0;
+ }
+ }
+
# Get username and password from parameters, or from module config
$user ||= $userconfig{'smtp_user'} || $config{'smtp_user'};
$pass ||= $userconfig{'smtp_pass'} || $config{'smtp_pass'};
@@ -963,16 +964,16 @@ elsif ($sm) {
&error("Failed to create Authen::SASL object") if (!$sasl);
local $conn = $sasl->client_new("smtp", &get_system_hostname());
local $arv = &smtp_command($h, "auth $auth\r\n", 1);
- if ($arv =~ /^(334)\s+(.*)/) {
+ if ($arv =~ /^(334)(\-\S+)?\s+(.*)/) {
# Server says to go ahead
- $extra = $2;
+ $extra = $3;
local $initial = $conn->client_start();
local $auth_ok;
if ($initial) {
local $enc = &encode_base64($initial);
$enc =~ s/\r|\n//g;
$arv = &smtp_command($h, "$enc\r\n", 1);
- if ($arv =~ /^(\d+)\s+(.*)/) {
+ if ($arv =~ /^(\d+)(\-\S+)?\s+(.*)/) {
if ($1 == 235) {
$auth_ok = 1;
}
@@ -980,7 +981,7 @@ elsif ($sm) {
&error("Unknown SMTP authentication response : $arv");
}
}
- $extra = $2;
+ $extra = $3;
}
while(!$auth_ok) {
local $message = &decode_base64($extra);
@@ -988,14 +989,14 @@ elsif ($sm) {
local $enc = &encode_base64($return);
$enc =~ s/\r|\n//g;
$arv = &smtp_command($h, "$enc\r\n", 1);
- if ($arv =~ /^(\d+)\s+(.*)/) {
+ if ($arv =~ /^(\d+)(\-\S+)?\s+(.*)/) {
if ($1 == 235) {
$auth_ok = 1;
}
elsif ($1 == 535) {
&error("SMTP authentication failed : $arv");
}
- $extra = $2;
+ $extra = $3;
}
else {
&error("Unknown SMTP authentication response : $arv");
@@ -1175,6 +1176,24 @@ if (!&close_http_connection($h)) {
return $lnum;
}
+# switch_smtp_to_ssl(&handle)
+# Switch an SMTP connection handle to SSL mode
+sub switch_smtp_to_ssl
+{
+my ($h) = @_;
+eval "use Net::SSLeay";
+$@ && &error($text{'link_essl'});
+eval "Net::SSLeay::SSLeay_add_ssl_algorithms()";
+eval "Net::SSLeay::load_error_strings()";
+$h->{'ssl_ctx'} = Net::SSLeay::CTX_new() ||
+ &error("Failed to create SSL context");
+$h->{'ssl_con'} = Net::SSLeay::new($h->{'ssl_ctx'}) ||
+ &error("Failed to create SSL connection");
+Net::SSLeay::set_fd($h->{'ssl_con'}, fileno($h->{'fh'}));
+Net::SSLeay::connect($h->{'ssl_con'}) ||
+ &error("SSL connect() failed");
+}
+
# unparse_mail(&attachments, eol, boundary)
# Convert an array of attachments into MIME format, and return them as an
# array of lines.
@@ -1363,6 +1382,7 @@ if ($c) {
}
my $r = &read_http_connection($h);
if ($r !~ /^[23]\d+/ && !$noerr) {
+ $c =~ s/\r|\n//g;
&error(&text('send_esmtp', "".&html_escape($c)."",
"".&html_escape($r).""));
}
diff --git a/webmin/edit_sendmail.cgi b/webmin/edit_sendmail.cgi
index 2f4786292..cfaf32b81 100755
--- a/webmin/edit_sendmail.cgi
+++ b/webmin/edit_sendmail.cgi
@@ -25,13 +25,20 @@ print &ui_table_row($text{'sendmail_smtp'},
&ui_radio("mode", $mode, [ [ 0, $text{'sendmail_smtp0'}."
" ],
[ 1, $text{'sendmail_smtp1'}."
" ],
[ 2, $text{'sendmail_smtp2'} ] ]).
- " ".&ui_textbox("smtp", $mode == 2 ? $smtp : "", 40).
- "
\n"." ".
- &ui_checkbox("ssl", 1, $text{'sendmail_ssl'}, $mconfig{'smtp_ssl'}).
- "
\n"." ".
+ " ".&ui_textbox("smtp", $mode == 2 ? $smtp : "", 40));
+
+
+# SMTP port
+print &ui_table_row($text{'sendmail_port'},
&ui_opt_textbox("port", $port, 6, $text{'sendmail_portdef'},
- $text{'sendmail_portsel'}),
- undef, [ "valign=top","valign=middle" ]);
+ $text{'sendmail_portsel'}));
+
+# SMTP encryption
+print &ui_table_row($text{'sendmail_ssl'},
+ &ui_select("ssl", int($mconfig{'smtp_ssl'}),
+ [ [ 0, $text{'sendmail_ssl0'} ],
+ [ 1, $text{'sendmail_ssl1'} ],
+ [ 2, $text{'sendmail_ssl2'} ] ]));
# SMTP login and password
$user = $mconfig{'smtp_user'};
diff --git a/webmin/lang/en b/webmin/lang/en
index 0caecdde6..f5f222c8e 100644
--- a/webmin/lang/en
+++ b/webmin/lang/en
@@ -1011,9 +1011,13 @@ sendmail_desc=This page controls how Webmin sends email, such as from scheduled
sendmail_header=Mail sending options
sendmail_system=Local mail server
sendmail_smtp=Send email using
+sendmail_port=SMTP port
sendmail_portdef=Use default port
sendmail_portsel=Use port number
-sendmail_ssl=Use SSL encryption?
+sendmail_ssl=Use SMTP SSL encryption?
+sendmail_ssl0=Never encrypt
+sendmail_ssl1=Always use TLS
+sendmail_ssl2=Switch with STARTTLS
sendmail_smtp0=Local mail server command
sendmail_smtp1=Via SMTP to local mail server
sendmail_smtp2=Via SMTP to remote mail server