421 lines
11 KiB
C
421 lines
11 KiB
C
/* Copyright (c) 1993, Microsoft Corporation, all rights reserved
|
|
**
|
|
** raschap.h
|
|
** Remote Access PPP Challenge Handshake Authentication Protocol
|
|
**
|
|
** 11/05/93 Steve Cobb
|
|
*/
|
|
|
|
#ifndef _RASCHAP_H_
|
|
#define _RASCHAP_H_
|
|
|
|
|
|
#include "md5.h"
|
|
#include <ntsamp.h>
|
|
|
|
#define TRACE_RASCHAP (0x00010000|TRACE_USE_MASK|TRACE_USE_MSEC|TRACE_USE_DATE)
|
|
|
|
#define TRACE(a) TracePrintfExA(g_dwTraceIdChap,TRACE_RASCHAP,a )
|
|
#define TRACE1(a,b) TracePrintfExA(g_dwTraceIdChap,TRACE_RASCHAP,a,b )
|
|
#define TRACE2(a,b,c) TracePrintfExA(g_dwTraceIdChap,TRACE_RASCHAP,a,b,c )
|
|
#define TRACE3(a,b,c,d) TracePrintfExA(g_dwTraceIdChap,TRACE_RASCHAP,a,b,c,d )
|
|
|
|
#define DUMPW(X,Y) TraceDumpExA(g_dwTraceIdChap,1,(LPBYTE)X,Y,4,1,NULL)
|
|
#define DUMPB(X,Y) TraceDumpExA(g_dwTraceIdChap,1,(LPBYTE)X,Y,1,1,NULL)
|
|
|
|
//General macros
|
|
#define GEN_RAND_ENCODE_SEED ((CHAR) ( 1 + rand() % 250 ))
|
|
|
|
/* CHAP packet codes from CHAP spec except ChangePw.
|
|
*/
|
|
#define CHAPCODE_Challenge 1
|
|
#define CHAPCODE_Response 2
|
|
#define CHAPCODE_Success 3
|
|
#define CHAPCODE_Failure 4
|
|
#define CHAPCODE_ChangePw1 5
|
|
#define CHAPCODE_ChangePw2 6
|
|
#define CHAPCODE_ChangePw3 7
|
|
|
|
#define MAXCHAPCODE 7
|
|
|
|
|
|
/* Returned by receive buffer parsing routines that discover the packet is
|
|
** corrupt, usually because the length fields don't make sense.
|
|
*/
|
|
#define ERRORBADPACKET (DWORD )-1
|
|
|
|
/* Maximum challenge and response lengths.
|
|
*/
|
|
#define MAXCHALLENGELEN 255
|
|
#define MSRESPONSELEN (LM_RESPONSE_LENGTH + NT_RESPONSE_LENGTH + 1)
|
|
#define MD5RESPONSELEN MD5_LEN
|
|
#define MAXRESPONSELEN max( MSRESPONSELEN, MD5RESPONSELEN )
|
|
|
|
#define MAXINFOLEN 1500
|
|
|
|
/* Defines states within the CHAP protocol.
|
|
*/
|
|
#define CHAPSTATE enum tagCHAPSTATE
|
|
CHAPSTATE
|
|
{
|
|
CS_Initial,
|
|
CS_WaitForChallenge,
|
|
CS_ChallengeSent,
|
|
CS_ResponseSent,
|
|
CS_Retry,
|
|
CS_ChangePw,
|
|
CS_ChangePw1,
|
|
CS_ChangePw2,
|
|
CS_ChangePw1Sent,
|
|
CS_ChangePw2Sent,
|
|
CS_WaitForAuthenticationToComplete1,
|
|
CS_WaitForAuthenticationToComplete2,
|
|
CS_Done
|
|
};
|
|
|
|
|
|
/* Defines the change password version 1 (NT 3.5) response data buffer.
|
|
*/
|
|
#define CHANGEPW1 struct tagCHANGEPW1
|
|
CHANGEPW1
|
|
{
|
|
BYTE abEncryptedLmOwfOldPw[ ENCRYPTED_LM_OWF_PASSWORD_LENGTH ];
|
|
BYTE abEncryptedLmOwfNewPw[ ENCRYPTED_LM_OWF_PASSWORD_LENGTH ];
|
|
BYTE abEncryptedNtOwfOldPw[ ENCRYPTED_NT_OWF_PASSWORD_LENGTH ];
|
|
BYTE abEncryptedNtOwfNewPw[ ENCRYPTED_NT_OWF_PASSWORD_LENGTH ];
|
|
BYTE abPasswordLength[ 2 ];
|
|
BYTE abFlags[ 2 ];
|
|
};
|
|
|
|
|
|
/* CHANGEPW1.abFlags bit definitions.
|
|
*/
|
|
#define CPW1F_UseNtResponse 0x00000001
|
|
|
|
|
|
/* Define the change password version 2 (NT 3.51) response data buffer.
|
|
*/
|
|
#define CHANGEPW2 struct tagCHANGEPW2
|
|
CHANGEPW2
|
|
{
|
|
BYTE abNewEncryptedWithOldNtOwf[ sizeof(SAMPR_ENCRYPTED_USER_PASSWORD) ];
|
|
BYTE abOldNtOwfEncryptedWithNewNtOwf[ ENCRYPTED_NT_OWF_PASSWORD_LENGTH ];
|
|
BYTE abNewEncryptedWithOldLmOwf[ sizeof(SAMPR_ENCRYPTED_USER_PASSWORD) ];
|
|
BYTE abOldLmOwfEncryptedWithNewNtOwf[ ENCRYPTED_NT_OWF_PASSWORD_LENGTH ];
|
|
BYTE abLmResponse[ LM_RESPONSE_LENGTH ];
|
|
BYTE abNtResponse[ NT_RESPONSE_LENGTH ];
|
|
BYTE abFlags[ 2 ];
|
|
};
|
|
|
|
|
|
/* CHANGEPW2.abFlags bit definitions.
|
|
*/
|
|
#define CPW2F_UseNtResponse 0x00000001
|
|
#define CPW2F_LmPasswordPresent 0x00000002
|
|
|
|
/* Define the change password for new MS-CHAP
|
|
*/
|
|
#define CHANGEPW3 struct tagCHANGEPW3
|
|
CHANGEPW3
|
|
{
|
|
BYTE abEncryptedPassword[ 516 ];
|
|
BYTE abEncryptedHash[ 16 ];
|
|
BYTE abPeerChallenge[ 24 ];
|
|
BYTE abNTResponse[ 24 ];
|
|
BYTE abFlags[ 2 ];
|
|
};
|
|
|
|
/* Union for storage effieciency (never need both formats at same time).
|
|
*/
|
|
#define CHANGEPW union tagCHANGEPW
|
|
CHANGEPW
|
|
{
|
|
/* This dummy field is included so the MIPS compiler will align the
|
|
** structure on a DWORD boundary. Normally, MIPS does not force alignment
|
|
** if the structure contains only BYTEs or BYTE arrays. This protects us
|
|
** from alignment faults should SAM or LSA interpret the byte arrays as
|
|
** containing some necessarily aligned type, though currently they do not.
|
|
*/
|
|
DWORD dwAlign;
|
|
|
|
CHANGEPW1 v1;
|
|
CHANGEPW2 v2;
|
|
CHANGEPW3 v3;
|
|
};
|
|
|
|
|
|
/* Defines the WorkBuf stored for us by the PPP engine.
|
|
*/
|
|
#define CHAPWB struct tagCHAPWB
|
|
CHAPWB
|
|
{
|
|
/* CHAP encryption method negotiated (MD5 or Microsoft extended). Note
|
|
** that server does not support MD5.
|
|
*/
|
|
BYTE bAlgorithm;
|
|
|
|
/* True if role is server, false if client.
|
|
*/
|
|
BOOL fServer;
|
|
|
|
/* The port handle on which the protocol is active.
|
|
*/
|
|
HPORT hport;
|
|
|
|
/* Number of authentication attempts left before we shut down. (Microsoft
|
|
** extended CHAP only)
|
|
*/
|
|
DWORD dwTriesLeft;
|
|
|
|
/* Client's credentials.
|
|
*/
|
|
CHAR szUserName[ UNLEN + DNLEN + 2 ];
|
|
CHAR szOldPassword[ PWLEN + 1 ];
|
|
CHAR szPassword[ PWLEN + 1 ];
|
|
CHAR szDomain[ DNLEN + 1 ];
|
|
|
|
/* The LUID is a logon ID required by LSA to determine the response. It
|
|
** must be determined in calling app's context and is therefore passed
|
|
** down. (client only)
|
|
*/
|
|
LUID Luid;
|
|
|
|
/* The challenge sent or received in the Challenge Packet and the length
|
|
** in bytes of same. Note that LUID above keeps this DWORD aligned.
|
|
*/
|
|
BYTE abChallenge[ MAXCHALLENGELEN ];
|
|
BYTE cbChallenge;
|
|
|
|
BYTE abComputedChallenge[ MAXCHALLENGELEN ];
|
|
|
|
/* Indicates whether a new challenge was provided in the last Failure
|
|
** packet. (client only)
|
|
*/
|
|
BOOL fNewChallengeProvided;
|
|
|
|
/* The response sent or received in the Response packet and the length in
|
|
** bytes of same. Note the BOOL above keeps this DWORD aligned.
|
|
*/
|
|
BYTE abResponse[ MAXRESPONSELEN ];
|
|
BYTE cbResponse;
|
|
|
|
/* The change password response sent or received in the ChangePw or
|
|
** ChangePw2 packets.
|
|
*/
|
|
CHANGEPW changepw;
|
|
|
|
/* The LM and user session keys retrieved when credentials are successfully
|
|
** authenticated.
|
|
*/
|
|
LM_SESSION_KEY keyLm;
|
|
USER_SESSION_KEY keyUser;
|
|
|
|
/* This flag indicates that the session key has been calculated
|
|
** from the password or retrieved from LSA.
|
|
*/
|
|
BOOL fSessionKeysObtained;
|
|
|
|
/* On the client, this contains the pointer to the MPPE keys. On the server
|
|
** this field is not used.
|
|
*/
|
|
|
|
RAS_AUTH_ATTRIBUTE * pMPPEKeys;
|
|
|
|
/* The current state in the CHAP protocol.
|
|
*/
|
|
CHAPSTATE state;
|
|
|
|
/* Sequencing ID expected on next packet received on this port and the
|
|
** value to send on the next outgoing packet.
|
|
*/
|
|
BYTE bIdExpected;
|
|
BYTE bIdToSend;
|
|
|
|
/* The final result, used to duplicate the original response in subsequent
|
|
** response packets. This is per CHAP spec to cover lost Success/Failure
|
|
** case without allowing malicious client to discover alternative
|
|
** identities under the covers during a connection. (applies to server
|
|
** only)
|
|
*/
|
|
PPPAP_RESULT result;
|
|
|
|
HPORT hPort;
|
|
|
|
DWORD dwInitialPacketId;
|
|
|
|
DWORD fConfigInfo;
|
|
|
|
RAS_AUTH_ATTRIBUTE * pAttributesFromAuthenticator;
|
|
|
|
//
|
|
// Used to send authentication request to backend server
|
|
//
|
|
|
|
RAS_AUTH_ATTRIBUTE * pUserAttributes;
|
|
CHAR chSeed; //Seed for encoding password.
|
|
};
|
|
|
|
|
|
/* Prototypes.
|
|
*/
|
|
|
|
DWORD
|
|
ChapInit(
|
|
IN BOOL fInitialize
|
|
);
|
|
|
|
DWORD ChapSMakeMessage( CHAPWB*, PPP_CONFIG*, PPP_CONFIG*, DWORD, PPPAP_RESULT*,
|
|
PPPAP_INPUT* );
|
|
DWORD
|
|
MakeAuthenticationRequestAttributes(
|
|
IN CHAPWB* pwb,
|
|
IN BOOL fMSChap,
|
|
IN BYTE bAlgorithm,
|
|
IN CHAR* szUserName,
|
|
IN BYTE* pbChallenge,
|
|
IN DWORD cbChallenge,
|
|
IN BYTE* pbResponse,
|
|
IN DWORD cbResponse,
|
|
IN BYTE bId
|
|
);
|
|
|
|
DWORD
|
|
GetErrorCodeFromAttributes(
|
|
IN CHAPWB* pwb
|
|
);
|
|
|
|
DWORD
|
|
LoadChapHelperFunctions(
|
|
VOID
|
|
);
|
|
|
|
DWORD ChapCMakeMessage( CHAPWB*, PPP_CONFIG*, PPP_CONFIG*, DWORD, PPPAP_RESULT*,
|
|
PPPAP_INPUT* );
|
|
DWORD ChapBegin( VOID**, VOID* );
|
|
DWORD ChapEnd( VOID* );
|
|
DWORD ChapMakeMessage( VOID*, PPP_CONFIG*, PPP_CONFIG*, DWORD, PPPAP_RESULT*,
|
|
PPPAP_INPUT* );
|
|
DWORD GetChallengeFromChallenge( CHAPWB*, PPP_CONFIG* );
|
|
DWORD MakeChangePw1Message( CHAPWB*, PPP_CONFIG*, DWORD );
|
|
DWORD MakeChangePw2Message( CHAPWB*, PPP_CONFIG*, DWORD );
|
|
DWORD MakeChangePw3Message( CHAPWB*, PPP_CONFIG*, DWORD, BOOL );
|
|
DWORD GetCredentialsFromResponse( PPP_CONFIG*, BYTE, CHAR*, BYTE* );
|
|
DWORD GetInfoFromChangePw1( PPP_CONFIG*, CHANGEPW1* );
|
|
DWORD GetInfoFromChangePw2( PPP_CONFIG*, CHANGEPW2*, BYTE* );
|
|
DWORD GetInfoFromChangePw3( PPP_CONFIG*, CHANGEPW3*, BYTE* );
|
|
VOID GetInfoFromFailure( CHAPWB*, PPP_CONFIG*, DWORD*, BOOL*, DWORD* );
|
|
BYTE HexCharValue( CHAR );
|
|
DWORD MakeChallengeMessage( CHAPWB*, PPP_CONFIG*, DWORD );
|
|
DWORD MakeResponseMessage( CHAPWB*, PPP_CONFIG*, DWORD, BOOL );
|
|
VOID ChapMakeResultMessage( CHAPWB*, DWORD, BOOL, PPP_CONFIG*, DWORD );
|
|
DWORD StoreCredentials( CHAPWB*, PPPAP_INPUT* );
|
|
|
|
DWORD
|
|
ChapChangeNotification(
|
|
VOID
|
|
);
|
|
|
|
DWORD
|
|
GetChallenge(
|
|
OUT PBYTE pChallenge
|
|
);
|
|
|
|
VOID
|
|
EndLSA(
|
|
VOID
|
|
);
|
|
|
|
DWORD
|
|
InitLSA(
|
|
VOID
|
|
);
|
|
|
|
DWORD
|
|
MakeChangePasswordV1RequestAttributes(
|
|
IN CHAPWB* pwb,
|
|
IN BYTE bId,
|
|
IN PCHAR pchIdentity,
|
|
IN PBYTE Challenge,
|
|
IN PENCRYPTED_LM_OWF_PASSWORD pEncryptedLmOwfOldPassword,
|
|
IN PENCRYPTED_LM_OWF_PASSWORD pEncryptedLmOwfNewPassword,
|
|
IN PENCRYPTED_NT_OWF_PASSWORD pEncryptedNtOwfOldPassword,
|
|
IN PENCRYPTED_NT_OWF_PASSWORD pEncryptedNtOwfNewPassword,
|
|
IN WORD LenPassword,
|
|
IN WORD wFlags,
|
|
IN DWORD cbChallenge,
|
|
IN BYTE * pbChallenge
|
|
);
|
|
|
|
DWORD
|
|
MakeChangePasswordV2RequestAttributes(
|
|
IN CHAPWB* pwb,
|
|
IN BYTE bId,
|
|
IN CHAR* pchIdentity,
|
|
IN SAMPR_ENCRYPTED_USER_PASSWORD* pNewEncryptedWithOldNtOwf,
|
|
IN ENCRYPTED_NT_OWF_PASSWORD* pOldNtOwfEncryptedWithNewNtOwf,
|
|
IN SAMPR_ENCRYPTED_USER_PASSWORD* pNewEncryptedWithOldLmOwf,
|
|
IN ENCRYPTED_NT_OWF_PASSWORD* pOldLmOwfEncryptedWithNewNtOwf,
|
|
IN DWORD cbChallenge,
|
|
IN BYTE * pbChallenge,
|
|
IN BYTE * pbResponse,
|
|
IN WORD wFlags
|
|
);
|
|
|
|
DWORD
|
|
MakeChangePasswordV3RequestAttributes(
|
|
IN CHAPWB* pwb,
|
|
IN BYTE bId,
|
|
IN CHAR* pchIdentity,
|
|
IN CHANGEPW3* pchangepw3,
|
|
IN DWORD cbChallenge,
|
|
IN BYTE * pbChallenge
|
|
);
|
|
|
|
DWORD
|
|
GetEncryptedPasswordsForChangePassword2(
|
|
IN CHAR* pszOldPassword,
|
|
IN CHAR* pszNewPassword,
|
|
OUT SAMPR_ENCRYPTED_USER_PASSWORD* pNewEncryptedWithOldNtOwf,
|
|
OUT ENCRYPTED_NT_OWF_PASSWORD* pOldNtOwfEncryptedWithNewNtOwf,
|
|
OUT SAMPR_ENCRYPTED_USER_PASSWORD* pNewEncryptedWithOldLmOwf,
|
|
OUT ENCRYPTED_NT_OWF_PASSWORD* pOldLmOwfEncryptedWithNewNtOwf,
|
|
OUT BOOLEAN* pfLmPresent
|
|
);
|
|
|
|
/* Globals.
|
|
*/
|
|
#ifdef RASCHAPGLOBALS
|
|
#define GLOBALS
|
|
#define EXTERN
|
|
#else
|
|
#define EXTERN extern
|
|
#endif
|
|
|
|
EXTERN DWORD g_dwTraceIdChap
|
|
#ifdef GLOBALS
|
|
= INVALID_TRACEID;
|
|
#endif
|
|
;
|
|
|
|
EXTERN DWORD g_dwRefCount
|
|
#ifdef GLOBALS
|
|
= 0;
|
|
#endif
|
|
;
|
|
|
|
EXTERN HANDLE g_hLsa
|
|
#ifdef GLOBALS
|
|
= INVALID_HANDLE_VALUE;
|
|
#endif
|
|
;
|
|
|
|
EXTERN
|
|
CHAR
|
|
szComputerName[CNLEN+1];
|
|
|
|
#undef EXTERN
|
|
#undef GLOBALS
|
|
|
|
|
|
#endif // _RASCHAP_H_
|