Bug 887984 - Send telemetry data from NTLM Init() methods. r=honzab
authorAdrian Lungu <alungu@mozilla.com>
Thu, 25 Jul 2013 09:54:11 -0700
changeset 153607 6364e33d76f5b456cd78377402727df544351d1d
parent 153606 a69d0630fb0616ee55002c57dfdeae4a5169c52c
child 153608 1774aaaad96a25a102a86bc611e113fece8755d5
push id382
push userakeybl@mozilla.com
push dateMon, 21 Oct 2013 21:47:13 +0000
treeherdermozilla-release@5f1868ee45cb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershonzab
bugs887984
milestone25.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 887984 - Send telemetry data from NTLM Init() methods. r=honzab
extensions/auth/nsAuthGSSAPI.cpp
extensions/auth/nsAuthSSPI.cpp
extensions/auth/nsAuthSSPI.h
extensions/auth/nsAuthSambaNTLM.cpp
extensions/auth/nsHttpNegotiateAuth.cpp
netwerk/base/public/nsIAuthModule.idl
netwerk/protocol/http/nsHttpNTLMAuth.cpp
security/manager/ssl/src/nsNTLMAuthModule.cpp
toolkit/components/telemetry/Histograms.json
--- a/extensions/auth/nsAuthGSSAPI.cpp
+++ b/extensions/auth/nsAuthGSSAPI.cpp
@@ -17,16 +17,17 @@
 #include "mozilla/Util.h"
 
 #include "prlink.h"
 #include "nsCOMPtr.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsIServiceManager.h"
 #include "nsNativeCharsetUtils.h"
+#include "mozilla/Telemetry.h"
 
 #include "nsAuthGSSAPI.h"
 
 #ifdef XP_MACOSX
 #include <Kerberos/Kerberos.h>
 #endif
 
 #ifdef XP_MACOSX
@@ -348,16 +349,27 @@ nsAuthGSSAPI::Init(const char *serviceNa
 
     LOG(("entering nsAuthGSSAPI::Init()\n"));
 
     if (!gssLibrary)
        return NS_ERROR_NOT_INITIALIZED;
 
     mServiceName = serviceName;
     mServiceFlags = serviceFlags;
+
+    static bool sTelemetrySent = false;
+    if (!sTelemetrySent) {
+        mozilla::Telemetry::Accumulate(
+            mozilla::Telemetry::NTLM_MODULE_USED,
+            serviceFlags | nsIAuthModule::REQ_PROXY_AUTH
+                ? NTLM_MODULE_KERBEROS_PROXY
+                : NTLM_MODULE_KERBEROS_DIRECT);
+        sTelemetrySent = true;
+    }
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAuthGSSAPI::GetNextToken(const void *inToken,
                            uint32_t    inTokenLen,
                            void      **outToken,
                            uint32_t   *outTokenLen)
--- a/extensions/auth/nsAuthSSPI.cpp
+++ b/extensions/auth/nsAuthSSPI.cpp
@@ -15,16 +15,17 @@
 
 #include "nsAuthSSPI.h"
 #include "nsIServiceManager.h"
 #include "nsIDNSService.h"
 #include "nsIDNSRecord.h"
 #include "nsNetCID.h"
 #include "nsCOMPtr.h"
 #include "nsICryptoHash.h"
+#include "mozilla/Telemetry.h"
 
 #include <windows.h>
 
 #define SEC_SUCCESS(Status) ((Status) >= 0)
 
 #ifndef KERB_WRAP_NO_ENCRYPT
 #define KERB_WRAP_NO_ENCRYPT 0x80000001
 #endif
@@ -234,17 +235,17 @@ nsAuthSSPI::Init(const char *serviceName
     rc = (sspi->QuerySecurityPackageInfoW)(package, &pinfo);
     if (rc != SEC_E_OK) {
         LOG(("%s package not found\n", package));
         return NS_ERROR_UNEXPECTED;
     }
     mMaxTokenLen = pinfo->cbMaxToken;
     (sspi->FreeContextBuffer)(pinfo);
 
-    TimeStamp useBefore;
+    MS_TimeStamp useBefore;
 
     SEC_WINNT_AUTH_IDENTITY_W ai;
     SEC_WINNT_AUTH_IDENTITY_W *pai = nullptr;
     
     // domain, username, and password will be null if nsHttpNTLMAuth's ChallengeReceived
     // returns false for identityInvalid. Use default credentials in this case by passing
     // null for pai.
     if (username && password) {
@@ -268,16 +269,27 @@ nsAuthSSPI::Init(const char *serviceName
                                            nullptr,
                                            pai,
                                            nullptr,
                                            nullptr,
                                            &mCred,
                                            &useBefore);
     if (rc != SEC_E_OK)
         return NS_ERROR_UNEXPECTED;
+
+    static bool sTelemetrySent = false;
+    if (!sTelemetrySent) {
+        mozilla::Telemetry::Accumulate(
+            mozilla::Telemetry::NTLM_MODULE_USED,
+            serviceFlags | nsIAuthModule::REQ_PROXY_AUTH
+                ? NTLM_MODULE_WIN_API_PROXY
+                : NTLM_MODULE_WIN_API_DIRECT);
+        sTelemetrySent = true;
+    }
+
     LOG(("AcquireCredentialsHandle() succeeded.\n"));
     return NS_OK;
 }
 
 // The arguments inToken and inTokenLen are used to pass in the server
 // certificate (when available) in the first call of the function. The
 // second time these arguments hold an input token. 
 NS_IMETHODIMP
@@ -288,17 +300,17 @@ nsAuthSSPI::GetNextToken(const void *inT
 {
     // String for end-point bindings.
     const char end_point[] = "tls-server-end-point:"; 
     const int end_point_length = sizeof(end_point) - 1;
     const int hash_size = 32;  // Size of a SHA256 hash.
     const int cbt_size = hash_size + end_point_length;
 	
     SECURITY_STATUS rc;
-    TimeStamp ignored;
+    MS_TimeStamp ignored;
 
     DWORD ctxAttr, ctxReq = 0;
     CtxtHandle *ctxIn;
     SecBufferDesc ibd, obd;
     // Optional second input buffer for the CBT (Channel Binding Token)
     SecBuffer ib[2], ob;
     // Pointer to the block of memory that stores the CBT
     char* sspi_cbt = nullptr;
--- a/extensions/auth/nsAuthSSPI.h
+++ b/extensions/auth/nsAuthSSPI.h
@@ -34,16 +34,18 @@ public:
 
     nsAuthSSPI(pType package = PACKAGE_TYPE_NEGOTIATE);
 
 private:
     ~nsAuthSSPI();
 
     void Reset();
 
+    typedef TimeStamp MS_TimeStamp;
+
 private:
     CredHandle   mCred;
     CtxtHandle   mCtxt;
     nsCString    mServiceName;
     uint32_t     mServiceFlags;
     uint32_t     mMaxTokenLen;
     pType        mPackage;
     nsString     mDomain;
--- a/extensions/auth/nsAuthSambaNTLM.cpp
+++ b/extensions/auth/nsAuthSambaNTLM.cpp
@@ -3,16 +3,17 @@
  * 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/. */
 
 #include "nsAuth.h"
 #include "nsAuthSambaNTLM.h"
 #include "prenv.h"
 #include "plbase64.h"
 #include "prerror.h"
+#include "mozilla/Telemetry.h"
 
 #include <stdlib.h>
 
 nsAuthSambaNTLM::nsAuthSambaNTLM()
     : mInitialMessage(nullptr), mChildPID(nullptr), mFromChildFD(nullptr),
       mToChildFD(nullptr)
 {
 }
@@ -205,16 +206,27 @@ nsAuthSambaNTLM::SpawnNTLMAuthHelper()
 NS_IMETHODIMP
 nsAuthSambaNTLM::Init(const char *serviceName,
                       uint32_t    serviceFlags,
                       const PRUnichar *domain,
                       const PRUnichar *username,
                       const PRUnichar *password)
 {
     NS_ASSERTION(!username && !domain && !password, "unexpected credentials");
+
+    static bool sTelemetrySent = false;
+    if (!sTelemetrySent) {
+        mozilla::Telemetry::Accumulate(
+            mozilla::Telemetry::NTLM_MODULE_USED,
+            serviceFlags | nsIAuthModule::REQ_PROXY_AUTH
+                ? NTLM_MODULE_SAMBA_AUTH_PROXY
+                : NTLM_MODULE_SAMBA_AUTH_DIRECT);
+        sTelemetrySent = true;
+    }
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAuthSambaNTLM::GetNextToken(const void *inToken,
                               uint32_t    inTokenLen,
                               void      **outToken,
                               uint32_t   *outTokenLen)
--- a/extensions/auth/nsHttpNegotiateAuth.cpp
+++ b/extensions/auth/nsHttpNegotiateAuth.cpp
@@ -99,16 +99,17 @@ nsHttpNegotiateAuth::ChallengeReceived(n
     nsAutoCString service;
 
     if (isProxyAuth) {
         if (!TestBoolPref(kNegotiateAuthAllowProxies)) {
             LOG(("nsHttpNegotiateAuth::ChallengeReceived proxy auth blocked\n"));
             return NS_ERROR_ABORT;
         }
 
+        req_flags |= nsIAuthModule::REQ_PROXY_AUTH;
         nsCOMPtr<nsIProxyInfo> proxyInfo;
         authChannel->GetProxyInfo(getter_AddRefs(proxyInfo));
         NS_ENSURE_STATE(proxyInfo);
 
         proxyInfo->GetHost(service);
     }
     else {
         bool allowed = TestNonFqdn(uri) ||
--- a/netwerk/base/public/nsIAuthModule.idl
+++ b/netwerk/base/public/nsIAuthModule.idl
@@ -19,16 +19,33 @@ interface nsIAuthModule : nsISupports
 
     /**
      * The server is allowed to impersonate the client.  The REQ_MUTUAL_AUTH
      * flag may also need to be specified in order for this flag to take
      * effect.
      */
     const unsigned long REQ_DELEGATE = (1 << 1);
 
+    /**
+     * The authentication is required for a proxy connection.
+     */
+    const unsigned long REQ_PROXY_AUTH = (1 << 2);
+
+    /**
+     * Flags used for telemetry.
+     */
+    const unsigned long NTLM_MODULE_SAMBA_AUTH_PROXY = 0;
+    const unsigned long NTLM_MODULE_SAMBA_AUTH_DIRECT = 1;
+    const unsigned long NTLM_MODULE_WIN_API_PROXY = 2;
+    const unsigned long NTLM_MODULE_WIN_API_DIRECT = 3;
+    const unsigned long NTLM_MODULE_GENERIC_PROXY = 4;
+    const unsigned long NTLM_MODULE_GENERIC_DIRECT = 5;
+    const unsigned long NTLM_MODULE_KERBEROS_PROXY = 6;
+    const unsigned long NTLM_MODULE_KERBEROS_DIRECT = 7;
+
     /** Other flags may be defined in the future */
 
     /**
      * Called to initialize an auth module.  The other methods cannot be called
      * unless this method succeeds.
      *
      * @param aServiceName
      *        the service name, which may be null if not applicable (e.g., for
--- a/netwerk/protocol/http/nsHttpNTLMAuth.cpp
+++ b/netwerk/protocol/http/nsHttpNTLMAuth.cpp
@@ -359,17 +359,21 @@ nsHttpNTLMAuth::GenerateCredentials(nsIH
             return rv;
         nsAutoCString serviceName, host;
         rv = uri->GetAsciiHost(host);
         if (NS_FAILED(rv))
             return rv;
         serviceName.AppendLiteral("HTTP@");
         serviceName.Append(host);
         // initialize auth module
-        rv = module->Init(serviceName.get(), nsIAuthModule::REQ_DEFAULT, domain, user, pass);
+        uint32_t reqFlags = nsIAuthModule::REQ_DEFAULT;
+        if (isProxyAuth)
+            reqFlags |= nsIAuthModule::REQ_PROXY_AUTH;
+
+        rv = module->Init(serviceName.get(), reqFlags, domain, user, pass);
         if (NS_FAILED(rv))
             return rv;
 
 // This update enables updated Windows machines (Win7 or patched previous
 // versions) and Linux machines running Samba (updated for Channel
 // Binding), to perform Channel Binding when authenticating using NTLMv2
 // and an outer secure channel.
 //
--- a/security/manager/ssl/src/nsNTLMAuthModule.cpp
+++ b/security/manager/ssl/src/nsNTLMAuthModule.cpp
@@ -7,16 +7,17 @@
 
 #include "nsNTLMAuthModule.h"
 #include "nsNSSShutDown.h"
 #include "nsNativeCharsetUtils.h"
 #include "prsystem.h"
 #include "pk11pub.h"
 #include "md4.h"
 #include "mozilla/Likely.h"
+#include "mozilla/Telemetry.h"
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo *
 GetNTLMLog()
 {
   static PRLogModuleInfo *sNTLMLog;
   if (!sNTLMLog)
     sNTLMLog = PR_NewLogModule("NTLM");
@@ -762,21 +763,33 @@ nsNTLMAuthModule::InitTest()
 
 NS_IMETHODIMP
 nsNTLMAuthModule::Init(const char      *serviceName,
                        uint32_t         serviceFlags,
                        const PRUnichar *domain,
                        const PRUnichar *username,
                        const PRUnichar *password)
 {
-  NS_ASSERTION(serviceFlags == nsIAuthModule::REQ_DEFAULT, "unexpected service flags");
+  NS_ASSERTION((serviceFlags & ~nsIAuthModule::REQ_PROXY_AUTH) == nsIAuthModule::REQ_DEFAULT,
+      "unexpected service flags");
 
   mDomain = domain;
   mUsername = username;
   mPassword = password;
+
+  static bool sTelemetrySent = false;
+  if (!sTelemetrySent) {
+      mozilla::Telemetry::Accumulate(
+          mozilla::Telemetry::NTLM_MODULE_USED,
+          serviceFlags | nsIAuthModule::REQ_PROXY_AUTH
+              ? NTLM_MODULE_GENERIC_PROXY
+              : NTLM_MODULE_GENERIC_DIRECT);
+      sTelemetrySent = true;
+  }
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNTLMAuthModule::GetNextToken(const void *inToken,
                                uint32_t    inTokenLen,
                                void      **outToken,
                                uint32_t   *outTokenLen)
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -3738,16 +3738,21 @@
     "kind": "boolean",
     "description": "The result of the startup default desktop browser check."
   },
   "MIXED_CONTENT_PAGE_LOAD": {
     "kind": "enumerated",
     "n_values": 4,
     "description": "Accumulates type of content (mixed, mixed passive, unmixed) per page load"
   },
+  "NTLM_MODULE_USED": {
+    "kind": "enumerated",
+    "n_values": 8,
+    "description": "The module used for the NTLM protocol (Windows_API, Kerberos, Samba_auth or Generic) and whether or not the authentication was used to connect to a proxy server. This data is collected only once per session (at first NTLM authentification)."
+  },
   "FX_THUMBNAILS_BG_QUEUE_SIZE_ON_CAPTURE": {
     "kind": "exponential",
     "high": 100,
     "n_buckets": 15,
     "extended_statistics_ok": true,
     "description": "BACKGROUND THUMBNAILS: Size of capture queue when a capture request is received"
   },
   "FX_THUMBNAILS_BG_CAPTURE_QUEUE_TIME_MS": {