* [PATCH 0/2] Ad support for Oauth2 and fix message-id bug in outlook
@ 2025-04-22 7:19 Aditya Garg via GitGitGadget
2025-04-22 7:19 ` [PATCH 1/2] send-email: implement SMTP bearer authentication Julian Swagemakers via GitGitGadget
2025-04-22 7:19 ` [PATCH 2/2] send-email: retrieve Message-ID from outlook SMTP server Aditya Garg via GitGitGadget
0 siblings, 2 replies; 4+ messages in thread
From: Aditya Garg via GitGitGadget @ 2025-04-22 7:19 UTC (permalink / raw)
To: git; +Cc: M Hickford, Julian Swagemakers, sandals, Shengyu Qu, Aditya Garg
This pull request introduces 2 changes:
1. It adds support for Oauth2 authentication, which is now compulsory my
Microsoft. This patch has been rebased to the latest version from the
original version at
https://lore.kernel.org/git/20250125190131.48717-1-julian@swagemakers.org/
2. The second patch makes the script reply to the message id set by the
outlook, since outlook has its own proprietary way to handle message
ids, and does not allow user to set their own. As a result, threads were
breaking.
Aditya Garg (1):
send-email: retrieve Message-ID from outlook SMTP server
Julian Swagemakers (1):
send-email: implement SMTP bearer authentication
Documentation/git-send-email.adoc | 5 ++-
git-send-email.perl | 75 ++++++++++++++++++++++++++++++-
2 files changed, 78 insertions(+), 2 deletions(-)
base-commit: 4bbb303af69990ccd05fe3a2eb58a1ce036f8220
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1949%2FAdityaGarg8%2Fmaster-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1949/AdityaGarg8/master-v1
Pull-Request: https://github.com/git/git/pull/1949
--
gitgitgadget
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH 1/2] send-email: implement SMTP bearer authentication
2025-04-22 7:19 [PATCH 0/2] Ad support for Oauth2 and fix message-id bug in outlook Aditya Garg via GitGitGadget
@ 2025-04-22 7:19 ` Julian Swagemakers via GitGitGadget
2025-04-22 7:19 ` [PATCH 2/2] send-email: retrieve Message-ID from outlook SMTP server Aditya Garg via GitGitGadget
1 sibling, 0 replies; 4+ messages in thread
From: Julian Swagemakers via GitGitGadget @ 2025-04-22 7:19 UTC (permalink / raw)
To: git
Cc: M Hickford, Julian Swagemakers, sandals, Shengyu Qu, Aditya Garg,
Julian Swagemakers
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 7f223db42dd..1bf75c060d3 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 1f613fa979d..aa6aad596f2 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 __("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.
@@ -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 => {
--
gitgitgadget
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 2/2] send-email: retrieve Message-ID from outlook SMTP server
2025-04-22 7:19 [PATCH 0/2] Ad support for Oauth2 and fix message-id bug in outlook Aditya Garg via GitGitGadget
2025-04-22 7:19 ` [PATCH 1/2] send-email: implement SMTP bearer authentication Julian Swagemakers via GitGitGadget
@ 2025-04-22 7:19 ` Aditya Garg via GitGitGadget
1 sibling, 0 replies; 4+ messages in thread
From: Aditya Garg via GitGitGadget @ 2025-04-22 7:19 UTC (permalink / raw)
To: git
Cc: M Hickford, Julian Swagemakers, sandals, Shengyu Qu, Aditya Garg,
Aditya Garg
From: Aditya Garg <gargaditya08@live.com>
Outlook does not accept the Message-ID header in the email body. Instead
it saves it in its own proprietary X-Microsoft-Original-Message-ID
header and a random Message-ID is set my the server. As a result,
replying to threads does not work.
The $smtp->message variable in this script for outlook is something like
this:
2.0.0 OK <Message-ID> [Hostname=Some-hostname]
This contains the Message-ID set by Microsoft in the first <>.
This patch retrieves the Message-ID from this server response
and sets it in the email headers instead of using the self generated one.
Signed-off-by: Aditya Garg <gargaditya08@live.com>
---
git-send-email.perl | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/git-send-email.perl b/git-send-email.perl
index aa6aad596f2..f2a926872de 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -1799,6 +1799,17 @@ EOF
$smtp->datasend("$line") or die $smtp->message;
}
$smtp->dataend() or die $smtp->message;
+
+ # Retrieve the Message-ID from the server response in case of Outlook
+ if ($smtp_server eq 'smtp.office365.com' || $smtp_server eq 'smtp-mail.outlook.com') {
+ if ($smtp->message =~ /<([^>]+)>/) {
+ $message_id = "<$1>";
+ print __("Outlook: Retrieved Message-ID: $message_id\n");
+ } else {
+ warn __("Warning: Could not retrieve Message-ID from server response.\n");
+ }
+ }
+
$smtp->code =~ /250|200/ or die sprintf(__("Failed to send %s\n"), $subject).$smtp->message;
}
if ($quiet) {
--
gitgitgadget
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 0/2] send-email: add oauth2 support and fix outlook breaking threads
@ 2025-04-22 6:54 Aditya Garg
2025-04-22 6:55 ` [PATCH 1/2] send-email: implement SMTP bearer authentication Aditya Garg
0 siblings, 1 reply; 4+ messages in thread
From: Aditya Garg @ 2025-04-22 6:54 UTC (permalink / raw)
To: git, Junio C Hamano; +Cc: Shengyu Qu, M Hickford, sandals, Aditya Garg
Hi all!
This patch series includes two changes:
1. It adds support for Oauth2 authentication, which is now compulsory by Microsoft.
This patch has been rebased to the latest version from the original version
at https://lore.kernel.org/git/20250125190131.48717-1-julian@swagemakers.org/
2. The second patch makes the script reply to the message id set by the outlook,
since outlook has its own proprietary way to handle message ids,
and does not allow user to set their own. As a result, threads were breaking.
Detailed description of each patch has been done in the respective patches
BTW, I am sending this series using the patched send-email by these patches from
Outlook!
Aditya Garg (1):
send-email: retrieve Message-ID from outlook SMTP server
Julian Swagemakers (1):
send-email: implement SMTP bearer authentication
Documentation/git-send-email.adoc | 5 ++-
git-send-email.perl | 75 ++++++++++++++++++++++++++++++-
2 files changed, 78 insertions(+), 2 deletions(-)
--
2.49.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] send-email: implement SMTP bearer authentication
2025-04-22 6:54 [PATCH 0/2] send-email: add oauth2 support and fix outlook breaking threads Aditya Garg
@ 2025-04-22 6:55 ` Aditya Garg
0 siblings, 0 replies; 4+ messages in thread
From: Aditya Garg @ 2025-04-22 6:55 UTC (permalink / raw)
To: git, Junio C Hamano
Cc: Shengyu Qu, M Hickford, sandals, Julian Swagemakers, Aditya Garg
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..aa6aad596f 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 __("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.
@@ -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
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-04-22 7:19 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-22 7:19 [PATCH 0/2] Ad support for Oauth2 and fix message-id bug in outlook Aditya Garg via GitGitGadget
2025-04-22 7:19 ` [PATCH 1/2] send-email: implement SMTP bearer authentication Julian Swagemakers via GitGitGadget
2025-04-22 7:19 ` [PATCH 2/2] send-email: retrieve Message-ID from outlook SMTP server Aditya Garg via GitGitGadget
-- strict thread matches above, loose matches on Subject: below --
2025-04-22 6:54 [PATCH 0/2] send-email: add oauth2 support and fix outlook breaking threads Aditya Garg
2025-04-22 6:55 ` [PATCH 1/2] send-email: implement SMTP bearer authentication Aditya Garg
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).