windows-nt/Source/XPSP1/NT/termsrv/remdsk/rds/t120/common/sesskey.cpp

546 lines
14 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include "precomp.h"
#include "fsdiag.h"
DEBUG_FILEZONE(ZONE_T120_UTILITY);
/*
* sesskey.cpp
*
* Copyright (c) 1995 by DataBeam Corporation, Lexington, KY
*
* Abstract:
* This is the implementation file for the class CSessKeyContainer. This class
* manages the data associated with a Session Key. Session Key's are used
* to uniquely identify an Application Protocol Session. The Application
* Protocol is identified by an Object Key and the particular session
* identified by an optional session ID. The CSessKeyContainer class uses an
* CObjectKeyContainer container to maintain the object key data internally. An
* unsigned short integer is used to hold the optional session ID.
*
* Protected Instance Variables:
* m_InternalSessKey
* Structure used to hold the object key data internally.
* m_SessionKeyPDU
* Storage for the "PDU" form of the session key.
* m_fValidSessionKeyPDU
* Flag indicating that memory has been allocated to hold the internal
* "PDU" session key.
* m_cbDataSize
* Variable holding the size of the memory which will be required to
* hold any data referenced by the "API" GCCSessionKey structure.
*
* Caveats:
* None.
*
* Author:
* jbo
*/
#include "sesskey.h"
/*
* CSessKeyContainer()
*
* Public Function Description:
* This constructor is used to create a CSessKeyContainer object from
* an "API" GCCSessionKey.
*/
CSessKeyContainer::
CSessKeyContainer(PGCCSessionKey session_key, PGCCError pRetCode)
:
CRefCount(MAKE_STAMP_ID('S','e','s','K')),
m_fValidSessionKeyPDU(FALSE),
m_cbDataSize(0)
{
GCCError rc;
/*
* Save the Object Key portion of the Session Key in the internal structure
* by creating a new CObjectKeyContainer object. Check to make sure the object
* is successfully created.
*/
DBG_SAVE_FILE_LINE
m_InternalSessKey.application_protocol_key = new CObjectKeyContainer(
&session_key->application_protocol_key,
&rc);
if (NULL != m_InternalSessKey.application_protocol_key && GCC_NO_ERROR == rc)
{
/*
* Save the session ID if the CObjectKeyContainer was saved correctly. A zero
* value of the GCC session ID will indicate that one is not actually
* present.
*/
m_InternalSessKey.session_id = session_key->session_id;
}
else if (GCC_BAD_OBJECT_KEY == rc)
{
ERROR_OUT(("CSessKeyContainer::SessionKeyData1: bad session key"));
rc = GCC_BAD_SESSION_KEY;
}
else
{
ERROR_OUT(("CSessKeyContainer::SessionKeyData1: Error creating new CObjectKeyContainer"));
rc = GCC_ALLOCATION_FAILURE;
}
*pRetCode = rc;
}
/*
* CSessKeyContainer()
*
* Public Function Description:
* This constructor is used to create a CSessKeyContainer object from
* a "PDU" SessionKey.
*/
CSessKeyContainer::
CSessKeyContainer(PSessionKey session_key, PGCCError pRetCode)
:
CRefCount(MAKE_STAMP_ID('S','e','s','K')),
m_fValidSessionKeyPDU(FALSE),
m_cbDataSize(0)
{
GCCError rc;
/*
* Save the Object Key portion of the Session Key in the internal structure
* by creating a new CObjectKeyContainer object. Check to make sure the object
* is successfully created.
*/
DBG_SAVE_FILE_LINE
m_InternalSessKey.application_protocol_key = new CObjectKeyContainer(
&session_key->application_protocol_key,
&rc);
if (NULL != m_InternalSessKey.application_protocol_key && GCC_NO_ERROR == rc)
{
/*
* Save the session ID if one is present and the CObjectKeyContainer was saved
* correctly. If a session ID is not present, set the internal session ID
* to zero to indicate this.
*/
if (session_key->bit_mask & SESSION_ID_PRESENT)
{
m_InternalSessKey.session_id = session_key->session_id;
}
else
{
m_InternalSessKey.session_id = 0;
}
}
else if (GCC_BAD_OBJECT_KEY == rc)
{
ERROR_OUT(("CSessKeyContainer::SessionKeyData2: bad session key"));
rc = GCC_BAD_SESSION_KEY;
}
else
{
ERROR_OUT(("CSessKeyContainer::SessionKeyData2: Error creating new CObjectKeyContainer"));
rc = GCC_ALLOCATION_FAILURE;
}
*pRetCode = rc;
}
/*
* CSessKeyContainer()
*
* Public Function Description:
* This copy constructor is used to create a new CSessKeyContainer object from
* another CSessKeyContainer object.
*/
CSessKeyContainer::
CSessKeyContainer(CSessKeyContainer *session_key, PGCCError pRetCode)
:
CRefCount(MAKE_STAMP_ID('S','e','s','K')),
m_fValidSessionKeyPDU(FALSE),
m_cbDataSize(0)
{
GCCError rc;
/*
* Copy the Object Key portion of the Session Key using the copy constructor
* of the CObjectKeyContainer class. Check to make sure the CObjectKeyContainer object
* is successfully created.
*/
DBG_SAVE_FILE_LINE
m_InternalSessKey.application_protocol_key = new CObjectKeyContainer(
session_key->m_InternalSessKey.application_protocol_key,
&rc);
if (NULL != m_InternalSessKey.application_protocol_key && GCC_NO_ERROR == rc)
{
/*
* Save the session ID if the CObjectKeyContainer was saved correctly. A zero
* value of the GCC session ID will indicate that one is not actually
* present.
*/
m_InternalSessKey.session_id = session_key->m_InternalSessKey.session_id;
}
else if (GCC_BAD_OBJECT_KEY == rc)
{
ERROR_OUT(("CSessKeyContainer::SessionKeyData3: bad session key"));
rc = GCC_BAD_SESSION_KEY;
}
else
{
ERROR_OUT(("CSessKeyContainer::SessionKeyData3: Error creating new CObjectKeyContainer"));
rc = GCC_ALLOCATION_FAILURE;
}
*pRetCode = rc;
}
/*
* ~CSessKeyContainer()
*
* Public Function Description
* The CSessKeyContainer destructor is responsible for freeing any memory
* allocated to hold the session key data.
*
*/
CSessKeyContainer::
~CSessKeyContainer(void)
{
/*
* If "PDU" data has been allocated for this object, free it now.
*/
if (m_fValidSessionKeyPDU)
{
FreeSessionKeyDataPDU();
}
/*
* Delete any object key data held internally.
*/
if (NULL != m_InternalSessKey.application_protocol_key)
{
m_InternalSessKey.application_protocol_key->Release();
}
}
/*
* LockSessionKeyData ()
*
* Public Function Description:
* This routine locks the session key data and determines the amount of
* memory referenced by the "API" session key data structure.
*/
UINT CSessKeyContainer::
LockSessionKeyData(void)
{
/*
* If this is the first time this routine is called, determine the size of
* the memory required to hold the data referenced by the session key
* structure. Otherwise, just increment the lock count.
*/
if (Lock() == 1)
{
/*
* Lock the data for the object key held within the session key. The
* pointer to the CObjectKeyContainer object is validated in the constructor.
*/
m_cbDataSize = m_InternalSessKey.application_protocol_key->LockObjectKeyData();
}
return m_cbDataSize;
}
/*
* GetGCCSessionKeyData ()
*
* Public Function Description:
* This routine retrieves session key data in the "API" form of a
* GCCSessionKey. This routine is called after "locking" the session
* key data.
*/
UINT CSessKeyContainer::
GetGCCSessionKeyData(PGCCSessionKey session_key, LPBYTE memory)
{
UINT cbDataSizeToRet = 0;
/*
* If the session key data has been locked, fill in the output structure and
* the data referenced by the structure. Call the "Get" routine for the
* ObjectKey to fill in the object key data.
*/
if (GetLockCount() > 0)
{
/*
* Fill in the output length parameter which indicates how much data
* referenced outside the structure will be written.
*/
cbDataSizeToRet = m_cbDataSize;
::ZeroMemory(memory, m_cbDataSize);
session_key->session_id = m_InternalSessKey.session_id;
m_InternalSessKey.application_protocol_key->GetGCCObjectKeyData(
&session_key->application_protocol_key,
memory);
}
else
{
ERROR_OUT(("CSessKeyContainer::GetGCCSessionKeyData: Error: data not locked"));
}
return cbDataSizeToRet;
}
/*
* UnlockSessionKeyData ()
*
* Public Function Description:
* This routine decrements the lock count and frees the memory associated
* with the "API" session key once the lock count reaches zero.
*/
void CSessKeyContainer::
UnLockSessionKeyData(void)
{
if (Unlock(FALSE) == 0)
{
/*
* Unlock the data associated with the internal CObjectKeyContainer and
* delete this object if the "free flag" is set.
*/
if (m_InternalSessKey.application_protocol_key != NULL)
{
m_InternalSessKey.application_protocol_key->UnLockObjectKeyData();
}
}
// we have to call Release() because we used Unlock(FALSE)
Release();
}
/*
* GetSessionKeyDataPDU ()
*
* Public Function Description:
* This routine converts the session key from it's internal form of a
* SESSION_KEY structure into the "PDU" form which can be passed in
* to the ASN.1 encoder. A pointer to a "PDU" "SessionKey" structure is
* returned.
*/
GCCError CSessKeyContainer::
GetSessionKeyDataPDU(PSessionKey session_key)
{
GCCError rc = GCC_NO_ERROR;
/*
* If this is the first time that PDU data has been requested then we must
* fill in the internal PDU structure and copy it into the structure pointed
* to by the output parameter. On subsequent calls to "GetPDU" we can just
* copy the internal PDU structure into the structure pointed to by the
* output parameter.
*/
if (m_fValidSessionKeyPDU == FALSE)
{
m_fValidSessionKeyPDU = TRUE;
/*
* Initialize the "PDU" session key's bit mask to zero.
*/
m_SessionKeyPDU.bit_mask = 0;
/*
* Fill in the "PDU" session key from the internal structure.
*/
if (m_InternalSessKey.application_protocol_key != NULL)
{
/*
* Fill in the object key portion of the session key by using the
* "GetPDU" routine of the internal CObjectKeyContainer object.
*/
rc = m_InternalSessKey.application_protocol_key->
GetObjectKeyDataPDU(&m_SessionKeyPDU.application_protocol_key);
}
else
{
rc = GCC_ALLOCATION_FAILURE;
}
/*
* Fill in the "PDU" session ID if one exists. A value of zero for the
* internal session ID indicates that one really does not exist.
*/
if (m_InternalSessKey.session_id != 0)
{
m_SessionKeyPDU.bit_mask |= SESSION_ID_PRESENT;
m_SessionKeyPDU.session_id = m_InternalSessKey.session_id;
}
}
/*
* Copy the internal PDU structure into the structure pointed to by the
* output parameter.
*/
*session_key = m_SessionKeyPDU;
return rc;
}
/*
* FreeSessionKeyDataPDU ()
*
* Public Function Description:
* This routine is used to free the session key data held internally in
* the "PDU" form of a "SessionKey".
*/
void CSessKeyContainer::
FreeSessionKeyDataPDU(void)
{
if (m_fValidSessionKeyPDU)
{
/*
* Set the flag indicating that PDU session key data is no longer
* allocated.
*/
m_fValidSessionKeyPDU = FALSE;
if (m_InternalSessKey.application_protocol_key != NULL)
{
m_InternalSessKey.application_protocol_key->FreeObjectKeyDataPDU ();
}
else
{
ERROR_OUT(("CSessKeyContainer::FreeSessionKeyDataPDU: Bad internal pointer"));
}
}
}
/*
* IsThisYourApplicationKey()
*
* Public Function Description:
* This routine is used to determine whether the specified application
* key is held within this session key.
*/
BOOL CSessKeyContainer::
IsThisYourApplicationKey(PGCCObjectKey application_key)
{
BOOL fRet = FALSE;
CObjectKeyContainer *object_key_data;
GCCError rc2;
DBG_SAVE_FILE_LINE
object_key_data = new CObjectKeyContainer(application_key, &rc2);
if ((object_key_data != NULL) && (rc2 == GCC_NO_ERROR))
{
if (*object_key_data == *m_InternalSessKey.application_protocol_key)
{
fRet = TRUE;
}
}
else
{
ERROR_OUT(("CSessKeyContainer::IsThisYourApplicationKey: Error creating new CObjectKeyContainer"));
}
if (NULL != object_key_data)
{
object_key_data->Release();
}
return fRet;
}
/*
* IsThisYourApplicationKeyPDU()
*
* Public Function Description:
* This routine is used to determine whether the specified application
* key is held within this session key.
*/
BOOL CSessKeyContainer::
IsThisYourApplicationKeyPDU(PKey application_key)
{
BOOL fRet = FALSE;
CObjectKeyContainer *object_key_data;
GCCError rc2;
DBG_SAVE_FILE_LINE
object_key_data = new CObjectKeyContainer(application_key, &rc2);
if ((object_key_data != NULL) && (rc2 == GCC_NO_ERROR))
{
if (*object_key_data == *m_InternalSessKey.application_protocol_key)
{
fRet = TRUE;
}
}
else
{
ERROR_OUT(("CSessKeyContainer::IsThisYourApplicationKeyPDU: Error creating new CObjectKeyContainer"));
}
if (NULL != object_key_data)
{
object_key_data->Release();
}
return fRet;
}
/*
* IsThisYourSessionKeyPDU ()
*
* Public Function Description:
* This routine is used to determine whether the specified session key
* is equal in value to this session key.
*/
BOOL CSessKeyContainer::
IsThisYourSessionKeyPDU(PSessionKey session_key)
{
BOOL fRet = FALSE;
CSessKeyContainer *session_key_data;
GCCError rc2;
DBG_SAVE_FILE_LINE
session_key_data = new CSessKeyContainer(session_key, &rc2);
if ((session_key_data != NULL) && (rc2 == GCC_NO_ERROR))
{
if (*session_key_data == *this)
{
fRet = TRUE;
}
}
else
{
ERROR_OUT(("CSessKeyContainer::IsThisYourSessionKeyPDU: Error creating new CSessKeyContainer"));
}
if (NULL != session_key_data)
{
session_key_data->Release();
}
return fRet;
}
/*
* operator== ()
*
* Public Function Description:
* This routine is used to determine whether or not two session keys are
* equal in value.
*/
BOOL operator==(const CSessKeyContainer& session_key_1, const CSessKeyContainer& session_key_2)
{
BOOL fRet = FALSE;
if ((session_key_1.m_InternalSessKey.application_protocol_key != NULL) &&
(session_key_2.m_InternalSessKey.application_protocol_key != NULL))
{
if (*session_key_1.m_InternalSessKey.application_protocol_key ==
*session_key_2.m_InternalSessKey.application_protocol_key)
{
if (session_key_1.m_InternalSessKey.session_id ==
session_key_2.m_InternalSessKey.session_id)
{
fRet = TRUE;
}
}
}
return fRet;
}