Skip to content

Commit 35035bb

Browse files
artagnongitster
authored andcommitted
send-email: be explicit with SSL certificate verification
When initiating an SSL connection without explicitly specifying the SSL certificate verification mode, Net::SMTP::SSL defaults to no verification, but recent versions of the module gives a warning against this use of the default. Enable certificate verification by default, using /etc/ssl/certs as the default path for certificates of certificate authorities. This path can be overriden by the --smtp-ssl-cert-path command line option and the sendemail.smtpSSLCertPath configuration variable. Passing an empty string as the path for CA certificates path disables the SSL certificate verification explicitly, which does not trigger the warning from recent versions of Net::SMTP::SSL. Signed-off-by: Ramkumar Ramachandra <[email protected]> Helped-by: Brian M. Carlson <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 531c8dd commit 35035bb

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

Documentation/config.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2022,6 +2022,10 @@ sendemail.smtpencryption::
20222022
sendemail.smtpssl::
20232023
Deprecated alias for 'sendemail.smtpencryption = ssl'.
20242024

2025+
sendemail.smtpsslcertpath::
2026+
Path to ca-certificates (either a directory or a single file).
2027+
Set it to an empty string to disable certificate verification.
2028+
20252029
sendemail.<identity>.*::
20262030
Identity-specific versions of the 'sendemail.*' parameters
20272031
found below, taking precedence over those when the this

Documentation/git-send-email.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,12 @@ must be used for each option.
198198
--smtp-ssl::
199199
Legacy alias for '--smtp-encryption ssl'.
200200

201+
--smtp-ssl-cert-path::
202+
Path to ca-certificates (either a directory or a single file).
203+
Set it to an empty string to disable certificate verification.
204+
Defaults to the value set to the 'sendemail.smtpsslcertpath'
205+
configuration variable, if set, or `/etc/ssl/certs` otherwise.
206+
201207
--smtp-user=<user>::
202208
Username for SMTP-AUTH. Default is the value of 'sendemail.smtpuser';
203209
if a username is not specified (with '--smtp-user' or 'sendemail.smtpuser'),

git-send-email.perl

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ sub usage {
6969
--smtp-pass <str> * Password for SMTP-AUTH; not necessary.
7070
--smtp-encryption <str> * tls or ssl; anything else disables.
7171
--smtp-ssl * Deprecated. Use '--smtp-encryption ssl'.
72+
--smtp-ssl-cert-path <str> * Path to ca-certificates (either directory or file).
73+
Pass an empty string to disable certificate
74+
verification.
7275
--smtp-domain <str> * The domain name sent to HELO/EHLO handshake
7376
--smtp-debug <0|1> * Disable, enable Net::SMTP debug.
7477

@@ -194,7 +197,7 @@ sub do_edit {
194197
my ($thread, $chain_reply_to, $suppress_from, $signed_off_by_cc);
195198
my ($to_cmd, $cc_cmd);
196199
my ($smtp_server, $smtp_server_port, @smtp_server_options);
197-
my ($smtp_authuser, $smtp_encryption);
200+
my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path);
198201
my ($identity, $aliasfiletype, @alias_files, $smtp_domain);
199202
my ($validate, $confirm);
200203
my (@suppress_cc);
@@ -222,6 +225,7 @@ sub do_edit {
222225
"smtpserveroption" => \@smtp_server_options,
223226
"smtpuser" => \$smtp_authuser,
224227
"smtppass" => \$smtp_authpass,
228+
"smtpsslcertpath" => \$smtp_ssl_cert_path,
225229
"smtpdomain" => \$smtp_domain,
226230
"to" => \@initial_to,
227231
"tocmd" => \$to_cmd,
@@ -302,6 +306,7 @@ sub signal_handler {
302306
"smtp-pass:s" => \$smtp_authpass,
303307
"smtp-ssl" => sub { $smtp_encryption = 'ssl' },
304308
"smtp-encryption=s" => \$smtp_encryption,
309+
"smtp-ssl-cert-path" => \$smtp_ssl_cert_path,
305310
"smtp-debug:i" => \$debug_net_smtp,
306311
"smtp-domain:s" => \$smtp_domain,
307312
"identity=s" => \$identity,
@@ -1089,6 +1094,34 @@ sub smtp_auth_maybe {
10891094
return $auth;
10901095
}
10911096

1097+
sub ssl_verify_params {
1098+
eval {
1099+
require IO::Socket::SSL;
1100+
IO::Socket::SSL->import(qw/SSL_VERIFY_PEER SSL_VERIFY_NONE/);
1101+
};
1102+
if ($@) {
1103+
print STDERR "Not using SSL_VERIFY_PEER due to out-of-date IO::Socket::SSL.\n";
1104+
return;
1105+
}
1106+
1107+
if (!defined $smtp_ssl_cert_path) {
1108+
$smtp_ssl_cert_path = "/etc/ssl/certs";
1109+
}
1110+
1111+
if ($smtp_ssl_cert_path eq "") {
1112+
return (SSL_verify_mode => SSL_VERIFY_NONE());
1113+
} elsif (-d $smtp_ssl_cert_path) {
1114+
return (SSL_verify_mode => SSL_VERIFY_PEER(),
1115+
SSL_ca_path => $smtp_ssl_cert_path);
1116+
} elsif (-f $smtp_ssl_cert_path) {
1117+
return (SSL_verify_mode => SSL_VERIFY_PEER(),
1118+
SSL_ca_file => $smtp_ssl_cert_path);
1119+
} else {
1120+
print STDERR "Not using SSL_VERIFY_PEER because the CA path does not exist.\n";
1121+
return (SSL_verify_mode => SSL_VERIFY_NONE());
1122+
}
1123+
}
1124+
10921125
# Returns 1 if the message was sent, and 0 otherwise.
10931126
# In actuality, the whole program dies when there
10941127
# is an error sending a message.
@@ -1194,7 +1227,8 @@ sub send_message {
11941227
$smtp_domain ||= maildomain();
11951228
$smtp ||= Net::SMTP::SSL->new($smtp_server,
11961229
Hello => $smtp_domain,
1197-
Port => $smtp_server_port);
1230+
Port => $smtp_server_port,
1231+
ssl_verify_params());
11981232
}
11991233
else {
12001234
require Net::SMTP;
@@ -1207,7 +1241,8 @@ sub send_message {
12071241
$smtp->command('STARTTLS');
12081242
$smtp->response();
12091243
if ($smtp->code == 220) {
1210-
$smtp = Net::SMTP::SSL->start_SSL($smtp)
1244+
$smtp = Net::SMTP::SSL->start_SSL($smtp,
1245+
ssl_verify_params())
12111246
or die "STARTTLS failed! ".$smtp->message;
12121247
$smtp_encryption = '';
12131248
# Send EHLO again to receive fresh

0 commit comments

Comments
 (0)