From: M Hickford <mirth.hickford@gmail.com>
To: julian@swagemakers.org
Cc: git@vger.kernel.org, wiagn233@outlook.com, sandals@crustytoothpaste.net
Subject: Re: [PATCH] send-email: implement SMTP bearer authentication
Date: Sat, 11 Jan 2025 21:27:01 +0000 [thread overview]
Message-ID: <20250111212701.723710-1-mirth.hickford@gmail.com> (raw)
In-Reply-To: 20240225103413.9845-1-julian@swagemakers.org
> Manually send SMTP AUTH command for auth type OAUTHBEARER and XOAUTH2.
> This is necessary since they are currently not supported by the Perls
> Authen::SASL module.
>
> The bearer token needs to be passed in as the password. This can be done
Please add documentation to git-send-email.txt
> with git-credential-oauth[0] after minor modifications[1]. Which will
> allow using git send-email with Gmail and oauth2 authentication:
>
> ```
> [credential]
> helper = cache --timeout 7200 # two hours
> helper = oauth
> [sendemail]
> smtpEncryption = tls
> smtpServer = smtp.gmail.com
> smtpUser = example@gmail.com
> smtpServerPort = 587
> smtpauth = OAUTHBEARER
> ```
>
> As well as Office 365 accounts:
>
> ```
> [credential]
> helper = cache --timeout 7200 # two hours
> helper = oauth
> [sendemail]
> smtpEncryption = tls
> smtpServer = smtp.office365.com
> smtpUser = example@example.com
> smtpServerPort = 587
> smtpauth = XOAUTH2
> ```
>
> [0] https://github.com/hickford/git-credential-oauth
> [1] https://github.com/hickford/git-credential-oauth/issues/48
>
> Signed-off-by: Julian Swagemakers <julian@swagemakers.org>
> ---
> git-send-email.perl | 65 +++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 63 insertions(+), 2 deletions(-)
>
> diff --git a/git-send-email.perl b/git-send-email.perl
> index 821b2b3a13..72d378f6fd 100755
> --- a/git-send-email.perl
> +++ b/git-send-email.perl
> @@ -1359,6 +1359,63 @@ sub smtp_host_string {
> }
> }
>
> +sub generate_oauthbearer_string {
> + # This will generate the oauthbearer string used for authentication.
> + #
> + # "n,a=" {User} ",^Ahost=" {Host} "^Aport=" {Port} "^Aauth=Bearer " {Access Token} "^A^A
> + #
> + # The first part `n,a=" {User} ",` is the gs2 header described in RFC5801.
> + # * gs2-cb-flag `n` -> client does not support CB
> + # * gs2-authzid `a=" {User} "`
> + #
> + # The second part are key value pairs containing host, port and auth as
> + # described in RFC7628.
> + #
> + # https://datatracker.ietf.org/doc/html/rfc5801
> + # https://datatracker.ietf.org/doc/html/rfc7628
> + my $username = shift;
> + my $token = shift;
> + return "n,a=$username,\001port=$smtp_server_port\001auth=Bearer $token\001\001";
> +}
> +
> +sub generate_xoauth2_string {
> + # "user=" {User} "^Aauth=Bearer " {Access Token} "^A^A"
> + # https://developers.google.com/gmail/imap/xoauth2-protocol#initial_client_response
> + my $username = shift;
> + my $token = shift;
> + return "user=$username\001auth=Bearer $token\001\001";
> +}
> +
> +sub smtp_bearer_auth {
> + my $username = shift;
> + my $token = shift;
> + my $auth_string;
> + if ($smtp_encryption ne "tls") {
> + # As described in RFC7628 TLS is required and will be will
> + # be enforced at this point.
> + #
> + # https://datatracker.ietf.org/doc/html/rfc7628#section-3
> + die __("For $smtp_auth TLS is required.")
> + }
> + if ($smtp_auth eq "OAUTHBEARER") {
> + $auth_string = generate_oauthbearer_string($username, $token);
> + } elsif ($smtp_auth eq "XOAUTH2") {
> + $auth_string = generate_xoauth2_string($username, $token);
> + }
> + my $encoded_auth_string = MIME::Base64::encode($auth_string, "");
> + $smtp->command("AUTH $smtp_auth $encoded_auth_string\r\n");
> + use Net::Cmd qw(CMD_OK);
> + if ($smtp->response() == CMD_OK){
> + return 1;
> + } else {
> + # Send dummy request on authentication failure according to rfc7628.
> + # https://datatracker.ietf.org/doc/html/rfc7628#section-3.2.3
> + $smtp->command(MIME::Base64::encode("\001"));
> + $smtp->response();
> + return 0;
> + }
> +}
> +
> # Returns 1 if authentication succeeded or was not necessary
> # (smtp_user was not specified), and 0 otherwise.
>
> @@ -1392,8 +1449,12 @@ sub smtp_auth_maybe {
> 'password' => $smtp_authpass
> }, sub {
> my $cred = shift;
> -
> - if ($smtp_auth) {
> + if ($smtp_auth eq "OAUTHBEARER" or $smtp_auth eq "XOAUTH2") {
Be careful to check that $smtp_auth is initialized to avoid warnings:
Use of uninitialized value $smtp_auth in string eq at /home/matt/libexec/git-core/git-send-email line 1493.
Use of uninitialized value $smtp_auth in string eq at /home/matt/libexec/git-core/git-send-email line 1493.
> + # Since Authen:SASL does not support XOAUTH2 nor OAUTHBEARER we will
> + # manuall authenticate for tese types. The password field should
> + # contain the auth token at this point.
> + return smtp_bearer_auth($cred->{'username'}, $cred->{'password'});
> + } elsif ($smtp_auth) {
> my $sasl = Authen::SASL->new(
> mechanism => $smtp_auth,
> callback => {
next reply other threads:[~2025-01-11 21:27 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-11 21:27 M Hickford [this message]
-- strict thread matches above, loose matches on Subject: below --
2025-01-07 19:49 [PATCH] send-email: implement SMTP bearer authentication M Hickford
2025-01-11 19:06 ` Julian Swagemakers
2025-01-11 21:19 ` M Hickford
2024-02-25 10:34 Julian Swagemakers
2024-02-28 17:53 ` M Hickford
2024-10-11 17:48 ` Shengyu Qu
2024-10-11 18:05 ` Junio C Hamano
2024-10-11 18:24 ` Shengyu Qu
[not found] ` < <TYCPR01MB8437CDD2208EA6555117E72C98792@TYCPR01MB8437.jpnprd01.prod.outlook.com>
2024-10-12 18:43 ` Julian Swagemakers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250111212701.723710-1-mirth.hickford@gmail.com \
--to=mirth.hickford@gmail.com \
--cc=git@vger.kernel.org \
--cc=julian@swagemakers.org \
--cc=sandals@crustytoothpaste.net \
--cc=wiagn233@outlook.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).