Bug 1046421 - Do not disclose the system hostname via NTLM handler. r=honzab
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Fri, 24 Jul 2015 13:36:11 +1200
changeset 286809 bf5fd6a7021ee8295db3160d7ddbc3db942db575
parent 286808 147b08201ced49b0059aefc2a6927bbb02ece874
child 286810 1a4960f6c56e401de4baaa7c52a39b3bca8bbec7
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershonzab
bugs1046421
milestone42.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 1046421 - Do not disclose the system hostname via NTLM handler. r=honzab The hostname here is matched on the AD DC to the userWorkstations attribute, however this is on a total trust basis in terms of what the client specifies here. The impact of this patch is that a user who is restricted by this attribute to log on to only certain (Windows, in reality) workstations, may not be able to perform a manual NTLM logon to an intranet site, unless they set network.generic-ntlm-auth.workstation to the name of their workstation (actually, any host in that list). The default value is set to WORKSTATION. This patch was originally written by Andrew Bartlett, and modified by Douglas Bagnall following review feedback from Honza Bambas and Tim Brown. Signed-off-by: Andrew Bartlett <abartlet@samba.org> Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
modules/libpref/init/all.js
security/manager/ssl/nsNTLMAuthModule.cpp
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1761,16 +1761,26 @@ pref("network.auth.force-generic-ntlm", 
 // The following prefs are used to enable automatic use of the operating
 // system's NTLM implementation to silently authenticate the user with their
 // Window's domain logon.  The trusted-uris pref follows the format of the
 // trusted-uris pref for negotiate authentication.
 pref("network.automatic-ntlm-auth.allow-proxies", true);
 pref("network.automatic-ntlm-auth.allow-non-fqdn", false);
 pref("network.automatic-ntlm-auth.trusted-uris", "");
 
+// The string to return to the server as the 'workstation' that the
+// user is using.  Bug 1046421 notes that the previous default, of the
+// system hostname, could be used for user fingerprinting.
+//
+// However, in some network environments where allowedWorkstations is in use
+// to provide a level of host-based access control, it must be set to a string
+// that is listed in allowedWorkstations for the user's account in their
+// AD Domain.
+pref("network.generic-ntlm-auth.workstation", "WORKSTATION");
+
 // Sub-resources HTTP-authentication:
 //   0 - don't allow sub-resources to open HTTP authentication credentials
 //       dialogs
 //   1 - allow sub-resources to open HTTP authentication credentials dialogs,
 //       but don't allow it for cross-origin sub-resources
 //   2 - allow the cross-origin authentication as well.
 pref("network.auth.allow-subresource-auth", 1);
 
--- a/security/manager/ssl/nsNTLMAuthModule.cpp
+++ b/security/manager/ssl/nsNTLMAuthModule.cpp
@@ -534,17 +534,17 @@ GenerateType3Msg(const nsString &domain,
                  const nsString &username,
                  const nsString &password,
                  const void     *inBuf,
                  uint32_t        inLen,
                  void          **outBuf,
                  uint32_t       *outLen)
 {
   // inBuf contains Type-2 msg (the challenge) from server
-
+  MOZ_ASSERT(NS_IsMainThread());
   nsresult rv;
   Type2Msg msg;
 
   rv = ParseType2Msg(inBuf, inLen, &msg);
   if (NS_FAILED(rv))
     return rv;
 
   bool unicode = (msg.flags & NTLM_NegotiateUnicode);
@@ -552,16 +552,17 @@ GenerateType3Msg(const nsString &domain,
   // There is no negotiation for NTLMv2, so we just do it unless we are forced
   // by explict user configuration to use the older DES-based cryptography.
   bool ntlmv2 = (sNTLMv1Forced == false);
 
   // temporary buffers for unicode strings
 #ifdef IS_BIG_ENDIAN
   nsAutoString ucsDomainBuf, ucsUserBuf;
 #endif
+  nsAutoCString hostBuf;
   nsAutoString ucsHostBuf; 
   // temporary buffers for oem strings
   nsAutoCString oemDomainBuf, oemUserBuf, oemHostBuf;
   // pointers and lengths for the string buffers; encoding is unicode if
   // the "negotiate unicode" flag was set in the Type-2 message.
   const void *domainPtr, *userPtr, *hostPtr;
   uint32_t domainLen, userLen, hostLen;
 
@@ -610,35 +611,40 @@ GenerateType3Msg(const nsString &domain,
   else
   {
     NS_CopyUnicodeToNative(username, oemUserBuf);
     userPtr = oemUserBuf.get();
     userLen = oemUserBuf.Length();
   }
 
   //
-  // get workstation name (use local machine's hostname)
+  // get workstation name
+  // (do not use local machine's hostname after bug 1046421)
   //
-  char hostBuf[SYS_INFO_BUFFER_LENGTH];
-  if (PR_GetSystemInfo(PR_SI_HOSTNAME, hostBuf, sizeof(hostBuf)) == PR_FAILURE)
-    return NS_ERROR_UNEXPECTED;
-  hostLen = strlen(hostBuf);
+  rv = mozilla::Preferences::GetCString("network.generic-ntlm-auth.workstation",
+                                        &hostBuf);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
   if (unicode)
   {
-    // hostname is ASCII, so we can do a simple zero-pad expansion:
-    CopyASCIItoUTF16(nsDependentCString(hostBuf, hostLen), ucsHostBuf);
+    ucsHostBuf = NS_ConvertUTF8toUTF16(hostBuf);
     hostPtr = ucsHostBuf.get();
     hostLen = ucsHostBuf.Length() * 2;
 #ifdef IS_BIG_ENDIAN
     WriteUnicodeLE((void *) hostPtr, reinterpret_cast<const char16_t*> (hostPtr),
                    ucsHostBuf.Length());
 #endif
   }
   else
-    hostPtr = hostBuf;
+  {
+    hostPtr = hostBuf.get();
+    hostLen = hostBuf.Length();
+  }
 
   //
   // now that we have generated all of the strings, we can allocate outBuf.
   //
   //
   // next, we compute the NTLM or NTLM2 responses.
   //
   uint8_t lmResp[LM_RESP_LEN];