send-email: provide whitelist of SMTP AUTH mechanisms
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>
Jan Viktorin committed
Aug 12, 2015 at 01:39 UTC
0f2e68b54c7f85656299539de8a4aebab795d369
2 files changed
+38
-1
Documentation/git-send-email.txt
+13
@@ -171,6 +171,19 @@ Sending
171
to determine your FQDN automatically. Default is the value of
172
'sendemail.smtpDomain'.
173
174
+--smtp-auth=<mechanisms>::
175
+ Whitespace-separated list of allowed SMTP-AUTH mechanisms. This setting
176
+ forces using only the listed mechanisms. Example:
177
++
178
+------
179
+$ git send-email --smtp-auth="PLAIN LOGIN GSSAPI" ...
180
+------
181
++
182
+If at least one of the specified mechanisms matches the ones advertised by the
183
+SMTP server and if it is supported by the utilized SASL library, the mechanism
184
+is used for authentication. If neither 'sendemail.smtpAuth' nor '--smtp-auth'
185
+is specified, all mechanisms supported by the SASL library can be used.
186
+
187
--smtp-pass[=<password>]::
188
Password for SMTP-AUTH. The argument is optional: If no
189
argument is specified, then the empty string is used as
git-send-email.perl
+25
-1
@@ -75,6 +75,8 @@ git send-email [options] <file | directory | rev-list options >
75
Pass an empty string to disable certificate
76
verification.
77
--smtp-domain <str> * The domain name sent to HELO/EHLO handshake
78
+ --smtp-auth <str> * Space-separated list of allowed AUTH mechanisms.
79
+ This setting forces to use one of the listed mechanisms.
80
--smtp-debug <0|1> * Disable, enable Net::SMTP debug.
81
82
Automating:
@@ -208,7 +210,7 @@ my ($cover_cc, $cover_to);
210
my ($to_cmd, $cc_cmd);
211
my ($smtp_server, $smtp_server_port, @smtp_server_options);
212
my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path);
211
-my ($identity, $aliasfiletype, @alias_files, $smtp_domain);
213
+my ($identity, $aliasfiletype, @alias_files, $smtp_domain, $smtp_auth);
214
my ($validate, $confirm);
215
my (@suppress_cc);
216
my ($auto_8bit_encoding);
@@ -239,6 +241,7 @@ my %config_settings = (
241
"smtppass" => \$smtp_authpass,
242
"smtpsslcertpath" => \$smtp_ssl_cert_path,
243
"smtpdomain" => \$smtp_domain,
244
+ "smtpauth" => \$smtp_auth,
245
"to" => \@initial_to,
246
"tocmd" => \$to_cmd,
247
"cc" => \@initial_cc,
@@ -310,6 +313,7 @@ my $rc = GetOptions("h" => \$help,
313
"smtp-ssl-cert-path=s" => \$smtp_ssl_cert_path,
314
"smtp-debug:i" => \$debug_net_smtp,
315
"smtp-domain:s" => \$smtp_domain,
316
+ "smtp-auth=s" => \$smtp_auth,
317
"identity=s" => \$identity,
318
"annotate!" => \$annotate,
319
"no-annotate" => sub {$annotate = 0},
@@ -1136,6 +1140,12 @@ sub smtp_auth_maybe {
1140
Authen::SASL->import(qw(Perl));
1141
};
1142
1143
+ # Check mechanism naming as defined in:
1144
+ # https://tools.ietf.org/html/rfc4422#page-8
1145
+ if ($smtp_auth !~ /^(\b[A-Z0-9-_]{1,20}\s*)*$/) {
1146
+ die "invalid smtp auth: '${smtp_auth}'";
1147
+ }
1148
+
1149
# TODO: Authentication may fail not because credentials were
1150
# invalid but due to other reasons, in which we should not
1151
# reject credentials.
@@ -1148,6 +1158,20 @@ sub smtp_auth_maybe {
1158
'password' => $smtp_authpass
1159
}, sub {
1160
my $cred = shift;
1161
+
1162
+ if ($smtp_auth) {
1163
+ my $sasl = Authen::SASL->new(
1164
+ mechanism => $smtp_auth,
1165
+ callback => {
1166
+ user => $cred->{'username'},
1167
+ pass => $cred->{'password'},
1168
+ authname => $cred->{'username'},
1169
+ }
1170
+ );
1171
+
1172
+ return !!$smtp->auth($sasl);
1173
+ }
1174
+
1175
return !!$smtp->auth($cred->{'username'}, $cred->{'password'});
1176
});
1177