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.

532 lines
16 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. ntlmsspi.h
  5. Abstract:
  6. Header file describing the interface to code common to the
  7. NT Lanman Security Support Provider (NtLmSsp) Service and the DLL.
  8. Author:
  9. Cliff Van Dyke (CliffV) 17-Sep-1993
  10. Revision History:
  11. --*/
  12. #ifndef _NTLMSSPI_INCLUDED_
  13. #define _NTLMSSPI_INCLUDED_
  14. #include <rc4.h>
  15. #include <md5.h>
  16. #include <hmac.h>
  17. #include <crypt.h>
  18. #ifndef __MACSSP__
  19. #define SEC_FAR
  20. #define FAR
  21. #define _fmemcpy memcpy
  22. #define _fmemcmp memcmp
  23. #define _fmemset memset
  24. #define _fstrcmp strcmp
  25. #define _fstrcpy strcpy
  26. #define _fstrlen strlen
  27. #define _fstrncmp strncmp
  28. #endif
  29. #ifdef DOS
  30. #ifndef FAR
  31. #define FAR far
  32. #endif
  33. #ifndef SEC_FAR
  34. #define SEC_FAR FAR
  35. #endif
  36. #endif
  37. //#include <sysinc.h>
  38. #define MSV1_0_CHALLENGE_LENGTH 8
  39. #ifndef IN
  40. #define IN
  41. #define OUT
  42. #define OPTIONAL
  43. #endif
  44. #define ARGUMENT_PRESENT(ArgumentPointer) (\
  45. (CHAR *)(ArgumentPointer) != (CHAR *)(NULL) )
  46. #define UNREFERENCED_PARAMETER(P)
  47. #ifdef MAC
  48. #define swaplong(Value) \
  49. Value = ( (((Value) & 0xFF000000) >> 24) \
  50. | (((Value) & 0x00FF0000) >> 8) \
  51. | (((Value) & 0x0000FF00) << 8) \
  52. | (((Value) & 0x000000FF) << 24))
  53. #else
  54. #define swaplong(Value)
  55. #endif
  56. #ifdef MAC
  57. #define swapshort(Value) \
  58. Value = ( (((Value) & 0x00FF) << 8) \
  59. | (((Value) & 0xFF00) >> 8))
  60. #else
  61. #define swapshort(Value)
  62. #endif
  63. #ifndef MAC
  64. typedef int BOOL;
  65. #endif
  66. #ifndef TRUE
  67. #define FALSE 0
  68. #define TRUE 1
  69. #endif
  70. #ifndef MAC
  71. typedef unsigned long ULONG, DWORD, *PULONG;
  72. typedef unsigned long SEC_FAR *LPULONG;
  73. typedef unsigned short USHORT, WORD;
  74. typedef char CHAR, *PCHAR;
  75. typedef unsigned char UCHAR, *PUCHAR;
  76. typedef unsigned char SEC_FAR *LPUCHAR;
  77. typedef void SEC_FAR *PVOID, *LPVOID;
  78. typedef unsigned char BOOLEAN;
  79. #endif
  80. #ifndef BLDR_KERNEL_RUNTIME
  81. typedef long LUID, *PLUID;
  82. #endif
  83. //
  84. // Calculate the address of the base of the structure given its type, and an
  85. // address of a field within the structure.
  86. //
  87. #define CONTAINING_RECORD(address, type, field) ((type *)( \
  88. (PCHAR)(address) - \
  89. (PCHAR)(&((type *)0)->field)))
  90. #ifndef BLDR_KERNEL_RUNTIME
  91. typedef struct _LIST_ENTRY {
  92. struct _LIST_ENTRY *Flink;
  93. struct _LIST_ENTRY *Blink;
  94. } LIST_ENTRY, *PLIST_ENTRY;
  95. #endif
  96. //
  97. // VOID
  98. // InitializeListHead(
  99. // PLIST_ENTRY ListHead
  100. // );
  101. //
  102. #define InitializeListHead(ListHead) (\
  103. (ListHead)->Flink = (ListHead)->Blink = (ListHead))
  104. //
  105. // VOID
  106. // RemoveEntryList(
  107. // PLIST_ENTRY Entry
  108. // );
  109. //
  110. #define RemoveEntryList(Entry) {\
  111. PLIST_ENTRY _EX_Blink;\
  112. PLIST_ENTRY _EX_Flink;\
  113. _EX_Flink = (Entry)->Flink;\
  114. _EX_Blink = (Entry)->Blink;\
  115. _EX_Blink->Flink = _EX_Flink;\
  116. _EX_Flink->Blink = _EX_Blink;\
  117. }
  118. //
  119. // VOID
  120. // InsertHeadList(
  121. // PLIST_ENTRY ListHead,
  122. // PLIST_ENTRY Entry
  123. // );
  124. //
  125. #define InsertHeadList(ListHead,Entry) {\
  126. PLIST_ENTRY _EX_Flink;\
  127. PLIST_ENTRY _EX_ListHead;\
  128. _EX_ListHead = (ListHead);\
  129. _EX_Flink = _EX_ListHead->Flink;\
  130. (Entry)->Flink = _EX_Flink;\
  131. (Entry)->Blink = _EX_ListHead;\
  132. _EX_Flink->Blink = (Entry);\
  133. _EX_ListHead->Flink = (Entry);\
  134. }
  135. //
  136. // BOOLEAN
  137. // IsListEmpty(
  138. // PLIST_ENTRY ListHead
  139. // );
  140. //
  141. #define IsListEmpty(ListHead) \
  142. ((ListHead)->Flink == (ListHead))
  143. //
  144. // Maximum lifetime of a context
  145. //
  146. //#define NTLMSSP_MAX_LIFETIME (2*60*1000)L // 2 minutes
  147. #define NTLMSSP_MAX_LIFETIME 120000L // 2 minutes
  148. ////////////////////////////////////////////////////////////////////////
  149. //
  150. // Opaque Messages passed between client and server
  151. //
  152. ////////////////////////////////////////////////////////////////////////
  153. #define NTLMSSP_SIGNATURE "NTLMSSP"
  154. //
  155. // MessageType for the following messages.
  156. //
  157. typedef enum {
  158. NtLmNegotiate = 1,
  159. NtLmChallenge,
  160. NtLmAuthenticate,
  161. #ifdef MAC
  162. NtLmUnknown
  163. #endif
  164. } NTLM_MESSAGE_TYPE;
  165. //
  166. // Signature structure
  167. //
  168. typedef struct _NTLMSSP_MESSAGE_SIGNATURE {
  169. ULONG Version;
  170. ULONG RandomPad;
  171. ULONG CheckSum;
  172. ULONG Nonce;
  173. } NTLMSSP_MESSAGE_SIGNATURE, * PNTLMSSP_MESSAGE_SIGNATURE;
  174. #define NTLMSSP_MESSAGE_SIGNATURE_SIZE sizeof(NTLMSSP_MESSAGE_SIGNATURE)
  175. #define NTLMSSP_SIGN_VERSION 1
  176. #define NTLMSSP_KEY_SALT 0xbd
  177. #define MSV1_0_NTLMV2_RESPONSE_LENGTH 16
  178. #define MSV1_0_NTLMV2_OWF_LENGTH 16
  179. #define MSV1_0_CHALLENGE_LENGTH 8
  180. //
  181. // valid QoP flags
  182. //
  183. #define QOP_NTLMV2 0x00000001
  184. //
  185. // this is an MSV1_0 private data structure, defining the layout of an Ntlmv2
  186. // response, as sent by a client in the NtChallengeResponse field of the
  187. // NETLOGON_NETWORK_INFO structure. If can be differentiated from an old style
  188. // NT response by its length. This is crude, but it needs to pass through
  189. // servers and the servers' DCs that do not understand Ntlmv2 but that are
  190. // willing to pass longer responses.
  191. //
  192. typedef struct _MSV1_0_NTLMV2_RESPONSE {
  193. UCHAR Response[MSV1_0_NTLMV2_RESPONSE_LENGTH]; // hash of OWF of password with all the following fields
  194. UCHAR RespType; // id number of response; current is 1
  195. UCHAR HiRespType; // highest id number understood by client
  196. USHORT Flags; // reserved; must be sent as zero at this version
  197. ULONG MsgWord; // 32 bit message from client to server (for use by auth protocol)
  198. ULONGLONG TimeStamp; // time stamp when client generated response -- NT system time, quad part
  199. UCHAR ChallengeFromClient[MSV1_0_CHALLENGE_LENGTH];
  200. ULONG AvPairsOff; // offset to start of AvPairs (to allow future expansion)
  201. UCHAR Buffer[1]; // start of buffer with AV pairs (or future stuff -- so use the offset)
  202. } MSV1_0_NTLMV2_RESPONSE, *PMSV1_0_NTLMV2_RESPONSE;
  203. #define MSV1_0_NTLMV2_INPUT_LENGTH (sizeof(MSV1_0_NTLMV2_RESPONSE) - MSV1_0_NTLMV2_RESPONSE_LENGTH)
  204. typedef struct {
  205. UCHAR Response[MSV1_0_NTLMV2_RESPONSE_LENGTH];
  206. UCHAR ChallengeFromClient[MSV1_0_CHALLENGE_LENGTH];
  207. } MSV1_0_LMV2_RESPONSE, *PMSV1_0_LMV2_RESPONSE;
  208. //
  209. // User, Group and Password lengths
  210. //
  211. #define UNLEN 256 // Maximum user name length
  212. #define LM20_UNLEN 20 // LM 2.0 Maximum user name length
  213. //
  214. // String Lengths for various LanMan names
  215. //
  216. #define CNLEN 15 // Computer name length
  217. #define LM20_CNLEN 15 // LM 2.0 Computer name length
  218. #define DNLEN CNLEN // Maximum domain name length
  219. #define LM20_DNLEN LM20_CNLEN // LM 2.0 Maximum domain name length
  220. //
  221. // Size of the largest message
  222. // (The largest message is the AUTHENTICATE_MESSAGE)
  223. //
  224. #define DNSLEN 256 // length of DNS name
  225. #define TARGET_INFO_LEN ((2*DNSLEN + DNLEN + CNLEN) * sizeof(WCHAR) + \
  226. 5 * sizeof(MSV1_0_AV_PAIR))
  227. // length of NTLM2 response
  228. #define NTLMV2_RESPONSE_LENGTH (sizeof(MSV1_0_NTLMV2_RESPONSE) + \
  229. TARGET_INFO_LEN)
  230. #define NTLMSSP_MAX_MESSAGE_SIZE (sizeof(AUTHENTICATE_MESSAGE) + \
  231. LM_RESPONSE_LENGTH + \
  232. NTLMV2_RESPONSE_LENGTH + \
  233. (DNLEN + 1) * sizeof(WCHAR) + \
  234. (UNLEN + 1) * sizeof(WCHAR) + \
  235. (CNLEN + 1) * sizeof(WCHAR))
  236. typedef struct _MSV1_0_AV_PAIR {
  237. USHORT AvId;
  238. USHORT AvLen;
  239. // Data is treated as byte array following structure
  240. } MSV1_0_AV_PAIR, *PMSV1_0_AV_PAIR;
  241. //
  242. // bootssp does not support RtlOemStringToUnicodeString or
  243. // RtlUnicodeStringToOemString, punt to Ansi Strings
  244. //
  245. #define SspOemStringToUnicodeString RtlAnsiStringToUnicodeString
  246. #define SspUnicodeStringToOemString RtlUnicodeStringToAnsiString
  247. #define CSSEALMAGIC "session key to client-to-server sealing key magic constant"
  248. #define SCSEALMAGIC "session key to server-to-client sealing key magic constant"
  249. #define CSSIGNMAGIC "session key to client-to-server signing key magic constant"
  250. #define SCSIGNMAGIC "session key to server-to-client signing key magic constant"
  251. //
  252. // Valid values of NegotiateFlags
  253. //
  254. #define NTLMSSP_NEGOTIATE_UNICODE 0x00000001 // Text strings are in unicode
  255. #define NTLMSSP_NEGOTIATE_OEM 0x00000002 // Text strings are in OEM
  256. #define NTLMSSP_REQUEST_TARGET 0x00000004 // Server should return its authentication realm
  257. #define NTLMSSP_NEGOTIATE_SIGN 0x00000010 // Request signature capability
  258. #define NTLMSSP_NEGOTIATE_SEAL 0x00000020 // Request confidentiality
  259. #define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040 // Use datagram style authentication
  260. #define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080 // Use LM session key for sign/seal
  261. #define NTLMSSP_NEGOTIATE_NETWARE 0x00000100 // NetWare authentication
  262. #define NTLMSSP_NEGOTIATE_NTLM 0x00000200 // NTLM authentication
  263. #define NTLMSSP_NEGOTIATE_NT_ONLY 0x00000400 // NT authentication only (no LM)
  264. #define NTLMSSP_NEGOTIATE_NULL_SESSION 0x00000800 // NULL Sessions on NT 5.0 and beyand
  265. #define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED 0x1000 // Domain Name supplied on negotiate
  266. #define NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED 0x2000 // Workstation Name supplied on negotiate
  267. #define NTLMSSP_NEGOTIATE_LOCAL_CALL 0x00004000 // Indicates client/server are same machine
  268. #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000 // Sign for all security levels
  269. //
  270. // Valid target types returned by the server in Negotiate Flags
  271. //
  272. #define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000 // TargetName is a domain name
  273. #define NTLMSSP_TARGET_TYPE_SERVER 0x00020000 // TargetName is a server name
  274. #define NTLMSSP_TARGET_TYPE_SHARE 0x00040000 // TargetName is a share name
  275. #define NTLMSSP_NEGOTIATE_NTLM2 0x00080000 // NTLM2 authentication added for NT4-SP4
  276. #define NTLMSSP_NEGOTIATE_IDENTIFY 0x00100000 // Create identify level token
  277. //
  278. // Valid requests for additional output buffers
  279. //
  280. #define NTLMSSP_REQUEST_INIT_RESPONSE 0x00100000 // get back session keys
  281. #define NTLMSSP_REQUEST_ACCEPT_RESPONSE 0x00200000 // get back session key, LUID
  282. #define NTLMSSP_REQUEST_NON_NT_SESSION_KEY 0x00400000 // request non-nt session key
  283. #define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000 // target info present in challenge message
  284. #define NTLMSSP_NEGOTIATE_EXPORTED_CONTEXT 0x01000000 // It's an exported context
  285. #define NTLMSSP_NEGOTIATE_128 0x20000000 // negotiate 128 bit encryption
  286. #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000 // exchange a key using key exchange key
  287. #define NTLMSSP_NEGOTIATE_56 0x80000000 // negotiate 56 bit encryption
  288. // flags used in client space to control sign and seal; never appear on the wire
  289. #define NTLMSSP_APP_SEQ 0x00000040 // Use application provided seq num
  290. typedef struct _NTLMV2_DERIVED_SKEYS {
  291. ULONG KeyLen; // key length in octets
  292. ULONG* pSendNonce; // ptr to nonce to use for send
  293. ULONG* pRecvNonce; // ptr to nonce to use for receive
  294. struct RC4_KEYSTRUCT* pSealRc4Sched; // ptr to key sched used for Seal
  295. struct RC4_KEYSTRUCT* pUnsealRc4Sched; // ptr to key sched used to Unseal
  296. ULONG SendNonce;
  297. ULONG RecvNonce;
  298. UCHAR SignSessionKey[sizeof(USER_SESSION_KEY)];
  299. UCHAR VerifySessionKey[sizeof(USER_SESSION_KEY)];
  300. UCHAR SealSessionKey[sizeof(USER_SESSION_KEY)];
  301. UCHAR UnsealSessionKey[sizeof(USER_SESSION_KEY)];
  302. ULONG64 Pad1; // pad keystructs to 64.
  303. struct RC4_KEYSTRUCT SealRc4Sched; // key struct used for Seal
  304. ULONG64 Pad2; // pad keystructs to 64.
  305. struct RC4_KEYSTRUCT UnsealRc4Sched; // key struct used to Unseal
  306. } NTLMV2_DERIVED_SKEYS, *PNTLMV2_DERIVED_SKEYS;
  307. //
  308. // Opaque message returned from first call to InitializeSecurityContext
  309. //
  310. typedef struct _NEGOTIATE_MESSAGE {
  311. UCHAR Signature[sizeof(NTLMSSP_SIGNATURE)];
  312. NTLM_MESSAGE_TYPE MessageType;
  313. ULONG NegotiateFlags;
  314. STRING32 OemDomainName;
  315. STRING32 OemWorkstationName;
  316. } NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;
  317. //
  318. // Opaque message returned from first call to AcceptSecurityContext
  319. //
  320. typedef struct _CHALLENGE_MESSAGE {
  321. UCHAR Signature[sizeof(NTLMSSP_SIGNATURE)];
  322. NTLM_MESSAGE_TYPE MessageType;
  323. STRING32 TargetName;
  324. ULONG NegotiateFlags;
  325. UCHAR Challenge[MSV1_0_CHALLENGE_LENGTH];
  326. ULONG64 ServerContextHandle;
  327. STRING32 TargetInfo;
  328. } CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE;
  329. //
  330. // Opaque message returned from second call to InitializeSecurityContext
  331. //
  332. typedef struct _AUTHENTICATE_MESSAGE {
  333. UCHAR Signature[sizeof(NTLMSSP_SIGNATURE)];
  334. NTLM_MESSAGE_TYPE MessageType;
  335. STRING32 LmChallengeResponse;
  336. STRING32 NtChallengeResponse;
  337. STRING32 DomainName;
  338. STRING32 UserName;
  339. STRING32 Workstation;
  340. STRING32 SessionKey;
  341. ULONG NegotiateFlags;
  342. } AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
  343. typedef enum _eSignSealOp {
  344. eSign, // MakeSignature is calling
  345. eVerify, // VerifySignature is calling
  346. eSeal, // SealMessage is calling
  347. eUnseal // UnsealMessage is calling
  348. } eSignSealOp;
  349. //
  350. // Version 1 is the structure above, using stream RC4 to encrypt the trailing
  351. // 12 bytes.
  352. //
  353. #define NTLM_SIGN_VERSION 1
  354. #ifdef __cplusplus
  355. extern "C" {
  356. #endif
  357. //
  358. // the following declarations may be duplicates
  359. //
  360. NTSTATUS
  361. RtlAnsiStringToUnicodeString(
  362. UNICODE_STRING* DestinationString,
  363. ANSI_STRING* SourceString,
  364. BOOLEAN AllocateDestinationString
  365. );
  366. VOID
  367. RtlInitString(
  368. OUT STRING* DestinationString,
  369. IN PCSTR SourceString OPTIONAL
  370. );
  371. NTSTATUS
  372. RtlUnicodeStringToAnsiString(
  373. OUT ANSI_STRING* DestinationString,
  374. IN UNICODE_STRING* SourceString,
  375. IN BOOLEAN AllocateDestinationString
  376. );
  377. WCHAR
  378. RtlUpcaseUnicodeChar(
  379. IN WCHAR SourceCharacter
  380. );
  381. ////////////////////////////////////////////////////////////////////////
  382. //
  383. // Procedure Forwards
  384. //
  385. ////////////////////////////////////////////////////////////////////////
  386. PVOID
  387. SspAlloc(
  388. int Size
  389. );
  390. void
  391. SspFree(
  392. PVOID Buffer
  393. );
  394. PSTRING
  395. SspAllocateString(
  396. PVOID Value
  397. );
  398. PSTRING
  399. SspAllocateStringBlock(
  400. PVOID Value,
  401. int Length
  402. );
  403. void
  404. SspFreeString(
  405. PSTRING * String
  406. );
  407. void
  408. SspCopyString(
  409. IN PVOID MessageBuffer,
  410. OUT PSTRING OutString,
  411. IN PSTRING InString,
  412. IN OUT PCHAR *Where,
  413. IN BOOLEAN Absolute
  414. );
  415. void
  416. SspCopyStringFromRaw(
  417. IN PVOID MessageBuffer,
  418. OUT STRING32* OutString,
  419. IN PCHAR InString,
  420. IN int InStringLength,
  421. IN OUT PCHAR *Where
  422. );
  423. DWORD
  424. SspTicks(
  425. );
  426. #ifdef __cplusplus
  427. }
  428. #endif
  429. #endif // ifndef _NTLMSSPI_INCLUDED_