LCOV - code coverage report
Current view: directory - netwerk/protocol/http - nsHttpNTLMAuth.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 172 64 37.2 %
Date: 2012-06-02 Functions: 15 11 73.3 %

       1                 : /* vim:set ts=4 sw=4 sts=4 et ci: */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Mozilla.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2003
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Darin Fisher <darin@meer.net>
      24                 :  *   Jim Mathies <jmathies@mozilla.com>
      25                 :  *   Guillermo Robla Vicario <groblavicario@gmail.com>
      26                 :  *
      27                 :  * Alternatively, the contents of this file may be used under the terms of
      28                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      29                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      31                 :  * of those above. If you wish to allow use of your version of this file only
      32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      33                 :  * use your version of this file under the terms of the MPL, indicate your
      34                 :  * decision by deleting the provisions above and replace them with the notice
      35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      36                 :  * the provisions above, a recipient may use your version of this file under
      37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      38                 :  *
      39                 :  * ***** END LICENSE BLOCK ***** */
      40                 : 
      41                 : #include <stdlib.h>
      42                 : #include "nsHttp.h"
      43                 : #include "nsHttpNTLMAuth.h"
      44                 : #include "nsIComponentManager.h"
      45                 : #include "nsIAuthModule.h"
      46                 : #include "nsCOMPtr.h"
      47                 : #include "plbase64.h"
      48                 : #include "prnetdb.h"
      49                 : 
      50                 : //-----------------------------------------------------------------------------
      51                 : 
      52                 : #include "nsIPrefBranch.h"
      53                 : #include "nsIPrefService.h"
      54                 : #include "nsIServiceManager.h"
      55                 : #include "nsIHttpAuthenticableChannel.h"
      56                 : #include "nsIURI.h"
      57                 : #include "nsIX509Cert.h"
      58                 : #include "nsISSLStatus.h"
      59                 : #include "nsISSLStatusProvider.h"
      60                 : 
      61                 : static const char kAllowProxies[] = "network.automatic-ntlm-auth.allow-proxies";
      62                 : static const char kAllowNonFqdn[] = "network.automatic-ntlm-auth.allow-non-fqdn";
      63                 : static const char kTrustedURIs[]  = "network.automatic-ntlm-auth.trusted-uris";
      64                 : static const char kForceGeneric[] = "network.auth.force-generic-ntlm";
      65                 : 
      66                 : // XXX MatchesBaseURI and TestPref are duplicated in nsHttpNegotiateAuth.cpp,
      67                 : // but since that file lives in a separate library we cannot directly share it.
      68                 : // bug 236865 addresses this problem.
      69                 : 
      70                 : static bool
      71               0 : MatchesBaseURI(const nsCSubstring &matchScheme,
      72                 :                const nsCSubstring &matchHost,
      73                 :                PRInt32             matchPort,
      74                 :                const char         *baseStart,
      75                 :                const char         *baseEnd)
      76                 : {
      77                 :     // check if scheme://host:port matches baseURI
      78                 : 
      79                 :     // parse the base URI
      80               0 :     const char *hostStart, *schemeEnd = strstr(baseStart, "://");
      81               0 :     if (schemeEnd) {
      82                 :         // the given scheme must match the parsed scheme exactly
      83               0 :         if (!matchScheme.Equals(Substring(baseStart, schemeEnd)))
      84               0 :             return false;
      85               0 :         hostStart = schemeEnd + 3;
      86                 :     }
      87                 :     else
      88               0 :         hostStart = baseStart;
      89                 : 
      90                 :     // XXX this does not work for IPv6-literals
      91               0 :     const char *hostEnd = strchr(hostStart, ':');
      92               0 :     if (hostEnd && hostEnd < baseEnd) {
      93                 :         // the given port must match the parsed port exactly
      94               0 :         int port = atoi(hostEnd + 1);
      95               0 :         if (matchPort != (PRInt32) port)
      96               0 :             return false;
      97                 :     }
      98                 :     else
      99               0 :         hostEnd = baseEnd;
     100                 : 
     101                 : 
     102                 :     // if we didn't parse out a host, then assume we got a match.
     103               0 :     if (hostStart == hostEnd)
     104               0 :         return true;
     105                 : 
     106               0 :     PRUint32 hostLen = hostEnd - hostStart;
     107                 : 
     108                 :     // matchHost must either equal host or be a subdomain of host
     109               0 :     if (matchHost.Length() < hostLen)
     110               0 :         return false;
     111                 : 
     112               0 :     const char *end = matchHost.EndReading();
     113               0 :     if (PL_strncasecmp(end - hostLen, hostStart, hostLen) == 0) {
     114                 :         // if matchHost ends with host from the base URI, then make sure it is
     115                 :         // either an exact match, or prefixed with a dot.  we don't want
     116                 :         // "foobar.com" to match "bar.com"
     117               0 :         if (matchHost.Length() == hostLen ||
     118               0 :             *(end - hostLen) == '.' ||
     119               0 :             *(end - hostLen - 1) == '.')
     120               0 :             return true;
     121                 :     }
     122                 : 
     123               0 :     return false;
     124                 : }
     125                 : 
     126                 : static bool
     127               0 : IsNonFqdn(nsIURI *uri)
     128                 : {
     129               0 :     nsCAutoString host;
     130                 :     PRNetAddr addr;
     131                 : 
     132               0 :     if (NS_FAILED(uri->GetAsciiHost(host)))
     133               0 :         return false;
     134                 : 
     135                 :     // return true if host does not contain a dot and is not an ip address
     136               0 :     return !host.IsEmpty() && host.FindChar('.') == kNotFound &&
     137               0 :            PR_StringToNetAddr(host.BeginReading(), &addr) != PR_SUCCESS;
     138                 : }
     139                 : 
     140                 : static bool
     141               1 : TestPref(nsIURI *uri, const char *pref)
     142                 : {
     143               2 :     nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
     144               1 :     if (!prefs)
     145               0 :         return false;
     146                 : 
     147               2 :     nsCAutoString scheme, host;
     148                 :     PRInt32 port;
     149                 : 
     150               1 :     if (NS_FAILED(uri->GetScheme(scheme)))
     151               0 :         return false;
     152               1 :     if (NS_FAILED(uri->GetAsciiHost(host)))
     153               0 :         return false;
     154               1 :     if (NS_FAILED(uri->GetPort(&port)))
     155               0 :         return false;
     156                 : 
     157                 :     char *hostList;
     158               1 :     if (NS_FAILED(prefs->GetCharPref(pref, &hostList)) || !hostList)
     159               0 :         return false;
     160                 : 
     161                 :     // pseudo-BNF
     162                 :     // ----------
     163                 :     //
     164                 :     // url-list       base-url ( base-url "," LWS )*
     165                 :     // base-url       ( scheme-part | host-part | scheme-part host-part )
     166                 :     // scheme-part    scheme "://"
     167                 :     // host-part      host [":" port]
     168                 :     //
     169                 :     // for example:
     170                 :     //   "https://, http://office.foo.com"
     171                 :     //
     172                 : 
     173               1 :     char *start = hostList, *end;
     174               0 :     for (;;) {
     175                 :         // skip past any whitespace
     176               2 :         while (*start == ' ' || *start == '\t')
     177               0 :             ++start;
     178               1 :         end = strchr(start, ',');
     179               1 :         if (!end)
     180               1 :             end = start + strlen(start);
     181               1 :         if (start == end)
     182               1 :             break;
     183               0 :         if (MatchesBaseURI(scheme, host, port, start, end))
     184               0 :             return true;
     185               0 :         if (*end == '\0')
     186               0 :             break;
     187               0 :         start = end + 1;
     188                 :     }
     189                 :     
     190               1 :     nsMemory::Free(hostList);
     191               1 :     return false;
     192                 : }
     193                 : 
     194                 : // Check to see if we should use our generic (internal) NTLM auth module.
     195                 : static bool
     196               1 : ForceGenericNTLM()
     197                 : {
     198               2 :     nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
     199               1 :     if (!prefs)
     200               0 :         return false;
     201               1 :     bool flag = false;
     202                 : 
     203               1 :     if (NS_FAILED(prefs->GetBoolPref(kForceGeneric, &flag)))
     204               0 :         flag = false;
     205                 : 
     206               1 :     LOG(("Force use of generic ntlm auth module: %d\n", flag));
     207               1 :     return flag;
     208                 : }
     209                 : 
     210                 : // Check to see if we should use default credentials for this host or proxy.
     211                 : static bool
     212               1 : CanUseDefaultCredentials(nsIHttpAuthenticableChannel *channel,
     213                 :                          bool isProxyAuth)
     214                 : {
     215               2 :     nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
     216               1 :     if (!prefs)
     217               0 :         return false;
     218                 : 
     219               1 :     if (isProxyAuth) {
     220                 :         bool val;
     221               0 :         if (NS_FAILED(prefs->GetBoolPref(kAllowProxies, &val)))
     222               0 :             val = false;
     223               0 :         LOG(("Default credentials allowed for proxy: %d\n", val));
     224               0 :         return val;
     225                 :     }
     226                 : 
     227               2 :     nsCOMPtr<nsIURI> uri;
     228               1 :     channel->GetURI(getter_AddRefs(uri));
     229                 : 
     230                 :     bool allowNonFqdn;
     231               1 :     if (NS_FAILED(prefs->GetBoolPref(kAllowNonFqdn, &allowNonFqdn)))
     232               0 :         allowNonFqdn = false;
     233               1 :     if (allowNonFqdn && uri && IsNonFqdn(uri)) {
     234               0 :         LOG(("Host is non-fqdn, default credentials are allowed\n"));
     235               0 :         return true;
     236                 :     }
     237                 : 
     238               1 :     bool isTrustedHost = (uri && TestPref(uri, kTrustedURIs));
     239               1 :     LOG(("Default credentials allowed for host: %d\n", isTrustedHost));
     240               1 :     return isTrustedHost;
     241                 : }
     242                 : 
     243                 : // Dummy class for session state object.  This class doesn't hold any data.
     244                 : // Instead we use its existence as a flag.  See ChallengeReceived.
     245                 : class nsNTLMSessionState : public nsISupports
     246               1 : {
     247                 : public:
     248                 :     NS_DECL_ISUPPORTS
     249                 : };
     250               3 : NS_IMPL_ISUPPORTS0(nsNTLMSessionState)
     251                 : 
     252                 : //-----------------------------------------------------------------------------
     253                 : 
     254              12 : NS_IMPL_ISUPPORTS1(nsHttpNTLMAuth, nsIHttpAuthenticator)
     255                 : 
     256                 : NS_IMETHODIMP
     257               1 : nsHttpNTLMAuth::ChallengeReceived(nsIHttpAuthenticableChannel *channel,
     258                 :                                   const char     *challenge,
     259                 :                                   bool            isProxyAuth,
     260                 :                                   nsISupports   **sessionState,
     261                 :                                   nsISupports   **continuationState,
     262                 :                                   bool           *identityInvalid)
     263                 : {
     264               1 :     LOG(("nsHttpNTLMAuth::ChallengeReceived [ss=%p cs=%p]\n",
     265                 :          *sessionState, *continuationState));
     266                 : 
     267                 :     // Use the native NTLM if available
     268               1 :     mUseNative = true;
     269                 : 
     270                 :     // NOTE: we don't define any session state, but we do use the pointer.
     271                 : 
     272               1 :     *identityInvalid = false;
     273                 : 
     274                 :     // Start a new auth sequence if the challenge is exactly "NTLM".
     275                 :     // If native NTLM auth apis are available and enabled through prefs,
     276                 :     // try to use them.
     277               1 :     if (PL_strcasecmp(challenge, "NTLM") == 0) {
     278               2 :         nsCOMPtr<nsISupports> module;
     279                 : 
     280                 :         // Check to see if we should default to our generic NTLM auth module
     281                 :         // through UseGenericNTLM. (We use native auth by default if the
     282                 :         // system provides it.) If *sessionState is non-null, we failed to
     283                 :         // instantiate a native NTLM module the last time, so skip trying again.
     284               1 :         bool forceGeneric = ForceGenericNTLM();
     285               1 :         if (!forceGeneric && !*sessionState) {
     286                 :             // Check for approved default credentials hosts and proxies. If 
     287                 :             // *continuationState is non-null, the last authentication attempt
     288                 :             // failed so skip default credential use.
     289               1 :             if (!*continuationState && CanUseDefaultCredentials(channel, isProxyAuth)) {
     290                 :                 // Try logging in with the user's default credentials. If
     291                 :                 // successful, |identityInvalid| is false, which will trigger
     292                 :                 // a default credentials attempt once we return.
     293               0 :                 module = do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "sys-ntlm");
     294                 :             }
     295                 : #ifdef XP_WIN
     296                 :             else {
     297                 :                 // Try to use native NTLM and prompt the user for their domain,
     298                 :                 // username, and password. (only supported by windows nsAuthSSPI module.)
     299                 :                 // Note, for servers that use LMv1 a weak hash of the user's password
     300                 :                 // will be sent. We rely on windows internal apis to decide whether
     301                 :                 // we should support this older, less secure version of the protocol.
     302                 :                 module = do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "sys-ntlm");
     303                 :                 *identityInvalid = true;
     304                 :             }
     305                 : #endif // XP_WIN
     306                 : #ifdef PR_LOGGING
     307               1 :             if (!module)
     308               1 :                 LOG(("Native sys-ntlm auth module not found.\n"));
     309                 : #endif
     310                 :         }
     311                 : 
     312                 : #ifdef XP_WIN
     313                 :         // On windows, never fall back unless the user has specifically requested so.
     314                 :         if (!forceGeneric && !module)
     315                 :             return NS_ERROR_UNEXPECTED;
     316                 : #endif
     317                 : 
     318                 :         // If no native support was available. Fall back on our internal NTLM implementation.
     319               1 :         if (!module) {
     320               1 :             if (!*sessionState) {
     321                 :                 // Remember the fact that we cannot use the "sys-ntlm" module,
     322                 :                 // so we don't ever bother trying again for this auth domain.
     323               1 :                 *sessionState = new nsNTLMSessionState();
     324               1 :                 if (!*sessionState)
     325               0 :                     return NS_ERROR_OUT_OF_MEMORY;
     326               1 :                 NS_ADDREF(*sessionState);
     327                 :             }
     328                 : 
     329                 :             // Use our internal NTLM implementation. Note, this is less secure,
     330                 :             // see bug 520607 for details.
     331               1 :             LOG(("Trying to fall back on internal ntlm auth.\n"));
     332               1 :             module = do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "ntlm");
     333                 :             
     334               1 :             mUseNative = false;
     335                 : 
     336                 :             // Prompt user for domain, username, and password.
     337               1 :             *identityInvalid = true;
     338                 :         }
     339                 : 
     340                 :         // If this fails, then it means that we cannot do NTLM auth.
     341               1 :         if (!module) {
     342               0 :             LOG(("No ntlm auth modules available.\n"));
     343               0 :             return NS_ERROR_UNEXPECTED;
     344                 :         }
     345                 : 
     346                 :         // A non-null continuation state implies that we failed to authenticate.
     347                 :         // Blow away the old authentication state, and use the new one.
     348               2 :         module.swap(*continuationState);
     349                 :     }
     350               1 :     return NS_OK;
     351                 : }
     352                 : 
     353                 : NS_IMETHODIMP
     354               0 : nsHttpNTLMAuth::GenerateCredentials(nsIHttpAuthenticableChannel *authChannel,
     355                 :                                     const char      *challenge,
     356                 :                                     bool             isProxyAuth,
     357                 :                                     const PRUnichar *domain,
     358                 :                                     const PRUnichar *user,
     359                 :                                     const PRUnichar *pass,
     360                 :                                     nsISupports    **sessionState,
     361                 :                                     nsISupports    **continuationState,
     362                 :                                     PRUint32       *aFlags,
     363                 :                                     char           **creds)
     364                 : 
     365                 : {
     366               0 :     LOG(("nsHttpNTLMAuth::GenerateCredentials\n"));
     367                 : 
     368               0 :     *creds = nsnull;
     369               0 :     *aFlags = 0;
     370                 : 
     371                 :     // if user or password is empty, ChallengeReceived returned
     372                 :     // identityInvalid = false, that means we are using default user
     373                 :     // credentials; see  nsAuthSSPI::Init method for explanation of this 
     374                 :     // condition
     375               0 :     if (!user || !pass)
     376               0 :         *aFlags = USING_INTERNAL_IDENTITY;
     377                 : 
     378                 :     nsresult rv;
     379               0 :     nsCOMPtr<nsIAuthModule> module = do_QueryInterface(*continuationState, &rv);
     380               0 :     NS_ENSURE_SUCCESS(rv, rv);
     381                 : 
     382                 :     void *inBuf, *outBuf;
     383                 :     PRUint32 inBufLen, outBufLen;
     384                 : 
     385                 :     // initial challenge
     386               0 :     if (PL_strcasecmp(challenge, "NTLM") == 0) {
     387                 :         // NTLM service name format is 'HTTP@host' for both http and https
     388               0 :         nsCOMPtr<nsIURI> uri;
     389               0 :         rv = authChannel->GetURI(getter_AddRefs(uri));
     390               0 :         if (NS_FAILED(rv))
     391               0 :             return rv;
     392               0 :         nsCAutoString serviceName, host;
     393               0 :         rv = uri->GetAsciiHost(host);
     394               0 :         if (NS_FAILED(rv))
     395               0 :             return rv;
     396               0 :         serviceName.AppendLiteral("HTTP@");
     397               0 :         serviceName.Append(host);
     398                 :         // initialize auth module
     399               0 :         rv = module->Init(serviceName.get(), nsIAuthModule::REQ_DEFAULT, domain, user, pass);
     400               0 :         if (NS_FAILED(rv))
     401               0 :             return rv;
     402                 : 
     403                 : // This update enables updated Windows machines (Win7 or patched previous
     404                 : // versions) and Linux machines running Samba (updated for Channel 
     405                 : // Binding), to perform Channel Binding when authenticating using NTLMv2 
     406                 : // and an outer secure channel.
     407                 : // 
     408                 : // Currently only implemented for Windows, linux support will be landing in 
     409                 : // a separate patch, update this #ifdef accordingly then.
     410                 : #if defined (XP_WIN) /* || defined (LINUX) */
     411                 :         // We should retrieve the server certificate and compute the CBT, 
     412                 :         // but only when we are using the native NTLM implementation and 
     413                 :         // not the internal one.
     414                 :         // It is a valid case not having the security info object.  This
     415                 :         // occures when we connect an https site through an ntlm proxy.
     416                 :         // After the ssl tunnel has been created, we get here the second
     417                 :         // time and now generate the CBT from now valid security info.
     418                 :         nsCOMPtr<nsIChannel> channel = do_QueryInterface(authChannel, &rv);
     419                 :         if (NS_FAILED(rv))
     420                 :             return rv;
     421                 : 
     422                 :         nsCOMPtr<nsISupports> security;
     423                 :         rv = channel->GetSecurityInfo(getter_AddRefs(security));
     424                 :         if (NS_FAILED(rv))
     425                 :             return rv;
     426                 : 
     427                 :         nsCOMPtr<nsISSLStatusProvider> statusProvider =
     428                 :             do_QueryInterface(security);
     429                 : 
     430                 :         if (mUseNative && statusProvider) {
     431                 :             nsCOMPtr<nsISSLStatus> status;
     432                 :             rv = statusProvider->GetSSLStatus(getter_AddRefs(status));
     433                 :             if (NS_FAILED(rv))
     434                 :                 return rv;
     435                 : 
     436                 :             nsCOMPtr<nsIX509Cert> cert;
     437                 :             rv = status->GetServerCert(getter_AddRefs(cert));
     438                 :             if (NS_FAILED(rv))
     439                 :                 return rv;
     440                 : 
     441                 :             PRUint32 length;
     442                 :             PRUint8* certArray;
     443                 :             cert->GetRawDER(&length, &certArray);                                              
     444                 :                         
     445                 :             // If there is a server certificate, we pass it along the
     446                 :             // first time we call GetNextToken().
     447                 :             inBufLen = length;
     448                 :             inBuf = certArray;
     449                 :         } else { 
     450                 :             // If there is no server certificate, we don't pass anything.
     451                 :             inBufLen = 0;
     452                 :             inBuf = nsnull;
     453                 :         }
     454                 : #else // Extended protection update is just for Linux and Windows machines.
     455               0 :         inBufLen = 0;
     456               0 :         inBuf = nsnull;
     457                 : #endif
     458                 :     }
     459                 :     else {
     460                 :         // decode challenge; skip past "NTLM " to the start of the base64
     461                 :         // encoded data.
     462               0 :         int len = strlen(challenge);
     463               0 :         if (len < 6)
     464               0 :             return NS_ERROR_UNEXPECTED; // bogus challenge
     465               0 :         challenge += 5;
     466               0 :         len -= 5;
     467                 : 
     468                 :         // strip off any padding (see bug 230351)
     469               0 :         while (challenge[len - 1] == '=')
     470               0 :           len--;
     471                 : 
     472                 :         // decode into the input secbuffer
     473               0 :         inBufLen = (len * 3)/4;      // sufficient size (see plbase64.h)
     474               0 :         inBuf = nsMemory::Alloc(inBufLen);
     475               0 :         if (!inBuf)
     476               0 :             return NS_ERROR_OUT_OF_MEMORY;
     477                 : 
     478               0 :         if (PL_Base64Decode(challenge, len, (char *) inBuf) == nsnull) {
     479               0 :             nsMemory::Free(inBuf);
     480               0 :             return NS_ERROR_UNEXPECTED; // improper base64 encoding
     481                 :         }
     482                 :     }
     483                 : 
     484               0 :     rv = module->GetNextToken(inBuf, inBufLen, &outBuf, &outBufLen);
     485               0 :     if (NS_SUCCEEDED(rv)) {
     486                 :         // base64 encode data in output buffer and prepend "NTLM "
     487               0 :         int credsLen = 5 + ((outBufLen + 2)/3)*4;
     488               0 :         *creds = (char *) nsMemory::Alloc(credsLen + 1);
     489               0 :         if (!*creds)
     490               0 :             rv = NS_ERROR_OUT_OF_MEMORY;
     491                 :         else {
     492               0 :             memcpy(*creds, "NTLM ", 5);
     493               0 :             PL_Base64Encode((char *) outBuf, outBufLen, *creds + 5);
     494               0 :             (*creds)[credsLen] = '\0'; // null terminate
     495                 :         }
     496                 :         // OK, we are done with |outBuf|
     497               0 :         nsMemory::Free(outBuf);
     498                 :     }
     499                 : 
     500               0 :     if (inBuf)
     501               0 :         nsMemory::Free(inBuf);
     502                 : 
     503               0 :     return rv;
     504                 : }
     505                 : 
     506                 : NS_IMETHODIMP
     507               1 : nsHttpNTLMAuth::GetAuthFlags(PRUint32 *flags)
     508                 : {
     509               1 :     *flags = CONNECTION_BASED | IDENTITY_INCLUDES_DOMAIN | IDENTITY_ENCRYPTED;
     510               1 :     return NS_OK;
     511                 : }

Generated by: LCOV version 1.7