The example WinCEAuthenticator shows how the methods listed in the previous section can be implemented. It is functionally very similar to the example NTAuthenticator in the Java code base.
MQERETURN winCEAuthenticator_new( MQeAttrPlugin_SubclassInitInput * pInput, MQeAuthenticator_SubclassInitOutput * pOutput ) { MQeStringHndl hClassName; MQeExceptBlock * pExceptBlock = (MQeExceptBlock*) pOutput->pExceptBlock; (void)mqeString_newChar8(pExceptBlock, &hClassName, "WinCEAuthenticator"); if (MQERETURN_OK == pExceptBlock->ec) { pOutput->pSubclassPrivateData = malloc(sizeof(MQEINT32)); if (NULL != pOutput->pSubclassPrivateData) { *((MQEINT32 *)pOutput->pSubclassPrivateData) = AUTHENTICATOR; pOutput->hClassName = hClassName; pOutput->regRequired = MQE_FALSE; /* key type unknown */ pOutput->keyType = MQE_KEY_NULL; /* pointers to subclass implementations of support methods */ pOutput->fFree = winCEAuthenticator_free; pOutput->fActivateMasterPrep = winCEAuthenticator_activateMasterPrep; pOutput->fActivateSlavePrep = winCEAuthenticator_activateSlavePrep; pOutput->fProcessSlaveResponse = winCEAuthenticator_processSlaveResponse; pOutput->fClose = NULL; } else { pExceptBlock->ec = MQERETURN_ALLOCATION_FAIL; pExceptBlock->erc = MQEREASON_NA; } } return pExceptBlock->ec; }Calling winCEAuthenticator_free() implements the free() function. It retrieves the private memory block allocated by winCEAuthenticator_new(), making sure the authenticator has got the right private signature, and then frees the memory block.
MQERETURN winCEAuthenticator_free(MQeAuthenticatorHndl hThis, MQeAttrPlugin_FreeInput * pInput, MQeAttrPlugin_FreeOutput * pOutput ) { MQeExceptBlock * pExceptBlock = (MQeExceptBlock*) pOutput->pExceptBlock; MQEINT32 * pType; pExceptBlock->ec = MQERETURN_INVALID_ARGUMENT; pExceptBlock->erc = MQEREASON_INVALID_SIGNATURE; if ((NULL != hThis) && (MQERETURN_OK == mqeAuthenticator_getPrivateData(hThis, pExceptBlock, (MQEVOID**) &pType)) ) { /* make sure it is an authenticator created here */ if (AUTHENTICATOR == *pType) { pExceptBlock->ec = MQERETURN_OK; pExceptBlock->erc = MQEREASON_NA; free(pType); } } return pExceptBlock->ec; }
MQERETURN winCEAuthenticator_activateMasterPrep( MQeAuthenticatorHndl hAuthenticator, MQeAttrPlugin_ActivateMasterPrepInput * pInput, MQeAttrPlugin_ActivateMasterPrepOutput * pOutput) { static MQeFieldsHndl hActivateMasterFields = NULL; MQEINT32 * pOutputDataLen = pOutput->pOutputDataLen; MQEBYTE * pOutputData = pOutput->pOutputData; MQeExceptBlock * pExceptBlock = (MQeExceptBlock*) pOutput->pExceptBlock; /* initialize exception block */ pExceptBlock->ec = MQERETURN_OK; pExceptBlock->erc = MQEREASON_NA; if (NULL == hActivateMasterFields) { /* get data for authentication */ (void)mqeFields_new(pExceptBlock, &hActivateMasterFields); if (MQERETURN_OK == pExceptBlock->ec) { /** * Write your code here which puts the input data, * for example., userid, password into hActivateMasterFields. * The format is not important as long as it can be * understood by your corresponding code in * winCEAuthenticator_activateSlavePrep, which digests * these data. */ prompt(hActivateMasterFields, pExceptBlock);} } if (MQERETURN_OK == pExceptBlock->ec) { /* dump the fields */ (void)mqeFields_dump(hActivateMasterFields, pExceptBlock, pOutputData, pOutputDataLen); } if ((NULL != hActivateMasterFields) && ((NULL != pOutputData) || (MQERETURN_OK != pExceptBlock->ec))) { /** * Caller has supplied a buffer or operation failed. * No need to keep the Fields any more. */ (void)mqeFields_free(hActivateMasterFields, NULL); hActivateMasterFields = NULL; } return pExceptBlock->ec; }
The winCEAuthenticator_activateSlavePrep() implements the activateSlave() function. The winCEAuthenticator_activateSlavePrep() method receives the data returned by winCEAuthenticator_activateMasterPrep(), restores it into an MQeFields structure and passes it into a validate() function. The validate() function unmasks the data and passes it to the system LogonUser() function. This function checks if the user name and password are valid.
MQERETURN winCEAuthenticator_activateSlavePrep( MQeAuthenticatorHndl hAuthenticator, MQeAttrPlugin_ActivateSlavePrepInput * pInput, MQeAttrPlugin_ActivateSlavePrepOutput * pOutput) { static MQeFieldsHndl hActivateSlaveFields = NULL; MQeFieldsHndl hTempFields = NULL; MQEINT32 inputDataLen = pInput->inputDataLen; MQEBYTE * pInputData = pInput->pInputData; MQEINT32 * pOutputDataLen = pOutput->pOutputDataLen; MQEBYTE * pOutputData = pOutput->pOutputData; MQeExceptBlock * pExceptBlock = (MQeExceptBlock*) pOutput->pExceptBlock; /* initialize exception block */ pExceptBlock->ec = MQERETURN_OK; pExceptBlock->erc = MQEREASON_NA; if (NULL == hActivateSlaveFields) { /* restore input */ (void)mqeFields_new(pExceptBlock, &hTempFields); if (MQERETURN_OK == pExceptBlock->ec) { /* restore it into an MQeFields */ (void)mqeFields_restore(hTempFields, pExceptBlock, pInputData, inputDataLen); if (MQERETURN_OK == pExceptBlock->ec) { MQeStringHndl hAuthenticID = NULL; /** * put your code, which digests(authenticates) * the input data your gathered in the * winCEAuthenticator_activateMasterPrep(). * If successful, create an AuthenicateID string * in hAuthenticID. */ (void)validate(hTempFields, pExceptBlock, &hAuthenticID); if (MQERETURN_OK == pExceptBlock->ec) { /** * If successfully authenticated, * set local id variable (recored a success) */ (void)mqeAuthenticator_setAuthenticatedID(hAuthenticator, pExceptBlock, hAuthenticID); /* preparation for sending the id to the master */ if (MQERETURN_OK == pExceptBlock->ec) { /** * Send the hAuthenticID to the Master, * indicating a a success. */ (void)mqeFields_new(pExceptBlock, &hActivateSlaceFields); if (MQERETURN_OK == pExceptBlock->ec) { MQeStringHndl hAuthenticIDField; (void)mqeString_newChar8(pExceptBlock, &hAuthenticIDField, AUTHENTIC_ID); if (MQERETURN_OK == pExceptBlock->ec) { (void)mqeFields_putAscii(hActivateSlaveFields, pExceptBlock, hAuthenticIDField, hAuthenticID); (void)mqeString_free(hAuthenticIDField, NULL); } } } } } (void)mqeFields_free(hTempFields, NULL); } } if (MQERETURN_OK == pExceptBlock->ec) { /* dump the fields */ (void)mqeFields_dump(hActivateSlaveFields, pExceptBlock, pOutputData, pOutputDataLen); } if ((NULL != hActivateSlaveFields) && ((NULL != pOutputData) || (MQERETURN_OK != pExceptBlock->ec))) { /** * Caller has supplied a buffer or operation failed. * No need to keep the Fields any more. */ (void)mqeFields_free(hActivateSlaveFields, NULL); hActivateSlaveFields = NULL; } return pExceptBlock->ec; }
MQERETURN winCEAuthenticator_processSlaveResponse( MQeAuthenticatorHndl hAuthenticator, MQeAttrPlugin_ProcessSlaveResponseInput * pInput, MQeAttrPlugin_ProcessSlaveResponseOutput * pOutput ) { MQEINT32 inputDataLen = pInput->inputDataLen; MQEBYTE * pInputData = pInput->pInputData; MQeFieldsHndl hFields; MQeExceptBlock * pExceptBlock = (MQeExceptBlock *)pOutput->pExceptBlock; /* initialize exception block */ pExceptBlock->ec = MQERETURN_OK; pExceptBlock->erc = MQEREASON_NA; /* restore input */ (void)mqeFields_new(pExceptBlock, &hFields); if (MQERETURN_OK == pExceptBlock->ec) { (void)mqeFields_restore(hFields, pExceptBlock, pInputData, inputDataLen); /* get ID */ if (MQERETURN_OK == pExceptBlock->ec) { MQeStringHndl hAuthenticIDField; (void)mqeString_newChar8(pExceptBlock, &hAuthenticIDField, AUTHENTIC_ID); if (MQERETURN_OK == pExceptBlock->ec) { MQeStringHndl hAuthenticID; (void)mqeFields_getAscii(hFields, pExceptBlock, &hAuthenticID, hAuthenticIDField); /** If the above call failed, * then the authentication by the slave was not successful. */ if (MQERETURN_OK == pExceptBlock->ec) { /* set local ID */ (void)mqeAuthenticator_setAuthenticatedID(hAuthenticator, pExceptBlock, hAuthenticID); } (void)mqeString_free(hAuthenticIDField, NULL); } } (void)mqeFields_free(hFields, NULL); } return pExceptBlock->ec; }
Parent topic: Writing authenticators in C