You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
322 lines
11 KiB
322 lines
11 KiB
/*
|
|
* sspdebug.cpp
|
|
* MSUAM
|
|
*
|
|
* Created by mconrad on Sun Sep 30 2001.
|
|
* Copyright (c) 2001 Microsoft Corp. All rights reserved.
|
|
*
|
|
*/
|
|
|
|
#ifdef SSP_TARGET_CARBON
|
|
#include <Carbon/Carbon.h>
|
|
#endif
|
|
|
|
#include <bootdefs.h>
|
|
#include <ntlmsspi.h>
|
|
#include <ntlmsspv2.h>
|
|
#include <debug.h> //windows version
|
|
#include <sspdebug.h>
|
|
|
|
#if defined(SSP_DEBUG) && defined(SSP_TARGET_CARBON)
|
|
|
|
//
|
|
// Valid values of NegotiateFlags
|
|
//
|
|
typedef struct _NTLM_NEG_FLAGS {
|
|
char* desc;
|
|
ULONG flag;
|
|
} NTLM_NEG_FLAGS;
|
|
|
|
NTLM_NEG_FLAGS g_flagTable[] = {
|
|
//
|
|
// Valid values of NegotiateFlags
|
|
//
|
|
{"NTLMSSP_NEGOTIATE_UNICODE", 0x00000001 }, // Text strings are in unicode
|
|
{"NTLMSSP_NEGOTIATE_OEM", 0x00000002 }, // Text strings are in OEM
|
|
{"NTLMSSP_REQUEST_TARGET", 0x00000004 }, // Server should return its authentication realm
|
|
{"NTLMSSP_NEGOTIATE_SIGN", 0x00000010 }, // Request signature capability
|
|
{"NTLMSSP_NEGOTIATE_SEAL", 0x00000020 }, // Request confidentiality
|
|
{"NTLMSSP_NEGOTIATE_DATAGRAM", 0x00000040 }, // Use datagram style authentication
|
|
{"NTLMSSP_NEGOTIATE_LM_KEY", 0x00000080 }, // Use LM session key for sign/seal
|
|
{"NTLMSSP_NEGOTIATE_NETWARE", 0x00000100 }, // NetWare authentication
|
|
{"NTLMSSP_NEGOTIATE_NTLM", 0x00000200 }, // NTLM authentication
|
|
{"NTLMSSP_NEGOTIATE_NT_ONLY", 0x00000400 }, // NT authentication only (no LM)
|
|
{"NTLMSSP_NEGOTIATE_NULL_SESSION", 0x00000800 }, // NULL Sessions on NT 5.0 and beyand
|
|
{"NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED", 0x1000 }, // Domain Name supplied on negotiate
|
|
{"NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED", 0x2000 }, // Workstation Name supplied on negotiate
|
|
{"NTLMSSP_NEGOTIATE_LOCAL_CALL", 0x00004000}, // Indicates client/server are same machine
|
|
{"NTLMSSP_NEGOTIATE_ALWAYS_SIGN", 0x00008000}, // Sign for all security levels
|
|
|
|
|
|
//
|
|
// Valid target types returned by the server in Negotiate Flags
|
|
//
|
|
{"NTLMSSP_TARGET_TYPE_DOMAIN", 0x00010000}, // TargetName is a domain name
|
|
{"NTLMSSP_TARGET_TYPE_SERVER", 0x00020000}, // TargetName is a server name
|
|
{"NTLMSSP_TARGET_TYPE_SHARE", 0x00040000}, // TargetName is a share name
|
|
{"NTLMSSP_NEGOTIATE_NTLM2", 0x00080000}, // NTLM2 authentication added for NT4-SP4
|
|
|
|
{"NTLMSSP_NEGOTIATE_IDENTIFY", 0x00100000}, // Create identify level token
|
|
|
|
//
|
|
// Valid requests for additional output buffers
|
|
//
|
|
{"NTLMSSP_REQUEST_INIT_RESPONSE", 0x00100000}, // get back session keys
|
|
{"NTLMSSP_REQUEST_ACCEPT_RESPONSE", 0x00200000}, // get back session key, LUID
|
|
{"NTLMSSP_REQUEST_NON_NT_SESSION_KEY", 0x00400000}, // request non-nt session key
|
|
{"NTLMSSP_NEGOTIATE_TARGET_INFO", 0x00800000}, // target info present in challenge message
|
|
|
|
{"NTLMSSP_NEGOTIATE_EXPORTED_CONTEXT", 0x01000000}, // It's an exported context
|
|
|
|
{"NTLMSSP_NEGOTIATE_128", 0x20000000}, // negotiate 128 bit encryption
|
|
{"NTLMSSP_NEGOTIATE_KEY_EXCH", 0x40000000}, // exchange a key using key exchange key
|
|
{"NTLMSSP_NEGOTIATE_56", 0x80000000}, // negotiate 56 bit encryption
|
|
|
|
//
|
|
// flags used in client space to control sign and seal; never appear on the wire
|
|
//
|
|
{"NTLMSSP_APP_SEQ", 0x0040}, // Use application provided seq num
|
|
};
|
|
|
|
char toChar(IN char c)
|
|
{
|
|
if (c >= 0x20 && c <= 0x7E) {
|
|
return c;
|
|
}
|
|
|
|
return '.';
|
|
}
|
|
|
|
void spaceIt(IN char* buf, IN ULONG len)
|
|
{
|
|
ULONG i;
|
|
|
|
for ( i = 0; i < len; i++) {
|
|
buf[i] = ' ';
|
|
}
|
|
}
|
|
|
|
char toHex(IN int c)
|
|
{
|
|
if (c >= 0x0 && c <= 0x9) {
|
|
return c + '0';
|
|
}
|
|
|
|
return c - 10 + 'a';
|
|
}
|
|
|
|
void _SspDebugPrintHex(IN const void *buffer, IN LONG len)
|
|
{
|
|
unsigned char* p = (unsigned char*) buffer;
|
|
int high = 0;
|
|
int low = 0;
|
|
char line[256] = {0};
|
|
int i;
|
|
|
|
if (!len) return;
|
|
|
|
spaceIt(line, 72);
|
|
|
|
for (i = 0; i < len; i++) {
|
|
high = p[i] / 16;
|
|
low = p[i] % 16;
|
|
|
|
line[3 * (i % 16)] = toHex(high);
|
|
line[3 * (i % 16) + 1] = toHex(low);
|
|
line [52 + (i % 16)] = toChar(p[i]);
|
|
|
|
if (i % 16 == 7 && i != (len - 1)) {
|
|
line[3 * (i % 16) + 2] = '-';
|
|
}
|
|
|
|
if (i % 16 == 15) {
|
|
|
|
printf(" %s\n", line);
|
|
spaceIt(line, 72);
|
|
}
|
|
}
|
|
|
|
printf(" %s\n", line);
|
|
}
|
|
|
|
void _SspDebugPrintString32(IN STRING32 str32, IN const void* base)
|
|
{
|
|
// printf("%d(%d):", str32.Length, str32.MaximumLength);
|
|
if (str32.Length <= 1024) {
|
|
_SspDebugPrintHex((const char*)base + (ULONG)str32.Buffer, str32.Length);
|
|
} else {
|
|
printf(" Length %d, MaximumLenght %d ", str32.Length, str32.MaximumLength);
|
|
printf(" <not initialized>\n");
|
|
}
|
|
}
|
|
|
|
PCSTR g_attr_table[] = {
|
|
"",
|
|
"NetbiosServerName",
|
|
"NetbiosDomainName",
|
|
"DnsComputerName",
|
|
"DnsDomainName",
|
|
"DnsTreeName",
|
|
"Flags",
|
|
"", "", "", "", "", "",
|
|
};
|
|
|
|
void _SspDebugPrintString32TargetInfo(IN STRING32* pTargetInfo, IN const void* buffer)
|
|
{
|
|
const char* start = reinterpret_cast<const char*>(buffer) + pTargetInfo->Buffer;
|
|
const char* p = NULL;
|
|
USHORT attr = 0;
|
|
USHORT len = 0;
|
|
|
|
if (pTargetInfo->Length >= 1024) {
|
|
|
|
printf("String32 TargetInfo too large\n");
|
|
return;
|
|
}
|
|
|
|
_SspDebugPrintHex(start, pTargetInfo->Length);
|
|
|
|
for (p = start; p < start + pTargetInfo->Length; p += (2 * sizeof(USHORT) + len)){
|
|
|
|
attr = reinterpret_cast<USHORT*>(const_cast<char*>(p))[0];
|
|
len = reinterpret_cast<USHORT*>(const_cast<char*>(p))[1];
|
|
|
|
if (attr >= MsvAvNbComputerName && attr <= MsvAvDnsTreeName) {
|
|
|
|
printf("%s: ", g_attr_table[attr]);
|
|
//debugNPrintfW(p + 2 * sizeof(USHORT), len);
|
|
printf("\n");
|
|
} else if (attr == MsvAvFlags) {
|
|
|
|
printf("Flags: 0x%x\n", (unsigned int)*reinterpret_cast<ULONG*>(const_cast<char*>(p + 2 * sizeof(USHORT))) );
|
|
} else if (attr == MsvAvEOL) {
|
|
|
|
break;
|
|
} else {
|
|
|
|
printf("Unrecognized attribute %d\n", attr);
|
|
}
|
|
}
|
|
}
|
|
|
|
void _SspDebugPrintNegFlags(IN ULONG flags)
|
|
{
|
|
unsigned int i;
|
|
|
|
printf(" 0x%x\n", (unsigned int)flags);
|
|
for (i = 0; i < sizeof(g_flagTable)/sizeof(*g_flagTable); i++) {
|
|
if (g_flagTable[i].flag & flags) {
|
|
flags &= ~g_flagTable[i].flag;
|
|
printf(" + %s\n", g_flagTable[i].desc);
|
|
}
|
|
}
|
|
|
|
if (flags) {
|
|
printf("unrecognized flags: 0x%x\n", (unsigned int)flags);
|
|
}
|
|
}
|
|
|
|
void _SspDebugPrintNTLMMsg(IN const void* buf, IN ULONG len)
|
|
{
|
|
const char* buffer = reinterpret_cast<const char*>(buf);
|
|
|
|
NTLM_MESSAGE_TYPE msgType;
|
|
ULONG negFlags;
|
|
NEGOTIATE_MESSAGE* pNeg = (NEGOTIATE_MESSAGE*) buffer;
|
|
CHALLENGE_MESSAGE* pCha = (CHALLENGE_MESSAGE*) buffer;
|
|
AUTHENTICATE_MESSAGE* pAut = (AUTHENTICATE_MESSAGE*) buffer;
|
|
STRING32 scratch = {0};
|
|
|
|
printf("buf %p, len %d\n", buf, (unsigned int)len);
|
|
|
|
if (!buf) {
|
|
|
|
printf("****Empty NTLM msg\n");
|
|
return;
|
|
}
|
|
|
|
if (strcmp(buffer, "NTLMSSP"))
|
|
{
|
|
printf("****buffer corrupted!\n");
|
|
return;
|
|
}
|
|
|
|
printf("******************* Message Begin *********************\n");
|
|
_SspDebugPrintHex(buffer,len);
|
|
printf("******************* Message END ***********************\n");
|
|
|
|
msgType = *((NTLM_MESSAGE_TYPE*) (buffer + strlen(buffer) + 1));
|
|
|
|
switch (msgType) {
|
|
case NtLmNegotiate:
|
|
printf("Msg type: Negociate\n");
|
|
printf("NegotiateFlags: ");
|
|
_SspDebugPrintNegFlags(pNeg->NegotiateFlags);
|
|
printf("OemDomainName: \n");
|
|
_SspDebugPrintString32(pNeg->OemDomainName, buffer);
|
|
printf("OemWorkstationName: \n");
|
|
_SspDebugPrintString32(pNeg->OemWorkstationName, buffer);
|
|
break;
|
|
case NtLmChallenge:
|
|
printf("Msg type: Challenge\n");
|
|
printf("TargeName: \n");
|
|
_SspDebugPrintString32(pCha->TargetName, buffer);
|
|
printf("NegotiateFlags: ");
|
|
_SspDebugPrintNegFlags(pCha->NegotiateFlags);
|
|
printf("Chanllenge: \n");
|
|
_SspDebugPrintHex(pCha->Challenge, MSV1_0_CHALLENGE_LENGTH);
|
|
printf("ServerContextHandle (Lower Upper): \n");
|
|
_SspDebugPrintHex(&pCha->ServerContextHandle, sizeof(pCha->ServerContextHandle));
|
|
printf("TargetInfo: \n");
|
|
_SspDebugPrintString32TargetInfo(&pCha->TargetInfo, buffer);
|
|
break;
|
|
case NtLmAuthenticate:
|
|
printf("Msg type: Authenticate\n");
|
|
|
|
memcpy(&scratch, &pAut->LmChallengeResponse, sizeof(scratch));
|
|
SspSwapString32Bytes(&scratch);
|
|
printf("LmChallengeResponse (length %d): \n", scratch.Length);
|
|
_SspDebugPrintHex(buffer + (ULONG) scratch.Buffer, scratch.Length);
|
|
|
|
memcpy(&scratch, &pAut->NtChallengeResponse, sizeof(scratch));
|
|
SspSwapString32Bytes(&scratch);
|
|
printf("NtChallengeResponse (length %d): \n", scratch.Length);
|
|
_SspDebugPrintHex(buffer + (ULONG) scratch.Buffer, scratch.Length);
|
|
|
|
printf("DomainName: \n");
|
|
memcpy(&scratch, &pAut->DomainName, sizeof(scratch));
|
|
SspSwapString32Bytes(&scratch);
|
|
_SspDebugPrintString32(scratch, buffer);
|
|
|
|
printf("UserName: \n");
|
|
memcpy(&scratch, &pAut->UserName, sizeof(scratch));
|
|
SspSwapString32Bytes(&scratch);
|
|
_SspDebugPrintString32(scratch, buffer);
|
|
|
|
printf("Workstation: \n");
|
|
memcpy(&scratch, &pAut->Workstation, sizeof(scratch));
|
|
SspSwapString32Bytes(&scratch);
|
|
_SspDebugPrintString32(scratch, buffer);
|
|
|
|
memcpy(&scratch, &pAut->SessionKey, sizeof(scratch));
|
|
SspSwapString32Bytes(&scratch);
|
|
printf("Sessionkey (length %d): \n", scratch.Length);
|
|
_SspDebugPrintHex(buffer + (ULONG) scratch.Buffer, scratch.Length);
|
|
|
|
printf("NegotiateFlags: ");
|
|
negFlags = pAut->NegotiateFlags;
|
|
swaplong(negFlags);
|
|
_SspDebugPrintNegFlags(negFlags);
|
|
break;
|
|
case NtLmUnknown:
|
|
printf("unknown msg.\n");
|
|
break;
|
|
default:
|
|
printf("buffer corrupted.\n");
|
|
break;
|
|
}
|
|
|
|
printf("******************** INTERP END ***********************\n");
|
|
}
|
|
|
|
#endif //SSP_DEBUG
|