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

📄 userapi.cxx

📁 安全支持提供器接口(SSPI)源码
💻 CXX
📖 第 1 页 / 共 5 页
字号:
//+-----------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation 1992 - 1999
//
// File:        userapi.cxx
//
// Contents:    User-mode APIs to the NtLm security package
//
//              Main user mode entry points into this dll:
//                SpUserModeInitialize
//                SpInstanceInit
//                SpDeleteUserModeContext
//                SpInitUserModeContext
//                SpMakeSignature
//                SpVerifySignature
//                SpSealMessage
//                SpUnsealMessage
//                SpGetContextToken
//                SpQueryContextAttributes
//                SpCompleteAuthToken
//                SpFormatCredentials
//                SpMarshallSupplementalCreds
//                SpExportSecurityContext
//                SpImportSecurityContext
//
//              Helper functions:
//                ReferenceUserContext
//                FreeUserContext
//                DereferenceUserContext
//                SspGenCheckSum
//                SspEncryptBuffer
//                NtLmMakePackedContext(this is called in the client's process)
//                NtLmCreateUserModeContext
//                SspGetTokenUser
//                SspCreateTokenDacl
//                SspMapContext (this is called in Lsa mode)
//
// History:     ChandanS 26-Jul-1996   Stolen from kerberos\client2\userapi.cxx
//
//------------------------------------------------------------------------
#include <global.h> // Globals!
#include "crc32.h"  // How to use crc32

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

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

typedef struct _NTLM_CLIENT_CONTEXT{
    union {
    LIST_ENTRY           Next;
    KSEC_LIST_ENTRY      KernelNext;
    };
    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_CLIENT_CONTEXT, * PNTLM_CLIENT_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"


LIST_ENTRY           NtLmUserContextList;
RTL_CRITICAL_SECTION NtLmUserContextLock;

// Counter for exported handles;never de-refed
// Should probably do a GetSystemInfo and get a space of handles that cannot
// be valid in the Lsa process
// BUGBUG check with user folks
ULONG_PTR ExportedContext = 0;

NTSTATUS
SspCreateTokenDacl(
    HANDLE Token
    );


//+-------------------------------------------------------------------------
//
//  Function:   SpUserModeInitialize
//
//  Synopsis:   Initialize an the MSV1_0 DLL in  a client's
//              address space
//
//  Effects:
//
//  Arguments:  LsaVersion - Version of the security dll loading the package
//              PackageVersion - Version of the MSV1_0 package
//              UserFunctionTable - Receives a copy of Kerberos's user mode
//                  function table
//              pcTables - Receives count of tables returned.
//
//  Requires:
//
//  Returns:    STATUS_SUCCESS
//
//  Notes: we do what was done in SspInitLocalContexts()
//         from net\svcdlls\ntlmssp\client\sign.c and more.
//
//
//--------------------------------------------------------------------------
NTSTATUS
SEC_ENTRY
SpUserModeInitialize(
    IN ULONG    LsaVersion,
    OUT PULONG  PackageVersion,
    OUT PSECPKG_USER_FUNCTION_TABLE * UserFunctionTable,
    OUT PULONG  pcTables
    )
{
    NTSTATUS Status = STATUS_SUCCESS;

#if DBG
    SspGlobalDbflag = SSP_CRITICAL;
    InitializeCriticalSection(&SspGlobalLogFileCritSect);
#endif

    if (LsaVersion != SECPKG_INTERFACE_VERSION)
    {
        Status = STATUS_INVALID_PARAMETER;
        goto Cleanup;
    }

    *PackageVersion = SECPKG_INTERFACE_VERSION;

    NtLmUserFunctionTable.InstanceInit = SpInstanceInit;
    NtLmUserFunctionTable.MakeSignature = SpMakeSignature;
    NtLmUserFunctionTable.VerifySignature = SpVerifySignature;
    NtLmUserFunctionTable.SealMessage = SpSealMessage;
    NtLmUserFunctionTable.UnsealMessage = SpUnsealMessage;
    NtLmUserFunctionTable.GetContextToken = SpGetContextToken;
    NtLmUserFunctionTable.QueryContextAttributes = SpQueryContextAttributes;
    NtLmUserFunctionTable.CompleteAuthToken = SpCompleteAuthToken;
    NtLmUserFunctionTable.InitUserModeContext = SpInitUserModeContext;
    NtLmUserFunctionTable.DeleteUserModeContext = SpDeleteUserModeContext;
    NtLmUserFunctionTable.FormatCredentials = SpFormatCredentials;
    NtLmUserFunctionTable.MarshallSupplementalCreds = SpMarshallSupplementalCreds;
    NtLmUserFunctionTable.ExportContext = SpExportSecurityContext;
    NtLmUserFunctionTable.ImportContext = SpImportSecurityContext;

    *UserFunctionTable = &NtLmUserFunctionTable;
    *pcTables = 1;

Cleanup:

    return(SspNtStatusToSecStatus(Status, SEC_E_INTERNAL_ERROR));
}



//+-------------------------------------------------------------------------
//
//  Function:   ReferenceUserContext
//
//  Synopsis:   locates a user context in the list, refrences it
//
//  Effects:
//
//  Arguments:
//
//  Requires:
//
//  Returns:    the context, if it is found, else NULL
//
//  Notes: This was SspContextReferenceContext() in
//         net\svcdlls\ntlmssp\common\context.c
//
//
//--------------------------------------------------------------------------
PNTLM_CLIENT_CONTEXT
ReferenceUserContext(
    IN ULONG_PTR ContextHandle,
    IN BOOLEAN RemoveContext )
{
    SspPrint(( SSP_API_MORE, "Entering ReferenceUserContext for 0x%x\n", ContextHandle ));
    PLIST_ENTRY ListEntry;
    PNTLM_CLIENT_CONTEXT pContext = NULL;

    RtlEnterCriticalSection(&NtLmUserContextLock);

    //
    // Look for a match for the LsaContext, not user context
    //

    for (ListEntry = NtLmUserContextList.Flink;
         ListEntry != &NtLmUserContextList;
         ListEntry = ListEntry->Flink ) {

        pContext = CONTAINING_RECORD(ListEntry, NTLM_CLIENT_CONTEXT, Next );


        if (pContext == NULL)
        {
            RtlLeaveCriticalSection(&NtLmUserContextLock);
            SspPrint(( SSP_API_MORE, "Leaving ReferenceUserContext for 0x%x\n", ContextHandle ));
            return NULL;
        }

        if (pContext->LsaContext == ContextHandle)
        {
            //
            // Found it!
            //

            if (!RemoveContext)
            {
                pContext->References += 1;
            }
            else
            {
                RemoveEntryList (&pContext->Next);
                SspPrint(( SSP_API_MORE, "Delinked Context 0x%lx\n", pContext ));
            }

            RtlLeaveCriticalSection(&NtLmUserContextLock);
            SspPrint(( SSP_API_MORE, "Leaving ReferenceUserContext for 0x%x\n", ContextHandle));
            return pContext;
        }
    }


    // No match found

    RtlLeaveCriticalSection(&NtLmUserContextLock);
    SspPrint(( SSP_API_MORE, "Leaving ReferenceUserContext for 0x%x\n", ContextHandle ));
    return NULL;
}

//+-------------------------------------------------------------------------
//
//  Function:   FreeUserContext
//
//  Synopsis:   frees alloced pointers in this context and
//              then frees the context
//
//  Arguments:  lContext  - the unlinked user context
//
//  Returns:    STATUS_SUCCESS on success
//
//  Notes:
//
//--------------------------------------------------------------------------
NTSTATUS
FreeUserContext (
    PNTLM_CLIENT_CONTEXT UserContext
    )
{
    SspPrint(( SSP_API_MORE, "Entering FreeUserContext for context 0x%x\n", UserContext ));

    NTSTATUS Status = STATUS_SUCCESS;

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

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

    SspPrint(( SSP_API_MORE, "Deleting Context 0x%x\n", UserContext));

    NtLmFree (UserContext);

    SspPrint(( SSP_API_MORE, "Leaving FreeUserContext for context 0x%x, status = 0x%x\n", Status ));

    return Status;
}

//+-------------------------------------------------------------------------
//
//  Function:   DereferenceUserContext
//
//  Synopsis:   frees alloced elements in the context, frees context
//
//  Effects:
//
//  Arguments:
//
//  Requires:
//
//  Returns:     None
//
//  Notes: This was SspContextDereferenceContext() in
//         net\svcdlls\ntlmssp\common\context.c
//
//
//--------------------------------------------------------------------------
NTSTATUS
DereferenceUserContext (
    PNTLM_CLIENT_CONTEXT pContext
    )
{
    SspPrint(( SSP_API_MORE, "Entering DereferenceUserContext 0x%lx\n", pContext ));
    NTSTATUS Status = STATUS_SUCCESS;

    ULONG References;

    //
    // Decrement the reference count
    //

    RtlEnterCriticalSection(&NtLmUserContextLock);
    ASSERT (pContext->References >= 1);
    References = -- pContext->References;
    RtlLeaveCriticalSection(&NtLmUserContextLock);

    //
    // If the count has dropped to zero, then free all alloced stuff
    //

    if (References == 0)
    {
        Status = FreeUserContext(pContext);
    }
    SspPrint(( SSP_API_MORE, "Leaving DereferenceUserContext\n" ));
    return Status;
}

//+-------------------------------------------------------------------------
//
//  Function:   SpInstanceInit
//
//  Synopsis:   Initialize an instance of the NtLm package in a client's
//              address space
//
//  Effects:
//
//  Arguments:  Version - Version of the security dll loading the package
//              FunctionTable - Contains helper routines for use by NtLm
//              UserFunctions - Receives a copy of NtLm's user mode
//                  function table
//
//  Requires:
//
//  Returns:    STATUS_SUCCESS
//
//  Notes: we do what was done in SspInitLocalContexts()
//         from net\svcdlls\ntlmssp\client\sign.c and more.
//
//
//--------------------------------------------------------------------------


NTSTATUS NTAPI
SpInstanceInit(
    IN ULONG Version,
    IN PSECPKG_DLL_FUNCTIONS DllFunctionTable,
    OUT PVOID * UserFunctionTable
    )
{
    SspPrint(( SSP_API, "Entering SpInstanceInit\n" ));
    NTSTATUS Status = STATUS_SUCCESS;



    // Save the Alloc/Free functions
    NtLmState = NtLmUserMode;
    UserFunctions = DllFunctionTable;


    InitializeListHead (&NtLmUserContextList);
    RtlInitializeCriticalSectionAndSpinCount (&NtLmUserContextLock, 5000);

    SspPrint(( SSP_API, "Leaving SpInstanceInit: 0x%lx\n", Status ));
    return(SspNtStatusToSecStatus(Status, SEC_E_INTERNAL_ERROR));
}



//+-------------------------------------------------------------------------
//
//  Function:   SpDeleteUserModeContext
//
//  Synopsis:   Deletes a user mode context by unlinking it and then
//              dereferencing it.
//
//  Effects:
//
//  Arguments:  ContextHandle - Lsa context handle of the context to delete
//
//  Requires:
//
//  Returns:    STATUS_SUCCESS on success, STATUS_INVALID_HANDLE if the
//              context can't be located
//
//  Notes:
//        If this is an exported context, send a flag back to the LSA so that
//        Lsa does not call the SecpDeleteSecurityContext in the lsa process
//
//
//--------------------------------------------------------------------------


NTSTATUS NTAPI
SpDeleteUserModeContext(
    IN ULONG_PTR ContextHandle
    )
{

⌨️ 快捷键说明

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