📄 krnlapi.cxx
字号:
// 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 + -