Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Functions | Variables
nsNTLMAuthModule.cpp File Reference
#include "prlog.h"
#include <stdlib.h>
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsServiceManagerUtils.h"
#include "nsCOMPtr.h"
#include "nsNSSShutDown.h"
#include "nsNTLMAuthModule.h"
#include "nsNativeCharsetUtils.h"
#include "nsReadableUtils.h"
#include "nsString.h"
#include "prsystem.h"
#include "nss.h"
#include "pk11func.h"
#include "md4.h"

Go to the source code of this file.

Classes

struct  Type2Msg

Defines

#define LOG(x)
#define NTLM_NegotiateUnicode   0x00000001
#define NTLM_NegotiateOEM   0x00000002
#define NTLM_RequestTarget   0x00000004
#define NTLM_Unknown1   0x00000008
#define NTLM_NegotiateSign   0x00000010
#define NTLM_NegotiateSeal   0x00000020
#define NTLM_NegotiateDatagramStyle   0x00000040
#define NTLM_NegotiateLanManagerKey   0x00000080
#define NTLM_NegotiateNetware   0x00000100
#define NTLM_NegotiateNTLMKey   0x00000200
#define NTLM_Unknown2   0x00000400
#define NTLM_Unknown3   0x00000800
#define NTLM_NegotiateDomainSupplied   0x00001000
#define NTLM_NegotiateWorkstationSupplied   0x00002000
#define NTLM_NegotiateLocalCall   0x00004000
#define NTLM_NegotiateAlwaysSign   0x00008000
#define NTLM_TargetTypeDomain   0x00010000
#define NTLM_TargetTypeServer   0x00020000
#define NTLM_TargetTypeShare   0x00040000
#define NTLM_NegotiateNTLM2Key   0x00080000
#define NTLM_RequestInitResponse   0x00100000
#define NTLM_RequestAcceptResponse   0x00200000
#define NTLM_RequestNonNTSessionKey   0x00400000
#define NTLM_NegotiateTargetInfo   0x00800000
#define NTLM_Unknown4   0x01000000
#define NTLM_Unknown5   0x02000000
#define NTLM_Unknown6   0x04000000
#define NTLM_Unknown7   0x08000000
#define NTLM_Unknown8   0x10000000
#define NTLM_Negotiate128   0x20000000
#define NTLM_NegotiateKeyExchange   0x40000000
#define NTLM_Negotiate56   0x80000000
#define NTLM_TYPE1_FLAGS
#define NTLM_TYPE1_HEADER_LEN   32
#define NTLM_TYPE2_HEADER_LEN   32
#define NTLM_TYPE3_HEADER_LEN   64
#define LM_HASH_LEN   16
#define LM_RESP_LEN   24
#define NTLM_HASH_LEN   16
#define NTLM_RESP_LEN   24
#define LogFlags(x)
#define LogBuf(a, b, c)
#define LogToken(a, b, c)
#define SWAP16(x)   ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
#define SWAP32(x)   ((SWAP16((x) & 0xffff) << 16) | (SWAP16((x) >> 16)))

Functions

static void des_makekey (const PRUint8 *raw, PRUint8 *key)
static void des_encrypt (const PRUint8 *key, const PRUint8 *src, PRUint8 *hash)
static void md5sum (const PRUint8 *input, PRUint32 inputLen, PRUint8 *result)
static PRBool SendLM ()
static voidWriteBytes (void *buf, const void *data, PRUint32 dataLen)
static voidWriteDWORD (void *buf, PRUint32 dword)
static voidWriteSecBuf (void *buf, PRUint16 length, PRUint32 offset)
static PRUint16 ReadUint16 (const PRUint8 *&buf)
static PRUint32 ReadUint32 (const PRUint8 *&buf)
static void ZapBuf (void *buf, size_t bufLen)
static void ZapString (nsCString &s)
static void ZapString (nsString &s)
static void LM_Hash (const nsString &password, unsigned char *hash)
 LM_Hash computes the LM hash of the given password.
static void NTLM_Hash (const nsString &password, unsigned char *hash)
 NTLM_Hash computes the NTLM hash of the given password.
static void LM_Response (const PRUint8 *hash, const PRUint8 *challenge, PRUint8 *response)
 LM_Response generates the LM response given a 16-byte password hash and the challenge from the Type-2 message.
static nsresult GenerateType1Msg (void **outBuf, PRUint32 *outLen)
static nsresult ParseType2Msg (const void *inBuf, PRUint32 inLen, Type2Msg *msg)
static nsresult GenerateType3Msg (const nsString &domain, const nsString &username, const nsString &password, const void *inBuf, PRUint32 inLen, void **outBuf, PRUint32 *outLen)
static PRUint8 des_setkeyparity (PRUint8 x)

Variables

static const char NTLM_SIGNATURE [] = "NTLMSSP"
static const char NTLM_TYPE1_MARKER [] = { 0x01, 0x00, 0x00, 0x00 }
static const char NTLM_TYPE2_MARKER [] = { 0x02, 0x00, 0x00, 0x00 }
static const char NTLM_TYPE3_MARKER [] = { 0x03, 0x00, 0x00, 0x00 }
static const unsigned char LM_MAGIC [] = "KGS!@#$%"

Class Documentation

struct Type2Msg

Definition at line 509 of file nsNTLMAuthModule.cpp.

Class Members
PRUint8 challenge
PRUint32 flags
const void * target
PRUint32 targetLen

Define Documentation

#define LM_HASH_LEN   16

Definition at line 124 of file nsNTLMAuthModule.cpp.

#define LM_RESP_LEN   24

Definition at line 125 of file nsNTLMAuthModule.cpp.

#define LOG (   x)

Definition at line 61 of file nsNTLMAuthModule.cpp.

#define LogBuf (   a,
  b,
  c 
)

Definition at line 268 of file nsNTLMAuthModule.cpp.

#define LogFlags (   x)

Definition at line 267 of file nsNTLMAuthModule.cpp.

#define LogToken (   a,
  b,
  c 
)

Definition at line 269 of file nsNTLMAuthModule.cpp.

Definition at line 127 of file nsNTLMAuthModule.cpp.

#define NTLM_Negotiate128   0x20000000

Definition at line 102 of file nsNTLMAuthModule.cpp.

#define NTLM_Negotiate56   0x80000000

Definition at line 104 of file nsNTLMAuthModule.cpp.

#define NTLM_NegotiateAlwaysSign   0x00008000

Definition at line 88 of file nsNTLMAuthModule.cpp.

Definition at line 79 of file nsNTLMAuthModule.cpp.

Definition at line 85 of file nsNTLMAuthModule.cpp.

Definition at line 103 of file nsNTLMAuthModule.cpp.

Definition at line 80 of file nsNTLMAuthModule.cpp.

#define NTLM_NegotiateLocalCall   0x00004000

Definition at line 87 of file nsNTLMAuthModule.cpp.

#define NTLM_NegotiateNetware   0x00000100

Definition at line 81 of file nsNTLMAuthModule.cpp.

#define NTLM_NegotiateNTLM2Key   0x00080000

Definition at line 92 of file nsNTLMAuthModule.cpp.

#define NTLM_NegotiateNTLMKey   0x00000200

Definition at line 82 of file nsNTLMAuthModule.cpp.

#define NTLM_NegotiateOEM   0x00000002

Definition at line 74 of file nsNTLMAuthModule.cpp.

#define NTLM_NegotiateSeal   0x00000020

Definition at line 78 of file nsNTLMAuthModule.cpp.

#define NTLM_NegotiateSign   0x00000010

Definition at line 77 of file nsNTLMAuthModule.cpp.

#define NTLM_NegotiateTargetInfo   0x00800000

Definition at line 96 of file nsNTLMAuthModule.cpp.

#define NTLM_NegotiateUnicode   0x00000001

Definition at line 73 of file nsNTLMAuthModule.cpp.

Definition at line 86 of file nsNTLMAuthModule.cpp.

Definition at line 94 of file nsNTLMAuthModule.cpp.

#define NTLM_RequestInitResponse   0x00100000

Definition at line 93 of file nsNTLMAuthModule.cpp.

Definition at line 95 of file nsNTLMAuthModule.cpp.

#define NTLM_RequestTarget   0x00000004

Definition at line 75 of file nsNTLMAuthModule.cpp.

Definition at line 128 of file nsNTLMAuthModule.cpp.

#define NTLM_TargetTypeDomain   0x00010000

Definition at line 89 of file nsNTLMAuthModule.cpp.

#define NTLM_TargetTypeServer   0x00020000

Definition at line 90 of file nsNTLMAuthModule.cpp.

#define NTLM_TargetTypeShare   0x00040000

Definition at line 91 of file nsNTLMAuthModule.cpp.

Value:
(NTLM_NegotiateUnicode |    \
   NTLM_NegotiateOEM |        \
   NTLM_RequestTarget |       \
   NTLM_NegotiateNTLMKey |    \
   NTLM_NegotiateAlwaysSign | \
   NTLM_NegotiateNTLM2Key)

Definition at line 107 of file nsNTLMAuthModule.cpp.

Definition at line 120 of file nsNTLMAuthModule.cpp.

Definition at line 121 of file nsNTLMAuthModule.cpp.

Definition at line 122 of file nsNTLMAuthModule.cpp.

#define NTLM_Unknown1   0x00000008

Definition at line 76 of file nsNTLMAuthModule.cpp.

#define NTLM_Unknown2   0x00000400

Definition at line 83 of file nsNTLMAuthModule.cpp.

#define NTLM_Unknown3   0x00000800

Definition at line 84 of file nsNTLMAuthModule.cpp.

#define NTLM_Unknown4   0x01000000

Definition at line 97 of file nsNTLMAuthModule.cpp.

#define NTLM_Unknown5   0x02000000

Definition at line 98 of file nsNTLMAuthModule.cpp.

#define NTLM_Unknown6   0x04000000

Definition at line 99 of file nsNTLMAuthModule.cpp.

#define NTLM_Unknown7   0x08000000

Definition at line 100 of file nsNTLMAuthModule.cpp.

#define NTLM_Unknown8   0x10000000

Definition at line 101 of file nsNTLMAuthModule.cpp.

#define SWAP16 (   x)    ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))

Definition at line 276 of file nsNTLMAuthModule.cpp.

#define SWAP32 (   x)    ((SWAP16((x) & 0xffff) << 16) | (SWAP16((x) >> 16)))

Definition at line 277 of file nsNTLMAuthModule.cpp.


Function Documentation

static void des_encrypt ( const PRUint8 key,
const PRUint8 src,
PRUint8 hash 
) [static]

Definition at line 881 of file nsNTLMAuthModule.cpp.

{
  CK_MECHANISM_TYPE cipherMech = CKM_DES_ECB;
  PK11SlotInfo *slot = nsnull;
  PK11SymKey *symkey = nsnull;
  PK11Context *ctxt = nsnull;
  SECItem keyItem, *param = nsnull;
  SECStatus rv;
  unsigned int n;
  
  slot = PK11_GetBestSlot(cipherMech, nsnull);
  if (!slot)
  {
    NS_ERROR("no slot");
    goto done;
  }

  keyItem.data = (PRUint8 *) key;
  keyItem.len = 8;
  symkey = PK11_ImportSymKey(slot, cipherMech,
                             PK11_OriginUnwrap, CKA_ENCRYPT,
                             &keyItem, nsnull);
  if (!symkey)
  {
    NS_ERROR("no symkey");
    goto done;
  }

  // no initialization vector required
  param = PK11_ParamFromIV(cipherMech, nsnull);
  if (!param)
  {
    NS_ERROR("no param");
    goto done;
  }

  ctxt = PK11_CreateContextBySymKey(cipherMech, CKA_ENCRYPT,
                                    symkey, param);
  if (!ctxt)
  {
    NS_ERROR("no context");
    goto done;
  }

  rv = PK11_CipherOp(ctxt, hash, (int *) &n, 8, (PRUint8 *) src, 8);
  if (rv != SECSuccess)
  {
    NS_ERROR("des failure");
    goto done;
  }

  rv = PK11_DigestFinal(ctxt, hash+8, &n, 0);
  if (rv != SECSuccess)
  {
    NS_ERROR("des failure");
    goto done;
  }

done:
  if (ctxt)
    PK11_DestroyContext(ctxt, PR_TRUE);
  if (symkey)
    PK11_FreeSymKey(symkey);
  if (param)
    SECITEM_FreeItem(param, PR_TRUE);
  if (slot)
    PK11_FreeSlot(slot);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void des_makekey ( const PRUint8 raw,
PRUint8 key 
) [static]

Definition at line 867 of file nsNTLMAuthModule.cpp.

{
  key[0] = des_setkeyparity(raw[0]);
  key[1] = des_setkeyparity((raw[0] << 7) | (raw[1] >> 1));
  key[2] = des_setkeyparity((raw[1] << 6) | (raw[2] >> 2));
  key[3] = des_setkeyparity((raw[2] << 5) | (raw[3] >> 3));
  key[4] = des_setkeyparity((raw[3] << 4) | (raw[4] >> 4));
  key[5] = des_setkeyparity((raw[4] << 3) | (raw[5] >> 5));
  key[6] = des_setkeyparity((raw[5] << 2) | (raw[6] >> 6));
  key[7] = des_setkeyparity((raw[6] << 1));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRUint8 des_setkeyparity ( PRUint8  x) [static]

Definition at line 854 of file nsNTLMAuthModule.cpp.

{
  if ((((x >> 7) ^ (x >> 6) ^ (x >> 5) ^
        (x >> 4) ^ (x >> 3) ^ (x >> 2) ^
        (x >> 1)) & 0x01) == 0)
    x |= 0x01;
  else
    x &= 0xfe;
  return x;
}

Here is the caller graph for this function:

static nsresult GenerateType1Msg ( void **  outBuf,
PRUint32 outLen 
) [static]

Definition at line 468 of file nsNTLMAuthModule.cpp.

{
  //
  // verify that bufLen is sufficient
  //
  *outLen = NTLM_TYPE1_HEADER_LEN;
  *outBuf = nsMemory::Alloc(*outLen);
  if (!*outBuf)
    return NS_ERROR_OUT_OF_MEMORY;

  //
  // write out type 1 msg
  //
  void *cursor = *outBuf;

  // 0 : signature
  cursor = WriteBytes(cursor, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE));

  // 8 : marker
  cursor = WriteBytes(cursor, NTLM_TYPE1_MARKER, sizeof(NTLM_TYPE1_MARKER));

  // 12 : flags
  cursor = WriteDWORD(cursor, NTLM_TYPE1_FLAGS);

  //
  // NOTE: it is common for the domain and workstation fields to be empty.
  //       this is true of Win2k clients, and my guess is that there is
  //       little utility to sending these strings before the charset has
  //       been negotiated.  we follow suite -- anyways, it doesn't hurt
  //       to save some bytes on the wire ;-)
  //

  // 16 : supplied domain security buffer (empty)
  cursor = WriteSecBuf(cursor, 0, 0);

  // 24 : supplied workstation security buffer (empty)
  cursor = WriteSecBuf(cursor, 0, 0);

  return NS_OK;
}

Here is the call graph for this function:

static nsresult GenerateType3Msg ( const nsString domain,
const nsString username,
const nsString password,
const void inBuf,
PRUint32  inLen,
void **  outBuf,
PRUint32 outLen 
) [static]

Definition at line 571 of file nsNTLMAuthModule.cpp.

{
  // inBuf contains Type-2 msg (the challenge) from server

  nsresult rv;
  Type2Msg msg;

  rv = ParseType2Msg(inBuf, inLen, &msg);
  if (NS_FAILED(rv))
    return rv;

  PRBool unicode = (msg.flags & NTLM_NegotiateUnicode);

  // temporary buffers for unicode strings
#ifdef IS_BIG_ENDIAN
  nsAutoString ucsDomainBuf, ucsUserBuf;
#endif
  nsAutoString ucsHostBuf; 
  // temporary buffers for oem strings
  nsCAutoString 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;
  PRUint32 domainLen, userLen, hostLen;

  //
  // get domain name
  //
  if (unicode)
  {
#ifdef IS_BIG_ENDIAN
    ucsDomainBuf = domain;
    domainPtr = ucsDomainBuf.get();
    domainLen = ucsDomainBuf.Length() * 2;
    WriteUnicodeLE((void *) domainPtr, (const PRUnichar *) domainPtr,
                   ucsDomainBuf.Length());
#else
    domainPtr = domain.get();
    domainLen = domain.Length() * 2;
#endif
  }
  else
  {
    NS_CopyUnicodeToNative(domain, oemDomainBuf);
    domainPtr = oemDomainBuf.get();
    domainLen = oemDomainBuf.Length();
  }

  //
  // get user name
  //
  if (unicode)
  {
#ifdef IS_BIG_ENDIAN
    ucsUserBuf = username;
    userPtr = ucsUserBuf.get();
    userLen = ucsUserBuf.Length() * 2;
    WriteUnicodeLE((void *) userPtr, (const PRUnichar *) userPtr,
                   ucsUserBuf.Length());
#else
    userPtr = username.get();
    userLen = username.Length() * 2;
#endif
  }
  else
  {
    NS_CopyUnicodeToNative(username, oemUserBuf);
    userPtr = oemUserBuf.get();
    userLen = oemUserBuf.Length();
  }

  //
  // get workstation name (use local machine's hostname)
  //
  char hostBuf[SYS_INFO_BUFFER_LENGTH];
  if (PR_GetSystemInfo(PR_SI_HOSTNAME, hostBuf, sizeof(hostBuf)) == PR_FAILURE)
    return NS_ERROR_UNEXPECTED;
  hostLen = strlen(hostBuf);
  if (unicode)
  {
    // hostname is ASCII, so we can do a simple zero-pad expansion:
    CopyASCIItoUCS2(nsDependentCString(hostBuf, hostLen), ucsHostBuf);
    hostPtr = ucsHostBuf.get();
    hostLen = ucsHostBuf.Length() * 2;
#ifdef IS_BIG_ENDIAN
    WriteUnicodeLE((void *) hostPtr, (const PRUnichar *) hostPtr,
                   ucsHostBuf.Length());
#endif
  }
  else
    hostPtr = hostBuf;

  //
  // now that we have generated all of the strings, we can allocate outBuf.
  //
  *outLen = NTLM_TYPE3_HEADER_LEN + hostLen + domainLen + userLen +
            LM_RESP_LEN + NTLM_RESP_LEN;
  *outBuf = nsMemory::Alloc(*outLen);
  if (!*outBuf)
    return NS_ERROR_OUT_OF_MEMORY;

  //
  // next, we compute the LM and NTLM responses.
  //
  PRUint8 lmResp[LM_RESP_LEN], ntlmResp[NTLM_RESP_LEN], ntlmHash[NTLM_HASH_LEN];
  if (msg.flags & NTLM_NegotiateNTLM2Key)
  {
    // compute NTLM2 session response
    PRUint8 sessionHash[16], temp[16];

    PK11_GenerateRandom(lmResp, 8);
    memset(lmResp + 8, 0, LM_RESP_LEN - 8);

    memcpy(temp, msg.challenge, 8);
    memcpy(temp + 8, lmResp, 8);
    md5sum(temp, 16, sessionHash);

    NTLM_Hash(password, ntlmHash);
    LM_Response(ntlmHash, sessionHash, ntlmResp);
  }
  else
  {
    NTLM_Hash(password, ntlmHash);
    LM_Response(ntlmHash, msg.challenge, ntlmResp);

    if (SendLM())
    {
      PRUint8 lmHash[LM_HASH_LEN];
      LM_Hash(password, lmHash);
      LM_Response(lmHash, msg.challenge, lmResp);
    }
    else
    {
      // According to http://davenport.sourceforge.net/ntlm.html#ntlmVersion2,
      // the correct way to not send the LM hash is to send the NTLM hash twice
      // in both the LM and NTLM response fields.
      LM_Response(ntlmHash, msg.challenge, lmResp);
    }
  }

  //
  // finally, we assemble the Type-3 msg :-)
  //
  void *cursor = *outBuf;
  PRUint32 offset;

  // 0 : signature
  cursor = WriteBytes(cursor, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE));

  // 8 : marker
  cursor = WriteBytes(cursor, NTLM_TYPE3_MARKER, sizeof(NTLM_TYPE3_MARKER));

  // 12 : LM response sec buf
  offset = NTLM_TYPE3_HEADER_LEN + domainLen + userLen + hostLen;
  cursor = WriteSecBuf(cursor, LM_RESP_LEN, offset);
  memcpy((PRUint8 *) *outBuf + offset, lmResp, LM_RESP_LEN);

  // 20 : NTLM response sec buf
  offset += LM_RESP_LEN;
  cursor = WriteSecBuf(cursor, NTLM_RESP_LEN, offset);
  memcpy((PRUint8 *) *outBuf + offset, ntlmResp, NTLM_RESP_LEN);

  // 28 : domain name sec buf
  offset = NTLM_TYPE3_HEADER_LEN;
  cursor = WriteSecBuf(cursor, domainLen, offset);
  memcpy((PRUint8 *) *outBuf + offset, domainPtr, domainLen);

  // 36 : user name sec buf
  offset += domainLen;
  cursor = WriteSecBuf(cursor, userLen, offset);
  memcpy((PRUint8 *) *outBuf + offset, userPtr, userLen);

  // 44 : workstation (host) name sec buf
  offset += userLen;
  cursor = WriteSecBuf(cursor, hostLen, offset);
  memcpy((PRUint8 *) *outBuf + offset, hostPtr, hostLen);

  // 52 : session key sec buf (not used)
  cursor = WriteSecBuf(cursor, 0, 0);

  // 60 : negotiated flags
  cursor = WriteDWORD(cursor, msg.flags & NTLM_TYPE1_FLAGS);

  return NS_OK;
}

Here is the call graph for this function:

static void LM_Hash ( const nsString password,
unsigned char *  hash 
) [static]

LM_Hash computes the LM hash of the given password.

Parameters:
passwordnull-terminated unicode password.
hash16-byte result buffer

Definition at line 384 of file nsNTLMAuthModule.cpp.

{
  // convert password to OEM character set.  we'll just use the native
  // filesystem charset.
  nsCAutoString passbuf;
  NS_CopyUnicodeToNative(password, passbuf);
  ToUpperCase(passbuf);
  PRUint32 n = passbuf.Length();
  passbuf.SetLength(14);
  for (PRUint32 i=n; i<14; ++i)
    passbuf.SetCharAt('\0', i);

  unsigned char k1[8], k2[8];
  des_makekey((const unsigned char *) passbuf.get()    , k1);
  des_makekey((const unsigned char *) passbuf.get() + 7, k2);
  ZapString(passbuf);

  // use password keys to hash LM magic string twice.
  des_encrypt(k1, LM_MAGIC, hash);
  des_encrypt(k2, LM_MAGIC, hash + 8);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void LM_Response ( const PRUint8 hash,
const PRUint8 challenge,
PRUint8 response 
) [static]

LM_Response generates the LM response given a 16-byte password hash and the challenge from the Type-2 message.

Parameters:
hash16-byte password hash
challenge8-byte challenge from Type-2 message
response24-byte buffer to contain the LM response upon return

Definition at line 449 of file nsNTLMAuthModule.cpp.

{
  PRUint8 keybytes[21], k1[8], k2[8], k3[8];

  memcpy(keybytes, hash, 16);
  ZapBuf(keybytes + 16, 5);

  des_makekey(keybytes     , k1);
  des_makekey(keybytes +  7, k2);
  des_makekey(keybytes + 14, k3);

  des_encrypt(k1, challenge, response);
  des_encrypt(k2, challenge, response + 8);
  des_encrypt(k3, challenge, response + 16);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void md5sum ( const PRUint8 input,
PRUint32  inputLen,
PRUint8 result 
) [static]

Definition at line 953 of file nsNTLMAuthModule.cpp.

{
  PK11Context *ctxt = PK11_CreateDigestContext(SEC_OID_MD5);
  if (ctxt)
  {
    if (PK11_DigestBegin(ctxt) == SECSuccess)
    {
      if (PK11_DigestOp(ctxt, input, inputLen) == SECSuccess)
      {
        PRUint32 resultLen = 16;
        PK11_DigestFinal(ctxt, result, &resultLen, resultLen);
      }
    }
    PK11_DestroyContext(ctxt, PR_TRUE);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void NTLM_Hash ( const nsString password,
unsigned char *  hash 
) [static]

NTLM_Hash computes the NTLM hash of the given password.

Parameters:
passwordnull-terminated unicode password.
hash16-byte result buffer

Definition at line 415 of file nsNTLMAuthModule.cpp.

{
  PRUint32 len = password.Length();
  PRUint8 *passbuf;
  
#ifdef IS_BIG_ENDIAN
  passbuf = (PRUint8 *) malloc(len * 2);
  WriteUnicodeLE(passbuf, password.get(), len);
#else
  passbuf = (PRUint8 *) password.get();
#endif

  md4sum(passbuf, len * 2, hash);

#ifdef IS_BIG_ENDIAN
  ZapBuf(passbuf, len * 2);
  free(passbuf);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static nsresult ParseType2Msg ( const void inBuf,
PRUint32  inLen,
Type2Msg msg 
) [static]

Definition at line 518 of file nsNTLMAuthModule.cpp.

{
  // make sure inBuf is long enough to contain a meaningful type2 msg.
  //
  // 0  NTLMSSP Signature
  // 8  NTLM Message Type
  // 12 Target Name
  // 20 Flags
  // 24 Challenge
  // 32 end of header, start of optional data blocks
  //
  if (inLen < NTLM_TYPE2_HEADER_LEN)
    return NS_ERROR_UNEXPECTED;

  const PRUint8 *cursor = (const PRUint8 *) inBuf;

  // verify NTLMSSP signature
  if (memcmp(cursor, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)) != 0)
    return NS_ERROR_UNEXPECTED;
  cursor += sizeof(NTLM_SIGNATURE);

  // verify Type-2 marker
  if (memcmp(cursor, NTLM_TYPE2_MARKER, sizeof(NTLM_TYPE2_MARKER)) != 0)
    return NS_ERROR_UNEXPECTED;
  cursor += sizeof(NTLM_TYPE2_MARKER);

  // read target name security buffer
  msg->targetLen = ReadUint16(cursor);
  ReadUint16(cursor); // discard next 16-bit value
  PRUint32 offset = ReadUint32(cursor); // get offset from inBuf
  msg->target = ((const PRUint8 *) inBuf) + offset;

  // read flags
  msg->flags = ReadUint32(cursor);

  // read challenge
  memcpy(msg->challenge, cursor, sizeof(msg->challenge));
  cursor += sizeof(msg->challenge);


  LOG(("NTLM type 2 message:\n"));
  LogBuf("target", (const PRUint8 *) msg->target, msg->targetLen);
  LogBuf("flags", (const PRUint8 *) &msg->flags, 4);
  LogFlags(msg->flags);
  LogBuf("challenge", msg->challenge, sizeof(msg->challenge));

  // we currently do not implement LMv2/NTLMv2 or NTLM2 responses,
  // so we can ignore target information.  we may want to enable
  // support for these alternate mechanisms in the future.
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRUint16 ReadUint16 ( const PRUint8 *&  buf) [static]

Definition at line 335 of file nsNTLMAuthModule.cpp.

{
  PRUint16 x = ((PRUint16) buf[0]) | ((PRUint16) buf[1] << 8);
  buf += sizeof(x);
  return x;
}

Here is the caller graph for this function:

static PRUint32 ReadUint32 ( const PRUint8 *&  buf) [static]

Definition at line 343 of file nsNTLMAuthModule.cpp.

{
  PRUint32 x = ( (PRUint32) buf[0])        |
               (((PRUint32) buf[1]) << 8)  |
               (((PRUint32) buf[2]) << 16) |
               (((PRUint32) buf[3]) << 24);
  buf += sizeof(x);
  return x;
}

Here is the caller graph for this function:

static PRBool SendLM ( ) [static]

Definition at line 132 of file nsNTLMAuthModule.cpp.

{
  nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
  if (!prefs)
    return PR_FALSE;

  PRBool val;
  nsresult rv = prefs->GetBoolPref("network.ntlm.send-lm-response", &val);
  return NS_SUCCEEDED(rv) && val;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void* WriteBytes ( void buf,
const void data,
PRUint32  dataLen 
) [static]

Definition at line 280 of file nsNTLMAuthModule.cpp.

{
  memcpy(buf, data, dataLen);
  return (PRUint8 *) buf + dataLen;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void* WriteDWORD ( void buf,
PRUint32  dword 
) [static]

Definition at line 287 of file nsNTLMAuthModule.cpp.

{
#ifdef IS_BIG_ENDIAN 
  // NTLM uses little endian on the wire
  dword = SWAP32(dword);
#endif
  return WriteBytes(buf, &dword, sizeof(dword));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void* WriteSecBuf ( void buf,
PRUint16  length,
PRUint32  offset 
) [static]

Definition at line 297 of file nsNTLMAuthModule.cpp.

{
#ifdef IS_BIG_ENDIAN
  length = SWAP16(length);
  offset = SWAP32(offset);
#endif
  buf = WriteBytes(buf, &length, sizeof(length));
  buf = WriteBytes(buf, &length, sizeof(length));
  buf = WriteBytes(buf, &offset, sizeof(offset));
  return buf;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ZapBuf ( void buf,
size_t  bufLen 
) [static]

Definition at line 356 of file nsNTLMAuthModule.cpp.

{
  memset(buf, 0, bufLen);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ZapString ( nsCString s) [static]

Definition at line 362 of file nsNTLMAuthModule.cpp.

{
  ZapBuf(s.BeginWriting(), s.Length());
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ZapString ( nsString s) [static]

Definition at line 368 of file nsNTLMAuthModule.cpp.

{
  ZapBuf(s.BeginWriting(), s.Length() * 2);
}

Here is the call graph for this function:


Variable Documentation

const unsigned char LM_MAGIC[] = "KGS!@#$%" [static]

Definition at line 373 of file nsNTLMAuthModule.cpp.

const char NTLM_SIGNATURE[] = "NTLMSSP" [static]

Definition at line 115 of file nsNTLMAuthModule.cpp.

const char NTLM_TYPE1_MARKER[] = { 0x01, 0x00, 0x00, 0x00 } [static]

Definition at line 116 of file nsNTLMAuthModule.cpp.

const char NTLM_TYPE2_MARKER[] = { 0x02, 0x00, 0x00, 0x00 } [static]

Definition at line 117 of file nsNTLMAuthModule.cpp.

const char NTLM_TYPE3_MARKER[] = { 0x03, 0x00, 0x00, 0x00 } [static]

Definition at line 118 of file nsNTLMAuthModule.cpp.