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

📄 ctxtapi.cxx

📁 安全支持提供器接口(SSPI)源码
💻 CXX
📖 第 1 页 / 共 2 页
字号:
//+-----------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation 1992 - 1996
//
// File:        ctxtapi.cxx
//
// Contents:    Context APIs for the NtLm security package
//              Main entry points into this dll:
//                SpDeleteContext
//                SpInitLsaModeContext
//                SpApplyControlToken
//                SpAcceptLsaModeContext
//
// History:     ChandanS 26-Jul-1996   Stolen from kerberos\client2\ctxtapi.cxx
//
//------------------------------------------------------------------------
#define NTLM_CTXTAPI
#include <global.h>




//+-------------------------------------------------------------------------
//
//  Function:   SpDeleteContext
//
//  Synopsis:   Deletes an NtLm context
//
//  Effects:
//
//  Arguments:  ContextHandle - The context to delete
//
//  Requires:
//
//  Returns:    STATUS_SUCCESS or STATUS_INVALID_HANDLE
//
//  Notes:
//
//
//--------------------------------------------------------------------------


NTSTATUS NTAPI
SpDeleteContext(
    IN ULONG_PTR ContextHandle
    )
/*++

Routine Description:

    Deletes the local data structures associated with the specified
    security context.

    This API terminates a context on the local machine.

Arguments:

    ContextHandle - Handle to the context to delete


Return Value:

    STATUS_SUCCESS - Call completed successfully

    SEC_E_NO_SPM -- Security Support Provider is not running
    SEC_E_INVALID_HANDLE -- Credential/Context Handle is invalid

--*/

{
    NTSTATUS Status = STATUS_SUCCESS;
    ULONG_PTR TempContextHandle = ContextHandle;
    SspPrint((SSP_API, "Entering SpDeleteContext for 0x%x\n", ContextHandle));
    // BUGBUG Check args specific to NTLM

    Status = SsprDeleteSecurityContext(
                    TempContextHandle );

    SspPrint((SSP_API, "Leaving SpDeleteContext for 0x%x\n", ContextHandle));
    return (SspNtStatusToSecStatus(Status, SEC_E_INTERNAL_ERROR));

}


//+-------------------------------------------------------------------------
//
//  Function:   SpInitLsaModeContext
//
//  Synopsis:   NtLm implementation of InitializeSecurityContext
//              while in Lsa mode. If we return TRUE in *MappedContext,
//              secur32 will call SpInitUserModeContext with
//              the returned context handle and ContextData
//              as input. Fill in whatever info needed for
//              the user mode apis
//
//  Effects:
//
//  Arguments:
//
//  Requires:
//
//  Returns:
//
//  Notes: This function can be called in various ways:
//         1. Generic users of ntlm make the first call to
//            InitializeSecurityContext and we return a NEGOTIATE_MESSAGE
//         2. The rdr makes the first call to InitializeSecurityContext
//            with no contextHandle but info is passed in through a
//            CHALLENGE_MESSAGE (& possibly an NTLM_CHALLENGE_MESSAGE),
//            we return an AUTHENTICATE_MESSAGE and an
//            NTLM_INITIALIZE_RESPONSE
//         3. Generic users of NTLM make the second call to
//            InitializeSecurityContext, passing in a CHALLENGE_MESSAGE
//            and we return an AUTHENTICATE_MESSAGE
//
//--------------------------------------------------------------------------


NTSTATUS NTAPI
SpInitLsaModeContext(
    IN OPTIONAL ULONG_PTR CredentialHandle,
    IN OPTIONAL ULONG_PTR OldContextHandle,
    IN OPTIONAL PUNICODE_STRING TargetName,
    IN ULONG ContextReqFlags,
    IN ULONG TargetDataRep,
    IN PSecBufferDesc InputBuffers,
    OUT PULONG_PTR NewContextHandle,
    IN OUT PSecBufferDesc OutputBuffers,
    OUT PULONG ContextAttributes,
    OUT PTimeStamp ExpirationTime,
    OUT PBOOLEAN MappedContext,
    OUT PSecBuffer ContextData
    )
{
    NTSTATUS Status = STATUS_SUCCESS;

    SecBuffer TempTokens[4];
    PSecBuffer FirstInputToken;
    PSecBuffer SecondInputToken;
    PSecBuffer FirstOutputToken;
    PSecBuffer SecondOutputToken;

    ULONG_PTR OriginalContextHandle = NULL;
    ULONG_PTR TempContextHandle = NULL;
    ULONG NegotiateFlags = 0;
    UCHAR SessionKey[MSV1_0_USER_SESSION_KEY_LENGTH];

    SspPrint((SSP_API, "Entering SpInitLsaModeContext for Old:0x%x, New:0x%x\n", OldContextHandle, *NewContextHandle));

    // BUGBUG Check args specific to NTLM



    RtlZeroMemory(
        TempTokens,
        sizeof(TempTokens)
        );

    FirstInputToken = &TempTokens[0];
    SecondInputToken = &TempTokens[1];
    FirstOutputToken = &TempTokens[2];
    SecondOutputToken = &TempTokens[3];


    *MappedContext = FALSE;

    ASSERT(ContextData);

    ContextData->pvBuffer = NULL;
    ContextData->cbBuffer = 0;

    RtlZeroMemory(SessionKey,
                  MSV1_0_USER_SESSION_KEY_LENGTH);

#ifdef notdef  // ? RPC passes 0x10 or 0 here depending on attitude
    if ( TargetDataRep != SECURITY_NATIVE_DREP ) {
        Status = STATUS_INVALID_PARAMETER;
        SspPrint((SSP_CRITICAL, "SpInitLsaModeContext, TargetdataRep is 0x%lx\n", TargetDataRep));
        goto Cleanup;
    }
#else // notdef
    UNREFERENCED_PARAMETER( TargetDataRep );
#endif // notdef

    //
    // Extract tokens from the SecBuffers
    //

    if ( !SspGetTokenBuffer( InputBuffers,
                             0,   // get the first SECBUFFER_TOKEN
                             &FirstInputToken,
                             TRUE
                             ) ) {
        Status = SEC_E_INVALID_TOKEN;
        SspPrint((SSP_CRITICAL, "SpInitLsaModeContext, SspGetTokenBuffer (FirstInputToken) returns %d\n", Status));
        goto Cleanup;
    }

    //
    //  If we are using supplied credentials, gte the second SECBUFFER_TOKEN
    //

    if (ContextReqFlags & ISC_REQ_USE_SUPPLIED_CREDS)
    {
        if ( !SspGetTokenBuffer( InputBuffers,
                             1,   // get the second SECBUFFER_TOKEN
                             &SecondInputToken,
                             TRUE
                             ) ) {
            Status = SEC_E_INVALID_TOKEN;
            SspPrint((SSP_CRITICAL, "SpInitLsaModeContext, SspGetTokenBuffer (SecondInputToken) returns %d\n", Status));
            goto Cleanup;
        }
    }

    if ( !SspGetTokenBuffer( OutputBuffers,
                             0,   // get the first SECBUFFER_TOKEN
                             &FirstOutputToken,
                             FALSE
                             ) ) {
        Status = SEC_E_INVALID_TOKEN;
        SspPrint((SSP_CRITICAL, "SpInitLsaModeContext, SspGetTokenBuffer (FirstOutputToken) returns %d\n", Status));
        goto Cleanup;
    }

    if ( !SspGetTokenBuffer( OutputBuffers,
                             1,   // get the second SECBUFFER_TOKEN
                             &SecondOutputToken,
                             FALSE
                             ) ) {
        Status = SEC_E_INVALID_TOKEN;
        SspPrint((SSP_CRITICAL, "SpInitLsaModeContext, SspGetTokenBuffer (SecondOutputToken) returns %d\n", Status));
        goto Cleanup;
    }

    //
    // Save the old context handle, in case someone changes it
    //

    TempContextHandle = OldContextHandle;
    OriginalContextHandle = OldContextHandle;

    //
    // If no previous context was passed
    // and if no legitimate input token existed, this is the first call
    //

    if ((OriginalContextHandle == 0 ) &&
        (FirstInputToken->cbBuffer == 0))
    {

        if ( !ARGUMENT_PRESENT( CredentialHandle ) ) {
            Status = STATUS_INVALID_HANDLE;
            SspPrint((SSP_CRITICAL, "SpInitLsaModeContext, No CredentialHandle\n"));
            goto Cleanup;
        }

        *NewContextHandle = 0;

        Status = SsprHandleFirstCall(
                        CredentialHandle,
                        NewContextHandle,
                        ContextReqFlags,
                        FirstInputToken->cbBuffer,
                        FirstInputToken->pvBuffer,
                        &FirstOutputToken->cbBuffer,
                        &FirstOutputToken->pvBuffer,
                        ContextAttributes,
                        ExpirationTime,
                        SessionKey,
                        &NegotiateFlags );

        TempContextHandle = *NewContextHandle;
    //
    // If context was passed in, continue where we left off.
    // Or if the redir's passing in stuff in the InputBuffers,
    // skip the first call and get on with the second
    //

    } else {

        *NewContextHandle = OldContextHandle;

        Status = SsprHandleChallengeMessage(
                        CredentialHandle,
                        &TempContextHandle,
                        NULL,   // No client token
                        NULL,   // No logon ID
                        ContextReqFlags,
                        FirstInputToken->cbBuffer,
                        FirstInputToken->pvBuffer,
                        SecondInputToken->cbBuffer,
                        SecondInputToken->pvBuffer,
                        &FirstOutputToken->cbBuffer,
                        &FirstOutputToken->pvBuffer,
                        &SecondOutputToken->cbBuffer,
                        &SecondOutputToken->pvBuffer,
                        ContextAttributes,
                        ExpirationTime,
                        SessionKey,
                        &NegotiateFlags
                        );
    }

    //
    // If the original handle is zero, set it to be the TempContextHandle.
    // This is for the datagram case, where we map the context after the
    // first call to initialize.
    //

    if (OriginalContextHandle == 0) {

        OriginalContextHandle = TempContextHandle;
        *NewContextHandle = OriginalContextHandle;
    }
    //
    // Only map the context if this is the real authentication, not a re-auth
    // or if this was datagram.
    //

    if (((Status == SEC_I_CONTINUE_NEEDED) &&
         ((*ContextAttributes & ISC_RET_DATAGRAM) != 0)) ||
        ((Status == SEC_E_OK) &&
         ((*ContextAttributes & (SSP_RET_REAUTHENTICATION | ISC_RET_DATAGRAM)) == 0))) {

        NTSTATUS TempStatus;

        TempStatus = SspMapContext(
                        &OriginalContextHandle,
                        SessionKey,
                        NegotiateFlags,
                        NULL,               // no token handle for clients
                        NULL,               // no password expiry for clients
                        0,                  // no userflags
                        ContextData
                        );

        if (!NT_SUCCESS(TempStatus)) {
            Status = TempStatus;
            SspPrint((SSP_CRITICAL, "SpInitLsaModeContext, SspMapContext returns %d\n", Status));
            goto Cleanup;
        }

        SspPrint((SSP_SESSION_KEYS, "Init sessionkey %lx %lx %lx %lx\n",
                ((DWORD*)SessionKey)[0],
                ((DWORD*)SessionKey)[1],
                ((DWORD*)SessionKey)[2],
                ((DWORD*)SessionKey)[3]
                ));


        //
        // Yes, do load msv1_0.dll in the client's process
        // and ContextData will contain info to be passed on
        // to the InitializeSecurityContext counterpart that
        // runs in the client's process

        *MappedContext = TRUE;
    }

    //
    // Make sure this bit isn't sent to the caller
    //

    *ContextAttributes &= ~SSP_RET_REAUTHENTICATION;


Cleanup:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -