546 lines
14 KiB
C++
546 lines
14 KiB
C++
#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;
|
|
}
|
|
|
|
|