#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; iu. 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; }