windows-nt/Source/XPSP1/NT/enduser/netmeeting/t120/mst120/password.cpp
2020-09-26 16:20:57 +08:00

3048 lines
87 KiB
C++

#include "precomp.h"
DEBUG_FILEZONE(ZONE_T120_GCCNC);
/*
* password.cpp
*
* Copyright (c) 1995 by DataBeam Corporation, Lexington, KY
*
* Abstract:
* This is the implementation file for the class CPassword. This class
* manages the data associated with a Password. Passwords are used to
* restrict access to conferences. A password can be one of two basic
* types. The simple type consists of either a simple numeric password or
* a simple textual password, or both. The "PDU" type "Password" is a
* structure which must contain the numeric form of the password and may
* optionally contain the textual part as well. The "PDU" type
* "PasswordSelector" is a union of the numeric and textual forms of a
* password and is therefore always one or the other but not both. When
* the password is not the simple type it assumes the form of a
* "PasswordChallengeRequestResponse". This complex structure allows a
* challenge-response scheme to be used to control access to conferences.
*
* Protected Instance Variables:
* m_fSimplePassword
* Flag indicating this password does not contain "challenge" data.
* m_fClearPassword
* Flag used when the password assumes the "challenge" form indicating
* that this password is "in the clear" meaning no true challenge
* data is present.
* m_pszNumeric
* String holding the numeric portion of the simple password.
* Text_String_Ptr
* String holding the textual portion of the simple password.
* m_pInternalRequest
* Structure holding the data associated with a password challenge
* request.
* m_pInternalResponse
* Structure holding the data associated with a password challenge
* response.
* m_pChallengeResponse
* Structure holding the "API" form of a challenge password.
* m_pPassword
* Structure holding the "API" form of a simple password.
* m_pUserDataMemory
* Memory container holding the user data associated with a
* challenge password.
* m_pChallengeItemListMemory
* Memory container holding the list of pointers to challenge items
* associated with a password challenge request.
* m_pObjectKeyMemory
* Memory container holding the object key data associated with the
* non-standard challenge response algorithm.
* m_ChallengeItemMemoryList
* Memory container holding the data for the challenge items
* associated with a password challenge request.
* m_ChallengeResponsePDU
* Storage for the "PDU" form of the challenge password.
* m_fValidChallengeResponsePDU
* Flag indicating that memory has been allocated to hold the internal
* "PDU" password.
*
* Caveats:
* None.
*
* Author:
* blp/jbo
*/
#include "password.h"
#include "userdata.h"
/*
* CPassword()
*
* Public Function Description:
* This constructor for the CPassword class is used when creating a
* CPassword object with an "API" GCCPassword structure. It saves the
* password data in the internal structures.
*/
CPassword::CPassword(PGCCPassword password,
PGCCError return_value)
:
CRefCount(MAKE_STAMP_ID('P','a','s','w')),
m_fValidChallengeResponsePDU(FALSE),
m_pInternalRequest(NULL),
m_pInternalResponse(NULL),
m_pChallengeResponse(NULL),
m_pPassword(NULL),
m_pChallengeItemListMemory(NULL),
m_pUserDataMemory(NULL),
m_pObjectKeyMemory(NULL),
m_pszNumeric(NULL),
m_pwszText(NULL)
{
*return_value = GCC_NO_ERROR;
/*
* Set the flag indicating that this is a "simple" password, without the
* challenge request-response information. The "clear" flag is also
* initialized here but should only be needed when the password is not
* "simple".
*/
m_fSimplePassword = TRUE;
m_fClearPassword = TRUE;
/*
* Save the numeric part of the password in the internal numeric string.
*/
if (password->numeric_string != NULL)
{
if (NULL == (m_pszNumeric = ::My_strdupA(password->numeric_string)))
{
ERROR_OUT(("CPassword::CPassword: can't create numeric string"));
*return_value = GCC_ALLOCATION_FAILURE;
}
}
else
{
ERROR_OUT(("CPassword::CPassword: No valid numeric password"));
*return_value = GCC_INVALID_PASSWORD;
}
/*
* Check to see if the textual part of the password is present. If so,
* save it in the internal UnicodeString. If not, set the text pointer
* to NULL.
*/
if ((password->text_string != NULL) && (*return_value == GCC_NO_ERROR))
{
if (NULL == (m_pwszText = ::My_strdupW(password->text_string)))
{
ERROR_OUT(("CPassword::CPassword: Error creating text string"));
*return_value = GCC_ALLOCATION_FAILURE;
}
}
else
m_pwszText = NULL;
}
/*
* CPassword()
*
* Public Function Description:
* This constructor is used when a CPassword object is being created
* with a "ChallengeRequestResponse" "API" structure. The password data
* is saved in the internal structures.
*/
CPassword::CPassword(PGCCChallengeRequestResponse challenge_response_data,
PGCCError return_value)
:
CRefCount(MAKE_STAMP_ID('P','a','s','w')),
m_fValidChallengeResponsePDU(FALSE),
m_pInternalRequest(NULL),
m_pInternalResponse(NULL),
m_pChallengeResponse(NULL),
m_pPassword(NULL),
m_pChallengeItemListMemory(NULL),
m_pUserDataMemory(NULL),
m_pObjectKeyMemory(NULL),
m_pszNumeric(NULL),
m_pwszText(NULL)
{
*return_value = GCC_NO_ERROR;
/*
* Set the flag indicating that this is not a "simple" password, meaning
* that it contains challenge request-response information. If the password
* is "clear" there is no need to create the internal "Challenge" structure
* used to hold the challenge request-response information.
*/
m_fSimplePassword = FALSE;
/*
* Check to see if a "clear" challenge password exists or if this is a
* true challenge request-response password.
*/
if (challenge_response_data->password_challenge_type ==
GCC_PASSWORD_IN_THE_CLEAR)
{
/*
* A "clear" password is being sent so set the flag indicating so.
* Also set the password type and save the numeric part of the password,
* if it exists. Note that since the "clear" password contained in the
* challenge is a PasswordSelector type, either the numeric or the text
* form of the password should exist, but not both.
*/
m_fClearPassword = TRUE;
if (challenge_response_data->u.password_in_the_clear.
numeric_string != NULL)
{
if (NULL == (m_pszNumeric = ::My_strdupA(
challenge_response_data->u.password_in_the_clear.numeric_string)))
{
ERROR_OUT(("CPassword::CPassword: can't create numeric string"));
*return_value = GCC_ALLOCATION_FAILURE;
}
}
else
{
m_pszNumeric = NULL;
}
/*
* Check to see if the textual part of the password is present. If it
* is, save it in the internal UnicodeString.
*/
if ((challenge_response_data->u.password_in_the_clear.
text_string != NULL) && (*return_value == GCC_NO_ERROR))
{
if (NULL == (m_pwszText = ::My_strdupW(
challenge_response_data->u.password_in_the_clear.text_string)))
{
ERROR_OUT(("CPassword::CPassword: Error creating text string"));
*return_value = GCC_ALLOCATION_FAILURE;
}
}
else
{
m_pwszText = NULL;
}
/*
* Check to make sure at least one form (text or numeric) of the
* "clear" password was saved. Report an error if neither was created.
*/
if ((*return_value == GCC_NO_ERROR) && (m_pszNumeric == NULL)
&& (m_pwszText == NULL))
{
ERROR_OUT(("CPassword::CPassword: Error creating password"));
*return_value = GCC_INVALID_PASSWORD;
}
}
else
{
/*
* This is a true challenge request-response password. Set the flag
* indicating that the password is not "clear" and create the
* "challenge" data structures to hold the password data internally.
*/
m_fClearPassword = FALSE;
/*
* Check to see if a challenge request is present.
*/
if (challenge_response_data->u.challenge_request_response.
challenge_request != NULL)
{
/*
* Create a RequestInfo stucture to hold the request data
* and copy the challenge request structure internally.
*/
DBG_SAVE_FILE_LINE
m_pInternalRequest = new RequestInfo;
if (m_pInternalRequest != NULL)
{
*return_value = ConvertAPIChallengeRequest (
challenge_response_data->u.
challenge_request_response.challenge_request);
}
else
{
ERROR_OUT(("CPassword::CPassword: Error creating new RequestInfo"));
*return_value = GCC_ALLOCATION_FAILURE;
}
}
/*
* Check to see if a challenge response is present.
*/
if ((challenge_response_data->u.challenge_request_response.
challenge_response != NULL) &&
(*return_value == GCC_NO_ERROR))
{
/*
* Create a ResponseInfo stucture to hold the response data
* and copy the challenge response structure internally.
*/
DBG_SAVE_FILE_LINE
m_pInternalResponse = new ResponseInfo;
if (m_pInternalResponse != NULL)
{
*return_value = ConvertAPIChallengeResponse (
challenge_response_data->u.
challenge_request_response.challenge_response);
}
else
{
ERROR_OUT(("CPassword::CPassword: Error creating new ResponseInfo"));
*return_value = GCC_ALLOCATION_FAILURE;
}
}
}
}
/*
* CPassword()
*
* Public Function Description
* This constructor for the CPassword class is used when creating a
* CPassword object with a "PDU" Password structure. It saves the
* password data in the internal structures.
*/
CPassword::CPassword(PPassword password_pdu,
PGCCError return_value)
:
CRefCount(MAKE_STAMP_ID('P','a','s','w')),
m_fValidChallengeResponsePDU(FALSE),
m_pInternalRequest(NULL),
m_pInternalResponse(NULL),
m_pChallengeResponse(NULL),
m_pPassword(NULL),
m_pChallengeItemListMemory(NULL),
m_pUserDataMemory(NULL),
m_pObjectKeyMemory(NULL),
m_pszNumeric(NULL),
m_pwszText(NULL)
{
*return_value = GCC_NO_ERROR;
/*
* Set the flag indicating that this is a "simple" password, without the
* challenge request-response information. The "clear" flag is also
* initialized here but should only be needed when the password is not
* "simple".
*/
m_fSimplePassword = TRUE;
m_fClearPassword = TRUE;
/*
* Save the numeric part of the password. The numeric portion of the
* password is required to be present so report an error if it is not.
*/
if (password_pdu->numeric != NULL)
{
if (NULL == (m_pszNumeric = ::My_strdupA(password_pdu->numeric)))
{
ERROR_OUT(("CPassword::CPassword: can't create numeric string"));
*return_value = GCC_ALLOCATION_FAILURE;
}
}
else
{
ERROR_OUT(("CPassword::CPassword: Error no valid numeric password in PDU"));
*return_value = GCC_INVALID_PASSWORD;
m_pszNumeric = NULL;
}
/*
* Check to see if the textual part of the password is present.
*/
if ((password_pdu->bit_mask & PASSWORD_TEXT_PRESENT) &&
(*return_value == GCC_NO_ERROR))
{
if (NULL == (m_pwszText = ::My_strdupW2(
password_pdu->password_text.length,
password_pdu->password_text.value)))
{
ERROR_OUT(("CPassword::CPassword: Error creating password text"));
*return_value = GCC_ALLOCATION_FAILURE;
}
}
else
m_pwszText = NULL;
}
/*
* CPassword()
*
* Public Function Description:
* This constructor for the CPassword class is used when creating a
* CPassword object with a "PDU" PasswordSelector structure. It saves
* the password data in it's internal structures but does not require
* saving any "challenge request-response" data.
*/
CPassword::CPassword(PPasswordSelector password_selector_pdu,
PGCCError return_value)
:
CRefCount(MAKE_STAMP_ID('P','a','s','w')),
m_fValidChallengeResponsePDU(FALSE),
m_pInternalRequest(NULL),
m_pInternalResponse(NULL),
m_pChallengeResponse(NULL),
m_pPassword(NULL),
m_pChallengeItemListMemory(NULL),
m_pUserDataMemory(NULL),
m_pObjectKeyMemory(NULL),
m_pszNumeric(NULL),
m_pwszText(NULL)
{
*return_value = GCC_NO_ERROR;
/*
* Set the flag indicating that this is a "simple" password, without the
* challenge request-response information.
*/
m_fSimplePassword = TRUE;
m_fClearPassword = TRUE;
/*
* The password selector contains either the numeric password or the
* textual password but not both. Check to see if the textual password
* is chosen.
*/
if (password_selector_pdu->choice == PASSWORD_SELECTOR_TEXT_CHOSEN)
{
if (NULL == (m_pwszText = ::My_strdupW2(
password_selector_pdu->u.password_selector_text.length,
password_selector_pdu->u.password_selector_text.value)))
{
ERROR_OUT(("CPassword::CPassword: Error creating password selector text"));
*return_value = GCC_ALLOCATION_FAILURE;
}
}
else
m_pwszText = NULL;
/*
* Check to see if the numeric password is chosen.
*/
if (password_selector_pdu->choice == PASSWORD_SELECTOR_NUMERIC_CHOSEN)
{
if (NULL == (m_pszNumeric = ::My_strdupA(
password_selector_pdu->u.password_selector_numeric)))
{
ERROR_OUT(("CPassword::CPassword: can't create numeric string"));
*return_value = GCC_ALLOCATION_FAILURE;
}
}
else
m_pszNumeric = NULL;
/*
* Check to make sure at least one form (text or numeric) of the
* password was saved. Report an error if neither was created.
*/
if ((*return_value == GCC_NO_ERROR) && (m_pszNumeric == NULL)
&& (m_pwszText == NULL))
{
ERROR_OUT(("CPassword::CPassword: Error creating password selector"));
*return_value = GCC_INVALID_PASSWORD;
}
}
/*
* CPassword()
*
* Public Function Description:
* This constructor for the CPassword class is used when creating a
* CPassword object with a "PDU" Challenge Request-Response structure.
* The password data is saved in the internal structures.
*/
CPassword::CPassword(PPasswordChallengeRequestResponse pdu_challenge_data,
PGCCError return_value)
:
CRefCount(MAKE_STAMP_ID('P','a','s','w')),
m_fValidChallengeResponsePDU(FALSE),
m_pInternalRequest(NULL),
m_pInternalResponse(NULL),
m_pChallengeResponse(NULL),
m_pPassword(NULL),
m_pChallengeItemListMemory(NULL),
m_pUserDataMemory(NULL),
m_pObjectKeyMemory(NULL),
m_pszNumeric(NULL),
m_pwszText(NULL)
{
*return_value = GCC_NO_ERROR;
/*
* Set the flag indicating that this is not "simple" password, meaning that
* it contains challenge request-response information. If the password is
* "clear" there is no need to create the internal "Challenge" structure
* used to hold the challenge request-response information.
*/
m_fSimplePassword = FALSE;
/*
* Check to see if a "clear" challenge password exists or if this is a
* true challenge request-response password.
*/
if (pdu_challenge_data->choice == CHALLENGE_CLEAR_PASSWORD_CHOSEN)
{
/*
* A "clear" password is being sent so set the flag indicating so.
* Also set the password type and save the numeric part of the password,
* if it is present.
*/
m_fClearPassword = TRUE;
if (pdu_challenge_data->u.challenge_clear_password.choice ==
PASSWORD_SELECTOR_NUMERIC_CHOSEN)
{
if (NULL == (m_pszNumeric = ::My_strdupA(
pdu_challenge_data->u.challenge_clear_password.u.password_selector_numeric)))
{
ERROR_OUT(("CPassword::CPassword: can't create numeric string"));
*return_value = GCC_ALLOCATION_FAILURE;
}
}
else
{
m_pszNumeric = NULL;
}
/*
* Check to see if the textual part of the password is present. If it
* is, save it in the internal structure.
*/
if (pdu_challenge_data->u.challenge_clear_password.choice ==
PASSWORD_SELECTOR_TEXT_CHOSEN)
{
if (NULL == (m_pwszText = ::My_strdupW2(
pdu_challenge_data->u.challenge_clear_password.
u.password_selector_text.length,
pdu_challenge_data->u.challenge_clear_password.
u.password_selector_text.value)))
{
ERROR_OUT(("CPassword::CPassword: Error creating password selector text"));
*return_value = GCC_ALLOCATION_FAILURE;
}
}
else
{
m_pwszText = NULL;
}
/*
* Check to make sure at least one form (text or numeric) of the
* "clear" password was saved. Report an error if neither was created.
*/
if ((*return_value == GCC_NO_ERROR) && (m_pszNumeric == NULL)
&& (m_pwszText == NULL))
{
ERROR_OUT(("CPassword::CPassword: Error creating password"));
*return_value = GCC_INVALID_PASSWORD;
}
}
else
{
/*
* This is a true challenge request-response password. Set the flag
* indicating that the password is not "clear" and create a
* "challenge data" structure to hold the password data internally.
*/
m_fClearPassword = FALSE;
/*
* Check to see if a challenge request is present.
*/
if (pdu_challenge_data->u.challenge_request_response.
bit_mask & CHALLENGE_REQUEST_PRESENT)
{
/*
* Create a RequestInfo stucture to hold the request data
* and copy the challenge request structure internally.
*/
DBG_SAVE_FILE_LINE
m_pInternalRequest = new RequestInfo;
if (m_pInternalRequest != NULL)
{
*return_value = ConvertPDUChallengeRequest (
&pdu_challenge_data->u.challenge_request_response.
challenge_request);
}
else
{
ERROR_OUT(("CPassword::CPassword: Error creating new RequestInfo"));
*return_value = GCC_ALLOCATION_FAILURE;
}
}
/*
* Check to see if a challenge response is present.
*/
if ((pdu_challenge_data->u.challenge_request_response.
bit_mask & CHALLENGE_RESPONSE_PRESENT) &&
(*return_value == GCC_NO_ERROR))
{
/*
* Create a ResponseInfo stucture to hold the response data
* and copy the challenge response structure internally.
*/
DBG_SAVE_FILE_LINE
m_pInternalResponse = new ResponseInfo;
if (m_pInternalResponse != NULL)
{
*return_value = ConvertPDUChallengeResponse (
&pdu_challenge_data->u.challenge_request_response.
challenge_response);
}
else
{
ERROR_OUT(("CPassword::CPassword: Error creating new ResponseInfo"));
*return_value = GCC_ALLOCATION_FAILURE;
}
}
}
}
/*
* ~CPassword()
*
* Public Function Description:
* This is the destructor for the CPassword class. It will free up
* any memory allocated during the life of this object.
*/
CPassword::~CPassword(void)
{
PChallengeItemInfo challenge_item_info_ptr;
delete m_pszNumeric;
delete m_pwszText;
/*
* If "PDU" data has been allocated for this object, free it now.
*/
if (m_fValidChallengeResponsePDU)
{
FreePasswordChallengeResponsePDU();
}
/*
* Delete the memory associated with the "API" "simple" password
* data structure.
*/
delete m_pPassword;
/*
* Free any data allocated for the "API" challenge password. This would be
* left around if "UnLock" was not called. Note that if the "challenge"
* password is "clear", the numeric and text pointers above would contain
* the "API" data so now we just need to delete the "challenge" password
* structure.
*/
if (m_pChallengeResponse != NULL)
{
if (m_fClearPassword == FALSE)
{
FreeAPIPasswordData();
}
else
{
delete m_pChallengeResponse;
}
}
/*
* Free any internal memory allocated for the challenge request information.
* Iterate through the list of challenge items associated with the
* challenge request, if it exists.
*/
if (m_pInternalRequest != NULL)
{
m_pInternalRequest->ChallengeItemList.Reset();
while (NULL != (challenge_item_info_ptr = m_pInternalRequest->ChallengeItemList.Iterate()))
{
/*
* Delete any memory being referenced in the ChallengeItemInfo
* structure.
*/
if (NULL != challenge_item_info_ptr->algorithm.object_key)
{
challenge_item_info_ptr->algorithm.object_key->Release();
}
delete challenge_item_info_ptr->algorithm.poszOctetString;
if (NULL!= challenge_item_info_ptr->challenge_data_list)
{
challenge_item_info_ptr->challenge_data_list->Release();
}
/*
* Delete the challenge item contained in the list.
*/
delete challenge_item_info_ptr;
}
/*
* Delete the request structure.
*/
delete m_pInternalRequest;
}
/*
* Delete any memory allocated for the challenge response information.
*/
if (m_pInternalResponse != NULL)
{
if (NULL != m_pInternalResponse->algorithm.object_key)
{
m_pInternalResponse->algorithm.object_key->Release();
}
delete m_pInternalResponse->algorithm.poszOctetString;
if (NULL != m_pInternalResponse->challenge_response_item.password)
{
m_pInternalResponse->challenge_response_item.password->Release();
}
if (NULL != m_pInternalResponse->challenge_response_item.response_data_list)
{
m_pInternalResponse->challenge_response_item.response_data_list->Release();
}
delete m_pInternalResponse;
}
}
/*
* LockPasswordData ()
*
* Public Function Description:
* This routine is called to "Lock" the password data. The first time this
* routine is called, the lock count will be zero and this will result
* in the password data being copied from the internal structures into an
* "API" structure of the proper form. Subsequent calls to this routine
* will result in the lock count being incremented.
*/
GCCError CPassword::LockPasswordData(void)
{
GCCError rc;
if (Lock() == 1)
{
rc = GCC_ALLOCATION_FAILURE;
/*
* Check to see whether or not the password contains "challenge"
* information. Fill in the appropriate internal structure.
*/
if (m_fSimplePassword)
{
if (m_pszNumeric == NULL)
{
ERROR_OUT(("CPassword::LockPasswordData: No valid numeric password data exists"));
goto MyExit;
}
DBG_SAVE_FILE_LINE
if (NULL == (m_pPassword = new GCCPassword))
{
ERROR_OUT(("CPassword::LockPasswordData: can't create GCCPassword"));
goto MyExit;
}
/*
* Fill in the numeric password string which must exist.
*/
m_pPassword->numeric_string = (GCCNumericString) m_pszNumeric;
/*
* Fill in the textual password string.
*/
m_pPassword->text_string = m_pwszText;
}
else
{
/*
* The password contains challenge information so create the
* structure to pass back the necessary information.
*/
DBG_SAVE_FILE_LINE
m_pChallengeResponse = new GCCChallengeRequestResponse;
if (m_pChallengeResponse == NULL)
{
ERROR_OUT(("CPassword::LockPasswordData: can't create GCCChallengeRequestResponse"));
goto MyExit;
}
::ZeroMemory(m_pChallengeResponse, sizeof(GCCChallengeRequestResponse));
/*
* Fill in the "API" password challenge structure after
* determining what type exists.
*/
if (m_fClearPassword)
{
/*
* This password contains no "challenge" information.
*/
m_pChallengeResponse->password_challenge_type = GCC_PASSWORD_IN_THE_CLEAR;
/*
* This "clear" part of the password is a "selector" which
* means the form is either numeric or text. The check to
* verify that at least one form exists was done on
* construction.
*/
m_pChallengeResponse->u.password_in_the_clear.numeric_string = m_pszNumeric;
m_pChallengeResponse->u.password_in_the_clear.text_string = m_pwszText;
}
else
{
/*
* This password contains real "challenge" information.
*/
m_pChallengeResponse->password_challenge_type = GCC_PASSWORD_CHALLENGE;
/*
* Check to see if a challenge request exists. If so,
* create a GCCChallengeRequest to hold the "API" data and
* fill in that structure.
*/
if (m_pInternalRequest != NULL)
{
DBG_SAVE_FILE_LINE
m_pChallengeResponse->u.challenge_request_response.
challenge_request = new GCCChallengeRequest;
if (m_pChallengeResponse->u.challenge_request_response.
challenge_request == NULL)
{
ERROR_OUT(("CPassword::LockPasswordData: can't create GCCChallengeRequest"));
goto MyExit;
}
if (GetGCCChallengeRequest(m_pChallengeResponse->u.
challenge_request_response.challenge_request) != GCC_NO_ERROR)
{
ERROR_OUT(("CPassword::LockPasswordData: can't gett GCCChallengeRequest"));
goto MyExit;
}
}
else
{
m_pChallengeResponse->u.challenge_request_response.challenge_request = NULL;
}
/*
* Check to see if a challenge response exists. If so,
* create a GCCChallengeResponse to hold the "API" data and
* fill in that structure.
*/
if (m_pInternalResponse != NULL)
{
DBG_SAVE_FILE_LINE
m_pChallengeResponse->u.challenge_request_response.
challenge_response = new GCCChallengeResponse;
if (m_pChallengeResponse->u.challenge_request_response.
challenge_response == NULL)
{
ERROR_OUT(("CPassword::LockPasswordData: can't create new GCCChallengeResponse"));
goto MyExit;
}
if (GetGCCChallengeResponse(m_pChallengeResponse->u.
challenge_request_response.challenge_response) != GCC_NO_ERROR)
{
ERROR_OUT(("CPassword::LockPasswordData: can't get GCCChallengeResponse"));
goto MyExit;
}
}
else
{
m_pChallengeResponse->u.challenge_request_response.
challenge_response = NULL;
}
}
}
}
rc = GCC_NO_ERROR;
MyExit:
if (GCC_NO_ERROR != rc)
{
if (! m_fSimplePassword)
{
if (NULL != m_pChallengeResponse)
{
delete m_pChallengeResponse->u.challenge_request_response.challenge_request;
delete m_pChallengeResponse->u.challenge_request_response.challenge_response;
delete m_pChallengeResponse;
m_pChallengeResponse = NULL;
}
}
}
return rc;
}
/*
* GetPasswordData ()
*
* Public Function Description:
* This routine is used to retrieve the password data in the form of
* the "API" structure "GCCPassword". No "challenge" information is
* returned.
*/
GCCError CPassword::GetPasswordData(PGCCPassword *gcc_password)
{
GCCError return_value = GCC_NO_ERROR;
/*
* If the pointer to the "API" password data is valid, set the output
* parameter to return a pointer to the "API" password data. Otherwise,
* report that the password data has yet to be locked into the "API" form.
*/
if (m_pPassword != NULL)
{
*gcc_password = m_pPassword;
}
else
{
*gcc_password = NULL;
return_value = GCC_ALLOCATION_FAILURE;
ERROR_OUT(("CPassword::GetPasswordData: Error Data Not Locked"));
}
return (return_value);
}
/*
* GetPasswordChallengeData ()
*
* Public Function Description:
* This routine is used to retrieve the password data in the form of
* the "API" structure "GCCChallengeRequestResponse".
*/
GCCError CPassword::GetPasswordChallengeData(PGCCChallengeRequestResponse *gcc_challenge_password)
{
GCCError return_value = GCC_NO_ERROR;
/*
* If the pointer to the "API" password challenge data is valid, set the
* output parameter to return a pointer to the "API" password challenge
* data. Otherwise, report that the password data has yet to be locked
* into the "API" form.
*/
if (m_pChallengeResponse != NULL)
{
*gcc_challenge_password = m_pChallengeResponse;
}
else
{
*gcc_challenge_password = NULL;
return_value = GCC_ALLOCATION_FAILURE;
ERROR_OUT(("CPassword::GetPasswordData: Error Data Not Locked"));
}
return (return_value);
}
/*
* UnLockPasswordData ()
*
* Public Function Description
* This routine decrements the lock count and frees the memory associated
* with "API" password data when the lock count reaches zero.
*/
void CPassword::UnLockPasswordData(void)
{
if (Unlock(FALSE) == 0)
{
/*
* Delete the memory associated with the "API" "simple" password
* data structure.
*/
delete m_pPassword;
m_pPassword = NULL;
/*
* Delete the memory associated with the "API" "challenge" password
* data structure.
*/
if (m_pChallengeResponse != NULL)
{
if (m_fClearPassword == FALSE)
{
FreeAPIPasswordData();
}
else
{
delete m_pChallengeResponse;
m_pChallengeResponse = NULL;
}
}
}
// we have to call Release() because we used Unlock(FALSE)
Release();
}
/*
* GetPasswordPDU ()
*
* Public Function Description:
* This routine is used to retrieve the password data in the "PDU" form
* of a "Password" structure.
*/
GCCError CPassword::GetPasswordPDU(PPassword pdu_password)
{
GCCError return_value = GCC_NO_ERROR;
pdu_password->bit_mask = 0;
/*
* Fill in the numeric portion of the password which must always exist.
*/
if (m_pszNumeric != NULL)
{
::lstrcpyA(pdu_password->numeric, m_pszNumeric);
}
else
return_value = GCC_ALLOCATION_FAILURE;
/*
* Fill in the optional textual portion of the password if it is present.
* Set the bitmask in the PDU structure to indicate that the text exists.
*/
if (m_pwszText != NULL)
{
pdu_password->bit_mask |= PASSWORD_TEXT_PRESENT;
pdu_password->password_text.value = m_pwszText;
pdu_password->password_text.length= ::lstrlenW(m_pwszText);
}
return (return_value);
}
/*
* GetPasswordSelectorPDU ()
*
* Public Function Description:
* This routine is used to retrieve the password data in the "PDU" form
* of a "PasswordSelector" structure. In a "PasswordSelector" either the
* numeric or the text version of the password exists, but not both.
*/
GCCError CPassword::GetPasswordSelectorPDU(PPasswordSelector password_selector_pdu)
{
GCCError return_value = GCC_NO_ERROR;
/*
* Fill in the version of the password which exists and set
* the "choice" to indicate what type of password this is.
*/
if (m_pszNumeric != NULL)
{
password_selector_pdu->choice = PASSWORD_SELECTOR_NUMERIC_CHOSEN;
::lstrcpyA(password_selector_pdu->u.password_selector_numeric, m_pszNumeric);
}
else if (m_pwszText != NULL)
{
password_selector_pdu->choice = PASSWORD_SELECTOR_TEXT_CHOSEN;
password_selector_pdu->u.password_selector_text.value = m_pwszText;
password_selector_pdu->u.password_selector_text.length = ::lstrlenW(m_pwszText);
}
else
{
ERROR_OUT(("CPassword::GetPasswordSelectorPDU: No valid data"));
return_value = GCC_INVALID_PASSWORD;
}
return (return_value);
}
/*
* GetPasswordChallengeResponsePDU ()
*
* Public Function Description:
* This routine fills in a password challenge request-response "PDU"
* structure with the password data.
*/
GCCError CPassword::GetPasswordChallengeResponsePDU(PPasswordChallengeRequestResponse challenge_pdu)
{
GCCError return_value = GCC_NO_ERROR;
/*
* Check to see if this is a "simple" password. If it is, then this routine
* has been called in error.
*/
if ((challenge_pdu == NULL) || m_fSimplePassword)
{
ERROR_OUT(("CPassword::GetPasswordChallengeResponsePDU: no challenge data"));
return (GCC_INVALID_PARAMETER);
}
/*
* 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_fValidChallengeResponsePDU == FALSE)
{
m_fValidChallengeResponsePDU = TRUE;
/*
* Fill in the password challenge PDU structure.
*/
if (m_fClearPassword)
{
/*
* If this is a clear password then fill in the text or
* numeric string as well as the choice. Only one form of the
* password exists for PasswordSelectors such as this.
*/
m_ChallengeResponsePDU.choice = CHALLENGE_CLEAR_PASSWORD_CHOSEN;
if (m_pszNumeric != NULL)
{
m_ChallengeResponsePDU.u.challenge_clear_password.choice =
PASSWORD_SELECTOR_NUMERIC_CHOSEN;
::lstrcpyA(m_ChallengeResponsePDU.u.challenge_clear_password.u.password_selector_numeric,
m_pszNumeric);
}
else if (m_pwszText != NULL)
{
m_ChallengeResponsePDU.u.challenge_clear_password.choice =
PASSWORD_SELECTOR_TEXT_CHOSEN;
m_ChallengeResponsePDU.u.challenge_clear_password.u.
password_selector_text.value = m_pwszText;
m_ChallengeResponsePDU.u.challenge_clear_password.u.
password_selector_text.length = ::lstrlenW(m_pwszText);
}
else
{
ERROR_OUT(("CPassword::GetPwordChallengeResPDU: No valid data"));
return_value = GCC_INVALID_PASSWORD;
}
}
else
{
/*
* The challenge password contains challenge information. Fill in
* the request and response structures if they exist.
*/
m_ChallengeResponsePDU.choice = CHALLENGE_REQUEST_RESPONSE_CHOSEN;
m_ChallengeResponsePDU.u.challenge_request_response.bit_mask = 0;
/*
* Check to see if a "request" exists.
*/
if (m_pInternalRequest != NULL)
{
m_ChallengeResponsePDU.u.challenge_request_response.bit_mask |=
CHALLENGE_REQUEST_PRESENT;
/*
* Call the routine which fills in the PDU form of the
* request structure.
*/
return_value = GetChallengeRequestPDU (&m_ChallengeResponsePDU.
u.challenge_request_response.challenge_request);
}
/*
* Check to see if a "response" exists.
*/
if ((m_pInternalResponse != NULL) && (return_value == GCC_NO_ERROR))
{
m_ChallengeResponsePDU.u.challenge_request_response.bit_mask |=
CHALLENGE_RESPONSE_PRESENT;
/*
* Call the routine which fills in the PDU form of the
* response structure.
*/
return_value = GetChallengeResponsePDU (&m_ChallengeResponsePDU.
u.challenge_request_response.challenge_response);
}
}
}
/*
* Copy the internal PDU structure into the structure pointed to by the
* output parameter.
*/
*challenge_pdu = m_ChallengeResponsePDU;
return (return_value);
}
/*
* FreePasswordChallengeResponsePDU ()
*
* Public Function Description:
* This routine is used to free any memory allocated to hold "PDU" data
* associated with the PasswordChallengeRequestResponse.
*/
void CPassword::FreePasswordChallengeResponsePDU(void)
{
/*
* Check to see if there has been any "PDU" memory allocated which now
* needs to be freed.
*/
if (m_fValidChallengeResponsePDU)
{
/*
* Set the flag indicating that PDU password data is no longer
* allocated.
*/
m_fValidChallengeResponsePDU = FALSE;
/*
* Check to see what type of password PDU is to be freed. If this is a
* clear password then no data was allocated which now must be freed.
*/
if (m_ChallengeResponsePDU.choice == CHALLENGE_REQUEST_RESPONSE_CHOSEN)
{
/*
* This is a challenge password so free any data which was allocated
* to hold the challenge information. Check the PDU structure
* bitmask which indicates what form of challenge exists.
*/
if (m_ChallengeResponsePDU.u.challenge_request_response.bit_mask &
CHALLENGE_REQUEST_PRESENT)
{
FreeChallengeRequestPDU ();
}
if (m_ChallengeResponsePDU.u.challenge_request_response.
bit_mask & CHALLENGE_RESPONSE_PRESENT)
{
FreeChallengeResponsePDU ();
}
}
}
}
/*
* GCCError ConvertAPIChallengeRequest(
* PGCCChallengeRequest challenge_request)
*
* Private member function of CPassword.
*
* Function Description:
* This routine is used to copy an "API" challenge request structure into
* the internal structure.
*
* Formal Parameters:
* challenge_request (i) The API structure to copy internally.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
* GCC_INVALID_PASSWORD - An invalid password passed in.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CPassword::ConvertAPIChallengeRequest(PGCCChallengeRequest challenge_request)
{
GCCError return_value = GCC_NO_ERROR;
GCCError error_value;
Int i;
PGCCChallengeItem challenge_item_ptr;
PChallengeItemInfo challenge_item_info_ptr;
/*
* Save the challenge tag and number of challenge items in the internal
* structure.
*/
m_pInternalRequest->challenge_tag = challenge_request->challenge_tag;
/*
* Save the list of challenge items in the internal Rogue Wave List.
*/
for (i = 0; i < challenge_request->number_of_challenge_items; i++)
{
DBG_SAVE_FILE_LINE
challenge_item_info_ptr = new ChallengeItemInfo;
if (challenge_item_info_ptr != NULL)
{
/*
* Initialize the pointers in the challenge item info structure
* to NULL.
*/
challenge_item_info_ptr->algorithm.object_key = NULL;
challenge_item_info_ptr->algorithm.poszOctetString = NULL;
challenge_item_info_ptr->challenge_data_list = NULL;
/*
* Insert the pointer to the new challenge item structure into the
* internal list.
*/
m_pInternalRequest->ChallengeItemList.Append(challenge_item_info_ptr);
/*
* Retrieve the pointer to the challenge item from the input list.
*/
challenge_item_ptr = challenge_request->challenge_item_list[i];
/*
* Copy the challenge response algorithm to the internal structure.
*/
return_value = CopyResponseAlgorithm (
&(challenge_item_ptr->response_algorithm),
&(challenge_item_info_ptr->algorithm));
if (return_value != GCC_NO_ERROR)
{
ERROR_OUT(("Password::ConvertAPIChallengeRequest: Error copying Response Algorithm."));
break;
}
/*
* Copy the challenge data.
*/
if ((challenge_item_ptr->number_of_challenge_data_members != 0) &&
(challenge_item_ptr->challenge_data_list != NULL))
{
DBG_SAVE_FILE_LINE
challenge_item_info_ptr->challenge_data_list = new CUserDataListContainer(
challenge_item_ptr->number_of_challenge_data_members,
challenge_item_ptr->challenge_data_list,
&error_value);
if ((challenge_item_info_ptr == NULL) ||
(error_value != GCC_NO_ERROR))
{
ERROR_OUT(("Password::ConvertAPIChallengeRequest: can't create CUserDataListContainer."));
return_value = GCC_ALLOCATION_FAILURE;
break;
}
}
else
{
challenge_item_info_ptr->challenge_data_list = NULL;
ERROR_OUT(("Password::ConvertAPIChallengeRequest: Error no valid user data."));
return_value = GCC_INVALID_PASSWORD;
break;
}
}
else
{
ERROR_OUT(("Password::ConvertAPIChallengeRequest: Error creating "
"new ChallengeItemInfo."));
return_value = GCC_ALLOCATION_FAILURE;
break;
}
}
return (return_value);
}
/*
* GCCError ConvertAPIChallengeResponse(
* PGCCChallengeResponse challenge_response)
*
* Private member function of CPassword.
*
* Function Description:
* This routine is used to copy an "API" challenge response structure into
* the internal structure.
*
* Formal Parameters:
* challenge_response (i) The API structure to copy internally.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
* GCC_INVALID_PASSWORD - An invalid password passed in.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CPassword::ConvertAPIChallengeResponse(PGCCChallengeResponse challenge_response)
{
GCCError return_value = GCC_NO_ERROR;
GCCError error_value;
/*
* Initialize the challenge response info structure pointers to NULL.
*/
m_pInternalResponse->challenge_response_item.password = NULL;
m_pInternalResponse->challenge_response_item.response_data_list = NULL;
/*
* Save the challenge tag in the internal structure.
*/
m_pInternalResponse->challenge_tag = challenge_response->challenge_tag;
/*
* Copy the challenge response algorithm to the internal structure.
*/
return_value = CopyResponseAlgorithm (
&(challenge_response->response_algorithm),
&(m_pInternalResponse->algorithm));
if (return_value != GCC_NO_ERROR)
{
ERROR_OUT(("Password::ConvertAPIChallengeResponse: Error copying Response Algorithm."));
}
/*
* Copy the challenge response item into the internal info structure.
* The challenge response item will consist of either a password string
* or else a response user data list.
*/
if (return_value == GCC_NO_ERROR)
{
if (challenge_response->response_algorithm.password_algorithm_type ==
GCC_IN_THE_CLEAR_ALGORITHM)
{
if (challenge_response->response_item.password_string != NULL)
{
DBG_SAVE_FILE_LINE
m_pInternalResponse->challenge_response_item.password = new
CPassword(challenge_response->response_item.password_string, &error_value);
if ((m_pInternalResponse->challenge_response_item.password ==
NULL)|| (error_value != GCC_NO_ERROR))
{
ERROR_OUT(("Password::ConvertAPIChallengeResp: Error creating new CPassword."));
return_value = GCC_ALLOCATION_FAILURE;
}
}
else
return_value = GCC_INVALID_PASSWORD;
}
else
{
if ((challenge_response->response_item.
number_of_response_data_members != 0) &&
(challenge_response->response_item.response_data_list != NULL))
{
/*
* Save the response data list in a CUserDataListContainer object.
*/
DBG_SAVE_FILE_LINE
m_pInternalResponse->challenge_response_item.response_data_list =
new CUserDataListContainer(challenge_response->response_item.number_of_response_data_members,
challenge_response->response_item.response_data_list,
&error_value);
if ((m_pInternalResponse->challenge_response_item.response_data_list == NULL) ||
(error_value != GCC_NO_ERROR))
{
ERROR_OUT(("Password::ConvertAPIChallengeResponse: can't create CUserDataListContainer."));
return_value = GCC_ALLOCATION_FAILURE;
}
}
else
return_value = GCC_INVALID_PASSWORD;
}
}
/*
* Check to make sure one type of response item was saved.
*/
if ((return_value == GCC_NO_ERROR) &&
(m_pInternalResponse->challenge_response_item.password == NULL) &&
(m_pInternalResponse->challenge_response_item.response_data_list ==
NULL))
{
ERROR_OUT(("Password::ConvertAPIChallengeResponse: Error no valid response item saved."));
return_value = GCC_ALLOCATION_FAILURE;
}
return (return_value);
}
/*
* GCCError CopyResponseAlgorithm(
* PGCCChallengeResponseAlgorithm source_algorithm,
* PResponseAlgorithmInfo destination_algorithm)
*
* Private member function of CPassword.
*
* Function Description:
* This routine is used to copy an "API" response algorithm into the
* internal storage structure.
*
* Formal Parameters:
* source_algorithm (i) The API algorithm structure to copy
* internally.
* destination_algorithm (o) Pointer to the internal algorithm structure
* which will hold the converted item.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
* GCC_INVALID_PASSWORD - An invalid password passed in.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CPassword::CopyResponseAlgorithm(
PGCCChallengeResponseAlgorithm source_algorithm,
PResponseAlgorithmInfo destination_algorithm)
{
GCCError return_value = GCC_NO_ERROR;
GCCError error_value;
/*
* Copy the challenge response algorithm.
*/
destination_algorithm->algorithm_type = source_algorithm->
password_algorithm_type;
if (destination_algorithm->algorithm_type == GCC_NON_STANDARD_ALGORITHM)
{
/*
* Create a new CObjectKeyContainer object to hold the algorithm's object key
* internally.
*/
DBG_SAVE_FILE_LINE
destination_algorithm->object_key = new CObjectKeyContainer(
&source_algorithm->non_standard_algorithm->object_key,
&error_value);
if (destination_algorithm->object_key == NULL)
{
ERROR_OUT(("CPassword::CopyResponseAlgorithm: Error creating new CObjectKeyContainer"));
return_value = GCC_ALLOCATION_FAILURE;
}
else if (error_value != GCC_NO_ERROR)
{
ERROR_OUT(("CPassword::CopyResponseAlgorithm: Error creating new CObjectKeyContainer"));
return_value = GCC_INVALID_PASSWORD;
}
if (return_value == GCC_NO_ERROR)
{
/*
* Create a new Rogue Wave string to hold the algorithm's octet
* string internally.
*/
if (NULL == (destination_algorithm->poszOctetString = ::My_strdupO2(
source_algorithm->non_standard_algorithm->parameter_data.value,
source_algorithm->non_standard_algorithm->parameter_data.length)))
{
ERROR_OUT(("CPassword::CopyResponseAlgorithm: can't create octet string in algorithm"));
return_value = GCC_ALLOCATION_FAILURE;
}
}
else
destination_algorithm->poszOctetString = NULL;
}
else
{
/*
* The algorithm is a standard type so initialize to NULL the pointers
* used to hold the data associated with a non-standard algorithm.
*/
destination_algorithm->object_key = NULL;
destination_algorithm->poszOctetString = NULL;
}
return (return_value);
}
/*
* GCCError ConvertPDUChallengeRequest (
* PChallengeRequest challenge_request);
*
* Private member function of CPassword.
*
* Function Description:
* This routine is used to copy a "PDU" challenge request structure into
* the internal storage structure.
*
* Formal Parameters:
* challenge_request (i) The API structure to copy internally.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
* GCC_INVALID_PASSWORD - An invalid password passed in.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CPassword::ConvertPDUChallengeRequest(PChallengeRequest challenge_request)
{
GCCError return_value = GCC_NO_ERROR;
PSetOfChallengeItems current_challenge_item_set;
PSetOfChallengeItems next_challenge_item_set;
/*
* Save the challenge tag in the internal structure.
*/
m_pInternalRequest->challenge_tag = challenge_request->challenge_tag;
if (challenge_request->set_of_challenge_items != NULL)
{
/*
* Loop through the PDU set of challenge items, converting each into
* the internal form.
*/
current_challenge_item_set = challenge_request->set_of_challenge_items;
while (1)
{
next_challenge_item_set = current_challenge_item_set->next;
/*
* The routine which converts the challenge items saves the internal
* form in a Rogue Wave list.
*/
if (ConvertPDUChallengeItem (&current_challenge_item_set->value) !=
GCC_NO_ERROR)
{
return_value = GCC_ALLOCATION_FAILURE;
break;
}
if (next_challenge_item_set != NULL)
current_challenge_item_set = next_challenge_item_set;
else
break;
}
}
return (return_value);
}
/*
* GCCError ConvertPDUChallengeItem (
* PChallengeItem challenge_item_ptr);
*
* Private member function of CPassword.
*
* Function Description:
* This routine is used to copy a "PDU" ChallengeItem structure into
* the internal ChallengeItemInfo storage structure.
*
* Formal Parameters:
* challenge_item_ptr (i) The PDU structure to copy internally.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
* GCC_INVALID_PASSWORD - An invalid password passed in.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CPassword::ConvertPDUChallengeItem(PChallengeItem challenge_item_ptr)
{
PChallengeItemInfo challenge_item_info_ptr;
GCCError return_value = GCC_NO_ERROR;
GCCError error_value = GCC_NO_ERROR;
/*
* Create a new challenge item and save it in the internal Rogue Wave List.
*/
DBG_SAVE_FILE_LINE
challenge_item_info_ptr = new ChallengeItemInfo;
if (challenge_item_info_ptr != NULL)
{
/*
* Insert the pointer to the new challenge item structure into the
* internal Rogue Wave list.
*/
challenge_item_info_ptr->challenge_data_list = NULL;
m_pInternalRequest->ChallengeItemList.Append(challenge_item_info_ptr);
/*
* Convert the challenge response algorithm to the internal structure.
*/
if (ConvertPDUResponseAlgorithm(
&(challenge_item_ptr->response_algorithm),
&(challenge_item_info_ptr->algorithm)) != GCC_NO_ERROR)
{
ERROR_OUT(("Password::ConvertAPIChallengeItem: Error converting Response Algorithm."));
return_value = GCC_ALLOCATION_FAILURE;
}
/*
* Convert the challenge data to internal form.
*/
if ((return_value == GCC_NO_ERROR) &&
(challenge_item_ptr->set_of_challenge_data != NULL))
{
DBG_SAVE_FILE_LINE
challenge_item_info_ptr->challenge_data_list = new CUserDataListContainer(
challenge_item_ptr->set_of_challenge_data,
&error_value);
if ((challenge_item_info_ptr->challenge_data_list == NULL) ||
(error_value != GCC_NO_ERROR))
{
ERROR_OUT(("Password::ConvertAPIChallengeItem: can't create CUserDataListContainer."));
return_value = GCC_ALLOCATION_FAILURE;
}
}
else
{
ERROR_OUT(("Password::ConvertAPIChallengeItem: Error no valid user data"));
return_value = GCC_INVALID_PASSWORD;
}
}
else
{
ERROR_OUT(("Password::ConvertAPIChallengeItem: Error creating "
"new ChallengeItemInfo."));
return_value = GCC_ALLOCATION_FAILURE;
}
return (return_value);
}
/*
* GCCError ConvertPDUChallengeResponse (
* PChallengeResponse challenge_response)
*
* Private member function of CPassword.
*
* Function Description:
* This routine is used to copy a "PDU" challenge response structure into
* the internal structure.
*
* Formal Parameters:
* challenge_response (i) The API structure to copy internally.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CPassword::ConvertPDUChallengeResponse(PChallengeResponse challenge_response)
{
GCCError return_value = GCC_NO_ERROR;
GCCError error_value = GCC_NO_ERROR;
/*
* Save the challenge tag in the internal structure.
*/
m_pInternalResponse->challenge_tag = challenge_response->challenge_tag;
/*
* Convert the challenge response algorithm to the internal structure.
*/
if (ConvertPDUResponseAlgorithm(
&(challenge_response->response_algorithm),
&(m_pInternalResponse->algorithm)) != GCC_NO_ERROR)
{
ERROR_OUT(("Password::ConvertPDUChallengeResponse: Error converting Response Algorithm."));
return_value = GCC_ALLOCATION_FAILURE;
}
/*
* Check to see what form the challenge response item has taken. Create
* the necessary object to hold the item internally.
*/
if ((challenge_response->response_item.choice == PASSWORD_STRING_CHOSEN) &&
(return_value == GCC_NO_ERROR))
{
DBG_SAVE_FILE_LINE
m_pInternalResponse->challenge_response_item.password = new CPassword(
&challenge_response->response_item.u.password_string,
&error_value);
if ((m_pInternalResponse->challenge_response_item.password == NULL) ||
(error_value != GCC_NO_ERROR))
{
ERROR_OUT(("Password::ConvertPDUChallengeResponse: Error creating new CPassword."));
return_value = GCC_ALLOCATION_FAILURE;
}
}
else
m_pInternalResponse->challenge_response_item.password = NULL;
if ((challenge_response->response_item.choice ==
SET_OF_RESPONSE_DATA_CHOSEN) && (return_value == GCC_NO_ERROR))
{
DBG_SAVE_FILE_LINE
m_pInternalResponse->challenge_response_item.response_data_list =
new CUserDataListContainer(challenge_response->response_item.u.set_of_response_data,
&error_value);
if ((m_pInternalResponse->challenge_response_item.
response_data_list == NULL) || (error_value != GCC_NO_ERROR))
{
ERROR_OUT(("Password::ConvertPDUChallengeResponse: can't create CUserDataListContainer."));
return_value = GCC_ALLOCATION_FAILURE;
}
}
else
{
m_pInternalResponse->challenge_response_item.response_data_list = NULL;
}
return (return_value);
}
/*
* GCCError ConvertPDUResponseAlgorithm (
* PChallengeResponseAlgorithm source_algorithm,
* PResponseAlgorithmInfo destination_algorithm);
*
* Private member function of CPassword.
*
* Function Description:
* This routine is used to convert a "PDU" response algorithm
* structure into the internal form.
*
* Formal Parameters:
* source_algorithm (i) The PDU algorithm structure to copy
* internally.
* destination_algorithm (o) Pointer to the internal structure which will
* hold the converted item.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
* GCC_INVALID_PARAMETER - A NULL pointer was passed in or
* the algorithm has invalid type.
* GCC_INVALID_PASSWORD - An invalid password was passed in.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CPassword::ConvertPDUResponseAlgorithm(
PChallengeResponseAlgorithm source_algorithm,
PResponseAlgorithmInfo destination_algorithm)
{
GCCError return_value = GCC_NO_ERROR;
GCCError error_value;;
if (source_algorithm != NULL)
{
/*
* Convert the challenge response algorithm type.
*/
if (source_algorithm->choice == ALGORITHM_CLEAR_PASSWORD_CHOSEN)
destination_algorithm->algorithm_type = GCC_IN_THE_CLEAR_ALGORITHM;
else if (source_algorithm->choice == NON_STANDARD_ALGORITHM_CHOSEN)
destination_algorithm->algorithm_type = GCC_NON_STANDARD_ALGORITHM;
else
{
ERROR_OUT(("CPassword::ConvertPDUResponseAlgorithm: Error: invalid password type"));
return_value = GCC_INVALID_PARAMETER;
}
}
else
{
ERROR_OUT(("CPassword::ConvertPDUResponseAlgorithm: Error: NULL source pointer."));
return_value = GCC_INVALID_PARAMETER;
}
if ((return_value == GCC_NO_ERROR) &&
(source_algorithm->choice == NON_STANDARD_ALGORITHM_CHOSEN))
{
/*
* Create a new CObjectKeyContainer object to hold the algorithm's object key
* internally.
*/
DBG_SAVE_FILE_LINE
destination_algorithm->object_key = new CObjectKeyContainer(
&source_algorithm->u.non_standard_algorithm.key,
&error_value);
if (destination_algorithm->object_key == NULL)
{
ERROR_OUT(("CPassword::ConvertPDUResponseAlgorithm: Error creating new CObjectKeyContainer"));
return_value = GCC_ALLOCATION_FAILURE;
}
else if (error_value != GCC_NO_ERROR)
{
ERROR_OUT(("CPassword::ConvertPDUResponseAlgorithm: Error creating new CObjectKeyContainer"));
return_value = GCC_INVALID_PASSWORD;
}
else
{
/*
* Create a new Rogue Wave string to hold the algorithm's octet
* string internally.
*/
if (NULL == (destination_algorithm->poszOctetString = ::My_strdupO2(
source_algorithm->u.non_standard_algorithm.data.value,
source_algorithm->u.non_standard_algorithm.data.length)))
{
ERROR_OUT(("CPassword::ConvertPDUResponseAlgorithm: can't create octet string in algorithm"));
return_value = GCC_ALLOCATION_FAILURE;
}
}
}
else
{
/*
* The algorithm is a standard type so initialize to NULL the pointers
* used to hold the data associated with a non-standard algorithm.
*/
destination_algorithm->poszOctetString = NULL;
destination_algorithm->object_key = NULL;
}
return (return_value);
}
/*
* GCCError GetGCCChallengeRequest (
* PGCCChallengeRequest challenge_request)
*
* Private member function of CPassword.
*
* Function Description:
* This routine is used to fill in the internal "API" challenge request
* structure from the internal storage structures. This is done on a
* "lock" in order to make data available which is suitable for being
* passed back up through the API.
*
* Formal Parameters:
* challenge_request (i) The API structure to fill in with the "API"
* challenge request data.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CPassword::GetGCCChallengeRequest(PGCCChallengeRequest challenge_request)
{
GCCError return_value = GCC_NO_ERROR;
UInt i = 0;
Int j = 0;
PGCCChallengeItem api_challenge_item_ptr;
PChallengeItemInfo internal_challenge_item_ptr;
PChallengeItemMemoryInfo internal_challenge_item_memory_ptr;
UINT object_key_length;
UINT user_data_length;
/*
* Save the challenge tag and retrieve the number of challenge items.
*/
challenge_request->challenge_tag = m_pInternalRequest->challenge_tag;
challenge_request->number_of_challenge_items =
(USHORT) m_pInternalRequest->ChallengeItemList.GetCount();
if (m_pInternalRequest->ChallengeItemList.GetCount() != 0)
{
/*
* Allocate the space needed for the list of pointers to GCC challenge
* items.
*/
DBG_SAVE_FILE_LINE
m_pChallengeItemListMemory = new BYTE[sizeof(PGCCChallengeItem) * m_pInternalRequest->ChallengeItemList.GetCount()];
if (m_pChallengeItemListMemory != NULL)
{
PChallengeItemInfo lpChItmInfo;
/*
* Retrieve the actual pointer to memory from the Memory object
* and save it in the internal API Challenge Item list.
*/
challenge_request->challenge_item_list = (GCCChallengeItem **)
m_pChallengeItemListMemory;
/*
* Initialize the pointers in the list to NULL.
*/
for (i=0; i < m_pInternalRequest->ChallengeItemList.GetCount(); i++)
challenge_request->challenge_item_list[i] = NULL;
/*
* Copy the data from the internal list of "ChallengeItemInfo"
* structures into the "API" form which is a list of pointers
* to GCCChallengeItem structures.
*/
m_pInternalRequest->ChallengeItemList.Reset();
while (NULL != (lpChItmInfo = m_pInternalRequest->ChallengeItemList.Iterate()))
{
/*
* Get a pointer to a new GCCChallengeItem structure.
*/
DBG_SAVE_FILE_LINE
api_challenge_item_ptr = new GCCChallengeItem;
if (api_challenge_item_ptr != NULL)
{
/*
* Go ahead and put the pointer in the list and
* post-increment the loop counter.
*/
challenge_request->challenge_item_list[j++] =
api_challenge_item_ptr;
/*
* Retrieve the ChallengeItemInfo structure from the Rogue
* Wave list.
*/
internal_challenge_item_ptr = lpChItmInfo;
/*
* Fill in the algorithm type for the challenge response
* algorithm.
*/
api_challenge_item_ptr->response_algorithm.
password_algorithm_type =
internal_challenge_item_ptr->
algorithm.algorithm_type;
/*
* The memory for the response algorithm's object key data
* and the challenge item's used data are stored in
* a ChallengeItemMemoryInfo structure so create one
* here. If the response algorithm is "clear" then the
* object key data element will not be used. The challenge
* item user data should always exist.
*/
DBG_SAVE_FILE_LINE
internal_challenge_item_memory_ptr = new ChallengeItemMemoryInfo;
if (internal_challenge_item_memory_ptr != NULL)
{
/*
* Initialize the pointers in the challenge item
* memory info structure to NULL.
*/
internal_challenge_item_memory_ptr->user_data_list_memory = NULL;
internal_challenge_item_memory_ptr->object_key_memory = NULL;
/*
* Insert the pointer to the new challenge item
* memory structure into the internal Rogue Wave
* list.
*/
m_ChallengeItemMemoryList.Append(internal_challenge_item_memory_ptr);
}
else
{
ERROR_OUT(("CPassword::GetGCCChallengeRequest: Error creating new ChallengeItemMemoryInfo"));
return_value = GCC_ALLOCATION_FAILURE;
break;
}
if (api_challenge_item_ptr->response_algorithm.password_algorithm_type ==
GCC_NON_STANDARD_ALGORITHM)
{
/*
* Create a new GCCNonStandardParameter to put in the
* ResponseAlgorithm structure.
*/
DBG_SAVE_FILE_LINE
api_challenge_item_ptr->response_algorithm.non_standard_algorithm =
new GCCNonStandardParameter;
if (api_challenge_item_ptr->response_algorithm.non_standard_algorithm == NULL)
{
ERROR_OUT(("CPassword::GetGCCChallengeRequest: Error creating new GCCNonStdParameter"));
return_value = GCC_ALLOCATION_FAILURE;
break;
}
/*
* Retrieve the API object key from the CObjectKeyContainer
* object in the ResponseAlgorithmInfo structure and
* fill in the GCCObjectKey in the non-standard
* algorithm. The CObjectKeyContainer object must be locked
* before getting the data.
*/
object_key_length = internal_challenge_item_ptr->
algorithm.object_key->LockObjectKeyData ();
DBG_SAVE_FILE_LINE
internal_challenge_item_memory_ptr->object_key_memory =
new BYTE[object_key_length];
if (internal_challenge_item_memory_ptr->object_key_memory != NULL)
{
internal_challenge_item_ptr->algorithm.object_key->GetGCCObjectKeyData(
&(api_challenge_item_ptr->response_algorithm.non_standard_algorithm->object_key),
internal_challenge_item_memory_ptr->object_key_memory);
}
else
{
ERROR_OUT(("CPassword::GetGCCChallengeReq: Error Allocating Memory"));
return_value = GCC_ALLOCATION_FAILURE;
break;
}
/*
* Fill in the parameter data for the non-standard
* algorithm. This includes the octet string pointer
* and length.
*/
api_challenge_item_ptr->response_algorithm.non_standard_algorithm->
parameter_data.value =
internal_challenge_item_ptr->algorithm.poszOctetString->value;
api_challenge_item_ptr->response_algorithm.non_standard_algorithm->
parameter_data.length =
internal_challenge_item_ptr->algorithm.poszOctetString->length;
}
else
{
/*
* The algorithm is not a non-standard type so set the
* non-standard pointer to NULL.
*/
api_challenge_item_ptr->response_algorithm.non_standard_algorithm = NULL;
}
/*
* Retrieve the API challenge data from the CUserDataListContainer
* object. The call to GetUserDataList also returns the
* number of user data members. The CUserDataListContainer object
* must be locked before getting the data in order to
* determine how much memory to allocate to hold the data.
*/
if (internal_challenge_item_ptr->challenge_data_list != NULL)
{
user_data_length = internal_challenge_item_ptr->
challenge_data_list->LockUserDataList ();
/*
* The memory for the user data is stored in the
* ChallengeItemMemoryInfo structure created above.
*/
DBG_SAVE_FILE_LINE
internal_challenge_item_memory_ptr->user_data_list_memory =
new BYTE[user_data_length];
if (internal_challenge_item_memory_ptr->user_data_list_memory != NULL)
{
/*
* Retrieve the actual pointer to memory from the
* Memory object and save it in the internal user
* data memory.
*/
internal_challenge_item_ptr->challenge_data_list->GetUserDataList(
&api_challenge_item_ptr->number_of_challenge_data_members,
&api_challenge_item_ptr->challenge_data_list,
internal_challenge_item_memory_ptr->user_data_list_memory);
}
else
{
ERROR_OUT(("CPassword::GetGCCChallengeRequest: Error Allocating Memory"));
return_value = GCC_ALLOCATION_FAILURE;
break;
}
}
else
{
ERROR_OUT(("CPassword::GetGCCChallengeRequest: Error no valid user data"));
return_value = GCC_ALLOCATION_FAILURE;
break;
}
}
else
{
ERROR_OUT(("CPassword::GetGCCChallengeRequest: Error creating new GCCChallengeItem"));
return_value = GCC_ALLOCATION_FAILURE;
break;
}
/*
* This is the end of the challenge item iterator loop.
*/
}
}
else
{
ERROR_OUT(("CPassword::GetGCCChallengeRequest: Error Allocating Memory"));
return_value = GCC_ALLOCATION_FAILURE;
}
}
else
{
/*
* There are no challenge items in the list so set the list pointer
* to NULL.
*/
challenge_request->challenge_item_list = NULL;
}
return (return_value);
}
/*
* GCCError GetGCCChallengeResponse (
* PGCCChallengeResponse challenge_response);
*
* Private member function of CPassword.
*
* Function Description:
* This routine is used to fill in the internal "API" challenge response
* structure from the internal storage structures. This is done on a
* "lock" in order to make data available which is suitable for being
* passed back up through the API.
*
* Formal Parameters:
* challenge_response (i) The API structure to fill in with the "API"
* challenge response data.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CPassword::GetGCCChallengeResponse(PGCCChallengeResponse challenge_response)
{
GCCError return_value = GCC_NO_ERROR;
UINT object_key_length;
UINT user_data_length;
challenge_response->challenge_tag = m_pInternalResponse->challenge_tag;
/*
* Fill in the algorithm type for the challenge response algorithm.
*/
challenge_response->response_algorithm.password_algorithm_type =
m_pInternalResponse->algorithm.algorithm_type;
/*
* If the response algorithm is of non-standard type, create a new
* GCCNonStandardParameter to put in the ResponseAlgorithm structure.
*/
if (challenge_response->response_algorithm.password_algorithm_type ==
GCC_NON_STANDARD_ALGORITHM)
{
DBG_SAVE_FILE_LINE
challenge_response->response_algorithm.non_standard_algorithm =
new GCCNonStandardParameter;
if (challenge_response->response_algorithm.non_standard_algorithm ==
NULL)
{
ERROR_OUT(("CPassword::GetGCCChallengeResponse: Error creating new GCCNonStandardParameter"));
return_value = GCC_ALLOCATION_FAILURE;
}
else
{
/*
* Retrieve the API object key from the CObjectKeyContainer object in the
* ResponseAlgorithmInfo structure and fill in the GCCObjectKey in
* the non-standard algorithm. The CObjectKeyContainer object must be
* locked before getting the data.
*/
object_key_length = m_pInternalResponse->algorithm.object_key->
LockObjectKeyData ();
DBG_SAVE_FILE_LINE
m_pObjectKeyMemory = new BYTE[object_key_length];
if (m_pObjectKeyMemory != NULL)
{
m_pInternalResponse->algorithm.object_key->
GetGCCObjectKeyData (&(challenge_response->
response_algorithm.non_standard_algorithm->
object_key),
m_pObjectKeyMemory);
}
else
{
ERROR_OUT(("CPassword::GetGCCChallengeResponse: Error Allocating Memory"));
return_value = GCC_ALLOCATION_FAILURE;
}
/*
* Fill in the parameter data for the non-standard algorithm.
*/
if (return_value == GCC_NO_ERROR)
{
/*
* Fill in the octet string pointer and length.
*/
challenge_response->response_algorithm.non_standard_algorithm->
parameter_data.value =
m_pInternalResponse->algorithm.poszOctetString->value;
challenge_response->response_algorithm.non_standard_algorithm->
parameter_data.length =
m_pInternalResponse->algorithm.poszOctetString->length;
}
else
{
ERROR_OUT(("CPassword::GetGCCChallengeRequest: Error getting GCCObjectKeyData"));
return_value = GCC_ALLOCATION_FAILURE;
}
}
}
else
{
/*
* The algorithm in not non-standard so set the non-standard algorithm
* pointer to NULL.
*/
challenge_response->response_algorithm.non_standard_algorithm = NULL;
}
/*
* Now fill in the challenge response item in the challenge response
* structure.
*/
if (return_value == GCC_NO_ERROR)
{
/*
* Check to see whether the challenge response item consists of a
* password string or a set of user data. Fill in the appropriate
* part.
*/
if (m_pInternalResponse->challenge_response_item.password != NULL)
{
/*
* Set the number of user data members to zero to avoid any
* confusion at the application. This should match up with the
* algorithm being set to "in the clear".
*/
challenge_response->response_item.
number_of_response_data_members = 0;
challenge_response->response_item.
response_data_list = NULL;
/*
* Retrieve the API GCCPassword from the CPassword object. The
* CPassword object must be locked before getting the data.
*/
if (m_pInternalResponse->challenge_response_item.
password->LockPasswordData () == GCC_NO_ERROR)
{
return_value = m_pInternalResponse->challenge_response_item.
password->GetPasswordData (&(challenge_response->
response_item.password_string));
}
else
{
ERROR_OUT(("CPassword::GetGCCChallengeRequest: Error locking CPassword"));
return_value = GCC_ALLOCATION_FAILURE;
}
}
else if (m_pInternalResponse->challenge_response_item.response_data_list != NULL)
{
/*
* Set the password string to NULL to avoid any confusion at the
* application. This should match up with the algorithm set to
* non-standard.
*/
challenge_response->response_item.password_string = NULL;
/*
* Retrieve the API challenge data from the CUserDataListContainer
* object. The call to GetUserDataList also returns the
* number of user data members. The CUserDataListContainer object
* must be locked before getting the data in order to
* determine how much memory to allocate to hold the data.
*/
user_data_length = m_pInternalResponse->challenge_response_item.
response_data_list->LockUserDataList ();
DBG_SAVE_FILE_LINE
m_pUserDataMemory = new BYTE[user_data_length];
if (m_pUserDataMemory != NULL)
{
/*
* Retrieve the actual pointer to memory from the Memory
* object and save it in the internal user data memory.
*/
m_pInternalResponse->challenge_response_item.response_data_list->
GetUserDataList (
&challenge_response->response_item.
number_of_response_data_members,
&challenge_response->response_item.
response_data_list,
m_pUserDataMemory);
}
else
{
ERROR_OUT(("CPassword::GetGCCChallengeRequest: Error allocating memory"));
return_value = GCC_ALLOCATION_FAILURE;
}
}
else
{
ERROR_OUT(("CPassword::GetGCCChallengeRequest: Error saving response item"));
return_value = GCC_ALLOCATION_FAILURE;
}
}
return (return_value);
}
/*
* GCCError GetChallengeRequestPDU (
* PChallengeRequest challenge_request);
*
* Private member function of CPassword.
*
* Function Description:
* This routine converts internal challenge request data to "PDU" form.
*
* Formal Parameters:
* challenge_request (i) The PDU structure to fill in with the
* challenge request data.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
* GCC_INVALID_PARAMETER - The algorithm type was not set
* properly.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CPassword::GetChallengeRequestPDU(PChallengeRequest challenge_request)
{
GCCError return_value = GCC_NO_ERROR;
PSetOfChallengeItems new_set_of_challenge_items;
PSetOfChallengeItems old_set_of_challenge_items;
DWORD number_of_items;
PChallengeItemInfo internal_challenge_item_ptr;
/*
* Fill in the challenge tag.
*/
challenge_request->challenge_tag = m_pInternalRequest->challenge_tag;
/*
* Initialize the set pointers to NULL in order to detect the first time
* through the iterator loop.
*/
challenge_request->set_of_challenge_items = NULL;
old_set_of_challenge_items = NULL;
/*
* Retrieve the number of challenge items in the internal list.
*/
number_of_items = m_pInternalRequest->ChallengeItemList.GetCount();
if (number_of_items > 0)
{
PChallengeItemInfo lpChItmInfo;
/*
* Iterate through the internal list of challenge items, creating a
* new "PDU" SetOfChallengeItems for each and filling it in.
*/
m_pInternalRequest->ChallengeItemList.Reset();
while (NULL != (lpChItmInfo = m_pInternalRequest->ChallengeItemList.Iterate()))
{
DBG_SAVE_FILE_LINE
new_set_of_challenge_items = new SetOfChallengeItems;
/*
* If an allocation failure occurs, call the routine which will
* iterate through the list freeing any data which had been
* allocated.
*/
if (new_set_of_challenge_items == NULL)
{
ERROR_OUT(("CPassword::GetChallengeRequestPDU: Allocation error, cleaning up"));
return_value = GCC_ALLOCATION_FAILURE;
FreeChallengeRequestPDU ();
break;
}
/*
* The first time through, set the PDU structure pointer equal
* to the first SetOfChallengeItems created. On subsequent loops,
* set the structure's "next" pointer equal to the new structure.
*/
if (challenge_request->set_of_challenge_items == NULL)
{
challenge_request->set_of_challenge_items =
new_set_of_challenge_items;
}
else
old_set_of_challenge_items->next = new_set_of_challenge_items;
/*
* Save the newly created set and initialize the new "next"
* pointer to NULL in case this is the last time through the loop.
*/
old_set_of_challenge_items = new_set_of_challenge_items;
new_set_of_challenge_items->next = NULL;
/*
* Retrieve the ChallengeItemInfo structure from the Rogue
* Wave list and fill in the "PDU" challenge item structure from
* the internal challenge item structure.
*/
internal_challenge_item_ptr = lpChItmInfo;
return_value = ConvertInternalChallengeItemToPDU (
internal_challenge_item_ptr,
&new_set_of_challenge_items->value);
/*
* Cleanup if an error has occurred.
*/
if (return_value != GCC_NO_ERROR)
{
FreeChallengeRequestPDU ();
}
}
}
else
{
ERROR_OUT(("CPassword::GetChallengeRequestPDU: Error no items"));
}
return (return_value);
}
/*
* GCCError ConvertInternalChallengeItemToPDU(
* PChallengeItemInfo internal_challenge_item,
* PChallengeItem pdu_challenge_item)
*
* Private member function of CPassword.
*
* Function Description:
* This routine converts an internal ChallengeItemInfo structure into
* the "PDU" form of a ChallengeItem structure.
*
* Formal Parameters:
* internal_challenge_item (i) The internal challenge item to convert.
* pdu_challenge_item (o) The output PDU form of the challenge
* item.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
* GCC_INVALID_PARAMETER - The algorithm type was not set
* properly.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CPassword::ConvertInternalChallengeItemToPDU(
PChallengeItemInfo internal_challenge_item,
PChallengeItem pdu_challenge_item)
{
GCCError return_value = GCC_NO_ERROR;
/*
* First convert the algorithm.
*/
if (internal_challenge_item->algorithm.algorithm_type ==
GCC_IN_THE_CLEAR_ALGORITHM)
{
pdu_challenge_item->response_algorithm.choice =
ALGORITHM_CLEAR_PASSWORD_CHOSEN;
}
else if (internal_challenge_item->algorithm.algorithm_type ==
GCC_NON_STANDARD_ALGORITHM)
{
pdu_challenge_item->response_algorithm.choice =
NON_STANDARD_ALGORITHM_CHOSEN;
/*
* Retrieve the "PDU" object key data from the internal CObjectKeyContainer
* object.
*/
if (internal_challenge_item->algorithm.object_key->
GetObjectKeyDataPDU (
&pdu_challenge_item->response_algorithm.u.
non_standard_algorithm.key) == GCC_NO_ERROR)
{
/*
* Retrieve the non-standard parameter data from the internal
* algorithm octet string.
*/
pdu_challenge_item->response_algorithm.u.non_standard_algorithm.data.value =
internal_challenge_item->algorithm.poszOctetString->value;
pdu_challenge_item->response_algorithm.u.non_standard_algorithm.data.length =
internal_challenge_item->algorithm.poszOctetString->length;
}
else
{
ERROR_OUT(("CPassword::ConvertInternalChallengeItemToPDU: Error getting ObjKeyData"));
return_value = GCC_ALLOCATION_FAILURE;
}
}
else
{
ERROR_OUT(("CPassword::ConvertInternalChallengeItemToPDU: Error bad algorithm type"));
return_value = GCC_INVALID_PARAMETER;
}
/*
* Now retrieve the set of user data.
*/
if (return_value == GCC_NO_ERROR)
{
return_value = internal_challenge_item->challenge_data_list->
GetUserDataPDU (&pdu_challenge_item->set_of_challenge_data);
}
return (return_value);
}
/*
* GCCError GetChallengeResponsePDU (
* PChallengeResponse challenge_response);
*
* Private member function of CPassword.
*
* Function Description:
* This routine converts internal challenge response data to "PDU" form.
*
* Formal Parameters:
* challenge_response (i) The PDU structure to fill in with the
* challenge response data.
*
* Return Value:
* GCC_NO_ERROR - No error.
* GCC_ALLOCATION_FAILURE - Error creating an object using the
* "new" operator.
* GCC_INVALID_PASSWORD - The form of the password is not
* valid.
* GCC_INVALID_PARAMETER - The algorithm type was not set
* properly.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
GCCError CPassword::GetChallengeResponsePDU(PChallengeResponse challenge_response)
{
GCCError return_value = GCC_NO_ERROR;
/*
* Fill in the challenge tag.
*/
challenge_response->challenge_tag = m_pInternalResponse->challenge_tag;
/*
* Fill in the response algorithm.
*/
if (m_pInternalResponse->algorithm.algorithm_type ==
GCC_IN_THE_CLEAR_ALGORITHM)
{
challenge_response->response_algorithm.choice =
ALGORITHM_CLEAR_PASSWORD_CHOSEN;
/*
* Now convert the challenge response item. The challenge response item
* will consist of either a password string or a set of user data.
*/
if (m_pInternalResponse->challenge_response_item.password != NULL)
{
/*
* If the password string exists, set the "PDU" choice and retrieve
* the password selector data from the internal CPassword object.
*/
challenge_response->response_item.choice = PASSWORD_STRING_CHOSEN;
return_value= m_pInternalResponse->challenge_response_item.password->
GetPasswordSelectorPDU (&challenge_response->response_item.
u.password_string);
}
else
return_value = GCC_INVALID_PASSWORD;
}
else if (m_pInternalResponse->algorithm.algorithm_type ==
GCC_NON_STANDARD_ALGORITHM)
{
challenge_response->response_algorithm.choice =
NON_STANDARD_ALGORITHM_CHOSEN;
/*
* Retrieve the "PDU" object key data from the internal CObjectKeyContainer
* object.
*/
if (m_pInternalResponse->algorithm.object_key->
GetObjectKeyDataPDU (
&challenge_response->response_algorithm.u.
non_standard_algorithm.key) == GCC_NO_ERROR)
{
/*
* Retrieve the non-standard parameter data from the internal
* algorithm octet string.
*/
challenge_response->response_algorithm.u.non_standard_algorithm.data.value =
m_pInternalResponse->algorithm.poszOctetString->value;
challenge_response->response_algorithm.u.non_standard_algorithm.data.length =
m_pInternalResponse->algorithm.poszOctetString->length;
if (m_pInternalResponse->challenge_response_item.response_data_list != NULL)
{
/*
* If the response data list exists, set the "PDU" choice and
* retrieve the response data from the internal
* CUserDataListContainer object.
*/
challenge_response->response_item.choice =
SET_OF_RESPONSE_DATA_CHOSEN;
return_value = m_pInternalResponse->challenge_response_item.
response_data_list->GetUserDataPDU (
&challenge_response->response_item.u.
set_of_response_data);
}
else
return_value = GCC_INVALID_PASSWORD;
}
else
{
return_value = GCC_ALLOCATION_FAILURE;
ERROR_OUT(("CPassword::GetChallengeResponsePDU: Error getting ObjKeyData"));
}
}
else
{
ERROR_OUT(("CPassword::GetChallengeResponsePDU: Error bad algorithm type"));
return_value = GCC_INVALID_PARAMETER;
}
return (return_value);
}
/*
* void FreeChallengeRequestPDU ();
*
* Private member function of CPassword.
*
* Function Description:
* This routine is used to free any "PDU" data allocated for the
* challenge request structure.
*
* Formal Parameters:
* None.
*
* Return Value:
* None.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
void CPassword::FreeChallengeRequestPDU(void)
{
PSetOfChallengeItems set_of_challenge_items;
PSetOfChallengeItems next_set_of_challenge_items;
PChallengeItemInfo challenge_item_ptr;
PChallengeRequest challenge_request;
/*
* Retrieve the challenge request pointer from the internally maintained
* PasswordChallengeRequestResponse structure and delete each set of
* challenge items which was created.
*/
challenge_request = &m_ChallengeResponsePDU.u.challenge_request_response.
challenge_request;
if (challenge_request != NULL)
{
if (challenge_request->set_of_challenge_items == NULL)
{
ERROR_OUT(("CPassword::FreeChallengeRequestPDU: NULL ptr passed"));
}
else
{
set_of_challenge_items = challenge_request->set_of_challenge_items;
while (1)
{
if (set_of_challenge_items == NULL)
break;
next_set_of_challenge_items = set_of_challenge_items->next;
delete set_of_challenge_items;
set_of_challenge_items = next_set_of_challenge_items;
}
}
}
else
{
WARNING_OUT(("CPassword::FreeChallengeRequestPDU: NULL pointer passed"));
}
/*
* Loop through the internal list of challenge items, freeing the data
* associated with each challenge item structure contained in the list.
*/
m_pInternalRequest->ChallengeItemList.Reset();
while (NULL != (challenge_item_ptr = m_pInternalRequest->ChallengeItemList.Iterate()))
{
/*
* Retrieve the ChallengeItemInfo structure from the Rogue
* Wave list and use the CUserDataListContainer object contained in the
* structure to free the PDU user data. Also use the CObjectKeyContainer
* object contained in the algorithm structure to free the PDU
* data associated with the object key.
*/
if (challenge_item_ptr != NULL)
{
if (challenge_item_ptr->algorithm.object_key != NULL)
{
challenge_item_ptr->algorithm.object_key->FreeObjectKeyDataPDU();
}
if (challenge_item_ptr->challenge_data_list != NULL)
{
challenge_item_ptr->challenge_data_list->FreeUserDataListPDU();
}
}
}
}
/*
* void FreeChallengeResponsePDU ();
*
* Private member function of CPassword.
*
* Function Description:
* This routine is used to free any "PDU" data allocated for the
* challenge response structure.
*
* Formal Parameters:
* None.
*
* Return Value:
* None.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
void CPassword::FreeChallengeResponsePDU(void)
{
PChallengeResponse challenge_response;
/*
* Retrieve the challenge response pointer from the internally maintained
* PasswordChallengeRequestResponse structure. If it is not equal to NULL
* then we know PDU response data has been allocated which must be freed.
*/
challenge_response = &m_ChallengeResponsePDU.u.challenge_request_response.
challenge_response;
if ((challenge_response != NULL) && (m_pInternalResponse != NULL))
{
if (m_pInternalResponse->algorithm.object_key != NULL)
m_pInternalResponse->algorithm.object_key->FreeObjectKeyDataPDU ();
if (m_pInternalResponse->challenge_response_item.password != NULL)
{
m_pInternalResponse->challenge_response_item.
password->FreePasswordChallengeResponsePDU ();
}
if (m_pInternalResponse->challenge_response_item.
response_data_list != NULL)
{
m_pInternalResponse->challenge_response_item.
response_data_list->FreeUserDataListPDU ();
}
}
}
/*
* void FreeAPIPasswordData ();
*
* Private member function of CPassword.
*
* Function Description:
* This routine is used to free any data allocated by this container to
* hold "API" data.
*
* Formal Parameters:
* None.
*
* Return Value:
* None.
*
* Side Effects:
* None.
*
* Caveats:
* None.
*/
void CPassword::FreeAPIPasswordData(void)
{
PGCCChallengeItem challenge_item_ptr;
PChallengeItemInfo challenge_item_info_ptr;
PChallengeItemMemoryInfo challenge_item_memory_info;
USHORT i;
/*
* Delete any "API" memory associated with the challenge request if
* it exists.
*/
if (m_pChallengeResponse->u.challenge_request_response.
challenge_request != NULL)
{
for (i=0; i<m_pChallengeResponse->u.
challenge_request_response.challenge_request->
number_of_challenge_items; i++)
{
challenge_item_ptr = m_pChallengeResponse->u.
challenge_request_response.challenge_request->
challenge_item_list[i];
if (challenge_item_ptr != NULL)
{
/*
* Delete the non-standard algorithm memory.
*/
delete challenge_item_ptr->response_algorithm.non_standard_algorithm;
delete challenge_item_ptr;
}
}
delete m_pChallengeResponse->u.challenge_request_response.
challenge_request;
}
/*
* Unlock any memory locked for the challenge request information.
*/
if (m_pInternalRequest != NULL)
{
/*
* Set up an iterator in order to loop through the list of challenge
* items, freeing up any allocated memory.
*/
m_pInternalRequest->ChallengeItemList.Reset();
while (NULL != (challenge_item_info_ptr = m_pInternalRequest->ChallengeItemList.Iterate()))
{
/*
* Unlock any memory being referenced in the ChallengeItemInfo
* structure.
*/
if (challenge_item_info_ptr->algorithm.object_key != NULL)
{
challenge_item_info_ptr->algorithm.object_key->
UnLockObjectKeyData ();
}
if (challenge_item_info_ptr->challenge_data_list != NULL)
{
challenge_item_info_ptr->challenge_data_list->
UnLockUserDataList ();
}
}
}
/*
* Call the Memory Manager to free the memory allocated to hold the
* challenge request data.
*/
while (NULL != (challenge_item_memory_info = m_ChallengeItemMemoryList.Get()))
{
delete challenge_item_memory_info->user_data_list_memory;
delete challenge_item_memory_info->object_key_memory;
delete challenge_item_memory_info;
}
/*
* Delete any memory associated with the challenge response if
* it exists.
*/
if (m_pChallengeResponse->u.challenge_request_response.
challenge_response != NULL)
{
/*
* Delete any memory associated with the non-standard algorithm and
* then delete the challenge response structure.
*/
delete m_pChallengeResponse->u.challenge_request_response.
challenge_response->response_algorithm.non_standard_algorithm;
delete m_pChallengeResponse->u.challenge_request_response.
challenge_response;
}
/*
* Unlock any memory allocated for the challenge response information.
*/
if (m_pInternalResponse != NULL)
{
if (m_pInternalResponse->algorithm.object_key != NULL)
{
m_pInternalResponse->algorithm.object_key->UnLockObjectKeyData();
}
if (m_pInternalResponse->challenge_response_item.password != NULL)
{
m_pInternalResponse->challenge_response_item.password->
UnLockPasswordData ();
}
if (m_pInternalResponse->challenge_response_item.
response_data_list != NULL)
{
m_pInternalResponse->challenge_response_item.response_data_list->
UnLockUserDataList ();
}
}
/*
* Call the Memory Manager to free the memory allocated to hold the
* challenge response data.
*/
delete m_pUserDataMemory;
m_pUserDataMemory = NULL;
delete m_pObjectKeyMemory;
m_pObjectKeyMemory = NULL;
/*
* Call the Memory Manager to free the memory allocated to hold the
* challenge request challenge item pointers.
*/
delete m_pChallengeItemListMemory;
m_pChallengeItemListMemory = NULL;
/*
* Delete the challenge password structure and set the pointer to NULL.
*/
delete m_pChallengeResponse;
m_pChallengeResponse = NULL;
}