Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Functions | Variables
ReadNTLM.cpp File Reference
#include <stdlib.h>
#include <stdio.h>
#include "plbase64.h"
#include "nsString.h"
#include "nsNativeCharsetUtils.h"
#include "nsReadableUtils.h"
#include "prmem.h"

Go to the source code of this file.

Classes

struct  SecBuf

Defines

#define kNegotiateUnicode   0x00000001
#define kNegotiateOEM   0x00000002
#define kRequestTarget   0x00000004
#define kUnknown1   0x00000008
#define kNegotiateSign   0x00000010
#define kNegotiateSeal   0x00000020
#define kNegotiateDatagramStyle   0x00000040
#define kNegotiateLanManagerKey   0x00000080
#define kNegotiateNetware   0x00000100
#define kNegotiateNTLMKey   0x00000200
#define kUnknown2   0x00000400
#define kUnknown3   0x00000800
#define kNegotiateDomainSupplied   0x00001000
#define kNegotiateWorkstationSupplied   0x00002000
#define kNegotiateLocalCall   0x00004000
#define kNegotiateAlwaysSign   0x00008000
#define kTargetTypeDomain   0x00010000
#define kTargetTypeServer   0x00020000
#define kTargetTypeShare   0x00040000
#define kNegotiateNTLM2Key   0x00080000
#define kRequestInitResponse   0x00100000
#define kRequestAcceptResponse   0x00200000
#define kRequestNonNTSessionKey   0x00400000
#define kNegotiateTargetInfo   0x00800000
#define kUnknown4   0x01000000
#define kUnknown5   0x02000000
#define kUnknown6   0x04000000
#define kUnknown7   0x08000000
#define kUnknown8   0x10000000
#define kNegotiate128   0x20000000
#define kNegotiateKeyExchange   0x40000000
#define kNegotiate56   0x80000000
#define NTLM_MARKER_LEN   4
#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 TEST(_flag)

Functions

static void PrintFlags (PRUint32 flags)
static void PrintBuf (const char *tag, const PRUint8 *buf, PRUint32 bufLen)
static PRUint16 ReadUint16 (const PRUint8 *&buf)
static PRUint32 ReadUint32 (const PRUint8 *&buf)
static void ReadSecBuf (SecBuf *s, const PRUint8 *&buf)
static void ReadType1MsgBody (const PRUint8 *inBuf, PRUint32 start)
static void ReadType2MsgBody (const PRUint8 *inBuf, PRUint32 start)
static void ReadType3MsgBody (const PRUint8 *inBuf, PRUint32 start)
static void ReadMsg (const char *base64buf, PRUint32 bufLen)
int main (int argc, char **argv)
 The Xalan testcases app.

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 }

Class Documentation

struct SecBuf

Definition at line 212 of file ReadNTLM.cpp.

Class Members
PRUint16 capacity
PRUint16 length
PRUint32 offset

Define Documentation

#define kNegotiate128   0x20000000

Definition at line 81 of file ReadNTLM.cpp.

#define kNegotiate56   0x80000000

Definition at line 83 of file ReadNTLM.cpp.

#define kNegotiateAlwaysSign   0x00008000

Definition at line 67 of file ReadNTLM.cpp.

#define kNegotiateDatagramStyle   0x00000040

Definition at line 58 of file ReadNTLM.cpp.

#define kNegotiateDomainSupplied   0x00001000

Definition at line 64 of file ReadNTLM.cpp.

#define kNegotiateKeyExchange   0x40000000

Definition at line 82 of file ReadNTLM.cpp.

#define kNegotiateLanManagerKey   0x00000080

Definition at line 59 of file ReadNTLM.cpp.

#define kNegotiateLocalCall   0x00004000

Definition at line 66 of file ReadNTLM.cpp.

#define kNegotiateNetware   0x00000100

Definition at line 60 of file ReadNTLM.cpp.

#define kNegotiateNTLM2Key   0x00080000

Definition at line 71 of file ReadNTLM.cpp.

#define kNegotiateNTLMKey   0x00000200

Definition at line 61 of file ReadNTLM.cpp.

#define kNegotiateOEM   0x00000002

Definition at line 53 of file ReadNTLM.cpp.

#define kNegotiateSeal   0x00000020

Definition at line 57 of file ReadNTLM.cpp.

#define kNegotiateSign   0x00000010

Definition at line 56 of file ReadNTLM.cpp.

#define kNegotiateTargetInfo   0x00800000

Definition at line 75 of file ReadNTLM.cpp.

#define kNegotiateUnicode   0x00000001

Definition at line 52 of file ReadNTLM.cpp.

Definition at line 65 of file ReadNTLM.cpp.

#define kRequestAcceptResponse   0x00200000

Definition at line 73 of file ReadNTLM.cpp.

#define kRequestInitResponse   0x00100000

Definition at line 72 of file ReadNTLM.cpp.

#define kRequestNonNTSessionKey   0x00400000

Definition at line 74 of file ReadNTLM.cpp.

#define kRequestTarget   0x00000004

Definition at line 54 of file ReadNTLM.cpp.

#define kTargetTypeDomain   0x00010000

Definition at line 68 of file ReadNTLM.cpp.

#define kTargetTypeServer   0x00020000

Definition at line 69 of file ReadNTLM.cpp.

#define kTargetTypeShare   0x00040000

Definition at line 70 of file ReadNTLM.cpp.

#define kUnknown1   0x00000008

Definition at line 55 of file ReadNTLM.cpp.

#define kUnknown2   0x00000400

Definition at line 62 of file ReadNTLM.cpp.

#define kUnknown3   0x00000800

Definition at line 63 of file ReadNTLM.cpp.

#define kUnknown4   0x01000000

Definition at line 76 of file ReadNTLM.cpp.

#define kUnknown5   0x02000000

Definition at line 77 of file ReadNTLM.cpp.

#define kUnknown6   0x04000000

Definition at line 78 of file ReadNTLM.cpp.

#define kUnknown7   0x08000000

Definition at line 79 of file ReadNTLM.cpp.

#define kUnknown8   0x10000000

Definition at line 80 of file ReadNTLM.cpp.

#define LM_HASH_LEN   16

Definition at line 95 of file ReadNTLM.cpp.

#define LM_RESP_LEN   24

Definition at line 96 of file ReadNTLM.cpp.

Definition at line 98 of file ReadNTLM.cpp.

Definition at line 90 of file ReadNTLM.cpp.

Definition at line 99 of file ReadNTLM.cpp.

Definition at line 91 of file ReadNTLM.cpp.

Definition at line 92 of file ReadNTLM.cpp.

Definition at line 93 of file ReadNTLM.cpp.

#define TEST (   _flag)
Value:
if (flags & k ## _flag) \
    printf("    0x%08x (" # _flag ")\n", k ## _flag)

Function Documentation

int main ( int  argc,
char **  argv 
)

The Xalan testcases app.

Definition at line 348 of file ReadNTLM.cpp.

{
  if (argc == 1)
  {
    printf("usage: ntlmread <msg>\n");
    return -1;
  }
  ReadMsg(argv[1], (PRUint32) strlen(argv[1]));
  return 0;
}

Here is the call graph for this function:

static void PrintBuf ( const char *  tag,
const PRUint8 buf,
PRUint32  bufLen 
) [static]

Definition at line 144 of file ReadNTLM.cpp.

{
  int i;

  printf("%s =\n", tag);
  while (bufLen > 0)
  {
    int count = bufLen;
    if (count > 8)
      count = 8;

    printf("    ");
    for (i=0; i<count; ++i)
    {
      printf("0x%02x ", int(buf[i]));
    }
    for (; i<8; ++i)
    {
      printf("     ");
    }

    printf("   ");
    for (i=0; i<count; ++i)
    {
      if (isprint(buf[i]))
        printf("%c", buf[i]);
      else
        printf(".");
    }
    printf("\n");

    bufLen -= count;
    buf += count;
  }
}

Here is the caller graph for this function:

static void PrintFlags ( PRUint32  flags) [static]

Definition at line 101 of file ReadNTLM.cpp.

{
#define TEST(_flag) \
  if (flags & k ## _flag) \
    printf("    0x%08x (" # _flag ")\n", k ## _flag)

  TEST(NegotiateUnicode);
  TEST(NegotiateOEM);
  TEST(RequestTarget);
  TEST(Unknown1);
  TEST(NegotiateSign);
  TEST(NegotiateSeal);
  TEST(NegotiateDatagramStyle);
  TEST(NegotiateLanManagerKey);
  TEST(NegotiateNetware);
  TEST(NegotiateNTLMKey);
  TEST(Unknown2);
  TEST(Unknown3);
  TEST(NegotiateDomainSupplied);
  TEST(NegotiateWorkstationSupplied);
  TEST(NegotiateLocalCall);
  TEST(NegotiateAlwaysSign);
  TEST(TargetTypeDomain);
  TEST(TargetTypeServer);
  TEST(TargetTypeShare);
  TEST(NegotiateNTLM2Key);
  TEST(RequestInitResponse);
  TEST(RequestAcceptResponse);
  TEST(RequestNonNTSessionKey);
  TEST(NegotiateTargetInfo);
  TEST(Unknown4);
  TEST(Unknown5);
  TEST(Unknown6);
  TEST(Unknown7);
  TEST(Unknown8);
  TEST(Negotiate128);
  TEST(NegotiateKeyExchange);
  TEST(Negotiate56);

#undef TEST
}

Here is the caller graph for this function:

static void ReadMsg ( const char *  base64buf,
PRUint32  bufLen 
) [static]

Definition at line 314 of file ReadNTLM.cpp.

{
  PRUint8 *inBuf = (PRUint8 *) PL_Base64Decode(base64buf, bufLen, NULL);
  if (!inBuf)
  {
    printf("PL_Base64Decode failed\n");
    return;
  }

  const PRUint8 *cursor = inBuf;

  PrintBuf("signature", cursor, 8);

  // verify NTLMSSP signature
  if (memcmp(cursor, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)) != 0)
  {
    printf("### invalid or corrupt NTLM signature\n");
  }
  cursor += sizeof(NTLM_SIGNATURE);

  PrintBuf("message type", cursor, 4);

  if (memcmp(cursor, NTLM_TYPE1_MARKER, sizeof(NTLM_MARKER_LEN)) == 0)
    ReadType1MsgBody(inBuf, 12);
  else if (memcmp(cursor, NTLM_TYPE2_MARKER, sizeof(NTLM_MARKER_LEN)) == 0)
    ReadType2MsgBody(inBuf, 12);
  else if (memcmp(cursor, NTLM_TYPE3_MARKER, sizeof(NTLM_MARKER_LEN)) == 0)
    ReadType3MsgBody(inBuf, 12);
  else
    printf("### invalid or unknown message type\n"); 

  PR_Free(inBuf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ReadSecBuf ( SecBuf s,
const PRUint8 *&  buf 
) [static]

Definition at line 219 of file ReadNTLM.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

static void ReadType1MsgBody ( const PRUint8 inBuf,
PRUint32  start 
) [static]

Definition at line 227 of file ReadNTLM.cpp.

{
  const PRUint8 *cursor = inBuf + start;
  PRUint32 flags;

  PrintBuf("flags", cursor, 4);
  // read flags
  flags = ReadUint32(cursor);
  PrintFlags(flags);

  // type 1 message may not include trailing security buffers
  if ((flags & kNegotiateDomainSupplied) | 
      (flags & kNegotiateWorkstationSupplied))
  {
    SecBuf secbuf;
    ReadSecBuf(&secbuf, cursor);
    PrintBuf("supplied domain", inBuf + secbuf.offset, secbuf.length);

    ReadSecBuf(&secbuf, cursor);
    PrintBuf("supplied workstation", inBuf + secbuf.offset, secbuf.length);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ReadType2MsgBody ( const PRUint8 inBuf,
PRUint32  start 
) [static]

Definition at line 251 of file ReadNTLM.cpp.

{
  PRUint16 targetLen, offset;
  PRUint32 flags;
  const PRUint8 *target;
  const PRUint8 *cursor = inBuf + start;

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

  PrintBuf("target", target, targetLen);

  PrintBuf("flags", cursor, 4);
  // read flags
  flags = ReadUint32(cursor);
  PrintFlags(flags);

  // read challenge
  PrintBuf("challenge", cursor, 8);
  cursor += 8;

  PrintBuf("context", cursor, 8);
  cursor += 8;

  SecBuf secbuf;
  ReadSecBuf(&secbuf, cursor);
  PrintBuf("target information", inBuf + secbuf.offset, secbuf.length);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ReadType3MsgBody ( const PRUint8 inBuf,
PRUint32  start 
) [static]

Definition at line 284 of file ReadNTLM.cpp.

{
  const PRUint8 *cursor = inBuf + start;

  SecBuf secbuf;

  ReadSecBuf(&secbuf, cursor); // LM response
  PrintBuf("LM response", inBuf + secbuf.offset, secbuf.length);

  ReadSecBuf(&secbuf, cursor); // NTLM response
  PrintBuf("NTLM response", inBuf + secbuf.offset, secbuf.length);

  ReadSecBuf(&secbuf, cursor); // domain name
  PrintBuf("domain name", inBuf + secbuf.offset, secbuf.length);

  ReadSecBuf(&secbuf, cursor); // user name
  PrintBuf("user name", inBuf + secbuf.offset, secbuf.length);

  ReadSecBuf(&secbuf, cursor); // workstation name
  PrintBuf("workstation name", inBuf + secbuf.offset, secbuf.length);

  ReadSecBuf(&secbuf, cursor); // session key
  PrintBuf("session key", inBuf + secbuf.offset, secbuf.length);

  PRUint32 flags = ReadUint32(cursor);
  PrintBuf("flags", (const PRUint8 *) &flags, sizeof(flags));
  PrintFlags(flags);
}

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 181 of file ReadNTLM.cpp.

{
  PRUint16 x;
#ifdef IS_BIG_ENDIAN
  x = ((PRUint16) buf[1]) | ((PRUint16) buf[0] << 8);
#else
  x = ((PRUint16) buf[0]) | ((PRUint16) buf[1] << 8);
#endif
  buf += sizeof(x);
  return x;
}

Here is the caller graph for this function:

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

Definition at line 194 of file ReadNTLM.cpp.

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

Here is the caller graph for this function:


Variable Documentation

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

Definition at line 85 of file ReadNTLM.cpp.

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

Definition at line 86 of file ReadNTLM.cpp.

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

Definition at line 87 of file ReadNTLM.cpp.

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

Definition at line 88 of file ReadNTLM.cpp.