3048 lines
87 KiB
C++
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 (¤t_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;
|
|
}
|