Skip to content

Commit

Permalink
send-email: provide whitelist of SMTP AUTH mechanisms
Browse files Browse the repository at this point in the history
When sending an e-mail, the client and server must agree on an
authentication mechanism. Some servers (due to misconfiguration
or a bug) deny valid credentials for certain mechanisms. In this
patch, a new option --smtp-auth and configuration entry smtpAuth
are introduced. If smtp_auth is defined, it works as a whitelist
of allowed mechanisms for authentication selected from the ones
supported by the installed SASL perl library.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jan Viktorin authored and Junio C Hamano committed Aug 17, 2015
1 parent a17c56c commit 0f2e68b
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
13 changes: 13 additions & 0 deletions Documentation/git-send-email.txt
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,19 @@ Sending
to determine your FQDN automatically. Default is the value of
'sendemail.smtpDomain'.

--smtp-auth=<mechanisms>::
Whitespace-separated list of allowed SMTP-AUTH mechanisms. This setting
forces using only the listed mechanisms. Example:
+
------
$ git send-email --smtp-auth="PLAIN LOGIN GSSAPI" ...
------
+
If at least one of the specified mechanisms matches the ones advertised by the
SMTP server and if it is supported by the utilized SASL library, the mechanism
is used for authentication. If neither 'sendemail.smtpAuth' nor '--smtp-auth'
is specified, all mechanisms supported by the SASL library can be used.

--smtp-pass[=<password>]::
Password for SMTP-AUTH. The argument is optional: If no
argument is specified, then the empty string is used as
Expand Down
26 changes: 25 additions & 1 deletion git-send-email.perl
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ sub usage {
Pass an empty string to disable certificate
verification.
--smtp-domain <str> * The domain name sent to HELO/EHLO handshake
--smtp-auth <str> * Space-separated list of allowed AUTH mechanisms.
This setting forces to use one of the listed mechanisms.
--smtp-debug <0|1> * Disable, enable Net::SMTP debug.
Automating:
Expand Down Expand Up @@ -208,7 +210,7 @@ sub do_edit {
my ($to_cmd, $cc_cmd);
my ($smtp_server, $smtp_server_port, @smtp_server_options);
my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path);
my ($identity, $aliasfiletype, @alias_files, $smtp_domain);
my ($identity, $aliasfiletype, @alias_files, $smtp_domain, $smtp_auth);
my ($validate, $confirm);
my (@suppress_cc);
my ($auto_8bit_encoding);
Expand Down Expand Up @@ -239,6 +241,7 @@ sub do_edit {
"smtppass" => \$smtp_authpass,
"smtpsslcertpath" => \$smtp_ssl_cert_path,
"smtpdomain" => \$smtp_domain,
"smtpauth" => \$smtp_auth,
"to" => \@initial_to,
"tocmd" => \$to_cmd,
"cc" => \@initial_cc,
Expand Down Expand Up @@ -310,6 +313,7 @@ sub signal_handler {
"smtp-ssl-cert-path=s" => \$smtp_ssl_cert_path,
"smtp-debug:i" => \$debug_net_smtp,
"smtp-domain:s" => \$smtp_domain,
"smtp-auth=s" => \$smtp_auth,
"identity=s" => \$identity,
"annotate!" => \$annotate,
"no-annotate" => sub {$annotate = 0},
Expand Down Expand Up @@ -1136,6 +1140,12 @@ sub smtp_auth_maybe {
Authen::SASL->import(qw(Perl));
};

# Check mechanism naming as defined in:
# https://tools.ietf.org/html/rfc4422#page-8
if ($smtp_auth !~ /^(\b[A-Z0-9-_]{1,20}\s*)*$/) {
die "invalid smtp auth: '${smtp_auth}'";
}

# TODO: Authentication may fail not because credentials were
# invalid but due to other reasons, in which we should not
# reject credentials.
Expand All @@ -1148,6 +1158,20 @@ sub smtp_auth_maybe {
'password' => $smtp_authpass
}, sub {
my $cred = shift;

if ($smtp_auth) {
my $sasl = Authen::SASL->new(
mechanism => $smtp_auth,
callback => {
user => $cred->{'username'},
pass => $cred->{'password'},
authname => $cred->{'username'},
}
);

return !!$smtp->auth($sasl);
}

return !!$smtp->auth($cred->{'username'}, $cred->{'password'});
});

Expand Down

0 comments on commit 0f2e68b

Please sign in to comment.