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.

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