|
|
/*++
Copyright (c) 2000, Microsoft Corporation
Module Name: elutil.c
Abstract:
Tools and ends
Revision History:
sachins, Apr 23 2001, Created
--*/
#include "precomp.h"
#pragma hdrstop
//
// EAPOLUI function mapping
//
EAPOLUIFUNCMAP EapolUIFuncMap[NUM_EAPOL_DLG_MSGS]= { {EAPOLUI_GET_USERIDENTITY, ElGetUserIdentityDlgWorker, ElGetUserIdentityDlgWorker, TRUE, SID_GetUserIdentity}, {EAPOLUI_GET_USERNAMEPASSWORD, ElGetUserNamePasswordDlgWorker, NULL, TRUE, SID_GetUserNamePassword}, {EAPOLUI_INVOKEINTERACTIVEUI, ElInvokeInteractiveUIDlgWorker, NULL, TRUE, SID_InvokeInteractiveUI}, {EAPOLUI_EAP_NOTIFICATION, NULL, NULL, TRUE, 0}, {EAPOLUI_REAUTHENTICATE, NULL, NULL, FALSE, 0}, {EAPOLUI_CREATEBALLOON, NULL, NULL, TRUE, SID_AuthenticationFailed}, {EAPOLUI_CLEANUP, NULL, NULL, FALSE, 0}, {EAPOLUI_DUMMY, NULL, NULL, FALSE, 0} };
//
// ElCanShowBalloon
//
// Description:
// Function called by netshell, to query if balloon is to be displayed
//
// Arguments:
// pGUIDConn - Interface GUID string
// pszConnectionName - Connection Name
// pszBalloonText - Pointer to text to be display
// pszCookie - EAPOL specific information
//
// Return values:
// S_OK - Display balloon
// S_FALSE - Do not display balloon
//
HRESULT ElCanShowBalloon ( IN const GUID * pGUIDConn, IN const WCHAR * pszConnectionName, IN OUT BSTR * pszBalloonText, IN OUT BSTR * pszCookie ) { EAPOL_EAP_UI_CONTEXT *pEapolUIContext = NULL; DWORD dwIndex = 0; DWORD dwSessionId = 0; WCHAR cwszBuffer[MAX_BALLOON_MSG_LEN]; WCHAR wsSSID[MAX_SSID_LEN+1]; DWORD dwSizeOfSSID = 0; BYTE *bSSID = NULL; WCHAR *pszFinalBalloonText = NULL; DWORD dwFinalStringId = 0; DWORD dwRetCode = NO_ERROR; DWORD dwRetCode1 = NO_ERROR; HRESULT hr = S_OK;
do { pEapolUIContext = (EAPOL_EAP_UI_CONTEXT *)(*pszCookie);
if (!ProcessIdToSessionId (GetCurrentProcessId (), &dwSessionId)) { dwRetCode = GetLastError (); break; }
if (pEapolUIContext->dwSessionId != dwSessionId) { // Not intended for this session
dwRetCode = ERROR_INVALID_PARAMETER; break; }
dwSizeOfSSID = pEapolUIContext->dwSizeOfSSID; bSSID = pEapolUIContext->bSSID;
for (dwIndex=0; dwIndex < NUM_EAPOL_DLG_MSGS; dwIndex++) { if (pEapolUIContext->dwEAPOLUIMsgType == EapolUIFuncMap[dwIndex].dwEAPOLUIMsgType) { if (EapolUIFuncMap[dwIndex].fShowBalloon) { TRACE1 (RPC, "ElCanShowBalloon: Response function found, msg (%ld)", EapolUIContext->dwEAPOLUIMsgType);
dwFinalStringId = EapolUIFuncMap[dwIndex].dwStringID;
// Verify is balloon indeed needs to be popped up OR
// can purpose be achieved without user involvement
if (EapolUIFuncMap[dwIndex].EapolUIVerify != NULL) { // Indicate that it is verification cycle, by passing
// NULL connection name, to indicate no display !
dwRetCode1 = EapolUIFuncMap[dwIndex].EapolUIVerify ( NULL, pEapolUIContext ); if (dwRetCode1 == ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION) { // Continue with show balloon
dwRetCode = NO_ERROR; } else { if (dwRetCode1 != NO_ERROR) { switch (dwRetCode1) { case ERROR_NO_EAPTLS_CERTIFICATE: // No certificate found
// Pop balloon accordingly
dwFinalStringId = SID_NoCertificateFound; // Since we wont take action on this
// balloon being clicked, flag it as
// EAPOLUI_DUMMY
pEapolUIContext->dwEAPOLUIMsgType = EAPOLUI_DUMMY; dwRetCode = NO_ERROR; break;
case ERROR_NO_SMART_CARD_READER: // No smartcard reader found
dwFinalStringId = SID_NoSmartCardReaderFound; // Since we wont take action on this
// balloon being clicked, flag it as
// EAPOLUI_DUMMY
pEapolUIContext->dwEAPOLUIMsgType = EAPOLUI_DUMMY; dwRetCode = NO_ERROR; break;
default: // Continue with show balloon for any
// error in verification function
dwRetCode = NO_ERROR; break; } } else { // No need to process more.
// Response has been sent successfully
// without user intervention
dwRetCode = ERROR_CAN_NOT_COMPLETE; break; } } }
if (dwFinalStringId != 0) { // Load string based on Id
if (dwFinalStringId <= SID_NoCertificateFound) { if (LoadString (GetModuleHandle(cszModuleName), dwFinalStringId, cwszBuffer, MAX_BALLOON_MSG_LEN) == 0) { dwRetCode = GetLastError (); break; } } else { if (LoadString (WZCGetSPResModule(), dwFinalStringId, cwszBuffer, MAX_BALLOON_MSG_LEN) == 0) { dwRetCode = GetLastError (); break; } }
// Append the network-name / SSID
if (dwSizeOfSSID != 0) { if (0 == MultiByteToWideChar ( CP_ACP, 0, bSSID, dwSizeOfSSID, wsSSID, MAX_SSID_LEN+1)) { dwRetCode = GetLastError(); break; }
if ((pszFinalBalloonText = MALLOC ((wcslen(cwszBuffer)+1+ dwSizeOfSSID)*sizeof(WCHAR))) == NULL) { dwRetCode = ERROR_NOT_ENOUGH_MEMORY; break; } wcscpy (pszFinalBalloonText, cwszBuffer); memcpy ((BYTE *)(pszFinalBalloonText + wcslen(cwszBuffer)), (BYTE *)wsSSID, dwSizeOfSSID*sizeof(WCHAR)); pszFinalBalloonText[wcslen(cwszBuffer)+dwSizeOfSSID] = L'\0'; } else { // Append a "." (period)
if ((pszFinalBalloonText = MALLOC ((wcslen(cwszBuffer) + 3)*sizeof(WCHAR))) == NULL) { dwRetCode = ERROR_NOT_ENOUGH_MEMORY; break; } wcscpy (pszFinalBalloonText, cwszBuffer); pszFinalBalloonText[wcslen(cwszBuffer)+1] = L'.'; pszFinalBalloonText[wcslen(cwszBuffer)+2] = L'\0'; }
if (*pszBalloonText) { if (!SysReAllocString (pszBalloonText, pszFinalBalloonText)) { dwRetCode = ERROR_CAN_NOT_COMPLETE; break; } } else { *pszBalloonText = SysAllocString (pszFinalBalloonText); if (*pszBalloonText == NULL) { dwRetCode = ERROR_NOT_ENOUGH_MEMORY; break; } } } else { // Display the string that was passed
}
// If notification message, check to see if explorer
// needs to be started off
if (pEapolUIContext->dwEAPOLUIMsgType == EAPOLUI_EAP_NOTIFICATION) { // Parse text message
// Attach to cookie
} } else { TRACE1 (RPC, "ElCanShowBalloon: No balloon display, msg (%ld)", EapolUIContext.dwEAPOLUIMsgType); } } }
} while (FALSE);
if (pszFinalBalloonText != NULL) { FREE (pszFinalBalloonText); }
if (dwRetCode != NO_ERROR) { hr = S_FALSE; } return hr; }
//
// ElOnBalloonClick
//
// Description:
//
// Function called by netshell, in response to a balloon click
//
// Arguments:
// pGUIDConn - Interface GUID string
// szCookie - EAPOL specific information
//
// Return values:
// S_OK - No error
// S_FALSE - Error
//
HRESULT ElOnBalloonClick ( IN const GUID * pGUIDConn, IN const WCHAR * pszConnectionName, IN const BSTR szCookie ) { EAPOL_EAP_UI_CONTEXT *pEapolUIContext = NULL; DWORD dwIndex = 0; DWORD dwSessionId = 0; DWORD dwRetCode = NO_ERROR; WCHAR *pwszConnectionName = NULL; HRESULT hr = S_OK;
do { pEapolUIContext = (EAPOL_EAP_UI_CONTEXT *)szCookie; pwszConnectionName = (WCHAR *)pszConnectionName;
for (dwIndex=0; dwIndex < NUM_EAPOL_DLG_MSGS; dwIndex++) { if (pEapolUIContext->dwEAPOLUIMsgType == EapolUIFuncMap[dwIndex].dwEAPOLUIMsgType) { if (EapolUIFuncMap[dwIndex].EapolUIFunc) { TRACE1 (RPC, "ElOnBalloonClick: Response function found, msg (%ld)", EapolUIContext->dwEAPOLUIMsgType); // Cleanup any previous dialogs for this interface
if ((dwRetCode = ElDialogCleanup ( (WCHAR *)pszConnectionName, szCookie )) != NO_ERROR) { TRACE0 (RPC, "ElOnBalloonClick: Error in dialog cleanup"); break; }
if ((dwRetCode = EapolUIFuncMap[dwIndex].EapolUIFunc ( pwszConnectionName, pEapolUIContext )) != NO_ERROR) { TRACE1 (RPC, "ElOnBalloonClick: Response function failed with error %ld", dwRetCode); } } else { TRACE1 (RPC, "ElOnBalloonClick: No response function, msg (%ld)", EapolUIContext.dwEAPOLUIMsgType); } break; } } } while (FALSE);
hr = HRESULT_FROM_NT (dwRetCode); return hr; }
//
// ElSecureEncodePw
//
// Description:
//
// Encrypt password locally using user-ACL
//
DWORD ElSecureEncodePw ( IN PWCHAR *ppwszPassword, OUT DATA_BLOB *pDataBlob ) { DWORD dwRetCode = NO_ERROR; DATA_BLOB blobIn, blobOut;
do { blobIn.cbData = (wcslen (*ppwszPassword) + 1)*sizeof(WCHAR); blobIn.pbData = (BYTE *)*ppwszPassword;
if (!CryptProtectData ( &blobIn, L"", NULL, NULL, NULL, 0, &blobOut)) { dwRetCode = GetLastError (); break; } // copy over blob to password
if (pDataBlob->pbData != NULL) { FREE (pDataBlob->pbData); pDataBlob->pbData = NULL; pDataBlob->cbData = 0; }
pDataBlob->pbData = MALLOC (blobOut.cbData); if (pDataBlob->pbData == NULL) { dwRetCode = ERROR_NOT_ENOUGH_MEMORY; break; }
memcpy (pDataBlob->pbData, blobOut.pbData, blobOut.cbData); pDataBlob->cbData = blobOut.cbData; } while (FALSE);
if (blobOut.pbData != NULL) { LocalFree (blobOut.pbData); }
if (dwRetCode != NO_ERROR) { if (pDataBlob->pbData != NULL) { FREE (pDataBlob->pbData); pDataBlob->pbData = NULL; pDataBlob->cbData = 0; } }
return dwRetCode; }
//
// ElQueryConnectionStatusText
//
// Description:
//
// Function called by netshell, to query appropriate text for 802.1X states
//
// Arguments:
// pGUIDConn - Interface GUID string
// ncs - NETCON_STATUS for the interface
// pszStatusText - Detailed 802.1X status to be displayed
//
// Return values:
// S_OK - No error
// S_FALSE - Error
//
HRESULT ElQueryConnectionStatusText ( IN const GUID * pGUIDConn, IN const NETCON_STATUS ncs, IN OUT BSTR * pszStatusText ) { WCHAR wszGuid[GUID_STRING_LEN_WITH_TERM]; WCHAR cwszBuffer[MAX_BALLOON_MSG_LEN]; EAPOL_INTF_STATE EapolIntfState = {0}; DWORD dwStringId = 0; DWORD dwRetCode = NO_ERROR; HRESULT hr = S_OK;
do { ZeroMemory ((PVOID)&EapolIntfState, sizeof(EAPOL_INTF_STATE)); StringFromGUID2 (pGUIDConn, wszGuid, GUID_STRING_LEN_WITH_TERM);
// Query current EAPOL state
if ((dwRetCode = WZCEapolQueryState ( NULL, wszGuid, &EapolIntfState )) != NO_ERROR) { break; }
// Assign appropriate display string
switch (EapolIntfState.dwEapUIState) { case 0: if (EapolIntfState.dwState == EAPOLSTATE_ACQUIRED) { dwStringId = SID_ContactingServer; } break; case EAPUISTATE_WAITING_FOR_IDENTITY: dwStringId = SID_AcquiringIdentity; break; case EAPUISTATE_WAITING_FOR_UI_RESPONSE: dwStringId = SID_UserResponse; break; }
if (dwStringId != 0) { // Load string based on Id
if (dwStringId <= SID_NoCertificateFound) { if (LoadString (GetModuleHandle(cszModuleName), dwStringId, cwszBuffer, MAX_BALLOON_MSG_LEN) == 0) { dwRetCode = GetLastError (); break; } } else { if (LoadString (WZCGetSPResModule(), dwStringId, cwszBuffer, MAX_BALLOON_MSG_LEN) == 0) { dwRetCode = GetLastError (); break; } }
if (*pszStatusText) { if (!SysReAllocString (pszStatusText, cwszBuffer)) { dwRetCode = ERROR_CAN_NOT_COMPLETE; break; } } else { *pszStatusText = SysAllocString (cwszBuffer); if (*pszStatusText == NULL) { dwRetCode = ERROR_NOT_ENOUGH_MEMORY; break; } } } else { // Indicate to netshell that it need not process this response
hr = S_FALSE; } } while (FALSE);
if (dwRetCode != NO_ERROR) hr = HRESULT_FROM_NT (dwRetCode);
WZCEapolFreeState (&EapolIntfState); return hr; }
|