git-send-email: use git credential to obtain password
If smtp_user is provided but smtp_pass is not, instead of prompting for password, make git-send-email use git credential command instead. Signed-off-by: Michal Nazarewicz <mina86@mina86.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Michal Nazarewicz committed
Feb 12, 2013 at 15:02 UTC
4d31a44a08365b90ff28c5e87e187363e10c2a31
2 files changed
+45
-30
Documentation/git-send-email.txt
+2
-2
@@ -164,8 +164,8 @@ Sending
164
Furthermore, passwords need not be specified in configuration files
165
or on the command line. If a username has been specified (with
166
'--smtp-user' or a 'sendemail.smtpuser'), but no password has been
167
-specified (with '--smtp-pass' or 'sendemail.smtppass'), then the
168
-user is prompted for a password while the input is masked for privacy.
167
+specified (with '--smtp-pass' or 'sendemail.smtppass'), then
168
+a password is obtained using 'git-credential'.
169
170
--smtp-server=<host>::
171
If set, specifies the outgoing SMTP server to use (e.g.
git-send-email.perl
+43
-28
@@ -1045,6 +1045,47 @@ sub maildomain {
1045
return maildomain_net() || maildomain_mta() || 'localhost.localdomain';
1046
}
1047
1048
+sub smtp_host_string {
1049
+ if (defined $smtp_server_port) {
1050
+ return "$smtp_server:$smtp_server_port";
1051
+ } else {
1052
+ return $smtp_server;
1053
+ }
1054
+}
1055
+
1056
+# Returns 1 if authentication succeeded or was not necessary
1057
+# (smtp_user was not specified), and 0 otherwise.
1058
+
1059
+sub smtp_auth_maybe {
1060
+ if (!defined $smtp_authuser || $auth) {
1061
+ return 1;
1062
+ }
1063
+
1064
+ # Workaround AUTH PLAIN/LOGIN interaction defect
1065
+ # with Authen::SASL::Cyrus
1066
+ eval {
1067
+ require Authen::SASL;
1068
+ Authen::SASL->import(qw(Perl));
1069
+ };
1070
+
1071
+ # TODO: Authentication may fail not because credentials were
1072
+ # invalid but due to other reasons, in which we should not
1073
+ # reject credentials.
1074
+ $auth = Git::credential({
1075
+ 'protocol' => 'smtp',
1076
+ 'host' => smtp_host_string(),
1077
+ 'username' => $smtp_authuser,
1078
+ # if there's no password, "git credential fill" will
1079
+ # give us one, otherwise it'll just pass this one.
1080
+ 'password' => $smtp_authpass
1081
+ }, sub {
1082
+ my $cred = shift;
1083
+ return !!$smtp->auth($cred->{'username'}, $cred->{'password'});
1084
+ });
1085
+
1086
+ return $auth;
1087
+}
1088
+
1089
# Returns 1 if the message was sent, and 0 otherwise.
1090
# In actuality, the whole program dies when there
1091
# is an error sending a message.
@@ -1155,9 +1196,7 @@ X-Mailer: git-send-email $gitversion
1196
else {
1197
require Net::SMTP;
1198
$smtp_domain ||= maildomain();
1158
- $smtp ||= Net::SMTP->new((defined $smtp_server_port)
1159
- ? "$smtp_server:$smtp_server_port"
1160
- : $smtp_server,
1199
+ $smtp ||= Net::SMTP->new(smtp_host_string(),
1200
Hello => $smtp_domain,
1201
Debug => $debug_net_smtp);
1202
if ($smtp_encryption eq 'tls' && $smtp) {
@@ -1185,31 +1224,7 @@ X-Mailer: git-send-email $gitversion
1224
defined $smtp_server_port ? " port=$smtp_server_port" : "";
1225
}
1226
1188
- if (defined $smtp_authuser) {
1189
- # Workaround AUTH PLAIN/LOGIN interaction defect
1190
- # with Authen::SASL::Cyrus
1191
- eval {
1192
- require Authen::SASL;
1193
- Authen::SASL->import(qw(Perl));
1194
- };
1195
-
1196
- if (!defined $smtp_authpass) {
1197
-
1198
- system "stty -echo";
1199
-
1200
- do {
1201
- print "Password: ";
1202
- $_ = <STDIN>;
1203
- print "\n";
1204
- } while (!defined $_);
1205
-
1206
- chomp($smtp_authpass = $_);
1207
-
1208
- system "stty echo";
1209
- }
1210
-
1211
- $auth ||= $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message;
1212
- }
1227
+ smtp_auth_maybe or die $smtp->message;
1228
1229
$smtp->mail( $raw_from ) or die $smtp->message;
1230
$smtp->to( @recipients ) or die $smtp->message;