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

/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
ntlmsspi.h
Abstract:
Header file describing the interface to code common to the
NT Lanman Security Support Provider (NtLmSsp) Service and the DLL.
Author:
Cliff Van Dyke (CliffV) 17-Sep-1993
Revision History:
--*/
#ifndef _NTLMSSPI_INCLUDED_
#define _NTLMSSPI_INCLUDED_
#include <rc4.h>
#include <md5.h>
#include <hmac.h>
#include <crypt.h>
#ifndef __MACSSP__
#define SEC_FAR
#define FAR
#define _fmemcpy memcpy
#define _fmemcmp memcmp
#define _fmemset memset
#define _fstrcmp strcmp
#define _fstrcpy strcpy
#define _fstrlen strlen
#define _fstrncmp strncmp
#endif
#ifdef DOS
#ifndef FAR
#define FAR far
#endif
#ifndef SEC_FAR
#define SEC_FAR FAR
#endif
#endif
//#include <sysinc.h>
#define MSV1_0_CHALLENGE_LENGTH 8
#ifndef IN
#define IN
#define OUT
#define OPTIONAL
#endif
#define ARGUMENT_PRESENT(ArgumentPointer) (\
(CHAR *)(ArgumentPointer) != (CHAR *)(NULL) )
#define UNREFERENCED_PARAMETER(P)
#ifdef MAC
#define swaplong(Value) \
Value = ( (((Value) & 0xFF000000) >> 24) \
| (((Value) & 0x00FF0000) >> 8) \
| (((Value) & 0x0000FF00) << 8) \
| (((Value) & 0x000000FF) << 24))
#else
#define swaplong(Value)
#endif
#ifdef MAC
#define swapshort(Value) \
Value = ( (((Value) & 0x00FF) << 8) \
| (((Value) & 0xFF00) >> 8))
#else
#define swapshort(Value)
#endif
#ifndef MAC
typedef int BOOL;
#endif
#ifndef TRUE
#define FALSE 0
#define TRUE 1
#endif
#ifndef MAC
typedef unsigned long ULONG, DWORD, *PULONG;
typedef unsigned long SEC_FAR *LPULONG;
typedef unsigned short USHORT, WORD;
typedef char CHAR, *PCHAR;
typedef unsigned char UCHAR, *PUCHAR;
typedef unsigned char SEC_FAR *LPUCHAR;
typedef void SEC_FAR *PVOID, *LPVOID;
typedef unsigned char BOOLEAN;
#endif
#ifndef BLDR_KERNEL_RUNTIME
typedef long LUID, *PLUID;
#endif
//
// Calculate the address of the base of the structure given its type, and an
// address of a field within the structure.
//
#define CONTAINING_RECORD(address, type, field) ((type *)( \
(PCHAR)(address) - \
(PCHAR)(&((type *)0)->field)))
#ifndef BLDR_KERNEL_RUNTIME
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY;
#endif
//
// VOID
// InitializeListHead(
// PLIST_ENTRY ListHead
// );
//
#define InitializeListHead(ListHead) (\
(ListHead)->Flink = (ListHead)->Blink = (ListHead))
//
// VOID
// RemoveEntryList(
// PLIST_ENTRY Entry
// );
//
#define RemoveEntryList(Entry) {\
PLIST_ENTRY _EX_Blink;\
PLIST_ENTRY _EX_Flink;\
_EX_Flink = (Entry)->Flink;\
_EX_Blink = (Entry)->Blink;\
_EX_Blink->Flink = _EX_Flink;\
_EX_Flink->Blink = _EX_Blink;\
}
//
// VOID
// InsertHeadList(
// PLIST_ENTRY ListHead,
// PLIST_ENTRY Entry
// );
//
#define InsertHeadList(ListHead,Entry) {\
PLIST_ENTRY _EX_Flink;\
PLIST_ENTRY _EX_ListHead;\
_EX_ListHead = (ListHead);\
_EX_Flink = _EX_ListHead->Flink;\
(Entry)->Flink = _EX_Flink;\
(Entry)->Blink = _EX_ListHead;\
_EX_Flink->Blink = (Entry);\
_EX_ListHead->Flink = (Entry);\
}
//
// BOOLEAN
// IsListEmpty(
// PLIST_ENTRY ListHead
// );
//
#define IsListEmpty(ListHead) \
((ListHead)->Flink == (ListHead))
//
// Maximum lifetime of a context
//
//#define NTLMSSP_MAX_LIFETIME (2*60*1000)L // 2 minutes
#define NTLMSSP_MAX_LIFETIME 120000L // 2 minutes
////////////////////////////////////////////////////////////////////////
//
// Opaque Messages passed between client and server
//
////////////////////////////////////////////////////////////////////////
#define NTLMSSP_SIGNATURE "NTLMSSP"
//
// MessageType for the following messages.
//
typedef enum {
NtLmNegotiate = 1,
NtLmChallenge,
NtLmAuthenticate,
#ifdef MAC
NtLmUnknown
#endif
} NTLM_MESSAGE_TYPE;
//
// Signature structure
//
typedef struct _NTLMSSP_MESSAGE_SIGNATURE {
ULONG Version;
ULONG RandomPad;
ULONG CheckSum;
ULONG Nonce;
} NTLMSSP_MESSAGE_SIGNATURE, * PNTLMSSP_MESSAGE_SIGNATURE;
#define NTLMSSP_MESSAGE_SIGNATURE_SIZE sizeof(NTLMSSP_MESSAGE_SIGNATURE)
#define NTLMSSP_SIGN_VERSION 1
#define NTLMSSP_KEY_SALT 0xbd
#define MSV1_0_NTLMV2_RESPONSE_LENGTH 16
#define MSV1_0_NTLMV2_OWF_LENGTH 16
#define MSV1_0_CHALLENGE_LENGTH 8
//
// valid QoP flags
//
#define QOP_NTLMV2 0x00000001
//
// this is an MSV1_0 private data structure, defining the layout of an Ntlmv2
// response, as sent by a client in the NtChallengeResponse field of the
// NETLOGON_NETWORK_INFO structure. If can be differentiated from an old style
// NT response by its length. This is crude, but it needs to pass through
// servers and the servers' DCs that do not understand Ntlmv2 but that are
// willing to pass longer responses.
//
typedef struct _MSV1_0_NTLMV2_RESPONSE {
UCHAR Response[MSV1_0_NTLMV2_RESPONSE_LENGTH]; // hash of OWF of password with all the following fields
UCHAR RespType; // id number of response; current is 1
UCHAR HiRespType; // highest id number understood by client
USHORT Flags; // reserved; must be sent as zero at this version
ULONG MsgWord; // 32 bit message from client to server (for use by auth protocol)
ULONGLONG TimeStamp; // time stamp when client generated response -- NT system time, quad part
UCHAR ChallengeFromClient[MSV1_0_CHALLENGE_LENGTH];
ULONG AvPairsOff; // offset to start of AvPairs (to allow future expansion)
UCHAR Buffer[1]; // start of buffer with AV pairs (or future stuff -- so use the offset)
} MSV1_0_NTLMV2_RESPONSE, *PMSV1_0_NTLMV2_RESPONSE;
#define MSV1_0_NTLMV2_INPUT_LENGTH (sizeof(MSV1_0_NTLMV2_RESPONSE) - MSV1_0_NTLMV2_RESPONSE_LENGTH)
typedef struct {
UCHAR Response[MSV1_0_NTLMV2_RESPONSE_LENGTH];
UCHAR ChallengeFromClient[MSV1_0_CHALLENGE_LENGTH];
} MSV1_0_LMV2_RESPONSE, *PMSV1_0_LMV2_RESPONSE;
//
// User, Group and Password lengths
//
#define UNLEN 256 // Maximum user name length
#define LM20_UNLEN 20 // LM 2.0 Maximum user name length
//
// String Lengths for various LanMan names
//
#define CNLEN 15 // Computer name length
#define LM20_CNLEN 15 // LM 2.0 Computer name length
#define DNLEN CNLEN // Maximum domain name length
#define LM20_DNLEN LM20_CNLEN // LM 2.0 Maximum domain name length
//
// Size of the largest message
// (The largest message is the AUTHENTICATE_MESSAGE)
//
#define DNSLEN 256 // length of DNS name
#define TARGET_INFO_LEN ((2*DNSLEN + DNLEN + CNLEN) * sizeof(WCHAR) + \
5 * sizeof(MSV1_0_AV_PAIR))
// length of NTLM2 response
#define NTLMV2_RESPONSE_LENGTH (sizeof(MSV1_0_NTLMV2_RESPONSE) + \
TARGET_INFO_LEN)
#define NTLMSSP_MAX_MESSAGE_SIZE (sizeof(AUTHENTICATE_MESSAGE) + \
LM_RESPONSE_LENGTH + \
NTLMV2_RESPONSE_LENGTH + \
(DNLEN + 1) * sizeof(WCHAR) + \
(UNLEN + 1) * sizeof(WCHAR) + \
(CNLEN + 1) * sizeof(WCHAR))
typedef struct _MSV1_0_AV_PAIR {
USHORT AvId;
USHORT AvLen;
// Data is treated as byte array following structure
} MSV1_0_AV_PAIR, *PMSV1_0_AV_PAIR;
//
// bootssp does not support RtlOemStringToUnicodeString or
// RtlUnicodeStringToOemString, punt to Ansi Strings
//
#define SspOemStringToUnicodeString RtlAnsiStringToUnicodeString
#define SspUnicodeStringToOemString RtlUnicodeStringToAnsiString
#define CSSEALMAGIC "session key to client-to-server sealing key magic constant"
#define SCSEALMAGIC "session key to server-to-client sealing key magic constant"
#define CSSIGNMAGIC "session key to client-to-server signing key magic constant"
#define SCSIGNMAGIC "session key to server-to-client signing key magic constant"
//
// Valid values of NegotiateFlags
//
#define NTLMSSP_NEGOTIATE_UNICODE 0x00000001 // Text strings are in unicode
#define NTLMSSP_NEGOTIATE_OEM 0x00000002 // Text strings are in OEM
#define NTLMSSP_REQUEST_TARGET 0x00000004 // Server should return its authentication realm
#define NTLMSSP_NEGOTIATE_SIGN 0x00000010 // Request signature capability
#define NTLMSSP_NEGOTIATE_SEAL 0x00000020 // Request confidentiality
#define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040 // Use datagram style authentication
#define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080 // Use LM session key for sign/seal
#define NTLMSSP_NEGOTIATE_NETWARE 0x00000100 // NetWare authentication
#define NTLMSSP_NEGOTIATE_NTLM 0x00000200 // NTLM authentication
#define NTLMSSP_NEGOTIATE_NT_ONLY 0x00000400 // NT authentication only (no LM)
#define NTLMSSP_NEGOTIATE_NULL_SESSION 0x00000800 // NULL Sessions on NT 5.0 and beyand
#define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED 0x1000 // Domain Name supplied on negotiate
#define NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED 0x2000 // Workstation Name supplied on negotiate
#define NTLMSSP_NEGOTIATE_LOCAL_CALL 0x00004000 // Indicates client/server are same machine
#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000 // Sign for all security levels
//
// Valid target types returned by the server in Negotiate Flags
//
#define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000 // TargetName is a domain name
#define NTLMSSP_TARGET_TYPE_SERVER 0x00020000 // TargetName is a server name
#define NTLMSSP_TARGET_TYPE_SHARE 0x00040000 // TargetName is a share name
#define NTLMSSP_NEGOTIATE_NTLM2 0x00080000 // NTLM2 authentication added for NT4-SP4
#define NTLMSSP_NEGOTIATE_IDENTIFY 0x00100000 // Create identify level token
//
// Valid requests for additional output buffers
//
#define NTLMSSP_REQUEST_INIT_RESPONSE 0x00100000 // get back session keys
#define NTLMSSP_REQUEST_ACCEPT_RESPONSE 0x00200000 // get back session key, LUID
#define NTLMSSP_REQUEST_NON_NT_SESSION_KEY 0x00400000 // request non-nt session key
#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000 // target info present in challenge message
#define NTLMSSP_NEGOTIATE_EXPORTED_CONTEXT 0x01000000 // It's an exported context
#define NTLMSSP_NEGOTIATE_128 0x20000000 // negotiate 128 bit encryption
#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000 // exchange a key using key exchange key
#define NTLMSSP_NEGOTIATE_56 0x80000000 // negotiate 56 bit encryption
// flags used in client space to control sign and seal; never appear on the wire
#define NTLMSSP_APP_SEQ 0x00000040 // Use application provided seq num
typedef struct _NTLMV2_DERIVED_SKEYS {
ULONG KeyLen; // key length in octets
ULONG* pSendNonce; // ptr to nonce to use for send
ULONG* pRecvNonce; // ptr to nonce to use for receive
struct RC4_KEYSTRUCT* pSealRc4Sched; // ptr to key sched used for Seal
struct RC4_KEYSTRUCT* pUnsealRc4Sched; // ptr to key sched used to Unseal
ULONG SendNonce;
ULONG RecvNonce;
UCHAR SignSessionKey[sizeof(USER_SESSION_KEY)];
UCHAR VerifySessionKey[sizeof(USER_SESSION_KEY)];
UCHAR SealSessionKey[sizeof(USER_SESSION_KEY)];
UCHAR UnsealSessionKey[sizeof(USER_SESSION_KEY)];
ULONG64 Pad1; // pad keystructs to 64.
struct RC4_KEYSTRUCT SealRc4Sched; // key struct used for Seal
ULONG64 Pad2; // pad keystructs to 64.
struct RC4_KEYSTRUCT UnsealRc4Sched; // key struct used to Unseal
} NTLMV2_DERIVED_SKEYS, *PNTLMV2_DERIVED_SKEYS;
//
// Opaque message returned from first call to InitializeSecurityContext
//
typedef struct _NEGOTIATE_MESSAGE {
UCHAR Signature[sizeof(NTLMSSP_SIGNATURE)];
NTLM_MESSAGE_TYPE MessageType;
ULONG NegotiateFlags;
STRING32 OemDomainName;
STRING32 OemWorkstationName;
} NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;
//
// Opaque message returned from first call to AcceptSecurityContext
//
typedef struct _CHALLENGE_MESSAGE {
UCHAR Signature[sizeof(NTLMSSP_SIGNATURE)];
NTLM_MESSAGE_TYPE MessageType;
STRING32 TargetName;
ULONG NegotiateFlags;
UCHAR Challenge[MSV1_0_CHALLENGE_LENGTH];
ULONG64 ServerContextHandle;
STRING32 TargetInfo;
} CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE;
//
// Opaque message returned from second call to InitializeSecurityContext
//
typedef struct _AUTHENTICATE_MESSAGE {
UCHAR Signature[sizeof(NTLMSSP_SIGNATURE)];
NTLM_MESSAGE_TYPE MessageType;
STRING32 LmChallengeResponse;
STRING32 NtChallengeResponse;
STRING32 DomainName;
STRING32 UserName;
STRING32 Workstation;
STRING32 SessionKey;
ULONG NegotiateFlags;
} AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
typedef enum _eSignSealOp {
eSign, // MakeSignature is calling
eVerify, // VerifySignature is calling
eSeal, // SealMessage is calling
eUnseal // UnsealMessage is calling
} eSignSealOp;
//
// Version 1 is the structure above, using stream RC4 to encrypt the trailing
// 12 bytes.
//
#define NTLM_SIGN_VERSION 1
#ifdef __cplusplus
extern "C" {
#endif
//
// the following declarations may be duplicates
//
NTSTATUS
RtlAnsiStringToUnicodeString(
UNICODE_STRING* DestinationString,
ANSI_STRING* SourceString,
BOOLEAN AllocateDestinationString
);
VOID
RtlInitString(
OUT STRING* DestinationString,
IN PCSTR SourceString OPTIONAL
);
NTSTATUS
RtlUnicodeStringToAnsiString(
OUT ANSI_STRING* DestinationString,
IN UNICODE_STRING* SourceString,
IN BOOLEAN AllocateDestinationString
);
WCHAR
RtlUpcaseUnicodeChar(
IN WCHAR SourceCharacter
);
////////////////////////////////////////////////////////////////////////
//
// Procedure Forwards
//
////////////////////////////////////////////////////////////////////////
PVOID
SspAlloc(
int Size
);
void
SspFree(
PVOID Buffer
);
PSTRING
SspAllocateString(
PVOID Value
);
PSTRING
SspAllocateStringBlock(
PVOID Value,
int Length
);
void
SspFreeString(
PSTRING * String
);
void
SspCopyString(
IN PVOID MessageBuffer,
OUT PSTRING OutString,
IN PSTRING InString,
IN OUT PCHAR *Where,
IN BOOLEAN Absolute
);
void
SspCopyStringFromRaw(
IN PVOID MessageBuffer,
OUT STRING32* OutString,
IN PCHAR InString,
IN int InStringLength,
IN OUT PCHAR *Where
);
DWORD
SspTicks(
);
#ifdef __cplusplus
}
#endif
#endif // ifndef _NTLMSSPI_INCLUDED_