📄 context.cxx
字号:
goto Cleanup;
}
//
// Allocate a new context
//
Context = SspContextAllocateContext( );
if ( Context == NULL ) {
Status = STATUS_NO_MEMORY;
SspPrint(( SSP_CRITICAL,
"SsprHandleNegotiateMessage: SspContextAllocateContext() returned NULL.\n" ));
goto Cleanup;
}
//
// Build a handle to the newly created context.
//
*ContextHandle = (ULONG_PTR) Context;
if ( (ContextReqFlags & ASC_REQ_IDENTIFY) != 0 ) {
*ContextAttributes |= ASC_RET_IDENTIFY;
Context->ContextFlags |= ASC_RET_IDENTIFY;
}
if ( (ContextReqFlags & ASC_REQ_DATAGRAM) != 0 ) {
*ContextAttributes |= ASC_RET_DATAGRAM;
Context->ContextFlags |= ASC_RET_DATAGRAM;
}
if ( (ContextReqFlags & ASC_REQ_CONNECTION) != 0 ) {
*ContextAttributes |= ASC_RET_CONNECTION;
Context->ContextFlags |= ASC_RET_CONNECTION;
}
if ( (ContextReqFlags & ASC_REQ_INTEGRITY) != 0 ) {
*ContextAttributes |= ASC_RET_INTEGRITY;
Context->ContextFlags |= ASC_RET_INTEGRITY;
}
if ( (ContextReqFlags & ASC_REQ_REPLAY_DETECT) != 0){
*ContextAttributes |= ASC_RET_REPLAY_DETECT;
Context->ContextFlags |= ASC_RET_REPLAY_DETECT;
}
if ( (ContextReqFlags & ASC_REQ_SEQUENCE_DETECT ) != 0) {
*ContextAttributes |= ASC_RET_SEQUENCE_DETECT;
Context->ContextFlags |= ASC_RET_SEQUENCE_DETECT;
}
// Nothing to return, we might need this on the next server side call.
if ( (ContextReqFlags & ASC_REQ_ALLOW_NULL_SESSION ) != 0) {
Context->ContextFlags |= ASC_REQ_ALLOW_NULL_SESSION;
}
if ( (ContextReqFlags & ASC_REQ_ALLOW_NON_USER_LOGONS ) != 0) {
*ContextAttributes |= ASC_RET_ALLOW_NON_USER_LOGONS;
Context->ContextFlags |= ASC_RET_ALLOW_NON_USER_LOGONS;
}
if ( ContextReqFlags & ASC_REQ_CONFIDENTIALITY ) {
if (NtLmGlobalEncryptionEnabled) {
*ContextAttributes |= ASC_RET_CONFIDENTIALITY;
Context->ContextFlags |= ASC_RET_CONFIDENTIALITY;
} else {
Status = STATUS_NOT_SUPPORTED;
SspPrint(( SSP_CRITICAL,
"SsprHandleNegotiateMessage: invalid ContextReqFlags 0x%lx\n", ContextReqFlags ));
goto Cleanup;
}
}
//
// Supported key strength(s)
//
NegotiateFlagsKeyStrength = NTLMSSP_NEGOTIATE_56;
if( NtLmSecPkg.MachineState & SECPKG_STATE_STRONG_ENCRYPTION_PERMITTED )
{
NegotiateFlagsKeyStrength |= NTLMSSP_NEGOTIATE_128;
}
//
// Get the NegotiateMessage. If we are re-establishing a datagram
// context then there may not be one.
//
if ( InputTokenSize >= sizeof(OLD_NEGOTIATE_MESSAGE) ) {
Status = SspContextGetMessage( InputToken,
InputTokenSize,
NtLmNegotiate,
(PVOID *)&NegotiateMessage );
if ( !NT_SUCCESS(Status) ) {
SspPrint(( SSP_CRITICAL,
"SsprHandleNegotiateMessage: "
"NegotiateMessage GetMessage returns 0x%lx\n",
Status ));
goto Cleanup;
}
//
// Compute the TargetName to return in the ChallengeMessage.
//
if ( NegotiateMessage->NegotiateFlags & NTLMSSP_REQUEST_TARGET ||
NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLM2 ) {
EnterCriticalSection (&NtLmGlobalCritSect);
if ( NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_UNICODE) {
Status = NtLmDuplicateUnicodeString( &NtLmLocalUnicodeTargetName, &NtLmGlobalUnicodeTargetName );
TargetName = *((PSTRING)&NtLmLocalUnicodeTargetName);
} else {
Status = NtLmDuplicateString( &NtLmLocalOemTargetName, &NtLmGlobalOemTargetName );
TargetName = NtLmLocalOemTargetName;
}
//
// if client is NTLM2-aware, send it target info AV pairs
//
if(NT_SUCCESS(Status))
{
Status = NtLmDuplicateUnicodeString( &TargetInfo, &NtLmGlobalNtLm3TargetInfo );
}
TargetFlags = NtLmGlobalTargetFlags;
LeaveCriticalSection (&NtLmGlobalCritSect);
TargetFlags |= NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO;
if(!NT_SUCCESS(Status)) {
SspPrint(( SSP_CRITICAL,
"SsprHandleNegotiateMessage: "
"failed to duplicate UnicodeTaretName or OemTargetName error 0x%lx\n",
Status ));
goto Cleanup;
}
} else {
TargetFlags = 0;
}
//
// Allocate a Challenge message
//
ChallengeMessageSize = sizeof(*ChallengeMessage) +
TargetName.Length +
TargetInfo.Length ;
if ((ContextReqFlags & ASC_REQ_ALLOCATE_MEMORY) == 0)
{
if ( ChallengeMessageSize > *OutputTokenSize ) {
SspPrint(( SSP_CRITICAL,
"SsprHandleNegotiateMessage: invalid ChallengeMessageSize\n"));
Status = SEC_E_BUFFER_TOO_SMALL;
goto Cleanup;
}
}
ChallengeMessage = (PCHALLENGE_MESSAGE)
NtLmAllocate( ChallengeMessageSize );
if ( ChallengeMessage == NULL ) {
SspPrint(( SSP_CRITICAL,
"SsprHandleNegotiateMessage: Error allocating ChallengeMessage.\n" ));
Status = STATUS_NO_MEMORY;
goto Cleanup;
}
ChallengeMessage->NegotiateFlags = 0;
//
// Check that both sides can use the same authentication model. For
// compatibility with beta 1 and 2 (builds 612 and 683), no requested
// authentication type is assumed to be NTLM. If NetWare is explicitly
// asked for, it is assumed that NTLM would have been also, so if it
// wasn't, return an error.
//
if ( (NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_NETWARE) &&
((NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLM) == 0) &&
((NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLM2) == 0)
) {
Status = STATUS_NOT_SUPPORTED;
SspPrint(( SSP_CRITICAL,
"SsprHandleNegotiateMessage: "
"NegotiateMessage asked for Netware only.\n" ));
goto Cleanup;
} else {
ChallengeMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
}
//
// if client can do NTLM2, nuke LM_KEY
//
if (NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLM2) {
NegotiateMessage->NegotiateFlags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
ChallengeMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM2;
} else if (NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_LM_KEY) {
ChallengeMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_LM_KEY;
}
//
// If the client wants to always sign messages, so be it.
//
if (NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN ) {
ChallengeMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
// BUGBUG: check when this is set, and update ContextAttributes accordingly
}
//
// If the caller wants identify level, so be it.
//
if (NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_IDENTIFY ) {
ChallengeMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_IDENTIFY;
*ContextAttributes |= ASC_RET_IDENTIFY;
Context->ContextFlags |= ASC_RET_IDENTIFY;
}
//
// Determine if the caller wants OEM or UNICODE
//
// Prefer UNICODE if caller allows both.
//
if ( NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_UNICODE ) {
ChallengeMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
} else if ( NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_OEM ){
ChallengeMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_OEM;
} else {
Status = SEC_E_INVALID_TOKEN;
SspPrint(( SSP_CRITICAL,
"SsprHandleNegotiateMessage: "
"NegotiateMessage bad NegotiateFlags 0x%lx\n",
NegotiateMessage->NegotiateFlags ));
goto Cleanup;
}
//
// Client wants Sign capability, OK.
//
if (NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_SIGN) {
ChallengeMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
*ContextAttributes |= (ASC_RET_SEQUENCE_DETECT | ASC_RET_REPLAY_DETECT);
Context->ContextFlags |= (ASC_RET_SEQUENCE_DETECT | ASC_RET_REPLAY_DETECT);
}
//
// Client wants Seal, OK.
//
if (NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_SEAL)
{
ChallengeMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
*ContextAttributes |= ASC_RET_CONFIDENTIALITY;
Context->ContextFlags |= ASC_RET_CONFIDENTIALITY;
}
if(NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_KEY_EXCH)
{
ChallengeMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
}
if( (NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_56) &&
(NegotiateFlagsKeyStrength & NTLMSSP_NEGOTIATE_56) )
{
ChallengeMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_56;
}
if( (NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_128) &&
(NegotiateFlagsKeyStrength & NTLMSSP_NEGOTIATE_128) )
{
ChallengeMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_128;
}
//
// If the client supplied the Domain Name and User Name,
// and did not request datagram, see if the client is running
// on this local machine.
//
if ( ( (NegotiateMessage->NegotiateFlags &
NTLMSSP_NEGOTIATE_DATAGRAM) == 0) &&
( (NegotiateMessage->NegotiateFlags &
(NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED|
NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED)) ==
(NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED|
NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED) ) ) {
//
// The client must pass the new negotiate message if they pass
// these flags
//
if (InputTokenSize < sizeof(NEGOTIATE_MESSAGE)) {
Status = SEC_E_INVALID_TOKEN;
SspPrint(( SSP_CRITICAL,
"SsprHandleNegotiateMessage: invalid InputTokenSize.\n" ));
goto Cleanup;
}
//
// Convert the names to absolute references so we
// can compare them
//
if ( !SspConvertRelativeToAbsolute(
NegotiateMessage,
InputTokenSize,
&NegotiateMessage->OemDomainName,
&OemDomainName,
FALSE, // No special alignment
FALSE ) ) { // NULL not OK
Status = SEC_E_INVALID_TOKEN;
SspPrint(( SSP_CRITICAL,
"SsprHandleNegotiateMessage: Error from SspConvertRelativeToAbsolute.\n" ));
goto Cleanup;
}
if ( !SspConvertRelativeToAbsolute(
NegotiateMessage,
InputTokenSize,
&NegotiateMessage->OemWorkstationName,
&OemWorkstationName,
FALSE, // No special alignment
FALSE ) ) { // NULL not OK
Status = SEC_E_INVALID_TOKEN;
SspPrint(( SSP_CRITICAL,
"SsprHandleNegotiateMessage: Error from SspConvertRelativeToAbsolute.\n" ));
goto Cleanup;
}
//
// If both strings match,
// this is a local call.
// The strings have already been uppercased.
//
EnterCriticalSection (&NtLmGlobalCritSect);
if ( RtlEqualString( &OemWorkstationName,
&NtLmGlobalOemComputerNameString,
FALSE ) &&
RtlEqualString( &OemDomainName,
&NtLmGlobalOemPrimaryDomainNameString,
FALSE ) ) {
ChallengeMessage->NegotiateFlags |=
NTLMSSP_NEGOTIATE_LOCAL_CALL;
SspPrint(( SSP_MISC,
"SsprHandleNegotiateMessage: Local Call.\n" ));
ChallengeMessage->ServerContextHandle = (ULONG64)*ContextHandle;
}
LeaveCriticalSection (&NtLmGlobalCritSect);
}
//
// Check if datagram is being negotiated
//
if ( (NegotiateMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_DATAGRAM) ==
NTLMSSP_NEGOTIATE_DATAGRAM) {
ChallengeMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_DATAGRAM;
}
} else {
//
// No negotiate message. We need to check if the caller is asking
// for datagram.
//
if ((ContextReqFlags & ASC_REQ_DATAGRAM) == 0 ) {
SspPrint(( SSP_CRITICAL,
"SsprHandleNegotiateMessage: "
"NegotiateMessage size wrong %ld\n",
InputTokenSize ));
Status = SEC_E_INVALID_TOKEN;
goto Cleanup;
}
//
// Allocate a Challenge message
//
//
// always send target info -- new for NTLM3!
//
TargetFlags = NTLMSSP_NEGOTIATE_TARGET_INFO;
ChallengeMessageSize = sizeof(*ChallengeMessage) + TargetInfo.Length;
if ((ContextReqFlags & ASC_REQ_ALLOCATE_MEMORY) == 0)
{
if ( ChallengeMessageSize > *OutputTokenSize ) {
Status = SEC_E_BUFFER_TOO_SMALL;
SspPrint(( SSP_CRITICAL,
"SsprHandleNegotiateMessage: invalid ChallengeMessageSize.\n" ));
goto Cleanup;
}
}
ChallengeMessage = (PCHALLENGE_MESSAGE)
NtLmAllocate(ChallengeMessageSize );
if ( ChallengeMessage == NULL ) {
Status = STATUS_NO_MEMORY;
SspPrint(( SSP_CRITICAL,
"SsprHandleNegotiateMessage: Error allocating ChallengeMessage.\n" ));
goto Cleanup;
}
//
// Record in the conte
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -