Leaked source code of windows server 2003
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.

321 lines
11 KiB

  1. /*
  2. * sspdebug.cpp
  3. * MSUAM
  4. *
  5. * Created by mconrad on Sun Sep 30 2001.
  6. * Copyright (c) 2001 Microsoft Corp. All rights reserved.
  7. *
  8. */
  9. #ifdef SSP_TARGET_CARBON
  10. #include <Carbon/Carbon.h>
  11. #endif
  12. #include <bootdefs.h>
  13. #include <ntlmsspi.h>
  14. #include <ntlmsspv2.h>
  15. #include <debug.h> //windows version
  16. #include <sspdebug.h>
  17. #if defined(SSP_DEBUG) && defined(SSP_TARGET_CARBON)
  18. //
  19. // Valid values of NegotiateFlags
  20. //
  21. typedef struct _NTLM_NEG_FLAGS {
  22. char* desc;
  23. ULONG flag;
  24. } NTLM_NEG_FLAGS;
  25. NTLM_NEG_FLAGS g_flagTable[] = {
  26. //
  27. // Valid values of NegotiateFlags
  28. //
  29. {"NTLMSSP_NEGOTIATE_UNICODE", 0x00000001 }, // Text strings are in unicode
  30. {"NTLMSSP_NEGOTIATE_OEM", 0x00000002 }, // Text strings are in OEM
  31. {"NTLMSSP_REQUEST_TARGET", 0x00000004 }, // Server should return its authentication realm
  32. {"NTLMSSP_NEGOTIATE_SIGN", 0x00000010 }, // Request signature capability
  33. {"NTLMSSP_NEGOTIATE_SEAL", 0x00000020 }, // Request confidentiality
  34. {"NTLMSSP_NEGOTIATE_DATAGRAM", 0x00000040 }, // Use datagram style authentication
  35. {"NTLMSSP_NEGOTIATE_LM_KEY", 0x00000080 }, // Use LM session key for sign/seal
  36. {"NTLMSSP_NEGOTIATE_NETWARE", 0x00000100 }, // NetWare authentication
  37. {"NTLMSSP_NEGOTIATE_NTLM", 0x00000200 }, // NTLM authentication
  38. {"NTLMSSP_NEGOTIATE_NT_ONLY", 0x00000400 }, // NT authentication only (no LM)
  39. {"NTLMSSP_NEGOTIATE_NULL_SESSION", 0x00000800 }, // NULL Sessions on NT 5.0 and beyand
  40. {"NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED", 0x1000 }, // Domain Name supplied on negotiate
  41. {"NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED", 0x2000 }, // Workstation Name supplied on negotiate
  42. {"NTLMSSP_NEGOTIATE_LOCAL_CALL", 0x00004000}, // Indicates client/server are same machine
  43. {"NTLMSSP_NEGOTIATE_ALWAYS_SIGN", 0x00008000}, // Sign for all security levels
  44. //
  45. // Valid target types returned by the server in Negotiate Flags
  46. //
  47. {"NTLMSSP_TARGET_TYPE_DOMAIN", 0x00010000}, // TargetName is a domain name
  48. {"NTLMSSP_TARGET_TYPE_SERVER", 0x00020000}, // TargetName is a server name
  49. {"NTLMSSP_TARGET_TYPE_SHARE", 0x00040000}, // TargetName is a share name
  50. {"NTLMSSP_NEGOTIATE_NTLM2", 0x00080000}, // NTLM2 authentication added for NT4-SP4
  51. {"NTLMSSP_NEGOTIATE_IDENTIFY", 0x00100000}, // Create identify level token
  52. //
  53. // Valid requests for additional output buffers
  54. //
  55. {"NTLMSSP_REQUEST_INIT_RESPONSE", 0x00100000}, // get back session keys
  56. {"NTLMSSP_REQUEST_ACCEPT_RESPONSE", 0x00200000}, // get back session key, LUID
  57. {"NTLMSSP_REQUEST_NON_NT_SESSION_KEY", 0x00400000}, // request non-nt session key
  58. {"NTLMSSP_NEGOTIATE_TARGET_INFO", 0x00800000}, // target info present in challenge message
  59. {"NTLMSSP_NEGOTIATE_EXPORTED_CONTEXT", 0x01000000}, // It's an exported context
  60. {"NTLMSSP_NEGOTIATE_128", 0x20000000}, // negotiate 128 bit encryption
  61. {"NTLMSSP_NEGOTIATE_KEY_EXCH", 0x40000000}, // exchange a key using key exchange key
  62. {"NTLMSSP_NEGOTIATE_56", 0x80000000}, // negotiate 56 bit encryption
  63. //
  64. // flags used in client space to control sign and seal; never appear on the wire
  65. //
  66. {"NTLMSSP_APP_SEQ", 0x0040}, // Use application provided seq num
  67. };
  68. char toChar(IN char c)
  69. {
  70. if (c >= 0x20 && c <= 0x7E) {
  71. return c;
  72. }
  73. return '.';
  74. }
  75. void spaceIt(IN char* buf, IN ULONG len)
  76. {
  77. ULONG i;
  78. for ( i = 0; i < len; i++) {
  79. buf[i] = ' ';
  80. }
  81. }
  82. char toHex(IN int c)
  83. {
  84. if (c >= 0x0 && c <= 0x9) {
  85. return c + '0';
  86. }
  87. return c - 10 + 'a';
  88. }
  89. void _SspDebugPrintHex(IN const void *buffer, IN LONG len)
  90. {
  91. unsigned char* p = (unsigned char*) buffer;
  92. int high = 0;
  93. int low = 0;
  94. char line[256] = {0};
  95. int i;
  96. if (!len) return;
  97. spaceIt(line, 72);
  98. for (i = 0; i < len; i++) {
  99. high = p[i] / 16;
  100. low = p[i] % 16;
  101. line[3 * (i % 16)] = toHex(high);
  102. line[3 * (i % 16) + 1] = toHex(low);
  103. line [52 + (i % 16)] = toChar(p[i]);
  104. if (i % 16 == 7 && i != (len - 1)) {
  105. line[3 * (i % 16) + 2] = '-';
  106. }
  107. if (i % 16 == 15) {
  108. printf(" %s\n", line);
  109. spaceIt(line, 72);
  110. }
  111. }
  112. printf(" %s\n", line);
  113. }
  114. void _SspDebugPrintString32(IN STRING32 str32, IN const void* base)
  115. {
  116. // printf("%d(%d):", str32.Length, str32.MaximumLength);
  117. if (str32.Length <= 1024) {
  118. _SspDebugPrintHex((const char*)base + (ULONG)str32.Buffer, str32.Length);
  119. } else {
  120. printf(" Length %d, MaximumLenght %d ", str32.Length, str32.MaximumLength);
  121. printf(" <not initialized>\n");
  122. }
  123. }
  124. PCSTR g_attr_table[] = {
  125. "",
  126. "NetbiosServerName",
  127. "NetbiosDomainName",
  128. "DnsComputerName",
  129. "DnsDomainName",
  130. "DnsTreeName",
  131. "Flags",
  132. "", "", "", "", "", "",
  133. };
  134. void _SspDebugPrintString32TargetInfo(IN STRING32* pTargetInfo, IN const void* buffer)
  135. {
  136. const char* start = reinterpret_cast<const char*>(buffer) + pTargetInfo->Buffer;
  137. const char* p = NULL;
  138. USHORT attr = 0;
  139. USHORT len = 0;
  140. if (pTargetInfo->Length >= 1024) {
  141. printf("String32 TargetInfo too large\n");
  142. return;
  143. }
  144. _SspDebugPrintHex(start, pTargetInfo->Length);
  145. for (p = start; p < start + pTargetInfo->Length; p += (2 * sizeof(USHORT) + len)){
  146. attr = reinterpret_cast<USHORT*>(const_cast<char*>(p))[0];
  147. len = reinterpret_cast<USHORT*>(const_cast<char*>(p))[1];
  148. if (attr >= MsvAvNbComputerName && attr <= MsvAvDnsTreeName) {
  149. printf("%s: ", g_attr_table[attr]);
  150. //debugNPrintfW(p + 2 * sizeof(USHORT), len);
  151. printf("\n");
  152. } else if (attr == MsvAvFlags) {
  153. printf("Flags: 0x%x\n", (unsigned int)*reinterpret_cast<ULONG*>(const_cast<char*>(p + 2 * sizeof(USHORT))) );
  154. } else if (attr == MsvAvEOL) {
  155. break;
  156. } else {
  157. printf("Unrecognized attribute %d\n", attr);
  158. }
  159. }
  160. }
  161. void _SspDebugPrintNegFlags(IN ULONG flags)
  162. {
  163. unsigned int i;
  164. printf(" 0x%x\n", (unsigned int)flags);
  165. for (i = 0; i < sizeof(g_flagTable)/sizeof(*g_flagTable); i++) {
  166. if (g_flagTable[i].flag & flags) {
  167. flags &= ~g_flagTable[i].flag;
  168. printf(" + %s\n", g_flagTable[i].desc);
  169. }
  170. }
  171. if (flags) {
  172. printf("unrecognized flags: 0x%x\n", (unsigned int)flags);
  173. }
  174. }
  175. void _SspDebugPrintNTLMMsg(IN const void* buf, IN ULONG len)
  176. {
  177. const char* buffer = reinterpret_cast<const char*>(buf);
  178. NTLM_MESSAGE_TYPE msgType;
  179. ULONG negFlags;
  180. NEGOTIATE_MESSAGE* pNeg = (NEGOTIATE_MESSAGE*) buffer;
  181. CHALLENGE_MESSAGE* pCha = (CHALLENGE_MESSAGE*) buffer;
  182. AUTHENTICATE_MESSAGE* pAut = (AUTHENTICATE_MESSAGE*) buffer;
  183. STRING32 scratch = {0};
  184. printf("buf %p, len %d\n", buf, (unsigned int)len);
  185. if (!buf) {
  186. printf("****Empty NTLM msg\n");
  187. return;
  188. }
  189. if (strcmp(buffer, "NTLMSSP"))
  190. {
  191. printf("****buffer corrupted!\n");
  192. return;
  193. }
  194. printf("******************* Message Begin *********************\n");
  195. _SspDebugPrintHex(buffer,len);
  196. printf("******************* Message END ***********************\n");
  197. msgType = *((NTLM_MESSAGE_TYPE*) (buffer + strlen(buffer) + 1));
  198. switch (msgType) {
  199. case NtLmNegotiate:
  200. printf("Msg type: Negociate\n");
  201. printf("NegotiateFlags: ");
  202. _SspDebugPrintNegFlags(pNeg->NegotiateFlags);
  203. printf("OemDomainName: \n");
  204. _SspDebugPrintString32(pNeg->OemDomainName, buffer);
  205. printf("OemWorkstationName: \n");
  206. _SspDebugPrintString32(pNeg->OemWorkstationName, buffer);
  207. break;
  208. case NtLmChallenge:
  209. printf("Msg type: Challenge\n");
  210. printf("TargeName: \n");
  211. _SspDebugPrintString32(pCha->TargetName, buffer);
  212. printf("NegotiateFlags: ");
  213. _SspDebugPrintNegFlags(pCha->NegotiateFlags);
  214. printf("Chanllenge: \n");
  215. _SspDebugPrintHex(pCha->Challenge, MSV1_0_CHALLENGE_LENGTH);
  216. printf("ServerContextHandle (Lower Upper): \n");
  217. _SspDebugPrintHex(&pCha->ServerContextHandle, sizeof(pCha->ServerContextHandle));
  218. printf("TargetInfo: \n");
  219. _SspDebugPrintString32TargetInfo(&pCha->TargetInfo, buffer);
  220. break;
  221. case NtLmAuthenticate:
  222. printf("Msg type: Authenticate\n");
  223. memcpy(&scratch, &pAut->LmChallengeResponse, sizeof(scratch));
  224. SspSwapString32Bytes(&scratch);
  225. printf("LmChallengeResponse (length %d): \n", scratch.Length);
  226. _SspDebugPrintHex(buffer + (ULONG) scratch.Buffer, scratch.Length);
  227. memcpy(&scratch, &pAut->NtChallengeResponse, sizeof(scratch));
  228. SspSwapString32Bytes(&scratch);
  229. printf("NtChallengeResponse (length %d): \n", scratch.Length);
  230. _SspDebugPrintHex(buffer + (ULONG) scratch.Buffer, scratch.Length);
  231. printf("DomainName: \n");
  232. memcpy(&scratch, &pAut->DomainName, sizeof(scratch));
  233. SspSwapString32Bytes(&scratch);
  234. _SspDebugPrintString32(scratch, buffer);
  235. printf("UserName: \n");
  236. memcpy(&scratch, &pAut->UserName, sizeof(scratch));
  237. SspSwapString32Bytes(&scratch);
  238. _SspDebugPrintString32(scratch, buffer);
  239. printf("Workstation: \n");
  240. memcpy(&scratch, &pAut->Workstation, sizeof(scratch));
  241. SspSwapString32Bytes(&scratch);
  242. _SspDebugPrintString32(scratch, buffer);
  243. memcpy(&scratch, &pAut->SessionKey, sizeof(scratch));
  244. SspSwapString32Bytes(&scratch);
  245. printf("Sessionkey (length %d): \n", scratch.Length);
  246. _SspDebugPrintHex(buffer + (ULONG) scratch.Buffer, scratch.Length);
  247. printf("NegotiateFlags: ");
  248. negFlags = pAut->NegotiateFlags;
  249. swaplong(negFlags);
  250. _SspDebugPrintNegFlags(negFlags);
  251. break;
  252. case NtLmUnknown:
  253. printf("unknown msg.\n");
  254. break;
  255. default:
  256. printf("buffer corrupted.\n");
  257. break;
  258. }
  259. printf("******************** INTERP END ***********************\n");
  260. }
  261. #endif //SSP_DEBUG