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

📄 krnlapi.cxx

📁 安全支持提供器接口(SSPI)源码
💻 CXX
📖 第 1 页 / 共 5 页
字号:
//              along with a nonce.
//
//  Effects:
//
//  Arguments:  KernelContextHandle - Handle of the context to use to sign the
//                      message.
//              MessageBuffers - Contains an array of signed buffers  and
//                      a signature buffer.
//              MessageSequenceNumber - Sequence number for this message,
//                      only used in datagram cases.
//              QualityOfProtection - Unused flags.
//
//  Requires:   STATUS_INVALID_HANDLE - the context could not be found or
//                      was not configured for message integrity.
//              STATUS_INVALID_PARAMETER - the signature buffer could not
//                      be found or was too small.
//
//  Returns:
//
//  Notes: This was stolen from net\svcdlls\ntlmssp\client\sign.c ,
//         routine SspHandleVerifyMessage. It's possible that
//         bugs got copied too
//
//
//--------------------------------------------------------------------------



NTSTATUS NTAPI
NtLmVerifySignature(
    IN ULONG_PTR KernelContextHandle,
    IN PSecBufferDesc pMessage,
    IN ULONG MessageSeqNo,
    OUT PULONG pfQOP
    )
{
    NTSTATUS Status = STATUS_SUCCESS;
    PNTLM_KERNEL_CONTEXT pContext;
    NTLMSSP_MESSAGE_SIGNATURE   Sig;
    PNTLMSSP_MESSAGE_SIGNATURE  pSig;    // pointer to buffer with sig in it

    MAYBE_PAGED_CODE();

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

    UNREFERENCED_PARAMETER(pfQOP);

    Status = NtlmReferenceContext( KernelContextHandle, FALSE );

    if ( NT_SUCCESS( Status ) )
    {
        pContext = (PNTLM_KERNEL_CONTEXT) KernelContextHandle ;
    }
    else
    {
        DebugLog(( DEB_ERROR,
          "Bad kernel context 0x%lx\n", KernelContextHandle));
        goto CleanUp_NoDeref;

    }


    Status = SspSignSealHelper(
                        pContext,
                        eVerify,
                        pMessage,
                        MessageSeqNo,
                        &Sig,
                        &pSig
                        );


    if( !NT_SUCCESS( Status ) )
    {
        DebugLog(( DEB_ERROR, "NtLmVerifySignature, SspSignSealHelper returns %lx\n", Status ));
        goto CleanUp;
    }

    if (pSig->Version != NTLM_SIGN_VERSION) {
        Status = SEC_E_INVALID_TOKEN;
        goto CleanUp;
    }

    // validate the signature...
    if (pSig->CheckSum != Sig.CheckSum)
    {
        Status = SEC_E_MESSAGE_ALTERED;
        goto CleanUp;
    }

    // with MD5 sig, this now matters!
    if (pSig->RandomPad != Sig.RandomPad)
    {
        Status = SEC_E_MESSAGE_ALTERED;
        goto CleanUp;
    }

    if (pSig->Nonce != Sig.Nonce)
    {
        Status = SEC_E_OUT_OF_SEQUENCE;
        goto CleanUp;
    }

CleanUp:

    NtlmDerefContext( pContext );

CleanUp_NoDeref:


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

}


//+-------------------------------------------------------------------------
//
//  Function:   NtLmSealMessage
//
//  Synopsis:   Verifies a signed message buffer by calculating a checksum over all
//              the non-read only data buffers and encrypting the checksum
//              along with a nonce.
//
//  Effects:
//
//  Arguments:  KernelContextHandle - Handle of the context to use to sign the
//                      message.
//              MessageBuffers - Contains an array of signed buffers  and
//                      a signature buffer.
//              MessageSequenceNumber - Sequence number for this message,
//                      only used in datagram cases.
//              QualityOfProtection - Unused flags.
//
//  Requires:   STATUS_INVALID_HANDLE - the context could not be found or
//                      was not configured for message integrity.
//              STATUS_INVALID_PARAMETER - the signature buffer could not
//                      be found or was too small.
//
//  Returns:
//
//  Notes: This was stolen from net\svcdlls\ntlmssp\client\sign.c ,
//         routine SspHandleSealMessage. It's possible that
//         bugs got copied too
//
//
//--------------------------------------------------------------------------

NTSTATUS NTAPI
NtLmSealMessage(
    IN ULONG_PTR KernelContextHandle,
    IN ULONG fQOP,
    IN PSecBufferDesc pMessage,
    IN ULONG MessageSeqNo
    )
{
    NTSTATUS Status = STATUS_SUCCESS;
    PNTLM_KERNEL_CONTEXT pContext;
    NTLMSSP_MESSAGE_SIGNATURE  Sig;
    PNTLMSSP_MESSAGE_SIGNATURE  pSig;    // pointer to buffer where sig goes

    MAYBE_PAGED_CODE();

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

    UNREFERENCED_PARAMETER(fQOP);

    Status = NtlmReferenceContext( KernelContextHandle, FALSE );

    if ( NT_SUCCESS( Status ) )
    {
        pContext = (PNTLM_KERNEL_CONTEXT) KernelContextHandle ;
    }
    else
    {
        DebugLog(( DEB_ERROR,
          "Bad kernel context 0x%lx\n", KernelContextHandle));
        goto CleanUp_NoDeref;

    }


    Status = SspSignSealHelper(
                    pContext,
                    eSeal,
                    pMessage,
                    MessageSeqNo,
                    &Sig,
                    &pSig
                    );

    if (!NT_SUCCESS(Status))
    {
        DebugLog(( DEB_ERROR, "SpSealMessage, SspSignSealHelper returns %lx\n", Status ));
        goto CleanUp;
    }

    RtlCopyMemory(
        pSig,
        &Sig,
        NTLMSSP_MESSAGE_SIGNATURE_SIZE
        );


CleanUp:

    NtlmDerefContext( pContext );

CleanUp_NoDeref:


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

}

//+-------------------------------------------------------------------------
//
//  Function:   NtLmUnsealMessage
//
//  Synopsis:   Verifies a signed message buffer by calculating a checksum over all
//              the non-read only data buffers and encrypting the checksum
//              along with a nonce.
//
//  Effects:
//
//  Arguments:  KernelContextHandle - Handle of the context to use to sign the
//                      message.
//              MessageBuffers - Contains an array of signed buffers  and
//                      a signature buffer.
//              MessageSequenceNumber - Sequence number for this message,
//                      only used in datagram cases.
//              QualityOfProtection - Unused flags.
//
//  Requires:   STATUS_INVALID_HANDLE - the context could not be found or
//                      was not configured for message integrity.
//              STATUS_INVALID_PARAMETER - the signature buffer could not
//                      be found or was too small.
//
//  Returns:
//
//  Notes: This was stolen from net\svcdlls\ntlmssp\client\sign.c ,
//         routine SspHandleUnsealMessage. It's possible that
//         bugs got copied too
//
//
//--------------------------------------------------------------------------


NTSTATUS NTAPI
NtLmUnsealMessage(
    IN ULONG_PTR KernelContextHandle,
    IN PSecBufferDesc pMessage,
    IN ULONG MessageSeqNo,
    OUT PULONG pfQOP
    )
{
    NTSTATUS Status = STATUS_SUCCESS;
    PNTLM_KERNEL_CONTEXT pContext;
    NTLMSSP_MESSAGE_SIGNATURE  Sig;
    PNTLMSSP_MESSAGE_SIGNATURE  pSig;    // pointer to buffer where sig goes

    MAYBE_PAGED_CODE();

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

    UNREFERENCED_PARAMETER(pfQOP);

    Status = NtlmReferenceContext( KernelContextHandle, FALSE );

    if ( NT_SUCCESS( Status ) )
    {
        pContext = (PNTLM_KERNEL_CONTEXT) KernelContextHandle ;
    }
    else
    {
        DebugLog(( DEB_ERROR,
          "Bad kernel context 0x%lx\n", KernelContextHandle));
        goto CleanUp_NoDeref;

    }

    Status = SspSignSealHelper(
                    pContext,
                    eUnseal,
                    pMessage,
                    MessageSeqNo,
                    &Sig,
                    &pSig
                    );

    if (!NT_SUCCESS(Status))
    {
        DebugLog(( DEB_ERROR, "SpUnsealMessage, SspSignSealHelper returns %lx\n", Status ));
        goto CleanUp;
    }

    if (pSig->Version != NTLM_SIGN_VERSION) {
        Status = SEC_E_INVALID_TOKEN;
        goto CleanUp;
    }

    // validate the signature...
    if (pSig->CheckSum != Sig.CheckSum)
    {
        Status = SEC_E_MESSAGE_ALTERED;
        goto CleanUp;
    }

    if (pSig->RandomPad != Sig.RandomPad)
    {
        Status = SEC_E_MESSAGE_ALTERED;
        goto CleanUp;
    }

    if (pSig->Nonce != Sig.Nonce)
    {
        Status = SEC_E_OUT_OF_SEQUENCE;
        goto CleanUp;
    }


CleanUp:

    NtlmDerefContext( pContext );

CleanUp_NoDeref:

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



//+-------------------------------------------------------------------------
//
//  Function:   NtLmGetContextToken
//
//  Synopsis:   returns a pointer to the token for a server-side context
//
//  Effects:
//
//  Arguments:
//
//  Requires:
//
//  Returns:
//
//  Notes:
//
//
//--------------------------------------------------------------------------


NTSTATUS NTAPI
NtLmGetContextToken(
    IN ULONG_PTR KernelContextHandle,
    OUT PHANDLE ImpersonationToken,
    OUT OPTIONAL PACCESS_TOKEN *RawToken
    )
{
    NTSTATUS Status = STATUS_SUCCESS;
    PNTLM_KERNEL_CONTEXT pContext = NULL;

    MAYBE_PAGED_CODE();

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

    Status = NtlmReferenceContext( KernelContextHandle, FALSE );

    if ( NT_SUCCESS( Status ) )
    {
        pContext = (PNTLM_KERNEL_CONTEXT) KernelContextHandle ;
    }
    else
    {
        DebugLog(( DEB_ERROR,
          "Bad kernel context 0x%lx\n", KernelContextHandle));
        goto CleanUp_NoDeref;

    }

    if (pContext->ClientTokenHandle == NULL)
    {
        DebugLog(( DEB_ERROR, "Invalid TokenHandle for context 0x%lx\n", pContext ));
        Status= SEC_E_NO_IMPERSONATION;
        goto CleanUp;
    }

    if (ARGUMENT_PRESENT(ImpersonationToken))
    {
        *ImpersonationToken = pContext->ClientTokenHandle;
    }

    if (ARGUMENT_PRESENT(RawToken))
    {
        if (pContext->ClientTokenHandle != NULL)
        {
            if (pContext->AccessToken == NULL)
            {
                Status = ObReferenceObjectByHandle(
                             pContext->ClientTokenHandle,
                             TOKEN_IMPERSONATE,
                             NULL,
                             KeGetPreviousMode(),
                             (PVOID *) &pContext->AccessToken,
                             NULL);
            }
        }

        if (NT_SUCCESS(Status))
        {
            ASSERT(pContext->AccessToken != NULL);
            *RawToken = pContext->AccessToken;
        }
    }


CleanUp:

    NtlmDerefContext( pContext );

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



//+-------------------------------------------------------------------------
//
//  Function:   NtLmQueryContextAttributes
//
//  Synopsis:   Querys attributes of the specified context
//              This API allows a customer of the security
//              services to determine certain attributes of
//              the context.  These are: sizes, names, and lifespan.
//
//  Effects:
//
//  Arguments:
//
//    ContextHandle - Handle to the context to query.
//
//    Attribute - Attribute to query.
//
//        #define SECPKG_ATTR_SIZES    0
//        #define SECPKG_ATTR_NAMES    1
//        #define SECPKG_ATTR_LIFESPAN 2
//
//    Buffer - Buffer to copy the data into.  The buffer must
//             be large enough to fit the queried attribute.
//
//
//  Requires:
//
//  Returns:
//
//        STATUS_SUCCESS - Call completed successfully
//

⌨️ 快捷键说明

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