Skip to content

Commit 34cc60c

Browse files
dstocgitster
authored andcommitted
send-email: Add support for SSL and SMTP-AUTH
Allows username and password to be given using --smtp-user and --smtp-pass. SSL use is flagged by --smtp-ssl. These are backed by corresponding defaults in the git configuration file. This implements Junio's 'mail identity' suggestion in a slightly more generalised manner. --identity=$identity, backed by sendemail.identity indicates that the configuration subsection [sendemail "$identity"] should take priority over the [sendemail] section for all configuration values. Signed-off-by: Douglas Stockwell <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 1e61b76 commit 34cc60c

File tree

2 files changed

+109
-27
lines changed

2 files changed

+109
-27
lines changed

Documentation/git-send-email.txt

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ The --cc option must be repeated for each user you want on the cc list.
7575
Make git-send-email less verbose. One line per email should be
7676
all that is output.
7777

78+
--identity::
79+
A configuration identity. When given, causes values in the
80+
'sendemail.<identity>' subsection to take precedence over
81+
values in the 'sendemail' section. The default identity is
82+
the value of 'sendemail.identity'.
83+
7884
--smtp-server::
7985
If set, specifies the outgoing SMTP server to use (e.g.
8086
`smtp.example.com` or a raw IP address). Alternatively it can
@@ -85,6 +91,17 @@ The --cc option must be repeated for each user you want on the cc list.
8591
`/usr/lib/sendmail` if such program is available, or
8692
`localhost` otherwise.
8793

94+
--smtp-user, --smtp-pass::
95+
Username and password for SMTP-AUTH. Defaults are the values of
96+
the configuration values 'sendemail.smtpuser' and
97+
'sendemail.smtppass', but see also 'sendemail.identity'.
98+
If not set, authentication is not attempted.
99+
100+
--smtp-ssl::
101+
If set, connects to the SMTP server using SSL.
102+
Default is the value of the 'sendemail.smtpssl' configuration value;
103+
if that is unspecified, does not use SSL.
104+
88105
--subject::
89106
Specify the initial subject of the email thread.
90107
Only necessary if --compose is also set. If --compose
@@ -122,6 +139,13 @@ The --to option must be repeated for each user you want on the to list.
122139

123140
CONFIGURATION
124141
-------------
142+
sendemail.identity::
143+
The default configuration identity. When specified,
144+
'sendemail.<identity>.<item>' will have higher precedence than
145+
'sendemail.<item>'. This is useful to declare multiple SMTP
146+
identities and to hoist sensitive authentication information
147+
out of the repository and into the global configuation file.
148+
125149
sendemail.aliasesfile::
126150
To avoid typing long email addresses, point this to one or more
127151
email aliases files. You must also supply 'sendemail.aliasfiletype'.
@@ -141,7 +165,16 @@ sendemail.chainreplyto::
141165
parameter.
142166

143167
sendemail.smtpserver::
144-
Default smtp server to use.
168+
Default SMTP server to use.
169+
170+
sendemail.smtpuser::
171+
Default SMTP-AUTH username.
172+
173+
sendemail.smtppass::
174+
Default SMTP-AUTH password.
175+
176+
sendemail.smtpssl::
177+
Boolean value specifying the default to the '--smtp-ssl' parameter.
145178

146179
Author
147180
------

git-send-email.perl

Lines changed: 75 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,18 @@ sub usage {
7373
--signed-off-cc Automatically add email addresses that appear in
7474
Signed-off-by: or Cc: lines to the cc: list. Defaults to on.
7575
76+
--identity The configuration identity, a subsection to prioritise over
77+
the default section.
78+
7679
--smtp-server If set, specifies the outgoing SMTP server to use.
7780
Defaults to localhost.
7881
82+
--smtp-user The username for SMTP-AUTH.
83+
84+
--smtp-pass The password for SMTP-AUTH.
85+
86+
--smtp-ssl If set, connects to the SMTP server using SSL.
87+
7988
--suppress-from Suppress sending emails to yourself if your address
8089
appears in a From: line. Defaults to off.
8190
@@ -145,7 +154,6 @@ sub format_2822_time {
145154
my (@to,@cc,@initial_cc,@bcclist,@xh,
146155
$initial_reply_to,$initial_subject,@files,$author,$sender,$compose,$time);
147156

148-
my $smtp_server;
149157
my $envelope_sender;
150158

151159
# Example reply to:
@@ -164,24 +172,26 @@ sub format_2822_time {
164172

165173
# Variables with corresponding config settings
166174
my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd);
175+
my ($smtp_server, $smtp_authuser, $smtp_authpass, $smtp_ssl);
176+
my ($identity, $aliasfiletype, @alias_files);
167177

168-
my %config_settings = (
178+
my %config_bool_settings = (
169179
"thread" => [\$thread, 1],
170180
"chainreplyto" => [\$chain_reply_to, 1],
171181
"suppressfrom" => [\$suppress_from, 0],
172182
"signedoffcc" => [\$signed_off_cc, 1],
173-
"cccmd" => [\$cc_cmd, ""],
183+
"smtpssl" => [\$smtp_ssl, 0],
174184
);
175185

176-
foreach my $setting (keys %config_settings) {
177-
my $config = $repo->config_bool("sendemail.$setting");
178-
${$config_settings{$setting}->[0]} = (defined $config) ? $config : $config_settings{$setting}->[1];
179-
}
180-
181-
@bcclist = $repo->config('sendemail.bcc');
182-
if (!@bcclist or !$bcclist[0]) {
183-
@bcclist = ();
184-
}
186+
my %config_settings = (
187+
"smtpserver" => \$smtp_server,
188+
"smtpuser" => \$smtp_authuser,
189+
"smtppass" => \$smtp_authpass,
190+
"cccmd" => \$cc_cmd,
191+
"aliasfiletype" => \$aliasfiletype,
192+
"bcc" => \@bcclist,
193+
"aliasesfile" => \@alias_files,
194+
);
185195

186196
# Begin by accumulating all the variables (defined above), that we will end up
187197
# needing, first, from the command line:
@@ -194,6 +204,10 @@ sub format_2822_time {
194204
"bcc=s" => \@bcclist,
195205
"chain-reply-to!" => \$chain_reply_to,
196206
"smtp-server=s" => \$smtp_server,
207+
"smtp-user=s" => \$smtp_authuser,
208+
"smtp-pass=s" => \$smtp_authpass,
209+
"smtp-ssl!" => \$smtp_ssl,
210+
"identity=s" => \$identity,
197211
"compose" => \$compose,
198212
"quiet" => \$quiet,
199213
"cc-cmd=s" => \$cc_cmd,
@@ -208,6 +222,43 @@ sub format_2822_time {
208222
usage();
209223
}
210224

225+
# Now, let's fill any that aren't set in with defaults:
226+
227+
sub read_config {
228+
my ($prefix) = @_;
229+
230+
foreach my $setting (keys %config_bool_settings) {
231+
my $target = $config_bool_settings{$setting}->[0];
232+
$$target = $repo->config_bool("$prefix.$setting") unless (defined $$target);
233+
}
234+
235+
foreach my $setting (keys %config_settings) {
236+
my $target = $config_settings{$setting};
237+
if (ref($target) eq "ARRAY") {
238+
unless (@$target) {
239+
my @values = $repo->config("$prefix.$setting");
240+
@$target = @values if (@values && defined $values[0]);
241+
}
242+
}
243+
else {
244+
$$target = $repo->config("$prefix.$setting") unless (defined $$target);
245+
}
246+
}
247+
}
248+
249+
# read configuration from [sendemail "$identity"], fall back on [sendemail]
250+
$identity = $repo->config("sendemail.identity") unless (defined $identity);
251+
read_config("sendemail.$identity") if (defined $identity);
252+
read_config("sendemail");
253+
254+
# fall back on builtin bool defaults
255+
foreach my $setting (values %config_bool_settings) {
256+
${$setting->[0]} = $setting->[1] unless (defined (${$setting->[0]}));
257+
}
258+
259+
my ($repoauthor) = $repo->ident_person('author');
260+
my ($repocommitter) = $repo->ident_person('committer');
261+
211262
# Verify the user input
212263

213264
foreach my $entry (@to) {
@@ -222,14 +273,7 @@ sub format_2822_time {
222273
die "Comma in --bcclist entry: $entry'\n" unless $entry !~ m/,/;
223274
}
224275

225-
# Now, let's fill any that aren't set in with defaults:
226-
227-
my ($repoauthor) = $repo->ident_person('author');
228-
my ($repocommitter) = $repo->ident_person('committer');
229-
230276
my %aliases;
231-
my @alias_files = $repo->config('sendemail.aliasesfile');
232-
my $aliasfiletype = $repo->config('sendemail.aliasfiletype');
233277
my %parse_alias = (
234278
# multiline formats can be supported in the future
235279
mutt => sub { my $fh = shift; while (<$fh>) {
@@ -320,10 +364,7 @@ sub expand_aliases {
320364
$initial_reply_to =~ s/(^\s+|\s+$)//g;
321365
}
322366

323-
if (!$smtp_server) {
324-
$smtp_server = $repo->config('sendemail.smtpserver');
325-
}
326-
if (!$smtp_server) {
367+
if (!defined $smtp_server) {
327368
foreach (qw( /usr/sbin/sendmail /usr/lib/sendmail )) {
328369
if (-x $_) {
329370
$smtp_server = $_;
@@ -553,8 +594,16 @@ sub send_message
553594
print $sm "$header\n$message";
554595
close $sm or die $?;
555596
} else {
556-
require Net::SMTP;
557-
$smtp ||= Net::SMTP->new( $smtp_server );
597+
if ($smtp_ssl) {
598+
require Net::SMTP::SSL;
599+
$smtp ||= Net::SMTP::SSL->new( $smtp_server, Port => 465 );
600+
}
601+
else {
602+
require Net::SMTP;
603+
$smtp ||= Net::SMTP->new( $smtp_server );
604+
}
605+
$smtp->auth( $smtp_authuser, $smtp_authpass )
606+
or die $smtp->message if (defined $smtp_authuser);
558607
$smtp->mail( $raw_from ) or die $smtp->message;
559608
$smtp->to( @recipients ) or die $smtp->message;
560609
$smtp->data or die $smtp->message;
@@ -661,7 +710,7 @@ sub send_message
661710
}
662711
close F;
663712

664-
if ($cc_cmd ne "") {
713+
if (defined $cc_cmd) {
665714
open(F, "$cc_cmd $t |")
666715
or die "(cc-cmd) Could not execute '$cc_cmd'";
667716
while(<F>) {

0 commit comments

Comments
 (0)