From 9d5403aaf9d0ae67a190ca4e6f08435c06b64727 Mon Sep 17 00:00:00 2001 From: Desirider Date: Fri, 4 Mar 2022 00:49:28 -0800 Subject: [PATCH] Added support for XOAUTH2 authorization, and documented in base.pod --- doc/base.pod | 34 ++++++++++++++++++++++++++++++++++ swaks | 18 +++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/doc/base.pod b/doc/base.pod index 387e0910..0289ba12 100644 --- a/doc/base.pod +++ b/doc/base.pod @@ -27,6 +27,14 @@ Deliver a standard test email, requiring CRAM-MD5 authentication as user me@exam =back +Deliver a standard test email, through Gmail SMTP server using XOAUTH2 authentication as user guser@gmail.com. An XOAUTH2 access token is read in from the access_token file. + +=over 4 + + swaks --to user@example.com --from guser@gmail.com --server smtp.gmail.com:587 -tls --auth XOAUTH2 -au guser@gmail.com -ap < access_token + +=back + Test a virus scanner using EICAR in an attachment. Don't show the message DATA part.: =over 4 @@ -581,6 +589,10 @@ The following tables lists the valid auth-types These basic authentication types are fully supported and tested and have no additional requirements +=item XOAUTH2 + +The XOAUTH2 is an authorization protocol used by many SMTP servers, and is required by Gmail going forward. An "access token" is required, which replaces the password. See the XOAUTH2 AUTHORIZATION section for instructions on how to obtain an access token from Google. + =item CRAM-MD5 The CRAM-MD5 authenticator requires the L module. It is fully tested and believed to work against any server that implements it. @@ -1050,6 +1062,28 @@ Display version information and exit. (Arg-None) =back +=head1 XOAUTH2 AUTHORIZATION + +This section documents the XOAUTH2 authorization procedure specifically for Gmail. Other providers have a similar setup. Gmail documentation is at L. + +Basically, there are three steps involved. + +=over 4 + +=item Z<>1. + +Register an app with Google, which will generate a client_id and client_secret. Instructions: L + +=item Z<>2. + +Download the Python2 script, oauth2.py, from Google: L + +oauth2.py connects to Google, generates access and refresh tokens using the client_id and client_secret from step 1. The access token is typically valid for 1 hour, while the refresh token lasts indefinitely. Use oauth2.py again with the refresh token to generate a new access token when required. + +=item Z<>3. + +Use the access token generated above as password for the XOAUTH2 authorization method. See example in the QUICK START section. + =head1 DEPRECATIONS The following features are deprecated and will be removed in a future version of Swaks diff --git a/swaks b/swaks index 3fc7a15b..9309443b 100755 --- a/swaks +++ b/swaks @@ -830,6 +830,12 @@ sub do_smtp_auth { $auth_attempted = 1; } } + foreach my $type (@{$G::auth_map_t{'XOAUTH2'}}) { + if ($btype eq $type) { + return(0) if (do_smtp_auth_xoauth2($au, $ap, $type)); + $auth_attempted = 1; + } + } foreach my $type (@{$G::auth_map_t{'PLAIN'}}) { if ($btype eq $type) { return(0) if (do_smtp_auth_plain($au, $ap, $type)); @@ -1012,6 +1018,16 @@ sub do_smtp_auth_plain { : "AUTH $as " . eb64("\0$u\0" . ($G::auth_hidepw || $p)))); } +sub do_smtp_auth_xoauth2 { + my $u = shift; # auth user = username@gmail.com + my $p = shift; # auth password = access token + my $as = shift; # auth string = XOAUTH2 + + return(do_smtp_gen("AUTH $as " . eb64("user=$u\001auth=Bearer $p\001\001"), '235', undef, '', + $G::auth_showpt ? "AUTH $as user=$u\\001auth=Bearer " . ($G::auth_hidepw || $p) . "\\001\\001" + : "AUTH $as " . eb64("user=$u\001auth=Bearer " . ($G::auth_hidepw || $p) . "\001\001"))); +} + sub do_smtp_helo { my $h = shift; # helo string to use my $e = shift; # this is a hashref that will be populated w/ server options @@ -3545,7 +3561,7 @@ sub process_args { # handle the --auth-map options plus our default mappings foreach (split(/\s*,\s*/, get_arg('auth_map', $o)),"PLAIN=PLAIN","LOGIN=LOGIN", - "CRAM-MD5=CRAM-MD5","DIGEST-MD5=DIGEST-MD5", + "CRAM-MD5=CRAM-MD5","DIGEST-MD5=DIGEST-MD5","XOAUTH2=XOAUTH2", "CRAM-SHA1=CRAM-SHA1","NTLM=NTLM","SPA=NTLM","MSN=NTLM") { if (/^([^=]+)=(.+)$/) {