Bug 1778576 - Break AUTH XOAUTH2 to two steps in Pop3Client to make some servers happy. r=#thunderbird-reviewers,mkmelin a=wsmwk
authorPing Chen <remotenonsense@gmail.com>
Sun, 10 Jul 2022 00:27:29 +0000
changeset 47344 562acd4516f96daf239219e699128dc391440a02
parent 47343 3e4e2bb36c6763994325a03b131f329b85cc02cd
child 47345 72eba3dbed7aa811acca982f10dc29d96d0f4211
push id3730
push userthunderbird@calypsoblue.org
push dateMon, 18 Jul 2022 15:35:33 +0000
treeherdercomm-beta@380a81bbcec0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswsmwk
bugs1778576
Bug 1778576 - Break AUTH XOAUTH2 to two steps in Pop3Client to make some servers happy. r=#thunderbird-reviewers,mkmelin a=wsmwk Differential Revision: https://phabricator.services.mozilla.com/D151423
mailnews/local/src/Pop3Client.jsm
--- a/mailnews/local/src/Pop3Client.jsm
+++ b/mailnews/local/src/Pop3Client.jsm
@@ -599,46 +599,44 @@ class Pop3Client {
         this._nextAction = this._actionAuthLoginUser;
         this._send("AUTH LOGIN");
         break;
       case "CRAM-MD5":
         this._nextAction = this._actionAuthCramMd5;
         this._send("AUTH CRAM-MD5");
         break;
       case "GSSAPI": {
-        this._nextAction = this._actionAuthGssapi;
         this._authenticator.initGssapiAuth("pop");
-        let token;
         try {
-          token = this._authenticator.getNextGssapiToken("");
+          let token = this._authenticator.getNextGssapiToken("");
+          this._nextAction = res => this._actionAuthGssapi(res, token);
         } catch (e) {
           this._logger.error(e);
           this._actionError("pop3GssapiFailure");
           return;
         }
-        this._send(`AUTH GSSAPI ${token}`, true);
+        this._send("AUTH GSSAPI");
         break;
       }
       case "NTLM": {
-        this._nextAction = this._actionAuthNtlm;
         this._authenticator.initNtlmAuth("pop");
-        let token;
         try {
-          token = this._authenticator.getNextNtlmToken("");
+          let token = this._authenticator.getNextNtlmToken("");
+          this._nextAction = res => this._actionAuthNtlm(res, token);
         } catch (e) {
           this._logger.error(e);
           this._actionDone(Cr.NS_ERROR_FAILURE);
+          return;
         }
-        this._send(`AUTH NTLM ${token}`, true);
+        this._send("AUTH NTLM");
         break;
       }
       case "XOAUTH2":
-        this._nextAction = this._actionAuthResponse;
-        let token = await this._authenticator.getOAuthToken();
-        this._send(`AUTH XOAUTH2 ${token}`, true);
+        this._nextAction = this._actionAuthXoauth;
+        this._send("AUTH XOAUTH2");
         break;
       default:
         this._actionDone();
     }
   };
 
   /**
    * Handle authentication response.
@@ -775,58 +773,84 @@ class Pop3Client {
       ),
       true
     );
   };
 
   /**
    * The second and next step of GSSAPI auth.
    * @param {Pop3Response} res - AUTH response received from the server.
+   * @param {string} firstToken - The first GSSAPI token to send.
    */
-  _actionAuthGssapi = res => {
+  _actionAuthGssapi = (res, firstToken) => {
     if (res.status != "+") {
       this._actionAuthResponse(res);
       return;
     }
 
+    if (firstToken) {
+      this._send(firstToken, true);
+      return;
+    }
+
     // Server returns a challenge, we send a new token. Can happen multiple times.
     let token;
     try {
       token = this._authenticator.getNextGssapiToken(res.statusText);
     } catch (e) {
       this._logger.error(e);
       this._actionAuthResponse({ success: false, data: "AUTH GSSAPI" });
       return;
     }
     this._send(token, true);
   };
 
   /**
    * The second and next step of NTLM auth.
    * @param {Pop3Response} res - AUTH response received from the server.
+   * @param {string} firstToken - The first NTLM token to send.
    */
-  _actionAuthNtlm = res => {
+  _actionAuthNtlm = (res, firstToken) => {
     if (res.status != "+") {
       this._actionAuthResponse(res);
       return;
     }
 
+    if (firstToken) {
+      this._send(firstToken, true);
+      return;
+    }
+
     // Server returns a challenge, we send a new token. Can happen multiple times.
     let token;
     try {
       token = this._authenticator.getNextNtlmToken(res.statusText);
     } catch (e) {
       this._logger.error(e);
       this._actionAuthResponse({ success: false, data: "AUTH NTLM" });
       return;
     }
     this._send(token, true);
   };
 
   /**
+   * The second step of XOAUTH2 auth.
+   * @param {Pop3Response} res - AUTH response received from the server.
+   */
+  _actionAuthXoauth = async res => {
+    if (res.status != "+") {
+      this._actionAuthResponse(res);
+      return;
+    }
+    this._nextAction = this._actionAuthResponse;
+    let token = await this._authenticator.getOAuthToken();
+    this._send(token, true);
+  };
+
+  /**
    * Send `STAT` request to the server.
    */
   _actionStat = () => {
     this._nextAction = this._actionStatResponse;
     this._send("STAT");
   };
 
   /**