|
|
/*++
Copyright (c) 2001 Microsoft Corporation All rights reserved
Module Name:
lsasecbfr.cxx
Abstract:
This file provides useful accssors and mutators.
Author:
Larry Zhu (LZhu) May 1, 2001 Created
Environment:
User Mode -Win32
Revision History:
--*/
#include "precomp.hxx"
#pragma hdrstop
#include "lsasecbfr.hxx"
#include <stdio.h>
#include <string.h>
#define SECBUFFER_ATTRMASK 0xF0000000
#define SECBUFFER_READONLY 0x80000000 // Buffer is read-only
#define SECBUFFER_RESERVED 0x40000000
#define SECBUFFER_READONLY_WITH_CHECKSUM 0x10000000 // Buffer is read-only, and checksummed
#define SECBUFFER_UNMAPPED 0x40000000
//
// This flag is used to indicate that the buffer was mapped into the LSA
// from kernel mode.
//
#define SECBUFFER_KERNEL_MAP 0x20000000
#if 0
#define SECBUFFER_EMPTY 0 // Undefined, replaced by provider
#define SECBUFFER_DATA 1 // Packet data
#define SECBUFFER_TOKEN 2 // Security token
#define SECBUFFER_PKG_PARAMS 3 // Package specific parameters
#define SECBUFFER_MISSING 4 // Missing Data indicator
#define SECBUFFER_EXTRA 5 // Extra data
#define SECBUFFER_STREAM_TRAILER 6 // Security Trailer
#define SECBUFFER_STREAM_HEADER 7 // Security Header
#define SECBUFFER_NEGOTIATION_INFO 8 // Hints from the negotiation pkg
#define SECBUFFER_PADDING 9 // non-data padding
#define SECBUFFER_STREAM 10 // whole encrypted message
#define SECBUFFER_MECHLIST 11
#define SECBUFFER_MECHLIST_SIGNATURE 12
#define SECBUFFER_TARGET 13
#define SECBUFFER_CHANNEL_BINDINGS 14
#endif
PCSTR TSecBuffer::GetSecBufferTypeStr(IN ULONG type) { static PCSTR aszSecBufferTypes[] = { "Empty", "Data", "Token", "Package", "Missing", "Extra", "Trailer", "Header", "NegoInfo", "Padding", "Stream", "MechList", "MechListSignature", "Target", "ChannelBinding"};
type &= ~SECBUFFER_ATTRMASK;
return (type < COUNTOF(aszSecBufferTypes)) ? aszSecBufferTypes[type] : kstrInvalid; }
void ShowSecBufferAttrs(IN PCSTR pszPad, IN ULONG cbBuf, IN CHAR* pBuf, IN ULONG ulFlags) { LONG cbUsed = 0;
#define BRANCH_AND_PRINT(x) \
do { \ if (ulFlags & SECBUFFER_##x) { \ cbUsed = _snprintf(pBuf, cbBuf, "%s ", #x); \ if (cbUsed <= 0) return; \ cbBuf -= cbUsed; \ pBuf += cbUsed; \ ulFlags &= ~ SECBUFFER_##x; \ } \ } while(0) \
cbUsed = _snprintf(pBuf, cbBuf, "%s%#x : ", pszPad, (ulFlags >> 28) & 0xF); if (cbUsed <= 0) return; cbBuf -= cbUsed; pBuf += cbUsed;
BRANCH_AND_PRINT(READONLY); BRANCH_AND_PRINT(READONLY_WITH_CHECKSUM); BRANCH_AND_PRINT(UNMAPPED); BRANCH_AND_PRINT(KERNEL_MAP);
if (ulFlags & SECBUFFER_ATTRMASK) { cbUsed = _snprintf(pBuf, cbBuf, "%#x", (ulFlags >> 28) & 0xF); if (cbUsed <= 0) return; cbBuf -= cbUsed; pBuf += cbUsed;
}
cbUsed = _snprintf(pBuf, cbBuf, "\n"); if (cbUsed <= 0) return; cbBuf -= cbUsed; pBuf += cbUsed;
#undef BRANCH_AND_PRINT
}
ULONG TSecBuffer::GetcbSecBufferSizeInArray(void) { //
// To get the size of one element we do as follows in case there is
// padding after each elements
//
static ULONG cbSecBufferTypeSize = ReadTypeSize(kstrSecBuffer); static ULONG cbTwoSecBufferTypeSize = ReadTypeSize("_SecBuffer[2]"); return cbTwoSecBufferTypeSize - cbSecBufferTypeSize; }
ULONG TSecBuffer::GetcbSecBufferSizeInArrayDirect(void) { static ULONG cbSecBuffer = 2 * sizeof(ULONG) + ReadPtrSize();
return cbSecBuffer; }
TSecBuffer::TSecBuffer(void) : m_hr(E_FAIL) { }
TSecBuffer::TSecBuffer(IN ULONG64 baseOffset) : m_baseOffset(baseOffset), m_hr(E_FAIL) { m_hr = Initialize(); }
TSecBuffer::~TSecBuffer(void) { }
HRESULT TSecBuffer::IsValid(void) const { return m_hr; }
ULONG TSecBuffer::GetcbBuffer(void) const { ULONG cbBuffer = 0;
ReadStructField(m_baseOffset, kstrSecBuffer, "cbBuffer", sizeof(cbBuffer), &cbBuffer);
return cbBuffer; }
ULONG TSecBuffer::GetcbBufferDirect(void) const { ULONG cbBuffer = 0;
if (!ReadMemory(m_baseOffset, &cbBuffer, sizeof(cbBuffer), NULL)) {
DBG_LOG(LSA_ERROR, ("Unable to read SecBuffer %#I64x cbBuffer\n", m_baseOffset));
throw "TSecBuffer::GetcbBufferDirect failed"; }
return cbBuffer; }
ULONG TSecBuffer::GetBufferType(void) const { ULONG BufferType = 0;
ReadStructField(m_baseOffset, kstrSecBuffer, "BufferType", sizeof(BufferType), &BufferType);
return BufferType; }
ULONG TSecBuffer::GetBufferTypeDirect(void) const { ULONG BufferType = 0;
if (!ReadMemory(m_baseOffset + sizeof(ULONG), &BufferType, sizeof(BufferType), NULL)) {
DBG_LOG(LSA_ERROR, ("Unable to read BufferType for SecBuffer at %#I64x\n", m_baseOffset));
throw "TSecBuffer::GetBufferTypeDirect failed"; }
return BufferType; }
ULONG64 TSecBuffer::GetpvBuffer(void) const { return ReadStructPtrField(m_baseOffset, kstrSecBuffer, "pvBuffer"); }
ULONG64 TSecBuffer::GetpvBufferDirect(void) const { DBG_LOG(LSA_LOG, ("TSecBuffer::GetpvBufferDirect reading _SecBuffer %#I64x pvBuffer\n", m_baseOffset));
return toPtr(ReadPtrVar(ForwardAdjustPtrAddr(m_baseOffset + 2 * sizeof(ULONG)))); }
PCSTR TSecBuffer::toStr(IN PCSTR pszBanner) const { static CHAR szBuffer[256] = {0}; LONG cbUsed = 0;
ULONG type = GetBufferType(); ULONG dwAttrMask = type & SECBUFFER_ATTRMASK;
ExitIfControlC();
szBuffer[RTL_NUMBER_OF(szBuffer) - 1] = '\0';
if ((cbUsed = _snprintf(szBuffer, RTL_NUMBER_OF(szBuffer) - 1, "%s%s %#x bytes, pvBuffer %s, attr ", pszBanner ? pszBanner : "", GetSecBufferTypeStr(type), GetcbBuffer(), PtrToStr(GetpvBuffer()))) <= 0) {
DBG_LOG(LSA_ERROR, ("Unable to print _SecBuffer %#I64x\n", m_baseOffset));
throw "TSecBuffer::toStr failed"; }
ShowSecBufferAttrs(kstrEmptyA, RTL_NUMBER_OF(szBuffer) - cbUsed, szBuffer + cbUsed, dwAttrMask );
return szBuffer; }
PCSTR TSecBuffer::toStrDirect(IN PCSTR pszBanner) const { static CHAR szBuffer[256] = {0}; LONG cbUsed;
ULONG type = GetBufferTypeDirect(); ULONG dwAttrMask = type & SECBUFFER_ATTRMASK;
ExitIfControlC();
szBuffer[RTL_NUMBER_OF(szBuffer) - 1] = '\0';
if ((cbUsed = _snprintf(szBuffer, RTL_NUMBER_OF(szBuffer) - 1, "%s%s %#x bytes, pvBuffer %s, attr ", pszBanner ? pszBanner : "", GetSecBufferTypeStr(type), GetcbBufferDirect(), PtrToStr(GetpvBufferDirect()))) <= 0) {
DBG_LOG(LSA_ERROR, ("Unable to print _SecBuffer %#I64x\n", m_baseOffset));
throw "TSecBuffer::toStrDirect failed"; }
ShowSecBufferAttrs(kstrEmptyA, RTL_NUMBER_OF(szBuffer) - cbUsed, szBuffer + cbUsed, dwAttrMask );
return szBuffer; }
void TSecBuffer::ShowDirect(IN PCSTR pszBanner, IN BOOL bVerbose) const { ULONG type = GetBufferTypeDirect(); ULONG dwAttrMask = type & SECBUFFER_ATTRMASK;
ULONG cbBuffer = 0; ULONG64 addrBuffer = 0; CHAR* pBuffer = NULL; CHAR szBuffer[256] = {0};
ExitIfControlC();
cbBuffer = GetcbBufferDirect(); addrBuffer = GetpvBufferDirect();
dprintf("%s%s %#x bytes, pvBuffer %s, attr ", pszBanner ? pszBanner : "", GetSecBufferTypeStr(type), cbBuffer, PtrToStr(addrBuffer)); ShowSecBufferAttrs(kstrEmptyA, RTL_NUMBER_OF(szBuffer), szBuffer, dwAttrMask ); dprintf("%s", szBuffer);
//
// Now print out the content of security buffers
//
if (bVerbose && addrBuffer) {
pBuffer = new char[cbBuffer];
if (!pBuffer) {
throw "TSecBuffer::ShowDirect out of memory"; }
if (ReadMemory(addrBuffer, pBuffer, cbBuffer, NULL)) {
debugPrintHex(pBuffer, cbBuffer);
} else {
DBG_LOG(LSA_ERROR, ("Unable to print SecBuffer::pvBuffer at %#I64x\n", toPtr(addrBuffer)));
delete[] pBuffer;
throw "TSecBuffer::ShowDirect read memory error"; } }
delete[] pBuffer; }
/******************************************************************************
Private Methods
******************************************************************************/ /*++
Routine Name:
Initialize
Routine Description:
Do necessary initialization.
Arguments:
None
Return Value:
An HRESULT
--*/ HRESULT TSecBuffer::Initialize(void) { HRESULT hRetval = E_FAIL;
hRetval = S_OK;
return hRetval; }
HRESULT TSecBuffer::Initialize(IN ULONG64 baseOffset) { m_baseOffset = baseOffset;
m_hr = Initialize();
return m_hr; }
|