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

📄 krnlapi.cxx

📁 安全支持提供器接口(SSPI)源码
💻 CXX
📖 第 1 页 / 共 5 页
字号:
//+-----------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation 1992 - 1999
//
// File:        krnlapi.cxx
//
// Contents:    Kernel-mode APIs to the NTLM package
//
//
// History:     07-Sep-1996   Created         ChandanS
//
//------------------------------------------------------------------------

#include <ntlmkrnl.h>
extern "C"
{
#include <cryptdll.h>
}

#include "crc32.h"  // How to use crc32

extern "C"
{
#include <rc4.h>    // How to use RC4 routine
#include <md5.h>
#include <hmac.h>
}


// Context Signatures

#define NTLM_CONTEXT_SIGNATURE 'MLTN'
#define NTLM_CONTEXT_DELETED_SIGNATURE 'XXXX'

// Keep this is sync with NTLM_KERNEL_CONTEXT defined in
// security\msv_sspi\userapi.cxx

typedef struct _NTLM_KERNEL_CONTEXT{
    KSEC_LIST_ENTRY      List;
    ULONG_PTR            LsaContext;
    ULONG                NegotiateFlags;
    HANDLE               ClientTokenHandle;
    PACCESS_TOKEN        AccessToken;

    PULONG                  pSendNonce;      // ptr to nonce to use for send
    PULONG                  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;
    LPWSTR               ContextNames;
    UCHAR                SessionKey[MSV1_0_USER_SESSION_KEY_LENGTH];
    ULONG                ContextSignature;
    ULONG                References ;
    TimeStamp            PasswordExpiry;
    ULONG                UserFlags;
    UCHAR                   SignSessionKey[MSV1_0_USER_SESSION_KEY_LENGTH];
    UCHAR                   VerifySessionKey[MSV1_0_USER_SESSION_KEY_LENGTH];
    UCHAR                   SealSessionKey[MSV1_0_USER_SESSION_KEY_LENGTH];
    UCHAR                   UnsealSessionKey[MSV1_0_USER_SESSION_KEY_LENGTH];

    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
} NTLM_KERNEL_CONTEXT, * PNTLM_KERNEL_CONTEXT;

#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"

typedef enum _eSignSealOp {
    eSign,      // MakeSignature is calling
    eVerify,    // VerifySignature is calling
    eSeal,      // SealMessage is calling
    eUnseal     // UnsealMessage is calling
} eSignSealOp;


//
// Make these extern "C" to allow them to be pageable.
//

extern "C"
{
KspInitPackageFn       NtLmInitKernelPackage;
KspDeleteContextFn     NtLmDeleteKernelContext;
KspInitContextFn       NtLmInitKernelContext;
KspMapHandleFn         NtLmMapKernelHandle;
KspMakeSignatureFn     NtLmMakeSignature;
KspVerifySignatureFn   NtLmVerifySignature;
KspSealMessageFn       NtLmSealMessage;
KspUnsealMessageFn     NtLmUnsealMessage;
KspGetTokenFn          NtLmGetContextToken;
KspQueryAttributesFn   NtLmQueryContextAttributes;
KspCompleteTokenFn     NtLmCompleteToken;
SpExportSecurityContextFn NtLmExportSecurityContext;
SpImportSecurityContextFn NtLmImportSecurityContext;
KspSetPagingModeFn     NtlmSetPagingMode ;

//
// Local prototypes:
//

NTSTATUS
NtLmCreateKernelModeContext(
    IN ULONG ContextHandle,
    IN PSecBuffer MarshalledContext,
    OUT PNTLM_KERNEL_CONTEXT * NewContext
    );

NTSTATUS
NtLmMakePackedContext(
    IN PNTLM_KERNEL_CONTEXT Context,
    OUT PBOOLEAN MappedContext,
    OUT PSecBuffer ContextData,
    IN ULONG Flags
    );

NTSTATUS
NtlmFreeKernelContext (
    PNTLM_KERNEL_CONTEXT KernelContext
    );

#define NtlmReferenceContext( Context, Remove ) \
            KSecReferenceListEntry( (PKSEC_LIST_ENTRY) Context, \
                                    NTLM_CONTEXT_SIGNATURE, \
                                    Remove )

VOID
NtlmDerefContext(
    PNTLM_KERNEL_CONTEXT Context
    );

void
SspGenCheckSum(
    IN  PSecBuffer  pMessage,
    OUT PNTLMSSP_MESSAGE_SIGNATURE  pSig
    );

VOID
SspEncryptBuffer(
    IN PNTLM_KERNEL_CONTEXT pContext,
    IN struct RC4_KEYSTRUCT * pRc4Key,
    IN ULONG BufferSize,
    IN OUT PVOID Buffer
    );

VOID
SspRc4Key(
    IN ULONG                NegotiateFlags,
    OUT struct RC4_KEYSTRUCT *pRc4Key,
    IN PUCHAR               pSessionKey
    );

SECURITY_STATUS
SspSignSealHelper(
    IN PNTLM_KERNEL_CONTEXT pContext,
    IN eSignSealOp Op,
    IN OUT PSecBufferDesc pMessage,
    IN ULONG MessageSeqNo,
    OUT PNTLMSSP_MESSAGE_SIGNATURE pSig,
    OUT PNTLMSSP_MESSAGE_SIGNATURE * ppSig
    );

} // extern "C"




#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, NtLmInitKernelPackage)
#pragma alloc_text(PAGE, NtLmDeleteKernelContext)
#pragma alloc_text(PAGE, NtLmInitKernelContext)
#pragma alloc_text(PAGE, NtLmMapKernelHandle)
#pragma alloc_text(PAGEMSG, NtLmMakeSignature)
#pragma alloc_text(PAGEMSG, NtLmVerifySignature)
#pragma alloc_text(PAGEMSG, NtLmSealMessage)
#pragma alloc_text(PAGEMSG, NtLmUnsealMessage)
#pragma alloc_text(PAGEMSG, NtLmGetContextToken)
#pragma alloc_text(PAGEMSG, NtLmQueryContextAttributes)
#pragma alloc_text(PAGEMSG, NtlmDerefContext )
#pragma alloc_text(PAGE, NtLmCompleteToken)
#pragma alloc_text(PAGE, NtLmExportSecurityContext)
#pragma alloc_text(PAGE, NtLmImportSecurityContext)
#pragma alloc_text(PAGEMSG, NtlmFreeKernelContext )

#pragma alloc_text(PAGE, NtLmCreateKernelModeContext )
#pragma alloc_text(PAGE, NtLmMakePackedContext )

#pragma alloc_text(PAGEMSG, SspGenCheckSum)
#pragma alloc_text(PAGEMSG, SspEncryptBuffer)
#pragma alloc_text(PAGE, SspRc4Key)
#pragma alloc_text(PAGEMSG, SspSignSealHelper)

#endif

SECPKG_KERNEL_FUNCTION_TABLE NtLmFunctionTable = {
    NtLmInitKernelPackage,
    NtLmDeleteKernelContext,
    NtLmInitKernelContext,
    NtLmMapKernelHandle,
    NtLmMakeSignature,
    NtLmVerifySignature,
    NtLmSealMessage,
    NtLmUnsealMessage,
    NtLmGetContextToken,
    NtLmQueryContextAttributes,
    NtLmCompleteToken,
    NtLmExportSecurityContext,
    NtLmImportSecurityContext,
    NtlmSetPagingMode
};

LIST_ENTRY NtLmKernelContextList;
ERESOURCE  NtLmKernelContextLock;
PSECPKG_KERNEL_FUNCTIONS LsaKernelFunctions;
POOL_TYPE NtlmPoolType ;
PVOID NtlmPagedList ;
PVOID NtlmNonPagedList ;
PVOID NtlmActiveList ;

#define MAYBE_PAGED_CODE() \
    if ( NtlmPoolType == PagedPool )    \
    {                                   \
        PAGED_CODE();                   \
    }



//+-------------------------------------------------------------------------
//
//  Function:   FreeKernelContext
//
//  Synopsis:   frees alloced pointers in this context and
//              then frees the context
//
//  Arguments:  KernelContext  - the unlinked kernel context
//
//  Returns:    STATUS_SUCCESS on success
//
//  Notes:
//
//--------------------------------------------------------------------------
NTSTATUS
NtlmFreeKernelContext (
    PNTLM_KERNEL_CONTEXT KernelContext
    )
{

    NTSTATUS Status = STATUS_SUCCESS;

    MAYBE_PAGED_CODE();

    DebugLog(( DEB_TRACE, "Entering FreeKernelContext\n" ));

    if (KernelContext->ContextNames != NULL)
    {
        NtLmFree (KernelContext->ContextNames);
    }

    if (KernelContext->ClientTokenHandle != NULL)
    {
        NTSTATUS IgnoreStatus;
        IgnoreStatus = NtClose(KernelContext->ClientTokenHandle);
        ASSERT (NT_SUCCESS (IgnoreStatus));
    }

    if (KernelContext->AccessToken != NULL)
    {
        ObDereferenceObject (KernelContext->AccessToken);
    }

    DebugLog(( DEB_TRACE, "Deleting Context 0x%lx\n", KernelContext));

    NtLmFree (KernelContext);

    DebugLog(( DEB_TRACE, "Leaving FreeKernelContext: 0x%lx\n", Status ));

    return Status;
}

//+---------------------------------------------------------------------------
//
//  Function:   NtlmDerefContext
//
//  Synopsis:   Dereference a kernel context
//
//  Arguments:  [Context] --
//
//  History:    7-07-98   RichardW   Created
//
//  Notes:
//
//----------------------------------------------------------------------------
VOID
NtlmDerefContext(
    PNTLM_KERNEL_CONTEXT Context
    )
{
    BOOLEAN Delete ;

    MAYBE_PAGED_CODE();

    KSecDereferenceListEntry(
                    &Context->List,
                    &Delete );

    if ( Delete )
    {
        NtlmFreeKernelContext( Context );
    }

}

//+-------------------------------------------------------------------------
//
//  Function:   NtLmInitKernelPackage
//
//  Synopsis:   Initialize an instance of the NtLm package in
//              a client's (kernel) address space
//
//  Arguments:  None
//
//  Returns:    STATUS_SUCCESS or
//              returns from ExInitializeResource
//
//  Notes:      we do what was done in SpInstanceInit()
//              from security\msv_sspi\userapi.cxx
//
//--------------------------------------------------------------------------


NTSTATUS NTAPI
NtLmInitKernelPackage(
    IN PSECPKG_KERNEL_FUNCTIONS KernelFunctions
    )
{
    NTSTATUS Status = STATUS_SUCCESS;

    PAGED_CODE();

    DebugLog(( DEB_TRACE, "Entering NtLmInitKernelPackage\n" ));

    LsaKernelFunctions = KernelFunctions;
    //
    // Set up Context list support:
    //

    NtlmPoolType = PagedPool ;
    NtlmPagedList = LsaKernelFunctions->CreateContextList( KSecPaged );
    NtlmActiveList = NtlmPagedList ;

    InitializeListHead (&NtLmKernelContextList);

    // BUGBUG When do we delete the resource?
    Status = ExInitializeResource(&NtLmKernelContextLock);

    if (!NT_SUCCESS(Status))
    {
        DebugLog(( DEB_ERROR,
          "Failed to initialize resource NtlmKernelContextLock, ret 0x%lx\n",
          Status ));
    }

    DebugLog(( DEB_TRACE, "Leaving NtLmInitKernelPackage 0x%lx\n", Status ));
    return(Status);
}



//+-------------------------------------------------------------------------
//
//  Function:   NtLmDeleteKernelContext
//
//  Synopsis:   Deletes a kernel mode context by unlinking it and then
//              dereferencing it.
//
//  Effects:
//
//  Arguments:  KernelContextHandle - Kernel context handle of the context to delete
//              LsaContextHandle    - The Lsa mode handle
//
//  Requires:
//
//  Returns:    STATUS_SUCCESS on success, STATUS_INVALID_HANDLE if the
//              context can't be located
//
//  Notes:
//
//
//--------------------------------------------------------------------------


NTSTATUS NTAPI
NtLmDeleteKernelContext(
    IN ULONG_PTR KernelContextHandle,
    OUT PULONG_PTR LsaContextHandle
    )
{

    PNTLM_KERNEL_CONTEXT pContext = NULL;
    NTSTATUS Status = STATUS_SUCCESS, SaveStatus = STATUS_SUCCESS;
    BOOLEAN Delete ;

    PAGED_CODE();

    DebugLog(( DEB_TRACE, "Entering NtLmDeleteKernelContext\n" ));


    Status = NtlmReferenceContext( KernelContextHandle, TRUE );

    if ( NT_SUCCESS( Status ) )
    {
        pContext = (PNTLM_KERNEL_CONTEXT) KernelContextHandle ;

    }
    else
    {
        *LsaContextHandle = KernelContextHandle;
        DebugLog(( DEB_ERROR,
          "Bad kernel context 0x%lx\n", KernelContextHandle));
        goto CleanUp;

    }

    *LsaContextHandle = pContext->LsaContext;
    if ((pContext->NegotiateFlags & NTLMSSP_NEGOTIATE_EXPORTED_CONTEXT) != 0)
    {
        // Ignore all other errors and pass back
        SaveStatus = SEC_I_NO_LSA_CONTEXT;
    }


CleanUp:


    if (pContext != NULL)
    {
        NtlmDerefContext( pContext );

    }

    if (SaveStatus == SEC_I_NO_LSA_CONTEXT)
    {
        Status = SaveStatus;
    }

    DebugLog(( DEB_TRACE, "Leaving NtLmDeleteKernelContext 0x%lx\n", Status ));
    return(Status);
}






⌨️ 快捷键说明

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