Bug 1193494 - Never prefer SASL PLAIN for JS-XMPP auth even over encrypted connections. r=clokep
authoraleth <aleth@instantbird.org>
Wed, 26 Aug 2015 17:00:41 +0200
changeset 18286 c37d201e97fa9f2baa9fe0f8edbbb41bf59c6498
parent 18285 2f0687ac8d3f9e56c28844b02ac502e4598e5f45
child 18287 cc0929afb85b8bbb34c3dc986fc0ebcab750de47
push id11223
push useraleth@instantbird.org
push dateWed, 26 Aug 2015 15:01:12 +0000
treeherdercomm-central@cc0929afb85b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersclokep
bugs1193494
Bug 1193494 - Never prefer SASL PLAIN for JS-XMPP auth even over encrypted connections. r=clokep
chat/protocols/xmpp/xmpp-session.jsm
--- a/chat/protocols/xmpp/xmpp-session.jsm
+++ b/chat/protocols/xmpp/xmpp-session.jsm
@@ -301,33 +301,36 @@ XMPPSession.prototype = {
 
       // Select the auth mechanism we will use. PLAIN will be treated
       // a bit differently as we want to avoid it over an unencrypted
       // connection, except if the user has explicly allowed that
       // behavior.
       let authMechanisms = this._account.authMechanisms || XMPPAuthMechanisms;
       let selectedMech = "";
       let canUsePlain = false;
-      mechs = mechs.getChildren("mechanism");
-      for each (let m in mechs) {
+      // RFC 6120, 6.4.1: The order of <mechanism/> elements in
+      // the XML indicates the preference order of the SASL mechanisms
+      // according to the receiving entity (which is not necessarily the
+      // preference order according to the initiating entity).
+      for (let m of mechs.getChildren("mechanism")) {
         let mech = m.innerText;
-        if (mech == "PLAIN" && !this._encrypted) {
-          // If PLAIN is proposed over an unencrypted connection,
-          // remember that it's a possibility but don't bother
-          // checking if the user allowed it until we have verified
+        if (mech == "PLAIN") {
+          // If PLAIN is proposed, remember that it's a possibility but don't
+          // bother checking if the user allowed it until we have verified
           // that nothing more secure is available.
           canUsePlain = true;
         }
         else if (authMechanisms.hasOwnProperty(mech)) {
           selectedMech = mech;
           break;
         }
       }
       if (!selectedMech && canUsePlain) {
-        if (this._connectionSecurity == "allow_unencrypted_plain_auth")
+        if (this._encrypted ||
+            this._connectionSecurity == "allow_unencrypted_plain_auth")
           selectedMech = "PLAIN";
         else {
           this.onError(Ci.prplIAccount.ERROR_AUTHENTICATION_IMPOSSIBLE,
                        _("connection.error.notSendingPasswordInClear"));
           return;
         }
       }
       if (!selectedMech) {