⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 context.cxx

📁 安全支持提供器接口(SSPI)源码
💻 CXX
📖 第 1 页 / 共 5 页
字号:
        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 + -