From: Aditya Garg <gargaditya08@live.com>
To: Julian Swagemakers <julian@swagemakers.org>,
git@vger.kernel.org, Junio C Hamano <gitster@pobox.com>
Cc: M Hickford <mirth.hickford@gmail.com>,
sandals@crustytoothpaste.net, Shengyu Qu <wiagn233@outlook.com>
Subject: [PATCH v4 1/3] send-email: implement SMTP bearer authentication
Date: Wed, 23 Apr 2025 12:19:45 +0000 [thread overview]
Message-ID: <PN3PR01MB9597776CB37BE7B05A7ADD80B8BA2@PN3PR01MB9597.INDPRD01.PROD.OUTLOOK.COM> (raw)
In-Reply-To: <PN3PR01MB9597A83D537E3AE96144227EB8BA2@PN3PR01MB9597.INDPRD01.PROD.OUTLOOK.COM>
From: Julian Swagemakers <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
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
Tested-by: M Hickford <mirth.hickford@gmail.com>
Signed-off-by: Julian Swagemakers <julian@swagemakers.org>
Signed-off-by: Aditya Garg <gargaditya08@live.com>
---
Documentation/git-send-email.adoc | 5 ++-
git-send-email.perl | 64 ++++++++++++++++++++++++++++++-
2 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-send-email.adoc b/Documentation/git-send-email.adoc
index 7f223db42d..1bf75c060d 100644
--- a/Documentation/git-send-email.adoc
+++ b/Documentation/git-send-email.adoc
@@ -213,7 +213,10 @@ SMTP server and if it is supported by the utilized SASL library, the mechanism
is used for authentication. If neither 'sendemail.smtpAuth' nor `--smtp-auth`
is specified, all mechanisms supported by the SASL library can be used. The
special value 'none' maybe specified to completely disable authentication
-independently of `--smtp-user`
+independently of `--smtp-user`. Specifying `OAUTHBEARER` or `XOAUTH2` will
+bypass SASL negotiation and force bearer authentication. In this case the
+bearer token must be provided with `--smtp-pass` or using a credential helper
+and `--smtp-encryption=tls` must be set.
--smtp-pass[=<password>]::
Password for SMTP-AUTH. The argument is optional: If no
diff --git a/git-send-email.perl b/git-send-email.perl
index 1f613fa979..a6cafda29c 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -1398,6 +1398,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 enforced
+ # at this point.
+ #
+ # https://datatracker.ietf.org/doc/html/rfc7628#section-3
+ die sprintf(__("For %s TLS is required."), $smtp_auth);
+ }
+ 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.
@@ -1436,7 +1493,12 @@ sub smtp_auth_maybe {
# catch all SMTP auth error in a unified eval block
eval {
- if ($smtp_auth) {
+ if (defined $smtp_auth && ($smtp_auth eq "OAUTHBEARER" || $smtp_auth eq "XOAUTH2")) {
+ # Since Authen:SASL does not support XOAUTH2 nor OAUTHBEARER we will
+ # manually authenticate for these types. The password field should
+ # contain the auth token at this point.
+ $result = smtp_bearer_auth($cred->{'username'}, $cred->{'password'});
+ } elsif ($smtp_auth) {
my $sasl = Authen::SASL->new(
mechanism => $smtp_auth,
callback => {
--
2.49.0
next prev parent reply other threads:[~2025-04-23 12:29 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-23 12:19 [PATCH v4 0/3] send-email: add oauth2 support and fix outlook breaking threads Aditya Garg
2025-04-23 12:19 ` Aditya Garg [this message]
2025-04-23 18:04 ` [PATCH v4 1/3] send-email: implement SMTP bearer authentication Junio C Hamano
2025-04-23 18:33 ` Aditya Garg
2025-04-24 6:36 ` Greg Kroah-Hartman
2025-04-24 8:23 ` Aditya Garg
2025-04-23 12:19 ` [PATCH v4 2/3] send-email: retrieve Message-ID from outlook SMTP server Aditya Garg
2025-04-23 18:54 ` Junio C Hamano
2025-04-23 22:52 ` brian m. carlson
2025-04-24 3:42 ` Aditya Garg
2025-04-23 12:19 ` [PATCH v4 3/3] send-email: add option to generate passswords like OAuth2 tokens Aditya Garg
2025-04-23 19:03 ` Junio C Hamano
2025-04-24 3:29 ` Aditya Garg
2025-04-24 12:43 ` Junio C Hamano
2025-04-23 20:50 ` [PATCH v4 0/3] send-email: add oauth2 support and fix outlook breaking threads M Hickford
2025-04-24 3:44 ` Aditya Garg
2025-04-24 7:53 ` [PATCH v5 " Aditya Garg
2025-04-24 7:53 ` [PATCH v5 1/3] send-email: implement SMTP bearer authentication Aditya Garg
2025-04-24 12:12 ` Julian Swagemakers
[not found] ` <CACOoB6jE=DgpYYaudhqTVDRd2SCz++aog7QYwTQs6-MAD8dBuw@mail.gmail.com>
2025-04-24 18:22 ` Aditya Garg
2025-04-24 19:20 ` Erik Huelsmann
2025-04-25 6:19 ` Julian Swagemakers
2025-04-25 6:25 ` Aditya Garg
2025-04-25 9:45 ` Aditya Garg
2025-04-25 10:17 ` Erik Hulsmann
2025-04-24 18:23 ` Aditya Garg
2025-04-24 7:53 ` [PATCH v5 2/3] send-email: retrieve Message-ID from outlook SMTP server Aditya Garg
2025-04-24 13:09 ` Greg Kroah-Hartman
2025-04-26 18:11 ` Yao Zi
2025-04-27 20:05 ` Aditya Garg
2025-04-28 4:16 ` Yao Zi
2025-04-27 19:44 ` Aditya Garg
2025-04-24 7:53 ` [PATCH v5 3/3] send-email: add option to generate passswords like OAuth2 tokens Aditya Garg
2025-04-24 12:28 ` Julian Swagemakers
2025-04-24 12:53 ` Aditya Garg
2025-04-24 15:20 ` Junio C Hamano
2025-04-24 15:46 ` Aditya Garg
2025-04-24 16:58 ` Junio C Hamano
2025-04-25 10:09 ` [PATCH v6 0/1] send-email: add oauth2 support and fix outlook breaking threads Aditya Garg
2025-04-25 10:09 ` [PATCH v6 1/1] send-email: retrieve Message-ID from outlook SMTP server Aditya Garg
2025-04-25 15:04 ` Aditya Garg
2025-04-25 16:22 ` Erik Huelsmann
2025-04-25 17:08 ` Junio C Hamano
2025-04-25 19:05 ` Erik Huelsmann
2025-04-25 19:08 ` Aditya Garg
2025-04-25 17:23 ` Junio C Hamano
2025-04-25 19:05 ` Aditya Garg
2025-04-26 8:36 ` Aditya Garg
2025-04-26 9:03 ` Eric Sunshine
2025-04-26 17:40 ` Aditya Garg
2025-04-28 16:52 ` Junio C Hamano
2025-04-28 17:52 ` [PATCH] send-email: add --smtp-outlook-id-tweak option Aditya Garg
2025-04-28 17:57 ` [PATCH v2] " Aditya Garg
2025-04-28 20:47 ` Junio C Hamano
2025-04-29 3:44 ` Aditya Garg
2025-04-29 10:52 ` [PATCH v3] send-email: add --[no-]outlook-id-fix option Aditya Garg
2025-04-29 11:00 ` Aditya Garg
2025-04-29 15:57 ` Junio C Hamano
2025-04-29 16:24 ` Junio C Hamano
2025-04-29 16:26 ` Aditya Garg
2025-04-29 16:37 ` [PATCH v4] " Aditya Garg
2025-04-29 23:08 ` Junio C Hamano
2025-04-30 8:31 ` Aditya Garg
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=PN3PR01MB9597776CB37BE7B05A7ADD80B8BA2@PN3PR01MB9597.INDPRD01.PROD.OUTLOOK.COM \
--to=gargaditya08@live.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=julian@swagemakers.org \
--cc=mirth.hickford@gmail.com \
--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).