From e822140b4a072560ae580f36e8539c0569274d67 Mon Sep 17 00:00:00 2001 From: Edouard Vanbelle Date: Wed, 27 Dec 2023 00:23:14 +0100 Subject: [PATCH] add OAUTH pseudo method * OAUTH pseudo method will elect either XOAUTH2 or OAUTHBEARER according to server's capabilities Signed-off-by: Edouard Vanbelle --- Net/SMTP.php | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/Net/SMTP.php b/Net/SMTP.php index 91162a9..efb1745 100644 --- a/Net/SMTP.php +++ b/Net/SMTP.php @@ -709,14 +709,17 @@ public function starttls() return true; } - + /** * Attempt to do SMTP authentication. * * @param string $uid The userid to authenticate as. * @param string $pwd The password to authenticate with. - * @param string $method The requested authentication method. If none is + * @param string $method The requested authentication method. If none is * specified, the best supported method will be used. + * If you use the special method `OAUTH`, library + * will choose between OAUTHBEARER or XOAUTH2 + * according the server's capabilities. * @param bool $tls Flag indicating whether or not TLS should be attempted. * @param string $authz An optional authorization identifier. If specified, this * identifier will be used as the authorization proxy. @@ -750,6 +753,19 @@ public function auth($uid, $pwd , $method = '', $tls = true, $authz = '') /* Return the PEAR_Error object from _getBestAuthMethod(). */ return $method; } + } elseif ($method === 'OAUTH') { + // special case of OAUTH, use the supported method + $found = false; + $available_methods = explode(' ', $this->esmtp['AUTH']); + foreach (['OAUTHBEARER', 'XOAUTH2'] as $method) { + if (in_array($method, $available_methods)) { + $found = true; + break; + } + } + if (!$found) { + return PEAR::raiseError("neither OAUTHBEARER nor XOAUTH2 is a supported authentication method"); + } } else { $method = strtoupper($method); if (!array_key_exists($method, $this->auth_methods)) { @@ -1110,10 +1126,10 @@ protected function authGSSAPI($uid, $pwd, $authz = '') * kind of failure, or true on success. * @since 1.9.0 */ - public function authXOAuth2($uid, $token, $authz, $conn) + protected function authXOAuth2($uid, $token, $authz, $conn) { $auth = base64_encode("user=$uid\1auth=$token\1\1"); - return $this->_authOAuth('XOAUTH2', $auth, $authz, $conn); + return $this->authenticateOAuth('XOAUTH2', $auth, $authz, $conn); } /** @@ -1129,10 +1145,10 @@ public function authXOAuth2($uid, $token, $authz, $conn) * @since 1.9.3 * @see https://www.rfc-editor.org/rfc/rfc7628.html */ - public function authOAuthBearer($uid, $token, $authz, $conn) + protected function authOAuthBearer($uid, $token, $authz, $conn) { $auth = base64_encode("n,a=$uid\1auth=$token\1\1"); - return $this->_authOAuth('OAUTHBEARER', $auth, $authz, $conn); + return $this->authenticateOAuth('OAUTHBEARER', $auth, $authz, $conn); } /** @@ -1146,7 +1162,7 @@ public function authOAuthBearer($uid, $token, $authz, $conn) * @return mixed Returns a PEAR_Error with an error message on any * kind of failure, or true on success. */ - protected function _authOAuth( $method, $auth, $authz, $conn) + protected function authenticateOAuth( $method, $auth, $authz, $conn) { // Maximum length of the base64-encoded token to be sent in the initial response is 504 - strlen($method) bytes, // according to RFC 4954 (https://datatracker.ietf.org/doc/html/rfc4954); for longer tokens an empty initial