Bug 1598861 - make sure to probe a found exchange server whether it supports IMAP/POP3. r=aleca a=mkmelin
authorMagnus Melin <mkmelin+mozilla@iki.fi>
Thu, 12 Dec 2019 23:52:19 +0200
changeset 37659 3d2a673f9024f7ed91ed398955947b46518d83ca
parent 37658 6a0479402139ab109836d93f61bc87e227e2680d
child 37660 148cc4c05d832e1f3bbd05cc6965a777949c0e2b
push id396
push userclokep@gmail.com
push dateMon, 06 Jan 2020 23:11:57 +0000
reviewersaleca, mkmelin
bugs1598861
Bug 1598861 - make sure to probe a found exchange server whether it supports IMAP/POP3. r=aleca a=mkmelin
mail/components/accountcreation/content/emailWizard.js
mail/components/accountcreation/content/exchangeAutoDiscover.js
mail/components/accountcreation/content/fetchhttp.js
mail/components/accountcreation/content/guessConfig.js
--- a/mail/components/accountcreation/content/emailWizard.js
+++ b/mail/components/accountcreation/content/emailWizard.js
@@ -745,17 +745,17 @@ EmailConfigWizard.prototype = {
         // success
         self._abortable = null;
         self.foundConfig(config);
         self.stopSpinner(
           Services.io.offline
             ? "guessed_settings_offline"
             : "found_settings_guess"
         );
-        this.resizeDialog();
+        self.resizeDialog();
       },
       function(e, config) {
         // guessconfig failed
         if (e instanceof CancelledException) {
           return;
         }
         self._abortable = null;
         gEmailWizardLogger.info("guessConfig failed: " + e);
--- a/mail/components/accountcreation/content/exchangeAutoDiscover.js
+++ b/mail/components/accountcreation/content/exchangeAutoDiscover.js
@@ -1,14 +1,15 @@
 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* import-globals-from emailWizard.js */
+/* import-globals-from guessConfig.js */
 
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.defineModuleGetter(
   this,
   "AddonManager",
   "resource://gre/modules/AddonManager.jsm"
 );
 var { logException } = ChromeUtils.import("resource:///modules/errUtils.js");
@@ -97,17 +98,17 @@ function fetchConfigFromExchange(
   let successive = new SuccessiveAbortable();
   let priority = new PriorityOrderAbortable(function(xml, call) {
     // success
     readAutoDiscoverResponse(
       xml,
       successive,
       username,
       password,
-      successCallback,
+      config => detectStandardProtocols(config, domain, successCallback),
       errorCallback
     );
   }, errorCallback); // all failed
 
   call = priority.addCall();
   fetch = new FetchHTTP(
     url1,
     callArgs,
@@ -499,8 +500,71 @@ function readAddonsJSON(json) {
       }
       addons.push(addon);
     } catch (e) {
       ddump(e);
     }
   }
   return addons;
 }
+
+/**
+ * Probe a found Exchange server for IMAP/POP3 and SMTP support.
+ *
+ * @param {AccountConfig} config - The initial detected Exchange configuration.
+ * @param {string} domain - The domain part of the user's email address
+ * @param {Function(config {AccountConfig})} successCallback - A callback that
+ *   will be called when we found an appropriate configuration.
+ *   The AccountConfig object will be passed in as first parameter.
+ */
+function detectStandardProtocols(config, domain, successCallback) {
+  gEmailWizardLogger.info("Exchange Autodiscover gave some results.");
+  let alts = [config.incoming, ...config.incomingAlternatives];
+  if (alts.find(alt => alt.type == "imap" || alt.type == "pop3")) {
+    // Autodiscover found an exchange server with advertized IMAP and/or
+    // POP3 support. We're done then.
+    successCallback(config);
+    return;
+  }
+
+  // Autodiscover is known not to advertize all that it supports. Let's see
+  // if there really isn't any IMAP/POP3 support by probing the Exchange
+  // server. Use the server hostname already found.
+  let config2 = new AccountConfig();
+  config2.incoming.hostname = config.incoming.hostname;
+  config2.incoming.username = config.incoming.username || "%EMAILADDRESS%";
+  // For Exchange 2013+ Kerberos/GSSAPI and NTLM options do not work by
+  // default at least for Linux users, even if support is detected.
+  config2.incoming.auth = Ci.nsMsgAuthMethod.passwordCleartext;
+
+  config2.outgoing.hostname = config.incoming.hostname;
+  config2.outgoing.username = config.incoming.username || "%EMAILADDRESS%";
+
+  config2.incomingAlternatives = config.incomingAlternatives;
+  config2.incomingAlternatives.push(config.incoming); // type=exchange
+
+  config2.outgoingAlternatives = config.outgoingAlternatives;
+  if (config.outgoing.hostname) {
+    config2.outgoingAlternatives.push(config.outgoing);
+  }
+
+  config2.oauthSettings = config.oauthSettings;
+
+  guessConfig(
+    domain,
+    function(type, hostname, port, ssl, done, config) {
+      gEmailWizardLogger.info(
+        `Probing exchange server ${hostname} for ${type} protocol support.`
+      );
+    },
+    function(probedConfig) {
+      // Probing succeded: found open protocols, yay!
+      successCallback(probedConfig);
+    },
+    function(e, probedConfig) {
+      // Probing didn't find any open protocols.
+      // Let's use the exchange (only) config that was listed then.
+      successCallback(config);
+    },
+    config2,
+    "both"
+  );
+}
--- a/mail/components/accountcreation/content/fetchhttp.js
+++ b/mail/components/accountcreation/content/fetchhttp.js
@@ -297,17 +297,17 @@ FetchHTTP.prototype = {
           console.error(e);
         }
         if (!errorStr) {
           // If we can't resolve the hostname in DNS etc., .statusText is empty.
           errorCode = -2;
           errorStr = getStringBundle(
             "chrome://messenger/locale/accountCreationUtil.properties"
           ).GetStringFromName("cannot_contact_server.error");
-          ddump(errorStr);
+          ddump(errorStr + " on <" + this._url + ">");
         }
       }
 
       // Callbacks
       if (success) {
         try {
           this._successCallback(this.result);
         } catch (e) {
--- a/mail/components/accountcreation/content/guessConfig.js
+++ b/mail/components/accountcreation/content/guessConfig.js
@@ -128,18 +128,18 @@ function guessConfig(
     );
   };
 
   var updateConfig = function(config) {
     resultConfig = config;
   };
 
   var errorInCallback = function(e) {
-    // The caller's errorCallback threw.
-    // hopefully shouldn't happen for users.
+    // The caller's errorCallback threw. Hopefully shouldn't happen for users.
+    console.error(e);
     alertPrompt("Error in errorCallback for guessConfig()", e);
   };
 
   var checkDone = function() {
     if (incomingEx) {
       try {
         errorCallback(incomingEx, resultConfig);
       } catch (e) {