{"thread":{"id":"10542","subject":"[PATCH] Implement sending mails over TLS in git-send-email.","startedAt":"2007-10-31T15:50:59Z","lastAt":"2007-10-31T23:59:24Z","messageCount":4,"participants":["Simon Sasburg","Baz"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"57710","messageId":"1193845859-1788-1-git-send-email-Simon.Sasburg@gmail.com","threadId":"10542","inReplyTo":null,"subject":"[PATCH] Implement sending mails over TLS in git-send-email.","fromName":"Simon Sasburg","fromEmail":"simon.sasburg@gmail.com","sentAt":"2007-10-31T15:50:59Z","receivedAt":"2007-10-31T15:50:59Z","isPatch":true,"sender":{"key":"simon.sasburg@gmail.com","avatar":null},"body":"Signed-off-by: Simon Sasburg <Simon.Sasburg@gmail.com>\n---\n\nWith this patch I was able to use git-send-email to send mail through gmail's\nsmpt server, which uses TLS.\n\nNet::SMTP::TLS apparently doesn't do proper error handling, so the TLS\ncodepath is essentially not checked for errors. I'm not really happy with this.\n\nThe Net::SMTP::TLS docs say this about error handling:\n>ERROR HANDLING:\n>This module will croak in the event of an SMTP error. Should you wish to handle this gracefully in your application, you may wrap your mail transmission in an eval {} block and check $@ afterward.\n\nBut my perl knowledge is way too limited for me to know if/how that helps.\n(This patch was just made by copying existing code and fiddling with it untill it did what i wanted)\n\nMaybe someone who knows more about perl than I do can finish this?\nOr give an estimate how difficult it would be for me to fix after pointing me in the right direction?\n(I'm willing to learn a little perl for this, but not too much :-p)\n---\n git-send-email.perl |   64 +++++++++++++++++++++++++++++++++-----------------\n 1 files changed, 42 insertions(+), 22 deletions(-)\n\ndiff --git a/git-send-email.perl b/git-send-email.perl\nindex 96051bc..5cf220f 100755\n--- a/git-send-email.perl\n+++ b/git-send-email.perl\n@@ -88,6 +88,9 @@ Options:\n \n    --smtp-ssl     If set, connects to the SMTP server using SSL.\n \n+   --smtp-tls     If set, connects to the SMTP server using TLS.\n+                  Overrides --smtp-ssl.\n+\n    --suppress-from Suppress sending emails to yourself if your address\n                   appears in a From: line. Defaults to off.\n \n@@ -175,7 +178,7 @@ my ($quiet, $dry_run) = (0, 0);\n \n # Variables with corresponding config settings\n my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd);\n-my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_authpass, $smtp_ssl);\n+my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_authpass, $smtp_ssl, $smtp_tls);\n my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts);\n \n my %config_bool_settings = (\n@@ -184,6 +187,7 @@ my %config_bool_settings = (\n     \"suppressfrom\" => [\\$suppress_from, 0],\n     \"signedoffcc\" => [\\$signed_off_cc, 1],\n     \"smtpssl\" => [\\$smtp_ssl, 0],\n+    \"smtptls\" => [\\$smtp_tls, 0],\n );\n \n my %config_settings = (\n@@ -213,6 +217,7 @@ my $rc = GetOptions(\"sender|from=s\" => \\$sender,\n \t\t    \"smtp-user=s\" => \\$smtp_authuser,\n \t\t    \"smtp-pass=s\" => \\$smtp_authpass,\n \t\t    \"smtp-ssl!\" => \\$smtp_ssl,\n+\t\t    \"smtp-tls!\" => \\$smtp_tls,\n \t\t    \"identity=s\" => \\$identity,\n \t\t    \"compose\" => \\$compose,\n \t\t    \"quiet\" => \\$quiet,\n@@ -613,31 +618,46 @@ X-Mailer: git-send-email $gitversion\n \t\t\tdie \"The required SMTP server is not properly defined.\"\n \t\t}\n \n-\t\tif ($smtp_ssl) {\n-\t\t\t$smtp_server_port ||= 465; # ssmtp\n-\t\t\trequire Net::SMTP::SSL;\n-\t\t\t$smtp ||= Net::SMTP::SSL->new($smtp_server, Port => $smtp_server_port);\n+\t\tif ($smtp_tls) {\n+\t\t\trequire Net::SMTP::TLS;\n+\t\t\t$smtp ||= Net::SMTP::TLS->new(\n+\t\t\t\t$smtp_server,\n+\t\t\t\tPort => $smtp_server_port,\n+\t\t\t\tUser => $smtp_authuser,\n+\t\t\t\tPassword=> $smtp_authpass);\n+\n+\t\t\t$smtp->mail( $raw_from );\n+\t\t\t$smtp->to( @recipients );\n+\t\t\t$smtp->data;\n+\t\t\t$smtp->datasend(\"$header\\n$message\");\n+\t\t\t$smtp->dataend();\n \t\t}\n \t\telse {\n-\t\t\trequire Net::SMTP;\n-\t\t\t$smtp ||= Net::SMTP->new((defined $smtp_server_port)\n-\t\t\t\t\t\t ? \"$smtp_server:$smtp_server_port\"\n-\t\t\t\t\t\t : $smtp_server);\n-\t\t}\n+\t\t\tif ($smtp_ssl) {\n+\t\t\t\trequire Net::SMTP::SSL;\n+\t\t\t\t$smtp ||= Net::SMTP::SSL->new($smtp_server, Port => $smtp_server_port);\n+\t\t\t}\n+\t\t\telse {\n+\t\t\t\trequire Net::SMTP;\n+\t\t\t\t$smtp ||= Net::SMTP->new((defined $smtp_server_port)\n+\t\t\t\t\t\t\t ? \"$smtp_server:$smtp_server_port\"\n+\t\t\t\t\t\t\t : $smtp_server);\n+\t\t\t}\n \n-\t\tif (!$smtp) {\n-\t\t\tdie \"Unable to initialize SMTP properly.  Is there something wrong with your config?\";\n-\t\t}\n+\t\t\tif (!$smtp) {\n+\t\t\t\tdie \"Unable to initialize SMTP properly.  Is there something wrong with your config?\";\n+\t\t\t}\n \n-\t\tif ((defined $smtp_authuser) && (defined $smtp_authpass)) {\n-\t\t\t$smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message;\n+\t\t\tif ((defined $smtp_authuser) && (defined $smtp_authpass)) {\n+\t\t\t\t$smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message;\n+\t\t\t}\n+\t\t\t$smtp->mail( $raw_from ) or die $smtp->message;\n+\t\t\t$smtp->to( @recipients ) or die $smtp->message;\n+\t\t\t$smtp->data or die $smtp->message;\n+\t\t\t$smtp->datasend(\"$header\\n$message\") or die $smtp->message;\n+\t\t\t$smtp->dataend() or die $smtp->message;\n+\t\t\t$smtp->ok or die \"Failed to send $subject\\n\".$smtp->message;\n \t\t}\n-\t\t$smtp->mail( $raw_from ) or die $smtp->message;\n-\t\t$smtp->to( @recipients ) or die $smtp->message;\n-\t\t$smtp->data or die $smtp->message;\n-\t\t$smtp->datasend(\"$header\\n$message\") or die $smtp->message;\n-\t\t$smtp->dataend() or die $smtp->message;\n-\t\t$smtp->ok or die \"Failed to send $subject\\n\".$smtp->message;\n \t}\n \tif ($quiet) {\n \t\tprintf (($dry_run ? \"Dry-\" : \"\").\"Sent %s\\n\", $subject);\n@@ -651,7 +671,7 @@ X-Mailer: git-send-email $gitversion\n \t\t\tprint \"Sendmail: $smtp_server \".join(' ',@sendmail_parameters).\"\\n\";\n \t\t}\n \t\tprint \"From: $sanitized_sender\\nSubject: $subject\\nCc: $cc\\nTo: $to\\n\\n\";\n-\t\tif ($smtp) {\n+\t\tif ($smtp && !$smtp_tls) {\n \t\t\tprint \"Result: \", $smtp->code, ' ',\n \t\t\t\t($smtp->message =~ /\\n([^\\n]+\\n)$/s), \"\\n\";\n \t\t} else {\n-- \n1.5.3.4.498.g9c514\n"},{"id":"57748","messageId":"2faad3050710311445l51d1152cs6761803e2f3a77d3@mail.gmail.com","threadId":"10542","inReplyTo":"1193845859-1788-1-git-send-email-Simon.Sasburg@gmail.com","subject":"Re: [PATCH] Implement sending mails over TLS in git-send-email.","fromName":"Baz","fromEmail":"brian.ewins@gmail.com","sentAt":"2007-10-31T21:45:42Z","receivedAt":"2007-10-31T21:45:42Z","isPatch":true,"sender":{"key":"brian.ewins@gmail.com","avatar":"https://gravatar.com/avatar/9ac03d89105e50a7151e695a1b4b1228151064ec3ac380a73b74ab397796baf7?d=mp&s=160"},"body":"On 31/10/2007, Simon Sasburg <simon.sasburg@gmail.com> wrote:\n> Signed-off-by: Simon Sasburg <Simon.Sasburg@gmail.com>\n> ---\n>\n> With this patch I was able to use git-send-email to send mail through gmail's\n> smpt server, which uses TLS.\n\nNet::SMTP::SSL handles this just fine.\n\n> Net::SMTP::TLS apparently doesn't do proper error handling, so the TLS\n> codepath is essentially not checked for errors. I'm not really happy with this.\n\nNet::SMTP::TLS is a bit ugly. It seems unable to do any checking of\nthe server certificate, a limitation its inherited from the original\nscript it was hacked from. I suspect some people wouldn't touch this\noption if that's the case (although I doubt any tin-foil hatters use\ngmail anyway, and we don't use this check for SSL either).\n\nSecondly, Net::SMTP::SSL has no problem connecting to gmail - it does\neverything Net::SMTP::TLS does and more; you can use all of the\noptions of IO::Socket::SSL with it. A common problem seems to be not\nhaving Authen::SASL installed (this is required to authenticate with\ngmail) - the one thing Net::SMTP::TLS *does* do is auth without using\nthat module.\n\nIn other words, this patch should be entirely unnecessary if you have\nAuthen::SASL installed - could you try this? (I've checked for myself,\ngit-send-email sends me mail fine via gmail without this patch)\n\n> The Net::SMTP::TLS docs say this about error handling:\n> >ERROR HANDLING:\n> >This module will croak in the event of an SMTP error. Should you wish to handle this gracefully in your application, you may wrap your mail transmission in an eval {} block and check $@ afterward.\n>\n> But my perl knowledge is way too limited for me to know if/how that helps.\n> (This patch was just made by copying existing code and fiddling with it untill it did what i wanted)\n>\n> Maybe someone who knows more about perl than I do can finish this?\n\nMy perl knowledge is a also bit stale, havent had to use it in anger\nfor a few years; your code looks ok to me, its the dodgy module I'm\nworried about :)\n\n> Or give an estimate how difficult it would be for me to fix after pointing me in the right direction?\n> (I'm willing to learn a little perl for this, but not too much :-p)\n> ---\n>  git-send-email.perl |   64 +++++++++++++++++++++++++++++++++-----------------\n>  1 files changed, 42 insertions(+), 22 deletions(-)\n>\n> diff --git a/git-send-email.perl b/git-send-email.perl\n> index 96051bc..5cf220f 100755\n> --- a/git-send-email.perl\n> +++ b/git-send-email.perl\n> @@ -88,6 +88,9 @@ Options:\n>\n>     --smtp-ssl     If set, connects to the SMTP server using SSL.\n>\n> +   --smtp-tls     If set, connects to the SMTP server using TLS.\n> +                  Overrides --smtp-ssl.\n> +\n>     --suppress-from Suppress sending emails to yourself if your address\n>                    appears in a From: line. Defaults to off.\n>\n> @@ -175,7 +178,7 @@ my ($quiet, $dry_run) = (0, 0);\n>\n>  # Variables with corresponding config settings\n>  my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd);\n> -my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_authpass, $smtp_ssl);\n> +my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_authpass, $smtp_ssl, $smtp_tls);\n>  my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts);\n>\n>  my %config_bool_settings = (\n> @@ -184,6 +187,7 @@ my %config_bool_settings = (\n>      \"suppressfrom\" => [\\$suppress_from, 0],\n>      \"signedoffcc\" => [\\$signed_off_cc, 1],\n>      \"smtpssl\" => [\\$smtp_ssl, 0],\n> +    \"smtptls\" => [\\$smtp_tls, 0],\n>  );\n>\n>  my %config_settings = (\n> @@ -213,6 +217,7 @@ my $rc = GetOptions(\"sender|from=s\" => \\$sender,\n>                     \"smtp-user=s\" => \\$smtp_authuser,\n>                     \"smtp-pass=s\" => \\$smtp_authpass,\n>                     \"smtp-ssl!\" => \\$smtp_ssl,\n> +                   \"smtp-tls!\" => \\$smtp_tls,\n>                     \"identity=s\" => \\$identity,\n>                     \"compose\" => \\$compose,\n>                     \"quiet\" => \\$quiet,\n> @@ -613,31 +618,46 @@ X-Mailer: git-send-email $gitversion\n>                         die \"The required SMTP server is not properly defined.\"\n>                 }\n>\n> -               if ($smtp_ssl) {\n> -                       $smtp_server_port ||= 465; # ssmtp\n> -                       require Net::SMTP::SSL;\n> -                       $smtp ||= Net::SMTP::SSL->new($smtp_server, Port => $smtp_server_port);\n> +               if ($smtp_tls) {\n> +                       require Net::SMTP::TLS;\n> +                       $smtp ||= Net::SMTP::TLS->new(\n> +                               $smtp_server,\n> +                               Port => $smtp_server_port,\n> +                               User => $smtp_authuser,\n> +                               Password=> $smtp_authpass);\n> +\n> +                       $smtp->mail( $raw_from );\n> +                       $smtp->to( @recipients );\n> +                       $smtp->data;\n> +                       $smtp->datasend(\"$header\\n$message\");\n> +                       $smtp->dataend();\n>                 }\n>                 else {\n> -                       require Net::SMTP;\n> -                       $smtp ||= Net::SMTP->new((defined $smtp_server_port)\n> -                                                ? \"$smtp_server:$smtp_server_port\"\n> -                                                : $smtp_server);\n> -               }\n> +                       if ($smtp_ssl) {\n> +                               require Net::SMTP::SSL;\n> +                               $smtp ||= Net::SMTP::SSL->new($smtp_server, Port => $smtp_server_port);\n> +                       }\n> +                       else {\n> +                               require Net::SMTP;\n> +                               $smtp ||= Net::SMTP->new((defined $smtp_server_port)\n> +                                                        ? \"$smtp_server:$smtp_server_port\"\n> +                                                        : $smtp_server);\n> +                       }\n>\n> -               if (!$smtp) {\n> -                       die \"Unable to initialize SMTP properly.  Is there something wrong with your config?\";\n> -               }\n> +                       if (!$smtp) {\n> +                               die \"Unable to initialize SMTP properly.  Is there something wrong with your config?\";\n> +                       }\n>\n> -               if ((defined $smtp_authuser) && (defined $smtp_authpass)) {\n> -                       $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message;\n> +                       if ((defined $smtp_authuser) && (defined $smtp_authpass)) {\n> +                               $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message;\n> +                       }\n> +                       $smtp->mail( $raw_from ) or die $smtp->message;\n> +                       $smtp->to( @recipients ) or die $smtp->message;\n> +                       $smtp->data or die $smtp->message;\n> +                       $smtp->datasend(\"$header\\n$message\") or die $smtp->message;\n> +                       $smtp->dataend() or die $smtp->message;\n> +                       $smtp->ok or die \"Failed to send $subject\\n\".$smtp->message;\n>                 }\n> -               $smtp->mail( $raw_from ) or die $smtp->message;\n> -               $smtp->to( @recipients ) or die $smtp->message;\n> -               $smtp->data or die $smtp->message;\n> -               $smtp->datasend(\"$header\\n$message\") or die $smtp->message;\n> -               $smtp->dataend() or die $smtp->message;\n> -               $smtp->ok or die \"Failed to send $subject\\n\".$smtp->message;\n>         }\n>         if ($quiet) {\n>                 printf (($dry_run ? \"Dry-\" : \"\").\"Sent %s\\n\", $subject);\n> @@ -651,7 +671,7 @@ X-Mailer: git-send-email $gitversion\n>                         print \"Sendmail: $smtp_server \".join(' ',@sendmail_parameters).\"\\n\";\n>                 }\n>                 print \"From: $sanitized_sender\\nSubject: $subject\\nCc: $cc\\nTo: $to\\n\\n\";\n> -               if ($smtp) {\n> +               if ($smtp && !$smtp_tls) {\n>                         print \"Result: \", $smtp->code, ' ',\n>                                 ($smtp->message =~ /\\n([^\\n]+\\n)$/s), \"\\n\";\n>                 } else {\n> --\n> 1.5.3.4.498.g9c514\n>\n>\n> -\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>\n"},{"id":"57751","messageId":"981e6de60710311504v666943beve3b87c6a713fb18c@mail.gmail.com","threadId":"10542","inReplyTo":"2faad3050710311445l51d1152cs6761803e2f3a77d3@mail.gmail.com","subject":"Re: [PATCH] Implement sending mails over TLS in git-send-email.","fromName":"Simon Sasburg","fromEmail":"simon.sasburg@gmail.com","sentAt":"2007-10-31T22:04:59Z","receivedAt":"2007-10-31T22:04:59Z","isPatch":true,"sender":{"key":"simon.sasburg@gmail.com","avatar":null},"body":"> Secondly, Net::SMTP::SSL has no problem connecting to gmail - it does\n> everything Net::SMTP::TLS does and more; you can use all of the\n> options of IO::Socket::SSL with it. A common problem seems to be not\n> having Authen::SASL installed (this is required to authenticate with\n> gmail) - the one thing Net::SMTP::TLS *does* do is auth without using\n> that module.\n\nAh, yes, i got the Authen::SASL errors at first, but even after\nresolving all missing module dependencies,\nthe --smpt-ssl still did not work for me, so i started looking at\nother solutions and found Net::SMTP::TLS.\n\n> In other words, this patch should be entirely unnecessary if you have\n> Authen::SASL installed - could you try this? (I've checked for myself,\n> git-send-email sends me mail fine via gmail without this patch)\n\nWell, it fails here, maybe maybe you can show me exactly what you did\n(configuration/parameters etc)?\n\nThis is what i do now:\n> git-send-email testfile.patch -to simon.sasburg@gmail.com --chain-reply-to --smtp-server smtp.gmail.com --smtp-user simon.sasburg --smtp-pass secret --smtp-ssl --smtp-server-port 587\nand it fails, while the same line using --smtp-tls instead of\n--smtp-ssl with my patch applied works.\n\nWhat am i missing?\n"},{"id":"57762","messageId":"2faad3050710311659s10cab8fbj45bac505b22bb0c2@mail.gmail.com","threadId":"10542","inReplyTo":"981e6de60710311504v666943beve3b87c6a713fb18c@mail.gmail.com","subject":"Re: [PATCH] Implement sending mails over TLS in git-send-email.","fromName":"Baz","fromEmail":"brian.ewins@gmail.com","sentAt":"2007-10-31T23:59:24Z","receivedAt":"2007-10-31T23:59:24Z","isPatch":true,"sender":{"key":"brian.ewins@gmail.com","avatar":"https://gravatar.com/avatar/9ac03d89105e50a7151e695a1b4b1228151064ec3ac380a73b74ab397796baf7?d=mp&s=160"},"body":"On 31/10/2007, Simon Sasburg <simon.sasburg@gmail.com> wrote:\n> > In other words, this patch should be entirely unnecessary if you have\n> > Authen::SASL installed - could you try this? (I've checked for myself,\n> > git-send-email sends me mail fine via gmail without this patch)\n>\n> Well, it fails here, maybe maybe you can show me exactly what you did\n> (configuration/parameters etc)?\n>\n> This is what i do now:\n> > git-send-email testfile.patch -to simon.sasburg@gmail.com --chain-reply-to --smtp-server smtp.gmail.com --smtp-user simon.sasburg --smtp-pass secret --smtp-ssl --smtp-server-port 587\n> and it fails, while the same line using --smtp-tls instead of\n> --smtp-ssl with my patch applied works.\n>\n> What am i missing?\n>\n\nok I'm going to downgrade what I said to 'it works fine with gmail' -\nit just doesnt do starttls, your code does.\n\ngit-send-email --from 'brian.ewins@gmail.com' --to\n'brian.ewins@gmail.com' --smtp-server smtp.gmail.com  --smtp-user\n'brian.ewins@gmail.com' --smtp-pass 'secret' --smtp-ssl\n0001-the-patch-goes-here\n\nThat's using SSL on port 465, not TLS. Did this not work for you? I\nthought Net::SMTP passed its constructor options to IO::Socket, but\nno. An alternate way of getting starttls to work, without using\nNet::SMTP::TLS, is this:\n\n#connect with Net::SMTP - not ::SSL or the connect will fail\n$smtp = Net::SMTP->new('smtp.gmail.com',\n                                 Port => 587,\n                                 Debug => 1) or die \"Could not connect\nto server\\n\";\n#issue the starttls command, assuming user asked for this\n$smtp->command('STARTTLS');\n$smtp->response();\n#if server says 220, then go ahead and convert the socket. Bless as\nNet::SMTP::SSL\n# - necessary to inherit both IO::Socket::SSL and Net::SMTP\n#start_SSL has been renamed, twice. Nice stable api :)\n#extra args for checking server cert etc can be passed to start_SSL.\n$smtp->code() == 220 and $smtp = Net::SMTP::SSL->start_SSL($smtp) or\ndie \"STARTTLS failed! \".$smtp->message;\n# say hello again to get server features (including auth)\n$smtp->hello();\n# now continue as before, with $smtp->auth()...\n"}]}