Bug 1023748 - Allow NTLMv1 over SSL/TLS by default, r=jduell
authorHonza Bambas <honzab.moz@firemni.cz>
Mon, 23 Jun 2014 19:43:40 +0200
changeset 190255 2ca9a20fb91ad7797e0913458a66c29c3302de19
parent 190254 6279aec8541c9c05ef914961a16d7b454fc93f40
child 190256 4881d7aaa67cb7401bc16260a37b65e98a636f9a
push id27004
push useremorley@mozilla.com
push dateTue, 24 Jun 2014 15:52:34 +0000
treeherdermozilla-central@7b174d47f3cc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjduell
bugs1023748
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1023748 - Allow NTLMv1 over SSL/TLS by default, r=jduell
modules/libpref/src/init/all.js
netwerk/protocol/http/nsHttpNTLMAuth.cpp
security/manager/ssl/src/nsNTLMAuthModule.cpp
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -1403,16 +1403,18 @@ pref("network.predictor.preserve", 80); 
 // which provides transparent Kerberos or NTLM authentication using the SPNEGO
 // protocol.  Each pref is a comma-separated list of keys, where each key has
 // the format:
 //   [scheme "://"] [host [":" port]]
 // For example, "foo.com" would match "http://www.foo.com/bar", etc.
 
 // Allow insecure NTLMv1 when needed.
 pref("network.negotiate-auth.allow-insecure-ntlm-v1", false);
+// Allow insecure NTLMv1 for HTTPS protected sites by default.
+pref("network.negotiate-auth.allow-insecure-ntlm-v1-https", true);
 
 // This list controls which URIs can use the negotiate-auth protocol.  This
 // list should be limited to the servers you know you'll need to login to.
 pref("network.negotiate-auth.trusted-uris", "");
 // This list controls which URIs can support delegation.
 pref("network.negotiate-auth.delegation-uris", "");
 
 // Do not allow SPNEGO by default when challenged by a local server.
--- a/netwerk/protocol/http/nsHttpNTLMAuth.cpp
+++ b/netwerk/protocol/http/nsHttpNTLMAuth.cpp
@@ -19,24 +19,27 @@
 #include "nsIHttpAuthenticableChannel.h"
 #include "nsIURI.h"
 #ifdef XP_WIN
 #include "nsIX509Cert.h"
 #include "nsISSLStatus.h"
 #include "nsISSLStatusProvider.h"
 #endif
 #include "mozilla/Attributes.h"
+#include "nsThreadUtils.h"
 
 namespace mozilla {
 namespace net {
 
 static const char kAllowProxies[] = "network.automatic-ntlm-auth.allow-proxies";
 static const char kAllowNonFqdn[] = "network.automatic-ntlm-auth.allow-non-fqdn";
 static const char kTrustedURIs[]  = "network.automatic-ntlm-auth.trusted-uris";
 static const char kForceGeneric[] = "network.auth.force-generic-ntlm";
+static const char kAllowGenericHTTP[] = "network.negotiate-auth.allow-insecure-ntlm-v1";
+static const char kAllowGenericHTTPS[] = "network.negotiate-auth.allow-insecure-ntlm-v1-https";
 
 // XXX MatchesBaseURI and TestPref are duplicated in nsHttpNegotiateAuth.cpp,
 // but since that file lives in a separate library we cannot directly share it.
 // bug 236865 addresses this problem.
 
 static bool
 MatchesBaseURI(const nsCSubstring &matchScheme,
                const nsCSubstring &matchHost,
@@ -172,16 +175,57 @@ ForceGenericNTLM()
 
     if (NS_FAILED(prefs->GetBoolPref(kForceGeneric, &flag)))
         flag = false;
 
     LOG(("Force use of generic ntlm auth module: %d\n", flag));
     return flag;
 }
 
+// Check to see if we should use our generic (internal) NTLM auth module.
+static bool
+AllowGenericNTLM()
+{
+    MOZ_ASSERT(NS_IsMainThread());
+
+    nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
+    if (!prefs)
+        return false;
+
+    bool flag = false;
+    if (NS_FAILED(prefs->GetBoolPref(kAllowGenericHTTP, &flag)))
+        flag = false;
+
+    LOG(("Allow use of generic ntlm auth module: %d\n", flag));
+    return flag;
+}
+
+// Check to see if we should use our generic (internal) NTLM auth module.
+static bool
+AllowGenericNTLMforHTTPS(nsIHttpAuthenticableChannel *channel)
+{
+    bool isSSL = false;
+    channel->GetIsSSL(&isSSL);
+    if (!isSSL)
+        return false;
+
+    MOZ_ASSERT(NS_IsMainThread());
+
+    nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
+    if (!prefs)
+        return false;
+
+    bool flag = false;
+    if (NS_FAILED(prefs->GetBoolPref(kAllowGenericHTTPS, &flag)))
+        flag = false;
+
+    LOG(("Allow use of generic ntlm auth module for only https: %d\n", flag));
+    return flag;
+}
+
 // Check to see if we should use default credentials for this host or proxy.
 static bool
 CanUseDefaultCredentials(nsIHttpAuthenticableChannel *channel,
                          bool isProxyAuth)
 {
     nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
     if (!prefs)
         return false;
@@ -293,18 +337,21 @@ nsHttpNTLMAuth::ChallengeReceived(nsIHtt
                 *sessionState = new nsNTLMSessionState();
                 if (!*sessionState)
                     return NS_ERROR_OUT_OF_MEMORY;
                 NS_ADDREF(*sessionState);
             }
 
             // Use our internal NTLM implementation. Note, this is less secure,
             // see bug 520607 for details.
-            LOG(("Trying to fall back on internal ntlm auth.\n"));
-            module = do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "ntlm");
+
+            if (AllowGenericNTLM() || AllowGenericNTLMforHTTPS(channel)) {
+                LOG(("Trying to fall back on internal ntlm auth.\n"));
+                module = do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "ntlm");
+            }
 	
             mUseNative = false;
 
             // Prompt user for domain, username, and password.
             *identityInvalid = true;
         }
 
         // If this fails, then it means that we cannot do NTLM auth.
--- a/security/manager/ssl/src/nsNTLMAuthModule.cpp
+++ b/security/manager/ssl/src/nsNTLMAuthModule.cpp
@@ -10,18 +10,16 @@
 #include "nsNativeCharsetUtils.h"
 #include "prsystem.h"
 #include "pk11pub.h"
 #include "md4.h"
 #include "mozilla/Likely.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Preferences.h"
 
-static bool sNTLMv1Enabled = false;
-
 #ifdef PR_LOGGING
 static PRLogModuleInfo *
 GetNTLMLog()
 {
   static PRLogModuleInfo *sNTLMLog;
   if (!sNTLMLog)
     sNTLMLog = PR_NewLogModule("NTLM");
   return sNTLMLog;
@@ -752,28 +750,16 @@ NS_IMPL_ISUPPORTS(nsNTLMAuthModule, nsIA
 nsNTLMAuthModule::~nsNTLMAuthModule()
 {
   ZapString(mPassword);
 }
 
 nsresult
 nsNTLMAuthModule::InitTest()
 {
-  static bool prefObserved = false;
-  if (!prefObserved) {
-    mozilla::Preferences::AddBoolVarCache(
-      &sNTLMv1Enabled, "network.negotiate-auth.allow-insecure-ntlm-v1", sNTLMv1Enabled);
-    prefObserved = true;
-  }
-
-  if (!sNTLMv1Enabled) {
-    // Unconditionally disallow usage of the generic module.
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
   nsNSSShutDownPreventionLock locker;
   //
   // disable NTLM authentication when FIPS mode is enabled.
   //
   return PK11_IsFIPS() ? NS_ERROR_NOT_AVAILABLE : NS_OK;
 }
 
 NS_IMETHODIMP