/* Copyright (c) 1997, Microsoft Corporation, all rights reserved Description: History: Nov 1997: Vijay Baliga created original version. */ #include // Required by windows.h #include // Required by windows.h #include // Required by windows.h #include // Win32 base API's #include #include // For swprintf #include // Required by raseapif.h #include // For RTASSERT #include // For EAPLOGONINFO #include // For ERROR_NO_SMART_CARD_READER #include #include #if WINVER > 0x0500 #include "wzcsapi.h" #endif #include #define SECURITY_WIN32 #include // For GetUserNameExA, CredHandle #include // For CredHandle #include #include #include const DWORD g_adwHelp[] = { IDC_RADIO_USE_CARD, IDH_RADIO_USE_CARD, IDC_RADIO_USE_REGISTRY, IDH_RADIO_USE_REGISTRY, IDC_CHECK_VALIDATE_CERT, IDH_CHECK_VALIDATE_CERT, IDC_CHECK_VALIDATE_NAME, IDH_CHECK_VALIDATE_NAME, IDC_EDIT_SERVER_NAME, IDH_EDIT_SERVER_NAME, IDC_STATIC_ROOT_CA_NAME, IDH_COMBO_ROOT_CA_NAME, IDC_CHECK_DIFF_USER, IDH_CHECK_DIFF_USER, IDC_STATIC_DIFF_USER, IDH_EDIT_DIFF_USER, IDC_EDIT_DIFF_USER, IDH_EDIT_DIFF_USER, IDC_STATIC_PIN, IDH_EDIT_PIN, IDC_EDIT_PIN, IDH_EDIT_PIN, IDC_CHECK_SAVE_PIN, IDH_CHECK_SAVE_PIN, IDC_STATIC_SERVER_NAME, IDH_COMBO_SERVER_NAME, IDC_COMBO_SERVER_NAME, IDH_COMBO_SERVER_NAME, IDC_STATIC_USER_NAME, IDH_COMBO_USER_NAME, IDC_COMBO_USER_NAME, IDH_COMBO_USER_NAME, IDC_STATIC_FRIENDLY_NAME, IDH_EDIT_FRIENDLY_NAME, IDC_EDIT_FRIENDLY_NAME, IDH_EDIT_FRIENDLY_NAME, IDC_STATIC_ISSUER, IDH_EDIT_ISSUER, IDC_EDIT_ISSUER, IDH_EDIT_ISSUER, IDC_STATIC_EXPIRATION, IDH_EDIT_EXPIRATION, IDC_EDIT_EXPIRATION, IDH_EDIT_EXPIRATION, 0, 0 }; /* Returns: VOID Notes: Calls WinHelp to popup context sensitive help. padwMap is an array of control-ID help-ID pairs terminated with a 0,0 pair. unMsg is WM_HELP or WM_CONTEXTMENU indicating the message received requesting help. wParam and lParam are the parameters of the message received requesting help. */ VOID ContextHelp( IN const DWORD* padwMap, IN HWND hWndDlg, IN UINT unMsg, IN WPARAM wParam, IN LPARAM lParam ) { HWND hWnd; UINT unType; WCHAR* pwszHelpFile = NULL; HELPINFO* pHelpInfo; if (unMsg == WM_HELP) { pHelpInfo = (HELPINFO*) lParam; if (pHelpInfo->iContextType != HELPINFO_WINDOW) { goto LDone; } hWnd = pHelpInfo->hItemHandle; unType = HELP_WM_HELP; } else { // Standard Win95 method that produces a one-item "What's This?" menu // that user must click to get help. hWnd = (HWND) wParam; unType = HELP_CONTEXTMENU; }; pwszHelpFile = WszFromId(GetHInstance(), IDS_HELPFILE); if (NULL == pwszHelpFile) { goto LDone; } WinHelp(hWnd, pwszHelpFile, unType, (ULONG_PTR)padwMap); LDone: LocalFree(pwszHelpFile); } VOID DisplayResourceError ( IN HWND hwndParent, IN DWORD dwResourceId ) { WCHAR* pwszTitle = NULL; WCHAR* pwszMessage = NULL; pwszTitle = WszFromId(GetHInstance(), IDS_CANT_CONFIGURE_SERVER_TITLE); // // Check to see which file the resource is to be loaded // switch ( dwResourceId ) { case IDS_VALIDATE_SERVER_TITLE: case IDS_CANT_CONFIGURE_SERVER_TEXT: case IDS_CONNECT: case IDS_HELPFILE: case IDS_PEAP_NO_SERVER_CERT: pwszMessage = WszFromId(GetHInstance(), dwResourceId); default: pwszMessage = WszFromId(GetResouceDLLHInstance(), dwResourceId); } MessageBox(hwndParent, (pwszMessage != NULL)? pwszMessage : L"", (pwszTitle != NULL) ? pwszTitle : L"", MB_OK | MB_ICONERROR); LocalFree(pwszTitle); LocalFree(pwszMessage); } /* Returns: VOID Notes: Display the error message corresponding to dwErrNum. Used only on the server side. */ VOID DisplayError( IN HWND hwndParent, IN DWORD dwErrNum ) { WCHAR* pwszTitle = NULL; WCHAR* pwszMessageFormat = NULL; WCHAR* pwszMessage = NULL; DWORD dwErr; pwszTitle = WszFromId(GetHInstance(), IDS_CANT_CONFIGURE_SERVER_TITLE); dwErr = MprAdminGetErrorString(dwErrNum, &pwszMessage); if (NO_ERROR != dwErr) { pwszMessageFormat = WszFromId(GetHInstance(), IDS_CANT_CONFIGURE_SERVER_TEXT); if (NULL != pwszMessageFormat) { pwszMessage = LocalAlloc(LPTR, wcslen(pwszMessageFormat) + 20); if (NULL != pwszMessage) { swprintf(pwszMessage, pwszMessageFormat, dwErrNum); } } } MessageBox(hwndParent, (pwszMessage != NULL)? pwszMessage : L"", (pwszTitle != NULL) ? pwszTitle : L"", MB_OK | MB_ICONERROR); LocalFree(pwszTitle); LocalFree(pwszMessageFormat); LocalFree(pwszMessage); } /* List view of check boxes state indices. */ #define SI_Unchecked 1 #define SI_Checked 2 #define SI_DisabledUnchecked 3 #define SI_DisabledChecked 4 #define LVXN_SETCHECK (LVN_LAST + 1) // //Work arounds for bugs in list ctrl... // BOOL ListView_GetCheck( IN HWND hwndLv, IN INT iItem ) /* Returns true if the check box of item 'iItem' of listview of checkboxes ** 'hwndLv' is checked, false otherwise. This function works on disabled ** check boxes as well as enabled ones. */ { UINT unState; unState = ListView_GetItemState( hwndLv, iItem, LVIS_STATEIMAGEMASK ); return !!((unState == INDEXTOSTATEIMAGEMASK( SI_Checked )) || (unState == INDEXTOSTATEIMAGEMASK( SI_DisabledChecked ))); } BOOL ListView_IsCheckDisabled ( IN HWND hwndLv, IN INT iItem) /* Returns true if the check box of item 'iItem' of listview of checkboxes ** 'hwndLv' is disabled, false otherwise. */ { UINT unState; unState = ListView_GetItemState( hwndLv, iItem, LVIS_STATEIMAGEMASK ); if ((unState == INDEXTOSTATEIMAGEMASK( SI_DisabledChecked )) || (unState == INDEXTOSTATEIMAGEMASK( SI_DisabledUnchecked ))) return TRUE; return FALSE; } VOID ListView_SetCheck( IN HWND hwndLv, IN INT iItem, IN BOOL fCheck ) /* Sets the check mark on item 'iItem' of listview of checkboxes 'hwndLv' ** to checked if 'fCheck' is true or unchecked if false. */ { NM_LISTVIEW nmlv; if (ListView_IsCheckDisabled(hwndLv, iItem)) return; ListView_SetItemState( hwndLv, iItem, INDEXTOSTATEIMAGEMASK( (fCheck) ? SI_Checked : SI_Unchecked ), LVIS_STATEIMAGEMASK ); nmlv.hdr.code = LVXN_SETCHECK; nmlv.hdr.hwndFrom = hwndLv; nmlv.iItem = iItem; FORWARD_WM_NOTIFY( GetParent(hwndLv), GetDlgCtrlID(hwndLv), &nmlv, SendMessage ); } /* Returns: FALSE (prevent Windows from setting the default keyboard focus). Notes: Response to the WM_INITDIALOG message. */ BOOL PinInitDialog( IN HWND hWnd, IN LPARAM lParam ) { EAPTLS_PIN_DIALOG* pEapTlsPinDialog; EAPTLS_USER_PROPERTIES* pUserProp; WCHAR* pwszTitleFormat = NULL; WCHAR* pwszTitle = NULL; WCHAR* pwszIdentity = NULL; SetWindowLongPtr(hWnd, DWLP_USER, lParam); pEapTlsPinDialog = (EAPTLS_PIN_DIALOG*)lParam; pUserProp = pEapTlsPinDialog->pUserProp; pEapTlsPinDialog->hWndStaticDiffUser = GetDlgItem(hWnd, IDC_STATIC_DIFF_USER); pEapTlsPinDialog->hWndEditDiffUser = GetDlgItem(hWnd, IDC_EDIT_DIFF_USER); pEapTlsPinDialog->hWndStaticPin = GetDlgItem(hWnd, IDC_STATIC_PIN); pEapTlsPinDialog->hWndEditPin = GetDlgItem(hWnd, IDC_EDIT_PIN); if (pUserProp->pwszDiffUser[0]) { SetWindowText(pEapTlsPinDialog->hWndEditDiffUser, pUserProp->pwszDiffUser); } if (pUserProp->pwszPin[0]) { SetWindowText(pEapTlsPinDialog->hWndEditPin, pUserProp->pwszPin); ZeroMemory(pUserProp->pwszPin, wcslen(pUserProp->pwszPin) * sizeof(WCHAR)); } if (!(pEapTlsPinDialog->fFlags & EAPTLS_PIN_DIALOG_FLAG_DIFF_USER)) { EnableWindow(pEapTlsPinDialog->hWndStaticDiffUser, FALSE); EnableWindow(pEapTlsPinDialog->hWndEditDiffUser, FALSE); } if (pUserProp->fFlags & EAPTLS_USER_FLAG_SAVE_PIN) { CheckDlgButton(hWnd, IDC_CHECK_SAVE_PIN, BST_CHECKED); } // Bug 428871 implies that SavePin must not be allowed. ShowWindow(GetDlgItem(hWnd, IDC_CHECK_SAVE_PIN), SW_HIDE); SetFocus(pEapTlsPinDialog->hWndEditPin); { // Set the title pwszTitleFormat = WszFromId(GetHInstance(), IDS_CONNECT); if (NULL != pwszTitleFormat) { pwszTitle = LocalAlloc(LPTR, (wcslen(pwszTitleFormat) + wcslen(pEapTlsPinDialog->pwszEntry)) * sizeof(WCHAR)); if (NULL != pwszTitle) { swprintf(pwszTitle, pwszTitleFormat, pEapTlsPinDialog->pwszEntry); SetWindowText(hWnd, pwszTitle); } } } LocalFree(pwszTitleFormat); LocalFree(pwszTitle); return(FALSE); } void ValidatePIN ( IN EAPTLS_PIN_DIALOG* pEapTlsPinDialog ) { pEapTlsPinDialog->dwRetCode = AssociatePinWithCertificate( pEapTlsPinDialog->pCertContext, pEapTlsPinDialog->pUserProp, FALSE, TRUE ); return; } /* Returns: TRUE: We prrocessed this message. FALSE: We did not prrocess this message. Notes: Response to the WM_COMMAND message. */ BOOL PinCommand( IN EAPTLS_PIN_DIALOG* pEapTlsPinDialog, IN WORD wNotifyCode, IN WORD wId, IN HWND hWndDlg, IN HWND hWndCtrl ) { DWORD dwNumChars; DWORD dwNameLength; DWORD dwPinLength; DWORD dwSize; EAPTLS_USER_PROPERTIES* pUserProp; switch(wId) { case IDOK: dwNameLength = GetWindowTextLength( pEapTlsPinDialog->hWndEditDiffUser); dwPinLength = GetWindowTextLength( pEapTlsPinDialog->hWndEditPin); // There is already one character in awszString. // Add the number of characters in DiffUser... dwNumChars = dwNameLength; // Add the number of characters in PIN... dwNumChars += dwPinLength; // Add one more for a terminating NULL. Use the extra character in // awszString for the other terminating NULL. dwNumChars += 1; dwSize = sizeof(EAPTLS_USER_PROPERTIES) + dwNumChars*sizeof(WCHAR); pUserProp = LocalAlloc(LPTR, dwSize); if (NULL == pUserProp) { EapTlsTrace("LocalAlloc in Command failed and returned %d", GetLastError()); } else { CopyMemory(pUserProp, pEapTlsPinDialog->pUserProp, sizeof(EAPTLS_USER_PROPERTIES)); pUserProp->dwSize = dwSize; pUserProp->pwszDiffUser = pUserProp->awszString; GetWindowText(pEapTlsPinDialog->hWndEditDiffUser, pUserProp->pwszDiffUser, dwNameLength + 1); pUserProp->dwPinOffset = dwNameLength + 1; pUserProp->pwszPin = pUserProp->awszString + pUserProp->dwPinOffset; GetWindowText(pEapTlsPinDialog->hWndEditPin, pUserProp->pwszPin, dwPinLength + 1); LocalFree(pEapTlsPinDialog->pUserProp); pEapTlsPinDialog->pUserProp = pUserProp; } if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_SAVE_PIN)) { pEapTlsPinDialog->pUserProp->fFlags |= EAPTLS_USER_FLAG_SAVE_PIN; } else { pEapTlsPinDialog->pUserProp->fFlags &= ~EAPTLS_USER_FLAG_SAVE_PIN; } // //Check if valid PIN has been entered and set the error code in pEapTlsPinDialog // ValidatePIN ( pEapTlsPinDialog); // Fall through case IDCANCEL: EndDialog(hWndDlg, wId); return(TRUE); default: return(FALSE); } } /* Returns: Notes: Callback function used with the DialogBoxParam function. It processes messages sent to the dialog box. See the DialogProc documentation in MSDN. */ INT_PTR CALLBACK PinDialogProc( IN HWND hWnd, IN UINT unMsg, IN WPARAM wParam, IN LPARAM lParam ) { EAPTLS_PIN_DIALOG* pEapTlsPinDialog; switch (unMsg) { case WM_INITDIALOG: return(PinInitDialog(hWnd, lParam)); case WM_HELP: case WM_CONTEXTMENU: { ContextHelp(g_adwHelp, hWnd, unMsg, wParam, lParam); break; } case WM_COMMAND: pEapTlsPinDialog = (EAPTLS_PIN_DIALOG*)GetWindowLongPtr(hWnd, DWLP_USER); return(PinCommand(pEapTlsPinDialog, HIWORD(wParam), LOWORD(wParam), hWnd, (HWND)lParam)); } return(FALSE); } /* ** Smart card and cert store accessing status dialog */ INT_PTR CALLBACK StatusDialogProc( IN HWND hWnd, IN UINT unMsg, IN WPARAM wParam, IN LPARAM lParam ) { switch (unMsg) { case WM_INITDIALOG: { ShowWindow(GetDlgItem(hWnd, IDC_BITMAP_SCARD), SW_SHOW ); ShowWindow(GetDlgItem(hWnd, IDC_STATUS_SCARD), SW_SHOW ); return TRUE; } } return FALSE; } /* Returns: VOID Notes: Enables or disables the controls in the "Validate server name" group. */ VOID EnableValidateNameControls( IN EAPTLS_CONN_DIALOG* pEapTlsConnDialog ) { BOOL fEnable; RTASSERT(NULL != pEapTlsConnDialog); fEnable = !(pEapTlsConnDialog->pConnPropv1->fFlags & EAPTLS_CONN_FLAG_NO_VALIDATE_CERT); EnableWindow(pEapTlsConnDialog->hWndCheckValidateName, fEnable); EnableWindow(pEapTlsConnDialog->hWndStaticRootCaName, fEnable); EnableWindow(pEapTlsConnDialog->hWndListRootCaName, fEnable); fEnable = ( fEnable && !(pEapTlsConnDialog->pConnPropv1->fFlags & EAPTLS_CONN_FLAG_NO_VALIDATE_NAME)); EnableWindow(pEapTlsConnDialog->hWndEditServerName, fEnable); fEnable = pEapTlsConnDialog->pConnPropv1->fFlags & EAPTLS_CONN_FLAG_REGISTRY; EnableWindow( pEapTlsConnDialog->hWndCheckUseSimpleSel, fEnable ); } /* Returns: VOID Notes: Displays the cert information */ VOID DisplayCertInfo( IN EAPTLS_USER_DIALOG* pEapTlsUserDialog ) { RTASSERT(NULL != pEapTlsUserDialog); // Erase old values first SetWindowText(pEapTlsUserDialog->hWndEditFriendlyName, L""); SetWindowText(pEapTlsUserDialog->hWndEditIssuer, L""); SetWindowText(pEapTlsUserDialog->hWndEditExpiration, L""); SetWindowText(pEapTlsUserDialog->hWndEditDiffUser, L""); if (NULL != pEapTlsUserDialog->pCert) { if (NULL != pEapTlsUserDialog->pCert->pwszFriendlyName) { SetWindowText(pEapTlsUserDialog->hWndEditFriendlyName, pEapTlsUserDialog->pCert->pwszFriendlyName); } if (NULL != pEapTlsUserDialog->pCert->pwszIssuer) { SetWindowText(pEapTlsUserDialog->hWndEditIssuer, pEapTlsUserDialog->pCert->pwszIssuer); } if (NULL != pEapTlsUserDialog->pCert->pwszExpiration) { SetWindowText(pEapTlsUserDialog->hWndEditExpiration, pEapTlsUserDialog->pCert->pwszExpiration); } if ( (NULL != pEapTlsUserDialog->pCert->pwszDisplayName) && (NULL != pEapTlsUserDialog->hWndEditDiffUser) && (EAPTLS_USER_DIALOG_FLAG_DIFF_USER & pEapTlsUserDialog->fFlags)) { SetWindowText(pEapTlsUserDialog->hWndEditDiffUser, pEapTlsUserDialog->pCert->pwszDisplayName); } } } VOID InitComboBoxFromGroup ( IN HWND hWnd, IN PEAPTLS_GROUPED_CERT_NODES pGroupList, IN EAPTLS_CERT_NODE* pCert //Selected certificate ) { DWORD dwIndex; DWORD dwItemIndex; WCHAR* pwszDisplayName; PEAPTLS_GROUPED_CERT_NODES pGListTemp = pGroupList; SendMessage(hWnd, CB_RESETCONTENT, 0, 0); dwIndex = 0; dwItemIndex = 0; while (NULL != pGListTemp) { pwszDisplayName = pGListTemp->pwszDisplayName; if (NULL == pwszDisplayName) { pwszDisplayName = L" "; } SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)pwszDisplayName); if (pGListTemp->pMostRecentCert == pCert) { dwItemIndex = dwIndex; } pGListTemp = pGListTemp->pNext; dwIndex++; } SendMessage(hWnd, CB_SETCURSEL, dwItemIndex, 0); } /* Returns: VOID Notes: Initializes a combo box */ VOID InitComboBox( IN HWND hWnd, IN EAPTLS_CERT_NODE* pCertList, IN EAPTLS_CERT_NODE* pCert ) { DWORD dwIndex; DWORD dwItemIndex; WCHAR* pwszDisplayName; SendMessage(hWnd, CB_RESETCONTENT, 0, 0); dwIndex = 0; dwItemIndex = 0; while (NULL != pCertList) { pwszDisplayName = pCertList->pwszDisplayName; if (NULL == pwszDisplayName) { pwszDisplayName = L" "; } SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)pwszDisplayName); SendMessage(hWnd, CB_SETITEMDATA, (WORD)dwIndex, (LPARAM)pCertList); if (pCertList == pCert) { dwItemIndex = dwIndex; } pCertList = pCertList->pNext; dwIndex++; } SendMessage(hWnd, CB_SETCURSEL, dwItemIndex, 0); } /* Returns: VOID Notes: Initializes a List box with selected certs */ VOID InitListBox ( IN HWND hWnd, IN EAPTLS_CERT_NODE * pCertList, IN DWORD dwNumSelCerts, IN EAPTLS_CERT_NODE ** ppSelectedCertList ) { int nIndex = 0; int nNewIndex = 0; DWORD dw = 0; WCHAR* pwszDisplayName; LVITEM lvItem; ListView_DeleteAllItems(hWnd); while (NULL != pCertList) { pwszDisplayName = pCertList->pwszDisplayName; if (NULL == pwszDisplayName) { pCertList = pCertList->pNext; continue; } ZeroMemory(&lvItem, sizeof(lvItem)); lvItem.mask = LVIF_TEXT|LVIF_PARAM; lvItem.pszText = pwszDisplayName; lvItem.iItem = nIndex; lvItem.lParam = (LPARAM)pCertList; nNewIndex = ListView_InsertItem ( hWnd, &lvItem ); for ( dw = 0; dw < dwNumSelCerts; dw ++ ) { if ( pCertList == *(ppSelectedCertList+dw) ) { ListView_SetCheckState(hWnd, nNewIndex,TRUE); } } nIndex++; pCertList = pCertList->pNext; } ListView_SetItemState( hWnd, 0, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED ); } VOID CertListSelectedCount ( HWND hWndCtrl, DWORD * pdwSelCertCount ) { DWORD dwItemIndex = 0; DWORD dwItemCount = 0; dwItemCount = ListView_GetItemCount(hWndCtrl); *pdwSelCertCount = 0; for ( dwItemIndex = 0; dwItemIndex < dwItemCount; dwItemIndex ++ ) { if ( ListView_GetCheckState(hWndCtrl, dwItemIndex) ) { (*pdwSelCertCount) ++; } } } VOID CertListSelected( IN HWND hWndCtrl, //Handle to the list box IN EAPTLS_CERT_NODE* pCertList, //List of certs in the listbox IN OUT EAPTLS_CERT_NODE** ppSelCertList, //List of selected IN OUT EAPTLS_HASH* pHash, //List of Hash IN DWORD dwNumHash //Number of Items in the list ) { DWORD dwItemIndex = 0; DWORD dwItemCount = ListView_GetItemCount(hWndCtrl); DWORD dwCertIndex = 0; LVITEM lvitem; if (NULL == pCertList) { return; } //Skip the one with null display name... pCertList = pCertList->pNext; // //Need to do two iterations on the list box. //I am sure there is a better way of doing this but //I just dont know... // for ( dwItemIndex = 0; dwItemIndex < dwItemCount; dwItemIndex ++ ) { if ( ListView_GetCheckState(hWndCtrl, dwItemIndex) ) { ZeroMemory( &lvitem, sizeof(lvitem) ); lvitem.mask = LVIF_PARAM; lvitem.iItem = dwItemIndex; ListView_GetItem(hWndCtrl, &lvitem); *(ppSelCertList + dwCertIndex ) = (EAPTLS_CERT_NODE *)lvitem.lParam; CopyMemory ( pHash + dwCertIndex, &(((EAPTLS_CERT_NODE *)lvitem.lParam)->Hash), sizeof(EAPTLS_HASH) ); dwCertIndex ++; } } } /* Returns: VOID Notes: hWndCtrl is the HWND of a combo box. pCertList is the associated list of certs. *ppCert will ultimately point to the cert that was selected. Its hash will be stored in *pHash. */ VOID CertSelected( IN HWND hWndCtrl, IN EAPTLS_CERT_NODE* pCertList, IN EAPTLS_CERT_NODE** ppCert, IN EAPTLS_HASH* pHash ) { LONG_PTR lIndex; LRESULT lrItemIndex; if (NULL == pCertList) { return; } if ( NULL == hWndCtrl ) { lrItemIndex = 0; } else { lrItemIndex = SendMessage(hWndCtrl, CB_GETCURSEL, 0, 0); } for (lIndex = 0; lIndex != lrItemIndex; lIndex++) { pCertList = pCertList->pNext; } *ppCert = pCertList; CopyMemory(pHash, &(pCertList->Hash), sizeof(EAPTLS_HASH)); } VOID GroupCertSelected( IN HWND hWndCtrl, IN PEAPTLS_GROUPED_CERT_NODES pGroupList, IN EAPTLS_CERT_NODE** ppCert, IN EAPTLS_HASH* pHash ) { LONG_PTR lIndex; LRESULT lrItemIndex; PEAPTLS_GROUPED_CERT_NODES pGList = pGroupList; if (NULL == pGList) { return; } if ( NULL == hWndCtrl ) { lrItemIndex = 0; } else { lrItemIndex = SendMessage(hWndCtrl, CB_GETCURSEL, 0, 0); } // // This is really a very bogus way of doing things... // We can setup a itemdata for this in the control itself... // for (lIndex = 0; lIndex != lrItemIndex; lIndex++) { pGList = pGList ->pNext; } *ppCert = pGList->pMostRecentCert; CopyMemory(pHash, &(pGList ->pMostRecentCert->Hash), sizeof(EAPTLS_HASH)); } /* Returns: FALSE (prevent Windows from setting the default keyboard focus). Notes: Response to the WM_INITDIALOG message. */ BOOL UserInitDialog( IN HWND hWnd, IN LPARAM lParam ) { EAPTLS_USER_DIALOG* pEapTlsUserDialog; WCHAR* pwszTitleFormat = NULL; WCHAR* pwszTitle = NULL; SetWindowLongPtr(hWnd, DWLP_USER, lParam); pEapTlsUserDialog = (EAPTLS_USER_DIALOG*)lParam; BringWindowToTop(hWnd); pEapTlsUserDialog->hWndComboUserName = GetDlgItem(hWnd, IDC_COMBO_USER_NAME); if (NULL == pEapTlsUserDialog->hWndComboUserName) { // We must be showing the server's cert selection dialog pEapTlsUserDialog->hWndComboUserName = GetDlgItem(hWnd, IDC_COMBO_SERVER_NAME); } pEapTlsUserDialog->hWndBtnViewCert = GetDlgItem(hWnd, IDC_BUTTON_VIEW_CERTIFICATE ); pEapTlsUserDialog->hWndEditFriendlyName = GetDlgItem(hWnd, IDC_EDIT_FRIENDLY_NAME); pEapTlsUserDialog->hWndEditIssuer = GetDlgItem(hWnd, IDC_EDIT_ISSUER); pEapTlsUserDialog->hWndEditExpiration = GetDlgItem(hWnd, IDC_EDIT_EXPIRATION); pEapTlsUserDialog->hWndStaticDiffUser = GetDlgItem(hWnd, IDC_STATIC_DIFF_USER); pEapTlsUserDialog->hWndEditDiffUser = GetDlgItem(hWnd, IDC_EDIT_DIFF_USER); if ( pEapTlsUserDialog->fFlags & EAPTLS_USER_DIALOG_FLAG_USE_SIMPLE_CERTSEL ) { InitComboBoxFromGroup(pEapTlsUserDialog->hWndComboUserName, pEapTlsUserDialog->pGroupedList, pEapTlsUserDialog->pCert); } else { InitComboBox(pEapTlsUserDialog->hWndComboUserName, pEapTlsUserDialog->pCertList, pEapTlsUserDialog->pCert); } if ( (NULL != pEapTlsUserDialog->hWndEditDiffUser) && (!(pEapTlsUserDialog->fFlags & EAPTLS_USER_DIALOG_FLAG_DIFF_USER))) { ShowWindow(pEapTlsUserDialog->hWndStaticDiffUser, SW_HIDE); ShowWindow(pEapTlsUserDialog->hWndEditDiffUser, SW_HIDE); } DisplayCertInfo(pEapTlsUserDialog); if (pEapTlsUserDialog->pUserProp->pwszDiffUser[0]) { SetWindowText(pEapTlsUserDialog->hWndEditDiffUser, pEapTlsUserDialog->pUserProp->pwszDiffUser); } SetFocus(pEapTlsUserDialog->hWndComboUserName); if (pEapTlsUserDialog->fFlags & EAPTLS_USER_DIALOG_FLAG_DIFF_TITLE) { // Set the title pwszTitleFormat = WszFromId(GetHInstance(), IDS_CONNECT); if (NULL != pwszTitleFormat) { pwszTitle = LocalAlloc(LPTR, (wcslen(pwszTitleFormat) + wcslen(pEapTlsUserDialog->pwszEntry)) * sizeof(WCHAR)); if (NULL != pwszTitle) { HWND hWndDuplicate = NULL; DWORD dwThreadProcessId = 0; DWORD dwRetCode = NO_ERROR; swprintf(pwszTitle, pwszTitleFormat, pEapTlsUserDialog->pwszEntry); if ((hWndDuplicate = FindWindow (NULL, pwszTitle)) != NULL) { GetWindowThreadProcessId (hWndDuplicate, &dwThreadProcessId); if ((GetCurrentProcessId ()) == dwThreadProcessId) { // Kill current dialog since old one may be in use if (!PostMessage (hWnd, WM_DESTROY, 0, 0)) { dwRetCode = GetLastError (); EapTlsTrace("PostMessage failed with error %ld", dwRetCode); } goto LDone; } else { EapTlsTrace("Matching Window does not have same process id"); } } else { EapTlsTrace ("FindWindow could not find matching window"); } SetWindowText(hWnd, pwszTitle); } } } LDone: LocalFree(pwszTitleFormat); LocalFree(pwszTitle); return(FALSE); } /* Returns: TRUE: We prrocessed this message. FALSE: We did not prrocess this message. Notes: Response to the WM_COMMAND message. */ BOOL UserCommand( IN EAPTLS_USER_DIALOG* pEapTlsUserDialog, IN WORD wNotifyCode, IN WORD wId, IN HWND hWndDlg, IN HWND hWndCtrl ) { DWORD dwNumChars; DWORD dwTextLength; DWORD dwSize; EAPTLS_USER_PROPERTIES* pUserProp; HCERTSTORE hCertStore; PCCERT_CONTEXT pCertContext = NULL; switch(wId) { case IDC_BUTTON_VIEW_CERTIFICATE: { WCHAR szError[256]; WCHAR szTitle[512] = {0}; CRYPT_HASH_BLOB chb; GetWindowText(hWndDlg, szTitle, 511 ); // // Show the certificate details here // if ( pEapTlsUserDialog->pCert ) { //There is a selected cert - show details. hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_STORE_READONLY_FLAG | ((pEapTlsUserDialog->fIdentity) ? CERT_SYSTEM_STORE_CURRENT_USER: CERT_SYSTEM_STORE_LOCAL_MACHINE ), pEapTlsUserDialog->pwszStoreName ); LoadString( GetResouceDLLHInstance(), IDS_NO_CERT_DETAILS, szError, 255); if ( !hCertStore ) { MessageBox ( hWndDlg, szError, szTitle, MB_OK|MB_ICONSTOP ); return(TRUE); } chb.cbData = pEapTlsUserDialog->pCert->Hash.cbHash; chb.pbData = pEapTlsUserDialog->pCert->Hash.pbHash; pCertContext = CertFindCertificateInStore( hCertStore, 0, 0, CERT_FIND_HASH, &chb, 0); if ( NULL == pCertContext ) { MessageBox ( hWndDlg, szError, szTitle, MB_OK|MB_ICONSTOP ); if ( hCertStore ) CertCloseStore( hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ); return(TRUE); } // // Show Cert detail // ShowCertDetails ( hWndDlg, hCertStore, pCertContext ); if ( pCertContext ) CertFreeCertificateContext(pCertContext); if ( hCertStore ) CertCloseStore( hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ); } return(TRUE); } case IDC_COMBO_USER_NAME: case IDC_COMBO_SERVER_NAME: if (CBN_SELCHANGE != wNotifyCode) { return(FALSE); // We will not process this message } if ( pEapTlsUserDialog->fFlags & EAPTLS_USER_DIALOG_FLAG_USE_SIMPLE_CERTSEL ) { GroupCertSelected(hWndCtrl, pEapTlsUserDialog->pGroupedList, &(pEapTlsUserDialog->pCert), &(pEapTlsUserDialog->pUserProp->Hash)); } else { CertSelected(hWndCtrl, pEapTlsUserDialog->pCertList, &(pEapTlsUserDialog->pCert), &(pEapTlsUserDialog->pUserProp->Hash)); } DisplayCertInfo(pEapTlsUserDialog); return(TRUE); case IDOK: if ( pEapTlsUserDialog->fFlags & EAPTLS_USER_DIALOG_FLAG_USE_SIMPLE_CERTSEL ) { GroupCertSelected(pEapTlsUserDialog->hWndComboUserName, pEapTlsUserDialog->pGroupedList, &(pEapTlsUserDialog->pCert), &(pEapTlsUserDialog->pUserProp->Hash)); } else { CertSelected(pEapTlsUserDialog->hWndComboUserName, pEapTlsUserDialog->pCertList, &(pEapTlsUserDialog->pCert), &(pEapTlsUserDialog->pUserProp->Hash)); } if (NULL != pEapTlsUserDialog->hWndEditDiffUser) { dwTextLength = GetWindowTextLength( pEapTlsUserDialog->hWndEditDiffUser); // There is already one character in awszString. // Add the number of characters in DiffUser... dwNumChars = dwTextLength; // Add the number of characters in PIN... dwNumChars += wcslen(pEapTlsUserDialog->pUserProp->pwszPin); // Add one more for a terminating NULL. Use the extra character in // awszString for the other terminating NULL. dwNumChars += 1; dwSize = sizeof(EAPTLS_USER_PROPERTIES) + dwNumChars*sizeof(WCHAR); pUserProp = LocalAlloc(LPTR, dwSize); if (NULL == pUserProp) { EapTlsTrace("LocalAlloc in Command failed and returned %d", GetLastError()); } else { CopyMemory(pUserProp, pEapTlsUserDialog->pUserProp, sizeof(EAPTLS_USER_PROPERTIES)); pUserProp->dwSize = dwSize; pUserProp->pwszDiffUser = pUserProp->awszString; GetWindowText(pEapTlsUserDialog->hWndEditDiffUser, pUserProp->pwszDiffUser, dwTextLength + 1); pUserProp->dwPinOffset = dwTextLength + 1; pUserProp->pwszPin = pUserProp->awszString + pUserProp->dwPinOffset; wcscpy(pUserProp->pwszPin, pEapTlsUserDialog->pUserProp->pwszPin); ZeroMemory(pEapTlsUserDialog->pUserProp, pEapTlsUserDialog->pUserProp->dwSize); LocalFree(pEapTlsUserDialog->pUserProp); pEapTlsUserDialog->pUserProp = pUserProp; } } // Fall through case IDCANCEL: EndDialog(hWndDlg, wId); return(TRUE); default: return(FALSE); } } /* Returns: Notes: Callback function used with the DialogBoxParam function. It processes messages sent to the dialog box. See the DialogProc documentation in MSDN. */ INT_PTR CALLBACK UserDialogProc( IN HWND hWnd, IN UINT unMsg, IN WPARAM wParam, IN LPARAM lParam ) { EAPTLS_USER_DIALOG* pEapTlsUserDialog; switch (unMsg) { case WM_INITDIALOG: return(UserInitDialog(hWnd, lParam)); case WM_HELP: case WM_CONTEXTMENU: { ContextHelp(g_adwHelp, hWnd, unMsg, wParam, lParam); break; } case WM_COMMAND: pEapTlsUserDialog = (EAPTLS_USER_DIALOG*)GetWindowLongPtr(hWnd, DWLP_USER); return(UserCommand(pEapTlsUserDialog, HIWORD(wParam), LOWORD(wParam), hWnd, (HWND)lParam)); case WM_DESTROY: EndDialog(hWnd, IDCANCEL); break; } return(FALSE); } VOID CenterWindow(HWND hWnd, HWND hWndParent, BOOL bRightTop) { RECT rcWndParent, rcWnd; // Get the window rect for the parent window. // if (hWndParent == NULL) GetWindowRect(GetDesktopWindow(), &rcWndParent); else GetWindowRect(hWndParent, &rcWndParent); // Get the window rect for the window to be centered. // GetWindowRect(hWnd, &rcWnd); // Now center the window. // if (bRightTop) { SetWindowPos(hWnd, HWND_TOPMOST, rcWndParent.right - (rcWnd.right - rcWnd.left) - 5, GetSystemMetrics(SM_CYCAPTION) * 2, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); } else { SetWindowPos(hWnd, NULL, rcWndParent.left + (rcWndParent.right - rcWndParent.left - (rcWnd.right - rcWnd.left)) / 2, rcWndParent.top + (rcWndParent.bottom - rcWndParent.top - (rcWnd.bottom - rcWnd.top)) / 2, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW); } } void DeleteGroupedList(PEAPTLS_GROUPED_CERT_NODES pList) { PEAPTLS_GROUPED_CERT_NODES pTemp = NULL; while ( pList ) { pTemp = pList->pNext; LocalFree(pList); pList = pTemp; } } DWORD GroupCertificates ( EAPTLS_USER_DIALOG * pEapTlsUserDialog ) { DWORD dwRetCode = NO_ERROR; PEAPTLS_GROUPED_CERT_NODES pGroupList = NULL; PEAPTLS_GROUPED_CERT_NODES pGroupListTemp = NULL; EAPTLS_CERT_NODE* pCertList = pEapTlsUserDialog->pCertList; EAPTLS_CERT_NODE* pSelCert = NULL; BOOL fItemProcessed; EapTlsTrace("GroupCertificates"); // // This second pass to do grouping is not really required but // is good in case we add // something more to the groups later // while ( pCertList ) { pGroupListTemp = pGroupList; fItemProcessed = FALSE; while ( pGroupListTemp ) { if ( pCertList->pwszDisplayName && pGroupListTemp->pwszDisplayName && ! wcscmp( pCertList->pwszDisplayName, pGroupListTemp->pwszDisplayName ) ) { // // Found the group. Now check to see // if the new cert is more current than // the one we have in the group. If so, // if ( ! pGroupListTemp->pMostRecentCert ) { pGroupListTemp->pMostRecentCert = pCertList; fItemProcessed = TRUE; break; } else { if ( CompareFileTime ( &(pGroupListTemp->pMostRecentCert->IssueDate), &(pCertList->IssueDate) ) < 0 ) { pGroupListTemp->pMostRecentCert = pCertList; } //Or else drop the item. fItemProcessed = TRUE; break; } } pGroupListTemp = pGroupListTemp->pNext; } if ( !fItemProcessed && pCertList->pwszDisplayName) { // // need to create a new group // pGroupListTemp = (PEAPTLS_GROUPED_CERT_NODES)LocalAlloc(LPTR, sizeof(EAPTLS_GROUPED_CERT_NODES)); if ( NULL == pGroupListTemp ) { dwRetCode = ERROR_OUTOFMEMORY; goto LDone; } pGroupListTemp->pNext = pGroupList; pGroupListTemp->pwszDisplayName = pCertList->pwszDisplayName; pGroupListTemp->pMostRecentCert = pCertList; pGroupList = pGroupListTemp; } pCertList = pCertList->pNext; } // // now that we have grouped all the certs, check to see if // the cert previously used is in the list. If so, // pGroupListTemp = pGroupList; while ( pGroupListTemp ) { if ( pEapTlsUserDialog->pCert == pGroupListTemp->pMostRecentCert ) { pSelCert = pEapTlsUserDialog->pCert; break; } pGroupListTemp = pGroupListTemp->pNext; } pEapTlsUserDialog->pGroupedList = pGroupList ; pGroupList = NULL; if ( NULL == pSelCert ) { // // Selected cert is not in the group. // pEapTlsUserDialog->pCert = pEapTlsUserDialog->pGroupedList->pMostRecentCert; } LDone: DeleteGroupedList( pGroupList ); return dwRetCode; } /* Returns: Notes: ppwszIdentity can be NULL. Break up this ugly function. */ DWORD GetCertInfo( IN BOOL fServer, IN BOOL fRouterConfig, IN DWORD dwFlags, IN const WCHAR* pwszPhonebook, IN const WCHAR* pwszEntry, IN HWND hwndParent, IN WCHAR* pwszStoreName, IN EAPTLS_CONN_PROPERTIES_V1* pConnProp, IN OUT EAPTLS_USER_PROPERTIES** ppUserProp, OUT WCHAR** ppwszIdentity ) { INT_PTR nRet; HCERTSTORE hCertStore = NULL; CRYPT_HASH_BLOB HashBlob; PCCERT_CONTEXT pCertContext = NULL; DWORD dwCertFlags; BOOL fRouter; BOOL fDiffUser = FALSE; BOOL fGotIdentity = FALSE; WCHAR* pwszIdentity = NULL; WCHAR* pwszTemp; DWORD dwNumChars; BOOL fLogon; EAPTLS_USER_DIALOG EapTlsUserDialog; EAPTLS_PIN_DIALOG EapTlsPinDialog; EAPTLS_USER_PROPERTIES* pUserProp = NULL; EAPTLS_USER_PROPERTIES* pUserPropTemp; RASCREDENTIALS RasCredentials; DWORD dwErr = NO_ERROR; DWORD dwNumCerts = 0; HWND hWndStatus = NULL; RTASSERT(NULL != pwszStoreName); RTASSERT(NULL != pConnProp); RTASSERT(NULL != ppUserProp); RTASSERT(NULL != *ppUserProp); // ppwszIdentity can be NULL. fRouter = dwFlags & RAS_EAP_FLAG_ROUTER; fLogon = dwFlags & RAS_EAP_FLAG_LOGON; EapTlsTrace("GetCertInfo"); pUserProp = *ppUserProp; ZeroMemory(&EapTlsUserDialog, sizeof(EapTlsUserDialog)); ZeroMemory(&EapTlsPinDialog, sizeof(EapTlsPinDialog)); if (EAPTLS_CONN_FLAG_DIFF_USER & pConnProp->fFlags) { fDiffUser = TRUE; EapTlsUserDialog.fFlags |= EAPTLS_USER_DIALOG_FLAG_DIFF_USER; EapTlsPinDialog.fFlags |= EAPTLS_PIN_DIALOG_FLAG_DIFF_USER; } EapTlsUserDialog.pwszEntry = pwszEntry; EapTlsPinDialog.pwszEntry = pwszEntry; if ( fServer || fRouter || dwFlags & RAS_EAP_FLAG_MACHINE_AUTH //if this is a machine cert authentication ) { dwCertFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE; } else { dwCertFlags = CERT_SYSTEM_STORE_CURRENT_USER; EapTlsUserDialog.fFlags |= EAPTLS_USER_DIALOG_FLAG_DIFF_TITLE; } //Use simple cert selection logic if ( pConnProp->fFlags & EAPTLS_CONN_FLAG_SIMPLE_CERT_SEL ) { EapTlsUserDialog.fFlags |= EAPTLS_USER_DIALOG_FLAG_USE_SIMPLE_CERTSEL; } if (fLogon) { if (pConnProp->fFlags & EAPTLS_CONN_FLAG_REGISTRY) { dwErr = ERROR_NO_REG_CERT_AT_LOGON; goto LDone; } else { EapTlsPinDialog.fFlags |= EAPTLS_PIN_DIALOG_FLAG_LOGON; } } if ( fRouter ) { EapTlsPinDialog.fFlags |= EAPTLS_PIN_DIALOG_FLAG_ROUTER; } if ( !fServer && !(pConnProp->fFlags & EAPTLS_CONN_FLAG_REGISTRY)) { //this is smart card stuff BOOL fCredentialsFound = FALSE; BOOL fGotAllInfo = FALSE; if ( dwFlags & RAS_EAP_FLAG_MACHINE_AUTH ) { // // Machine auth requested along with // smart card auth so return an interactive // mode error. // dwErr = ERROR_INTERACTIVE_MODE; goto LDone; } hWndStatus = CreateDialogParam (GetResouceDLLHInstance(), MAKEINTRESOURCE(IDD_SCARD_STATUS), hwndParent, StatusDialogProc, 1 ); if ( NULL != hWndStatus ) { CenterWindow(hWndStatus, NULL, FALSE); ShowWindow(hWndStatus, SW_SHOW); UpdateWindow(hWndStatus); } if (!FSmartCardReaderInstalled()) { dwErr = ERROR_NO_SMART_CARD_READER; goto LDone; } if (pUserProp->fFlags & EAPTLS_USER_FLAG_SAVE_PIN) { ZeroMemory(&RasCredentials, sizeof(RasCredentials)); RasCredentials.dwSize = sizeof(RasCredentials); RasCredentials.dwMask = RASCM_Password; dwErr = RasGetCredentials(pwszPhonebook, pwszEntry, &RasCredentials); if ( (dwErr == NO_ERROR) && (RasCredentials.dwMask & RASCM_Password)) { fCredentialsFound = TRUE; } else { pUserProp->fFlags &= ~EAPTLS_USER_FLAG_SAVE_PIN; } dwErr = NO_ERROR; } if ( fCredentialsFound && ( !fDiffUser || (0 != pUserProp->pwszDiffUser[0]))) { fGotAllInfo = TRUE; } if ( !fGotAllInfo && (dwFlags & RAS_EAP_FLAG_NON_INTERACTIVE)) { dwErr = ERROR_INTERACTIVE_MODE; goto LDone; } dwErr = GetCertFromCard(&pCertContext); if (NO_ERROR != dwErr) { goto LDone; } //Check the time validity of the certificate //got from the card if ( !FCheckTimeValidity( pCertContext) ) { dwErr = CERT_E_EXPIRED; goto LDone; } pUserProp->Hash.cbHash = MAX_HASH_SIZE; if (!CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID, pUserProp->Hash.pbHash, &(pUserProp->Hash.cbHash))) { dwErr = GetLastError(); EapTlsTrace("CertGetCertificateContextProperty failed and " "returned 0x%x", dwErr); goto LDone; } EapTlsPinDialog.pUserProp = pUserProp; if ( !fDiffUser || (0 == pUserProp->pwszDiffUser[0])) { if (!FCertToStr(pCertContext, 0, fRouter, &pwszIdentity)) { dwErr = E_FAIL; goto LDone; } dwErr = AllocUserDataWithNewIdentity(pUserProp, pwszIdentity, &pUserPropTemp); LocalFree(pwszIdentity); pwszIdentity = NULL; if (NO_ERROR != dwErr) { goto LDone; } LocalFree(pUserProp); EapTlsPinDialog.pUserProp = pUserProp = *ppUserProp = pUserPropTemp; } if (fCredentialsFound) { dwErr = AllocUserDataWithNewPin( pUserProp, (PBYTE)RasCredentials.szPassword, lstrlen(RasCredentials.szPassword), &pUserPropTemp); if (NO_ERROR != dwErr) { goto LDone; } LocalFree(pUserProp); EapTlsPinDialog.pUserProp = pUserProp = *ppUserProp = pUserPropTemp; } EapTlsPinDialog.pCertContext = pCertContext; if ( !fGotAllInfo || (dwFlags & RAS_EAP_FLAG_PREVIEW)) { if ( NULL != hWndStatus ) { DestroyWindow(hWndStatus); hWndStatus = NULL; } nRet = DialogBoxParam( GetHInstance(), MAKEINTRESOURCE(IDD_USERNAME_PIN_UI), hwndParent, PinDialogProc, (LPARAM)&EapTlsPinDialog); // EapTlsPinDialog.pUserProp may have been realloced pUserProp = *ppUserProp = EapTlsPinDialog.pUserProp; if (-1 == nRet) { dwErr = GetLastError(); goto LDone; } else if (IDOK != nRet) { dwErr = ERROR_CANCELLED; goto LDone; } ZeroMemory(&RasCredentials, sizeof(RasCredentials)); RasCredentials.dwSize = sizeof(RasCredentials); RasCredentials.dwMask = RASCM_Password; if (EapTlsPinDialog.pUserProp->fFlags & EAPTLS_USER_FLAG_SAVE_PIN) { wcscpy(RasCredentials.szPassword, EapTlsPinDialog.pUserProp->pwszPin); RasSetCredentials(pwszPhonebook, pwszEntry, &RasCredentials, FALSE /* fClearCredentials */); } else { RasSetCredentials(pwszPhonebook, pwszEntry, &RasCredentials, TRUE /* fClearCredentials */); } } EncodePin(EapTlsPinDialog.pUserProp); pwszIdentity = LocalAlloc(LPTR, (wcslen(pUserProp->pwszDiffUser) + 1) * sizeof(WCHAR)); if (NULL == pwszIdentity) { dwErr = GetLastError(); EapTlsTrace("LocalAlloc failed and returned %d", dwErr); goto LDone; } wcscpy(pwszIdentity, pUserProp->pwszDiffUser); if (NULL != ppwszIdentity) { *ppwszIdentity = pwszIdentity; pwszIdentity = NULL; } if (!fDiffUser) { pUserProp->pwszDiffUser[0] = 0; } if ( EapTlsPinDialog.dwRetCode != NO_ERROR ) dwErr = EapTlsPinDialog.dwRetCode ; goto LDone; } dwCertFlags |= CERT_STORE_READONLY_FLAG; hCertStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_W, X509_ASN_ENCODING, 0, dwCertFlags, pwszStoreName); if (NULL == hCertStore) { dwErr = GetLastError(); EapTlsTrace("CertOpenStore failed and returned 0x%x", dwErr); goto LDone; } if ( ( dwFlags & RAS_EAP_FLAG_MACHINE_AUTH) ) { //if this is not machine authentication //This is propably not the best way to do things. //We should provide a way in which //Get the default machine certificate and //populate the out data structures... dwErr = GetDefaultClientMachineCert(hCertStore, &pCertContext ); if ( NO_ERROR == dwErr ) { EapTlsTrace("Got the default Machine Cert"); pUserProp->Hash.cbHash = MAX_HASH_SIZE; if (!CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID, pUserProp->Hash.pbHash, &(pUserProp->Hash.cbHash))) { dwErr = GetLastError(); EapTlsTrace("CertGetCertificateContextProperty failed and " "returned 0x%x", dwErr); } pUserProp->pwszDiffUser[0] = 0; if ( FMachineAuthCertToStr(pCertContext, &pwszIdentity)) { //format the identity in the domain\machinename format. FFormatMachineIdentity1 (pwszIdentity, ppwszIdentity ); pwszIdentity = NULL; } else { //if not possible get it from the subject field if ( FCertToStr(pCertContext, 0, TRUE, &pwszIdentity)) { //format the identity in the domain\machinename format. FFormatMachineIdentity1 (pwszIdentity, ppwszIdentity ); pwszIdentity = NULL; } } *ppUserProp = pUserProp; } goto LDone; } HashBlob.cbData = pUserProp->Hash.cbHash; HashBlob.pbData = pUserProp->Hash.pbHash; pCertContext = CertFindCertificateInStore(hCertStore, X509_ASN_ENCODING, 0, CERT_FIND_HASH, &HashBlob, NULL); if ( (NULL == pCertContext) || ( fDiffUser && (0 == pUserProp->pwszDiffUser[0]))) { // We don't have complete information. Note that for registry certs, // pwszDiffUser is not a different dialog. if (fServer) { dwErr = GetDefaultMachineCert(hCertStore, &pCertContext); if (NO_ERROR == dwErr) { pUserProp->Hash.cbHash = MAX_HASH_SIZE; if (!CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID, pUserProp->Hash.pbHash, &(pUserProp->Hash.cbHash))) { dwErr = GetLastError(); EapTlsTrace("CertGetCertificateContextProperty failed and " "returned 0x%x", dwErr); } } dwErr = NO_ERROR; } } else { if ( !fServer && !fRouterConfig && !(dwFlags & RAS_EAP_FLAG_PREVIEW) && !(FCheckSCardCertAndCanOpenSilentContext ( pCertContext )) ) { fGotIdentity = FALSE; if (!fDiffUser) { pUserProp->pwszDiffUser[0] = 0; } if ( fDiffUser && (pUserProp->pwszDiffUser[0])) { pwszIdentity = LocalAlloc(LPTR, (wcslen(pUserProp->pwszDiffUser)+1) * sizeof(WCHAR));; if (NULL == pwszIdentity) { dwErr = GetLastError(); EapTlsTrace("LocalAlloc failed and returned %d", dwErr); goto LDone; } wcscpy(pwszIdentity, pUserProp->pwszDiffUser); EapTlsTrace("(saved) Sending EAP identity %ws", pwszIdentity); fGotIdentity = TRUE; } else if (FCertToStr(pCertContext, 0, fRouter, &pwszIdentity)) { EapTlsTrace("(saved) The name in the certificate is: %ws", pwszIdentity); fGotIdentity = TRUE; } if (fGotIdentity) { RTASSERT(NULL != ppwszIdentity); *ppwszIdentity = pwszIdentity; pwszIdentity = NULL; goto LDone; } } } EapTlsUserDialog.pUserProp = pUserProp; CreateCertList( fServer, fRouter, FALSE /* fRoot */, &(EapTlsUserDialog.pCertList), &(EapTlsUserDialog.pCert), 1, &(EapTlsUserDialog.pUserProp->Hash), pwszStoreName); if (NULL == EapTlsUserDialog.pCertList) { dwErr = ERROR_NO_EAPTLS_CERTIFICATE; if (fServer || fRouter) { if (dwFlags & RAS_EAP_FLAG_NON_INTERACTIVE) { dwErr = ERROR_INTERACTIVE_MODE; goto LDone; } DisplayError(hwndParent, dwErr); } goto LDone; } else { if ( NULL == EapTlsUserDialog.pCert ) { EapTlsUserDialog.pCert = EapTlsUserDialog.pCertList; } EapTlsUserDialog.pwszStoreName = pwszStoreName; if ( !fServer && !fRouter ) { // if this is a client - not a server and not a router // There are more than one certificates or the user has // chosen to provide different identity // if ( EapTlsUserDialog.pCertList->pNext || EapTlsUserDialog.fFlags & EAPTLS_USER_DIALOG_FLAG_DIFF_USER ) { if (dwFlags & RAS_EAP_FLAG_NON_INTERACTIVE) { dwErr = ERROR_INTERACTIVE_MODE; goto LDone; } // // Group Certs for the client UI // if ( !fServer ) { if ( EapTlsUserDialog.fFlags & EAPTLS_USER_DIALOG_FLAG_USE_SIMPLE_CERTSEL ) { // // Grouping is done only if it is specified in // the connection properties // dwErr = GroupCertificates (&EapTlsUserDialog); if ( NO_ERROR != dwErr ) { EapTlsTrace("Error grouping certificates. 0x%x", dwErr ); goto LDone; } } // // Now check to see if we have only one group // if ( EapTlsUserDialog.fFlags & EAPTLS_USER_DIALOG_FLAG_USE_SIMPLE_CERTSEL && !(EapTlsUserDialog.fFlags & EAPTLS_USER_DIALOG_FLAG_DIFF_USER ) && !(EapTlsUserDialog.pGroupedList->pNext) ) { // // only one group. So select the cert and use it // CertSelected(NULL, EapTlsUserDialog.pCertList, &(EapTlsUserDialog.pGroupedList->pMostRecentCert), &(EapTlsUserDialog.pUserProp->Hash) ); } else { EapTlsUserDialog.fIdentity = TRUE; nRet = DialogBoxParam( GetResouceDLLHInstance(), MAKEINTRESOURCE(IDD_IDENTITY_UI), hwndParent, UserDialogProc, (LPARAM)&EapTlsUserDialog); if (-1 == nRet) { dwErr = GetLastError(); goto LDone; } else if (IDOK != nRet) { dwErr = ERROR_CANCELLED; goto LDone; } } } else { // // No server side code on XPSP1 to save on resources // #if 0 nRet = DialogBoxParam( GetHInstance(), MAKEINTRESOURCE(IDD_SERVER_UI), hwndParent, UserDialogProc, (LPARAM)&EapTlsUserDialog); if (-1 == nRet) { dwErr = GetLastError(); goto LDone; } else if (IDOK != nRet) { dwErr = ERROR_CANCELLED; goto LDone; } #endif } // EapTlsUserDialog.pUserProp may have been realloced pUserProp = *ppUserProp = EapTlsUserDialog.pUserProp; } else { // // There is only one relevant certificate so auto select it. // CertSelected(NULL, EapTlsUserDialog.pCertList, &(EapTlsUserDialog.pCert), &(EapTlsUserDialog.pUserProp->Hash)); } } else { if (dwFlags & RAS_EAP_FLAG_NON_INTERACTIVE) { dwErr = ERROR_INTERACTIVE_MODE; goto LDone; } if ( EapTlsUserDialog.fFlags & EAPTLS_USER_DIALOG_FLAG_USE_SIMPLE_CERTSEL ) { // // Grouping is done only if it is specified in // the connection properties // dwErr = GroupCertificates (&EapTlsUserDialog); if ( NO_ERROR != dwErr ) { EapTlsTrace("Error grouping certificates. 0x%x", dwErr ); goto LDone; } } // // No server side UI on the client for XPSP1 to save on resources // nRet = DialogBoxParam( GetResouceDLLHInstance(), MAKEINTRESOURCE(IDD_IDENTITY_UI), hwndParent, UserDialogProc, (LPARAM)&EapTlsUserDialog); #if 0 nRet = DialogBoxParam( GetHInstance(), MAKEINTRESOURCE(fServer ? IDD_SERVER_UI : IDD_IDENTITY_UI), hwndParent, UserDialogProc, (LPARAM)&EapTlsUserDialog); #endif // EapTlsUserDialog.pUserProp may have been realloced pUserProp = *ppUserProp = EapTlsUserDialog.pUserProp; if (-1 == nRet) { dwErr = GetLastError(); goto LDone; } else if (IDOK != nRet) { dwErr = ERROR_CANCELLED; goto LDone; } } } if (NULL != EapTlsUserDialog.pCert) { if ( fDiffUser && (0 != EapTlsUserDialog.pUserProp->pwszDiffUser[0])) { pwszTemp = EapTlsUserDialog.pUserProp->pwszDiffUser; } else { pwszTemp = EapTlsUserDialog.pCert->pwszDisplayName; } pwszIdentity = LocalAlloc(LPTR, (wcslen(pwszTemp) + 1)*sizeof(WCHAR)); if (NULL == pwszIdentity) { dwErr = GetLastError(); EapTlsTrace("LocalAlloc failed and returned %d", dwErr); goto LDone; } wcscpy(pwszIdentity, pwszTemp); if (NULL != ppwszIdentity) { *ppwszIdentity = pwszIdentity; pwszIdentity = NULL; } } LDone: if ( NULL != hWndStatus ) { DestroyWindow(hWndStatus); hWndStatus = NULL; } if (NULL != pCertContext) { CertFreeCertificateContext(pCertContext); // Always returns TRUE; } if (NULL != hCertStore) { if (!CertCloseStore(hCertStore, 0)) { EapTlsTrace("CertCloseStore failed and returned 0x%x", GetLastError()); } } if ( pwszIdentity ) LocalFree(pwszIdentity); FreeCertList(EapTlsUserDialog.pCertList); ZeroMemory(&RasCredentials, sizeof(RasCredentials)); return(dwErr); } /* Returns: FALSE (prevent Windows from setting the default keyboard focus). Notes: Response to the WM_INITDIALOG message (Config UI). */ BOOL ConnInitDialog( IN HWND hWnd, IN LPARAM lParam ) { EAPTLS_CONN_DIALOG* pEapTlsConnDialog; LVCOLUMN lvColumn; SetWindowLongPtr(hWnd, DWLP_USER, lParam); pEapTlsConnDialog = (EAPTLS_CONN_DIALOG*)lParam; pEapTlsConnDialog->hWndRadioUseCard = GetDlgItem(hWnd, IDC_RADIO_USE_CARD); pEapTlsConnDialog->hWndRadioUseRegistry = GetDlgItem(hWnd, IDC_RADIO_USE_REGISTRY); pEapTlsConnDialog->hWndCheckValidateCert = GetDlgItem(hWnd, IDC_CHECK_VALIDATE_CERT); pEapTlsConnDialog->hWndCheckValidateName = GetDlgItem(hWnd, IDC_CHECK_VALIDATE_NAME); pEapTlsConnDialog->hWndEditServerName = GetDlgItem(hWnd, IDC_EDIT_SERVER_NAME); pEapTlsConnDialog->hWndStaticRootCaName = GetDlgItem(hWnd, IDC_STATIC_ROOT_CA_NAME); //pEapTlsConnDialog->hWndComboRootCaName = // GetDlgItem(hWnd, IDC_COMBO_ROOT_CA_NAME); pEapTlsConnDialog->hWndListRootCaName = GetDlgItem(hWnd, IDC_LIST_ROOT_CA_NAME); pEapTlsConnDialog->hWndCheckDiffUser = GetDlgItem(hWnd, IDC_CHECK_DIFF_USER); pEapTlsConnDialog->hWndCheckUseSimpleSel = GetDlgItem(hWnd, IDC_CHECK_USE_SIMPLE_CERT_SEL); pEapTlsConnDialog->hWndViewCertDetails = GetDlgItem(hWnd, IDC_BUTTON_VIEW_CERTIFICATE); //Set the style to set list boxes. ListView_SetExtendedListViewStyle ( pEapTlsConnDialog->hWndListRootCaName, ListView_GetExtendedListViewStyle(pEapTlsConnDialog->hWndListRootCaName) | LVS_EX_CHECKBOXES ); ZeroMemory ( &lvColumn, sizeof(lvColumn)); lvColumn.fmt = LVCFMT_LEFT; ListView_InsertColumn( pEapTlsConnDialog->hWndListRootCaName, 0, &lvColumn ); ListView_SetColumnWidth(pEapTlsConnDialog->hWndListRootCaName, 0, LVSCW_AUTOSIZE_USEHEADER ); // //Now we need to init the //list box with all the certs and selected cert InitListBox ( pEapTlsConnDialog->hWndListRootCaName, pEapTlsConnDialog->pCertList, pEapTlsConnDialog->pConnPropv1->dwNumHashes, pEapTlsConnDialog->ppSelCertList ); SetWindowText(pEapTlsConnDialog->hWndEditServerName, (LPWSTR )(pEapTlsConnDialog->pConnPropv1->bData + sizeof( EAPTLS_HASH ) * pEapTlsConnDialog->pConnPropv1->dwNumHashes) ); if (pEapTlsConnDialog->fFlags & EAPTLS_CONN_DIALOG_FLAG_ROUTER) { pEapTlsConnDialog->pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_REGISTRY; EnableWindow(pEapTlsConnDialog->hWndRadioUseCard, FALSE); } CheckRadioButton(hWnd, IDC_RADIO_USE_CARD, IDC_RADIO_USE_REGISTRY, (pEapTlsConnDialog->pConnPropv1->fFlags & EAPTLS_CONN_FLAG_REGISTRY) ? IDC_RADIO_USE_REGISTRY : IDC_RADIO_USE_CARD); CheckDlgButton(hWnd, IDC_CHECK_VALIDATE_CERT, (pEapTlsConnDialog->pConnPropv1->fFlags & EAPTLS_CONN_FLAG_NO_VALIDATE_CERT) ? BST_UNCHECKED : BST_CHECKED); CheckDlgButton(hWnd, IDC_CHECK_VALIDATE_NAME, (pEapTlsConnDialog->pConnPropv1->fFlags & EAPTLS_CONN_FLAG_NO_VALIDATE_NAME) ? BST_UNCHECKED : BST_CHECKED); CheckDlgButton(hWnd, IDC_CHECK_DIFF_USER, (pEapTlsConnDialog->pConnPropv1->fFlags & EAPTLS_CONN_FLAG_DIFF_USER) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hWnd, IDC_CHECK_USE_SIMPLE_CERT_SEL, (pEapTlsConnDialog->pConnPropv1->fFlags & EAPTLS_CONN_FLAG_SIMPLE_CERT_SEL) ? BST_CHECKED : BST_UNCHECKED); EnableValidateNameControls(pEapTlsConnDialog); // // Check to see if we are in readonly mode // If so, disable the OK button and // make the dialog go into readonly mode // return(FALSE); } DWORD GetSelCertContext(EAPTLS_CERT_NODE* pCertList, int nIndex, HCERTSTORE * phCertStore, LPWSTR pwszStoreName, PCCERT_CONTEXT * ppCertContext ) { PCCERT_CONTEXT pCertContext = NULL; EAPTLS_CERT_NODE * pTemp = pCertList; DWORD dwErr= NO_ERROR; HCERTSTORE hStore = NULL; CRYPT_HASH_BLOB chb; if ( nIndex >= 0 ) { pTemp = pTemp->pNext; while ( nIndex && pTemp ) { pTemp = pTemp->pNext; nIndex --; } } if ( pTemp ) { *phCertStore = CertOpenStore (CERT_STORE_PROV_SYSTEM, 0, 0, CERT_STORE_READONLY_FLAG |CERT_SYSTEM_STORE_CURRENT_USER, pwszStoreName ); if ( !*phCertStore ) { dwErr = GetLastError(); goto LDone; } chb.cbData = pTemp->Hash.cbHash; chb.pbData = pTemp->Hash.pbHash; pCertContext = CertFindCertificateInStore( *phCertStore, 0, 0, CERT_FIND_HASH, &chb, 0); if ( NULL == pCertContext ) { dwErr = GetLastError(); } } else { dwErr = ERROR_NOT_FOUND; goto LDone; } *ppCertContext = pCertContext; LDone: if ( NO_ERROR != dwErr ) { if ( pCertContext ) CertFreeCertificateContext(pCertContext); if ( *phCertStore ) CertCloseStore( *phCertStore, CERT_CLOSE_STORE_FORCE_FLAG ); } return dwErr; } /* Returns: TRUE: We prrocessed this message. FALSE: We did not prrocess this message. Notes: Response to the WM_COMMAND message (Config UI). */ BOOL ConnCommand( IN EAPTLS_CONN_DIALOG* pEapTlsConnDialog, IN WORD wNotifyCode, IN WORD wId, IN HWND hWndDlg, IN HWND hWndCtrl ) { DWORD dwNumChars; EAPTLS_CONN_PROPERTIES_V1 * pConnProp; switch(wId) { case IDC_RADIO_USE_CARD: pEapTlsConnDialog->pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_REGISTRY; pEapTlsConnDialog->pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_SIMPLE_CERT_SEL; EnableValidateNameControls(pEapTlsConnDialog); return(TRUE); case IDC_RADIO_USE_REGISTRY: pEapTlsConnDialog->pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_REGISTRY; pEapTlsConnDialog->pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_SIMPLE_CERT_SEL; CheckDlgButton(hWndDlg, IDC_CHECK_USE_SIMPLE_CERT_SEL, BST_CHECKED); EnableValidateNameControls(pEapTlsConnDialog); return(TRUE); case IDC_CHECK_USE_SIMPLE_CERT_SEL: if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_USE_SIMPLE_CERT_SEL)) { pEapTlsConnDialog->pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_SIMPLE_CERT_SEL; } else { pEapTlsConnDialog->pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_SIMPLE_CERT_SEL; } return TRUE; case IDC_CHECK_VALIDATE_CERT: if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_VALIDATE_CERT)) { pEapTlsConnDialog->pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_NO_VALIDATE_CERT; pEapTlsConnDialog->pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_NO_VALIDATE_NAME; CheckDlgButton(hWndDlg, IDC_CHECK_VALIDATE_NAME, BST_CHECKED); } else { pEapTlsConnDialog->pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_NO_VALIDATE_CERT; pEapTlsConnDialog->pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_NO_VALIDATE_NAME; CheckDlgButton(hWndDlg, IDC_CHECK_VALIDATE_NAME, BST_UNCHECKED); } EnableValidateNameControls(pEapTlsConnDialog); return(TRUE); case IDC_CHECK_VALIDATE_NAME: if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_VALIDATE_NAME)) { pEapTlsConnDialog->pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_NO_VALIDATE_NAME; } else { pEapTlsConnDialog->pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_NO_VALIDATE_NAME; } EnableValidateNameControls(pEapTlsConnDialog); return(TRUE); case IDC_CHECK_DIFF_USER: if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_DIFF_USER)) { pEapTlsConnDialog->pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_DIFF_USER; } else { pEapTlsConnDialog->pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_DIFF_USER; } return(TRUE); case IDC_BUTTON_VIEW_CERTIFICATE: { //Show cert details here INT nIndex = -1; HCERTSTORE hCertStore = NULL; PCCERT_CONTEXT pCertContext = NULL; LVITEM lvItem; nIndex = ListView_GetNextItem(pEapTlsConnDialog->hWndListRootCaName, -1, LVNI_SELECTED ); if ( nIndex >= 0 ) { ZeroMemory( &lvItem, sizeof(lvItem) ); lvItem.iItem = nIndex; lvItem.mask = LVIF_PARAM; ListView_GetItem ( pEapTlsConnDialog->hWndListRootCaName, &lvItem ); if ( NO_ERROR == GetSelCertContext( (EAPTLS_CERT_NODE*)(lvItem.lParam), -1, &hCertStore, L"ROOT", &pCertContext ) ) { ShowCertDetails( hWndDlg, hCertStore, pCertContext ); CertFreeCertificateContext(pCertContext); CertCloseStore( hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ); } } } return TRUE; case IDOK: { EAPTLS_HASH * pHash = NULL; DWORD dwNumHash = 0; DWORD dwSelCount = 0; EAPTLS_CERT_NODE ** ppSelCertList = NULL; WCHAR wszTitle[200] = {0}; WCHAR wszMessage[200] = {0}; CertListSelectedCount ( pEapTlsConnDialog->hWndListRootCaName, &dwSelCount ); if ( pEapTlsConnDialog->fFlags & EAPTLS_CONN_DIALOG_FLAG_ROUTER) { // // If we are a router, // check to see if Validate Server certificate is selected // and no cert is selected. // Also, check to see if server name is checked and no server's // are entered. // if ( !( pEapTlsConnDialog->pConnPropv1->fFlags & EAPTLS_CONN_FLAG_NO_VALIDATE_CERT) && 0 == dwSelCount ) { LoadString ( GetHInstance(), IDS_CANT_CONFIGURE_SERVER_TITLE, wszTitle, sizeof(wszTitle)/sizeof(WCHAR) ); LoadString ( GetResouceDLLHInstance(), IDS_NO_ROOT_CERT, wszMessage, sizeof(wszMessage)/sizeof(WCHAR) ); MessageBox ( GetFocus(), wszMessage, wszTitle, MB_OK|MB_ICONWARNING ); return TRUE; } if ( !( pEapTlsConnDialog->pConnPropv1->fFlags & EAPTLS_CONN_FLAG_NO_VALIDATE_NAME) && !GetWindowTextLength(pEapTlsConnDialog->hWndEditServerName) ) { // // Nothing entered in server name field // LoadString ( GetHInstance(), IDS_CANT_CONFIGURE_SERVER_TITLE, wszTitle, sizeof(wszTitle)/sizeof(WCHAR) ); LoadString ( GetResouceDLLHInstance(), IDS_NO_SERVER_NAME, wszMessage, sizeof(wszMessage)/sizeof(WCHAR) ); MessageBox ( GetFocus(), wszMessage, wszTitle, MB_OK|MB_ICONWARNING ); return TRUE; } } if ( dwSelCount > 0 ) { ppSelCertList = (EAPTLS_CERT_NODE **)LocalAlloc(LPTR, sizeof(EAPTLS_CERT_NODE *) * dwSelCount ); if ( NULL == ppSelCertList ) { EapTlsTrace("LocalAlloc in Command failed and returned %d", GetLastError()); return TRUE; } pHash = (EAPTLS_HASH *)LocalAlloc(LPTR, sizeof(EAPTLS_HASH ) * dwSelCount ); if ( NULL == pHash ) { EapTlsTrace("LocalAlloc in Command failed and returned %d", GetLastError()); return TRUE; } CertListSelected( pEapTlsConnDialog->hWndListRootCaName, pEapTlsConnDialog->pCertList, ppSelCertList, pHash, dwSelCount ); } dwNumChars = GetWindowTextLength(pEapTlsConnDialog->hWndEditServerName); pConnProp = LocalAlloc( LPTR, sizeof(EAPTLS_CONN_PROPERTIES_V1) + sizeof(EAPTLS_HASH) * dwSelCount + dwNumChars * sizeof(WCHAR) + sizeof(WCHAR) //one for null. ); if (NULL == pConnProp) { EapTlsTrace("LocalAlloc in Command failed and returned %d", GetLastError()); } else { CopyMemory( pConnProp, pEapTlsConnDialog->pConnPropv1, sizeof(EAPTLS_CONN_PROPERTIES_V1) ); pConnProp->dwSize = sizeof(EAPTLS_CONN_PROPERTIES_V1) + sizeof(EAPTLS_HASH) * dwSelCount + dwNumChars * sizeof(WCHAR); CopyMemory ( pConnProp->bData, pHash, sizeof(EAPTLS_HASH) * dwSelCount ); pConnProp->dwNumHashes = dwSelCount; GetWindowText(pEapTlsConnDialog->hWndEditServerName, (LPWSTR)(pConnProp->bData + sizeof(EAPTLS_HASH) * dwSelCount) , dwNumChars + 1); LocalFree(pEapTlsConnDialog->pConnPropv1); if ( pEapTlsConnDialog->ppSelCertList ) LocalFree(pEapTlsConnDialog->ppSelCertList); pEapTlsConnDialog->ppSelCertList = ppSelCertList; pEapTlsConnDialog->pConnPropv1 = pConnProp; } } // Fall through case IDCANCEL: EndDialog(hWndDlg, wId); return(TRUE); default: return(FALSE); } } BOOL ConnNotify( EAPTLS_CONN_DIALOG *pEaptlsConnDialog, WPARAM wParam, LPARAM lParam, HWND hWnd ) { HCERTSTORE hCertStore = NULL; PCCERT_CONTEXT pCertContext = NULL; LPNMITEMACTIVATE lpnmItem; LVITEM lvItem; if ( wParam == IDC_LIST_ROOT_CA_NAME ) { lpnmItem = (LPNMITEMACTIVATE) lParam; if ( lpnmItem->hdr.code == NM_DBLCLK ) { ZeroMemory(&lvItem, sizeof(lvItem) ); lvItem.mask = LVIF_PARAM; lvItem.iItem = lpnmItem->iItem; ListView_GetItem(lpnmItem->hdr.hwndFrom, &lvItem); if ( NO_ERROR == GetSelCertContext( //pEaptlsConnDialog->pCertList, (EAPTLS_CERT_NODE*)(lvItem.lParam) , -1, &hCertStore, L"ROOT", &pCertContext ) ) { ShowCertDetails( hWnd, hCertStore, pCertContext ); CertFreeCertificateContext(pCertContext); CertCloseStore( hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ); return TRUE; } return TRUE; } } return FALSE; } /* Returns: Notes: Callback function used with the Config UI DialogBoxParam function. It processes messages sent to the dialog box. See the DialogProc documentation in MSDN. */ INT_PTR CALLBACK ConnDialogProc( IN HWND hWnd, IN UINT unMsg, IN WPARAM wParam, IN LPARAM lParam ) { EAPTLS_CONN_DIALOG* pEapTlsConnDialog; switch (unMsg) { case WM_INITDIALOG: return(ConnInitDialog(hWnd, lParam)); case WM_HELP: case WM_CONTEXTMENU: { ContextHelp(g_adwHelp, hWnd, unMsg, wParam, lParam); break; } case WM_NOTIFY: { pEapTlsConnDialog = (EAPTLS_CONN_DIALOG*)GetWindowLongPtr(hWnd, DWLP_USER); return ConnNotify( pEapTlsConnDialog, wParam, lParam, hWnd ); } case WM_COMMAND: pEapTlsConnDialog = (EAPTLS_CONN_DIALOG*)GetWindowLongPtr(hWnd, DWLP_USER); return(ConnCommand(pEapTlsConnDialog, HIWORD(wParam), LOWORD(wParam), hWnd, (HWND)lParam)); } return(FALSE); } DWORD RasEapTlsInvokeConfigUI( IN DWORD dwEapTypeId, IN HWND hwndParent, IN DWORD dwFlags, IN BYTE* pConnectionDataIn, IN DWORD dwSizeOfConnectionDataIn, OUT BYTE** ppConnectionDataOut, OUT DWORD* pdwSizeOfConnectionDataOut ) { DWORD dwErr = NO_ERROR; BOOL fRouter = FALSE; INT_PTR nRet; EAPTLS_CONN_DIALOG EapTlsConnDialog; RTASSERT(NULL != ppConnectionDataOut); RTASSERT(NULL != pdwSizeOfConnectionDataOut); EapTlsInitialize2(TRUE, TRUE /* fUI */); *ppConnectionDataOut = NULL; *pdwSizeOfConnectionDataOut = 0; ZeroMemory(&EapTlsConnDialog, sizeof(EAPTLS_CONN_DIALOG)); if (dwFlags & RAS_EAP_FLAG_ROUTER) { fRouter = TRUE; EapTlsConnDialog.fFlags = EAPTLS_CONN_DIALOG_FLAG_ROUTER; } #if 0 if ( dwFlags & RAS_EAP_FLAG_READ_ONLY_UI ) { EapTlsConnDialog.fFlags |= EAPTLS_CONN_DIALOG_FLAG_READONLY; } #endif dwErr = ReadConnectionData( ( dwFlags & RAS_EAP_FLAG_8021X_AUTH ), pConnectionDataIn, dwSizeOfConnectionDataIn, &(EapTlsConnDialog.pConnProp) ); if (NO_ERROR != dwErr) { goto LDone; } dwErr = ConnPropGetV1Struct ( EapTlsConnDialog.pConnProp, &(EapTlsConnDialog.pConnPropv1) ); if ( NO_ERROR != dwErr ) { goto LDone; } // //if there are certificates that need to be selected, allocate //memory upfront for them // if ( EapTlsConnDialog.pConnPropv1->dwNumHashes ) { EapTlsConnDialog.ppSelCertList = (EAPTLS_CERT_NODE **)LocalAlloc(LPTR, sizeof(EAPTLS_CERT_NODE *) * EapTlsConnDialog.pConnPropv1->dwNumHashes ); if ( NULL == EapTlsConnDialog.ppSelCertList ) { dwErr = GetLastError(); EapTlsTrace("LocalAlloc failed and returned %d", dwErr); goto LDone; } } CreateCertList( FALSE /* fServer */, fRouter, TRUE /* fRoot */, &(EapTlsConnDialog.pCertList), //lined list of all certs in the store. EapTlsConnDialog.ppSelCertList, //list of selected certificates - null if nothing's in the list EapTlsConnDialog.pConnPropv1->dwNumHashes, (EAPTLS_HASH*)(EapTlsConnDialog.pConnPropv1->bData), L"ROOT" ); nRet = DialogBoxParam( GetResouceDLLHInstance(), MAKEINTRESOURCE(IDD_CONFIG_UI), hwndParent, ConnDialogProc, (LPARAM)&EapTlsConnDialog); if (-1 == nRet) { dwErr = GetLastError(); goto LDone; } else if (IDOK != nRet) { dwErr = ERROR_CANCELLED; goto LDone; } // //Convert the connpropv1 back to connpropv0 + extra cludge //here // RTASSERT(NULL != EapTlsConnDialog.pConnPropv1); dwErr = ConnPropGetV0Struct ( EapTlsConnDialog.pConnPropv1, (EAPTLS_CONN_PROPERTIES ** )ppConnectionDataOut ); if ( NO_ERROR != dwErr ) { goto LDone; } *pdwSizeOfConnectionDataOut = ((EAPTLS_CONN_PROPERTIES * )*ppConnectionDataOut)->dwSize; LDone: EapTlsInitialize2(FALSE, TRUE /* fUI */); FreeCertList(EapTlsConnDialog.pCertList); if ( EapTlsConnDialog.ppSelCertList ) { LocalFree( EapTlsConnDialog.ppSelCertList ); EapTlsConnDialog.ppSelCertList = NULL; } LocalFree( EapTlsConnDialog.pConnProp ); LocalFree( EapTlsConnDialog.pConnPropv1 ); return dwErr; } DWORD RasEapPeapInvokeConfigUI( IN DWORD dwEapTypeId, IN HWND hwndParent, IN DWORD dwFlags, IN BYTE* pConnectionDataIn, IN DWORD dwSizeOfConnectionDataIn, OUT BYTE** ppConnectionDataOut, OUT DWORD* pdwSizeOfConnectionDataOut ) { DWORD dwRetCode = NO_ERROR; PEAP_CONN_DIALOG PeapConnDialog; BOOL fRouter = FALSE; INT_PTR nRet; // // Do the following here: // // Get a list of Root Certs: // Get the list of all the eaptypes registered for PEAP: // and set in in the GUI // EapTlsInitialize2(TRUE, TRUE /* fUI */); *ppConnectionDataOut = NULL; *pdwSizeOfConnectionDataOut = 0; ZeroMemory(&PeapConnDialog, sizeof(PEAP_CONN_DIALOG)); if (dwFlags & RAS_EAP_FLAG_ROUTER) { fRouter = TRUE; PeapConnDialog.fFlags = PEAP_CONN_DIALOG_FLAG_ROUTER; } if ( dwFlags & RAS_EAP_FLAG_8021X_AUTH ) { PeapConnDialog.fFlags |= PEAP_CONN_DIALOG_FLAG_8021x; } dwRetCode = PeapReadConnectionData(( dwFlags & RAS_EAP_FLAG_8021X_AUTH ), pConnectionDataIn, dwSizeOfConnectionDataIn, &(PeapConnDialog.pConnProp)); if (NO_ERROR != dwRetCode) { goto LDone; } // //if there are certificates that need to be selected, allocate //memory upfront for them // if ( PeapConnDialog.pConnProp->EapTlsConnProp.dwNumHashes ) { PeapConnDialog.ppSelCertList = (EAPTLS_CERT_NODE **)LocalAlloc(LPTR, sizeof(EAPTLS_CERT_NODE *) * PeapConnDialog.pConnProp->EapTlsConnProp.dwNumHashes ); if ( NULL == PeapConnDialog.ppSelCertList ) { dwRetCode = GetLastError(); EapTlsTrace("LocalAlloc failed and returned %d", dwRetCode); goto LDone; } } CreateCertList( FALSE /* fServer */, fRouter, TRUE /* fRoot */, &(PeapConnDialog.pCertList), //lined list of all certs in the store. PeapConnDialog.ppSelCertList, //list of selected certificates - null if nothing's in the list PeapConnDialog.pConnProp->EapTlsConnProp.dwNumHashes, (EAPTLS_HASH*)(PeapConnDialog.pConnProp->EapTlsConnProp.bData), L"ROOT" ); // // Create a list of all Eap Types here // dwRetCode = PeapEapInfoGetList ( NULL, &(PeapConnDialog.pEapInfo) ); if ( NO_ERROR != dwRetCode ) { EapTlsTrace("Error Creating list of PEAP EapTypes"); goto LDone; } // Setup the conn props for each of the eaptypes from our PeapConnprop // in dwRetCode = PeapEapInfoSetConnData ( PeapConnDialog.pEapInfo, PeapConnDialog.pConnProp ); nRet = DialogBoxParam( GetResouceDLLHInstance(), MAKEINTRESOURCE(IDD_PEAP_CONFIG_UI), hwndParent, PeapConnDialogProc, (LPARAM)&PeapConnDialog); if (-1 == nRet) { dwRetCode = GetLastError(); goto LDone; } else if (IDOK != nRet) { dwRetCode = ERROR_CANCELLED; goto LDone; } // //Convert the connpropv1 back to connpropv0 + extra cludge //here // RTASSERT(NULL != PeapConnDialog.pConnProp); *ppConnectionDataOut = (PBYTE)PeapConnDialog.pConnProp; *pdwSizeOfConnectionDataOut = PeapConnDialog.pConnProp->dwSize; PeapConnDialog.pConnProp = NULL; LDone: EapTlsInitialize2(FALSE, TRUE /* fUI */); FreeCertList(PeapConnDialog.pCertList); if ( PeapConnDialog.ppSelCertList ) { LocalFree( PeapConnDialog.ppSelCertList ); PeapConnDialog.ppSelCertList = NULL; } PeapEapInfoFreeList ( PeapConnDialog.pEapInfo ); LocalFree( PeapConnDialog.pConnProp ); return dwRetCode; } /* Returns: Notes: Called to get the EAP-TLS properties for a connection. */ DWORD RasEapInvokeConfigUI( IN DWORD dwEapTypeId, IN HWND hwndParent, IN DWORD dwFlags, IN BYTE* pConnectionDataIn, IN DWORD dwSizeOfConnectionDataIn, OUT BYTE** ppConnectionDataOut, OUT DWORD* pdwSizeOfConnectionDataOut ) { DWORD dwErr = ERROR_INVALID_PARAMETER; // // This is invoked in case of client configuration // if ( PPP_EAP_TLS == dwEapTypeId ) { dwErr = RasEapTlsInvokeConfigUI( dwEapTypeId, hwndParent, dwFlags, pConnectionDataIn, dwSizeOfConnectionDataIn, ppConnectionDataOut, pdwSizeOfConnectionDataOut ); } #ifdef IMPL_PEAP else { //Invoke the client config UI dwErr = RasEapPeapInvokeConfigUI( dwEapTypeId, hwndParent, dwFlags, pConnectionDataIn, dwSizeOfConnectionDataIn, ppConnectionDataOut, pdwSizeOfConnectionDataOut ); } #endif return(dwErr); } /* Returns: Notes: pConnectionDataIn, pUserDataIn, and ppwszIdentity may be NULL. */ DWORD EapTlsInvokeIdentityUI( IN BOOL fServer, IN BOOL fRouterConfig, IN DWORD dwFlags, IN WCHAR* pwszStoreName, IN const WCHAR* pwszPhonebook, IN const WCHAR* pwszEntry, IN HWND hwndParent, IN BYTE* pConnectionDataIn, IN DWORD dwSizeOfConnectionDataIn, IN BYTE* pUserDataIn, IN DWORD dwSizeOfUserDataIn, OUT BYTE** ppUserDataOut, OUT DWORD* pdwSizeOfUserDataOut, OUT WCHAR** ppwszIdentity ) { DWORD dwErr = NO_ERROR; EAPTLS_USER_PROPERTIES* pUserProp = NULL; EAPTLS_CONN_PROPERTIES* pConnProp = NULL; EAPTLS_CONN_PROPERTIES_V1 * pConnPropv1 = NULL; WCHAR* pwszIdentity = NULL; PBYTE pbEncPIN = NULL; DWORD cbEncPIN = 0; RTASSERT(NULL != pwszStoreName); RTASSERT(NULL != ppUserDataOut); RTASSERT(NULL != pdwSizeOfUserDataOut); // pConnectionDataIn, pUserDataIn, and ppwszIdentity may be NULL. EapTlsInitialize2(TRUE, TRUE /* fUI */); EapTlsTrace("EapTlsInvokeIdentityUI"); *ppUserDataOut = NULL; *pdwSizeOfUserDataOut = 0; if (NULL != ppwszIdentity) { *ppwszIdentity = NULL; } dwErr = ReadConnectionData( ( dwFlags & RAS_EAP_FLAG_8021X_AUTH ), pConnectionDataIn, dwSizeOfConnectionDataIn, &pConnProp); if (NO_ERROR != dwErr) { goto LDone; } dwErr = ConnPropGetV1Struct ( pConnProp, &pConnPropv1 ); if ( NO_ERROR != dwErr ) { goto LDone; } dwErr = ReadUserData(pUserDataIn, dwSizeOfUserDataIn, &pUserProp); if (NO_ERROR != dwErr) { goto LDone; } if ( !(dwFlags & RAS_EAP_FLAG_LOGON) || (NULL == pUserDataIn)) { dwErr = GetCertInfo(fServer, fRouterConfig, dwFlags, pwszPhonebook, pwszEntry, hwndParent, pwszStoreName, pConnPropv1, &pUserProp, ppwszIdentity); if (NO_ERROR != dwErr) { #if WINVER > 0x0500 if ( dwErr == SCARD_E_CANCELLED || dwErr == SCARD_W_CANCELLED_BY_USER ) { dwErr = ERROR_READING_SCARD; } #endif goto LDone; } if ( (!fServer) && ( dwFlags & RAS_EAP_FLAG_8021X_AUTH ) && !(pConnProp->fFlags & EAPTLS_CONN_FLAG_REGISTRY) ) { // // Encrypt PIN and send it back // dwErr = EncryptData ( (PBYTE)pUserProp->pwszPin, lstrlen(pUserProp->pwszPin) * sizeof(WCHAR), &pbEncPIN, &cbEncPIN ); if ( NO_ERROR != dwErr ) { goto LDone; } dwErr = AllocUserDataWithNewPin(pUserProp, pbEncPIN, cbEncPIN, &pUserProp); } *ppUserDataOut = (BYTE*)(pUserProp); *pdwSizeOfUserDataOut = pUserProp->dwSize; pUserProp = NULL; goto LDone; } else { if (EAPTLS_CONN_FLAG_REGISTRY & pConnProp->fFlags) { dwErr = ERROR_NO_REG_CERT_AT_LOGON; goto LDone; } if (EAPTLS_CONN_FLAG_DIFF_USER & pConnProp->fFlags) { dwErr = ERROR_NO_DIFF_USER_AT_LOGON; goto LDone; } dwErr = GetIdentityFromLogonInfo(pUserDataIn, dwSizeOfUserDataIn, &pwszIdentity); if (NO_ERROR != dwErr) { goto LDone; } if (NULL != ppwszIdentity) { *ppwszIdentity = pwszIdentity; pwszIdentity = NULL; } } LDone: EapTlsInitialize2(FALSE, TRUE /* fUI */); LocalFree(pwszIdentity); LocalFree(pUserProp); LocalFree(pConnProp); LocalFree(pConnPropv1); LocalFree(pbEncPIN); return(dwErr); } DWORD PeapInvokeServerConfigUI ( IN HWND hWnd, IN WCHAR * pwszMachineName ) { // // Since this is the client side code only for xpsp1, we remove // serve side resources. // return ERROR_CALL_NOT_IMPLEMENTED; #if 0 WCHAR awszStoreName[MAX_COMPUTERNAME_LENGTH + 10 + 1]; DWORD dwStrLen; BYTE* pUserDataOut = NULL; DWORD dwSizeOfUserDataOut; BOOL fLocal = FALSE; PEAP_SERVER_CONFIG_DIALOG ServerConfigDialog; PPEAP_ENTRY_USER_PROPERTIES pEntryProp = NULL; INT_PTR nRet = -1; DWORD dwErr = NO_ERROR; EapTlsInitialize2(TRUE, TRUE /* fUI */); ZeroMemory ( &ServerConfigDialog, sizeof(ServerConfigDialog)); if (0 == *pwszMachineName) { fLocal = TRUE; } ServerConfigDialog.pwszMachineName = pwszMachineName; wcscpy(awszStoreName, L"\\\\"); wcsncat(awszStoreName, pwszMachineName, MAX_COMPUTERNAME_LENGTH); dwErr = PeapServerConfigDataIO(TRUE /* fRead */, fLocal ? NULL : awszStoreName, (BYTE**)&( ServerConfigDialog.pUserProp), 0); if (NO_ERROR != dwErr) { goto LDone; } // // Create cert list to display and then show the server config UI. // dwStrLen = wcslen(awszStoreName); wcsncat(awszStoreName, L"\\MY", wcslen(L"\\MY") ); CreateCertList( TRUE, FALSE, /*fRouter */ TRUE /* fRoot */, &(ServerConfigDialog.pCertList), &(ServerConfigDialog.pSelCertList), 1, &(ServerConfigDialog.pUserProp->CertHash), fLocal ? L"MY": awszStoreName); wcsncat(awszStoreName, L"\\MY", wcslen(L"\\MY")); awszStoreName[dwStrLen] = 0; // Get rid of the \MY // // Create list of All EAP Types allowed // dwErr = PeapEapInfoGetList ( pwszMachineName, &(ServerConfigDialog.pEapInfo) ); if ( NO_ERROR != dwErr ) { goto LDone; } // // From the user info get the selected PEAP Type if any // dwErr = PeapGetFirstEntryUserProp ( ServerConfigDialog.pUserProp, &pEntryProp ); if ( NO_ERROR == dwErr ) { // Set the selected EAP type // PeapEapInfoFindListNode ( pEntryProp->dwEapTypeId, ServerConfigDialog.pEapInfo, &(ServerConfigDialog.pSelEapInfo) ); } // // Invoke the config UI. // nRet = DialogBoxParam( GetResouceDLLHInstance(), MAKEINTRESOURCE(IDD_PEAP_SERVER_UI), hWnd, PeapServerDialogProc, (LPARAM)&ServerConfigDialog); if (-1 == nRet) { dwErr = GetLastError(); goto LDone; } else if (IDOK != nRet) { dwErr = ERROR_CANCELLED; goto LDone; } if ( ServerConfigDialog.pNewUserProp ) { dwErr = PeapServerConfigDataIO(FALSE /* fRead */, fLocal ? NULL : awszStoreName, (PBYTE *) &(ServerConfigDialog.pNewUserProp), sizeof(PEAP_USER_PROP)); } LDone: // Ignore errors RasEapFreeMemory(pUserDataOut); LocalFree(ServerConfigDialog.pNewUserProp ); LocalFree(ServerConfigDialog.pUserProp ); PeapEapInfoFreeList ( ServerConfigDialog.pEapInfo ); EapTlsInitialize2(FALSE, TRUE /* fUI */); return dwErr; #endif } /* Returns: NO_ERROR: iff Success Notes: Congigure EAP-TLS for the RAS server. */ DWORD InvokeServerConfigUI( IN HWND hWnd, IN WCHAR* pwszMachineName ) { #define MAX_STORE_NAME_LENGTH MAX_COMPUTERNAME_LENGTH + 10 WCHAR awszStoreName[MAX_STORE_NAME_LENGTH + 1]; DWORD dwStrLen; EAPTLS_USER_PROPERTIES* pUserProp = NULL; BYTE* pUserDataOut = NULL; DWORD dwSizeOfUserDataOut; BOOL fLocal = FALSE; DWORD dwErr = NO_ERROR; if (0 == *pwszMachineName) { fLocal = TRUE; } wcscpy(awszStoreName, L"\\\\"); wcsncat(awszStoreName, pwszMachineName, MAX_COMPUTERNAME_LENGTH); dwErr = ServerConfigDataIO(TRUE /* fRead */, fLocal ? NULL : awszStoreName, (BYTE**)&pUserProp, 0); if (NO_ERROR != dwErr) { goto LDone; } dwStrLen = wcslen(awszStoreName); wcsncat(awszStoreName, L"\\MY", wcslen(L"\\MY")); dwErr = EapTlsInvokeIdentityUI( TRUE /* fServer */, FALSE /* fRouterConfig */, 0 /* dwFlags */, fLocal ? L"MY" : awszStoreName, L"" /* pwszPhonebook */, L"" /* pwszEntry */, hWnd, NULL /* pConnectionDataIn */, 0 /* dwSizeOfConnectionDataIn */, (BYTE*)pUserProp, pUserProp->dwSize, &pUserDataOut, &dwSizeOfUserDataOut, NULL /* pszIdentity */); if (NO_ERROR != dwErr) { goto LDone; } awszStoreName[dwStrLen] = 0; // Get rid of the \MY dwErr = ServerConfigDataIO(FALSE /* fRead */, fLocal ? NULL : awszStoreName, &pUserDataOut, dwSizeOfUserDataOut); LDone: // Ignore errors RasEapFreeMemory(pUserDataOut); LocalFree(pUserProp); return(dwErr); } DWORD PeapGetIdentity( IN DWORD dwEapTypeId, IN HWND hwndParent, IN DWORD dwFlags, IN const WCHAR* pwszPhonebook, IN const WCHAR* pwszEntry, IN BYTE* pConnectionDataIn, IN DWORD dwSizeOfConnectionDataIn, IN BYTE* pUserDataIn, IN DWORD dwSizeOfUserDataIn, OUT BYTE** ppUserDataOut, OUT DWORD* pdwSizeOfUserDataOut, OUT WCHAR** ppwszIdentityOut ) { DWORD dwRetCode = NO_ERROR; PPEAP_CONN_PROP pConnProp = NULL; PPEAP_USER_PROP pUserProp = NULL; PPEAP_USER_PROP pUserPropNew = NULL; PPEAP_EAP_INFO pEapInfo = NULL; PPEAP_EAP_INFO pFirstEapInfo = NULL; PEAP_ENTRY_CONN_PROPERTIES UNALIGNED * pFirstEntryConnProp = NULL; PEAP_ENTRY_USER_PROPERTIES UNALIGNED * pFirstEntryUserProp = NULL; PEAP_DEFAULT_CRED_DIALOG DefaultCredDialog; INT_PTR nRet; LPWSTR lpwszLocalMachineName = NULL; // // Since PEAP itself does not have any client identity of its own, // check the first configured eap type and call it's get identity // entry point. If we dont have any eaptype configured, it is an // error condition. // dwRetCode = PeapReadConnectionData( ( dwFlags & RAS_EAP_FLAG_8021X_AUTH ), pConnectionDataIn, dwSizeOfConnectionDataIn, &pConnProp ); if ( NO_ERROR != dwRetCode ) { goto LDone; } dwRetCode = PeapReadUserData ( pUserDataIn, dwSizeOfUserDataIn, &pUserProp ); if ( NO_ERROR != dwRetCode ) { goto LDone; } // // This is probably not a very good thing. Modify PeapReadConnectionData to // put in the default of first eap type that it finds... // For now we have the only one - mschap v2 so may not be an issue... // if ( !pConnProp->dwNumPeapTypes ) { dwRetCode = ERROR_PROTOCOL_NOT_CONFIGURED; goto LDone; } // // Check to see if the conn prop and user prop are mismatched. If so, we need to get the // User props all over again // // Now invoke the first EAP method configured ( in this release, the only EAP ) // method and get the config info from it... // dwRetCode = PeapEapInfoGetList ( NULL, &pEapInfo); if ( NO_ERROR != dwRetCode ) { goto LDone; } // // If we have come this far, we have at least one configured eaptype in // PEAP. So, get the entry properties for it. // dwRetCode = PeapGetFirstEntryConnProp ( pConnProp, &pFirstEntryConnProp ); if ( NO_ERROR != dwRetCode ) { goto LDone; } dwRetCode = PeapGetFirstEntryUserProp ( pUserProp, &pFirstEntryUserProp ); if ( NO_ERROR != dwRetCode ) { goto LDone; } dwRetCode = PeapEapInfoFindListNode ( pFirstEntryConnProp->dwEapTypeId, pEapInfo, &pFirstEapInfo ); if ( NO_ERROR != dwRetCode ) { goto LDone; } if ( pFirstEntryConnProp->dwEapTypeId != pFirstEntryUserProp->dwEapTypeId ) { // // We have mismatched user prop and conn prop. So Reset the USer Prop Structure // LocalFree ( pUserProp ); dwRetCode = PeapReDoUserData (pFirstEntryConnProp->dwEapTypeId, &pUserProp ); if ( NO_ERROR != dwRetCode ) { goto LDone; } dwRetCode = PeapGetFirstEntryUserProp ( pUserProp, &pFirstEntryUserProp ); if ( NO_ERROR != dwRetCode ) { goto LDone; } } if ( pFirstEntryConnProp->dwSize > sizeof(PEAP_ENTRY_CONN_PROPERTIES)) { pFirstEapInfo->pbClientConfigOrig = pFirstEntryConnProp->bData; pFirstEapInfo->dwClientConfigOrigSize = pFirstEntryConnProp->dwSize - sizeof(PEAP_ENTRY_CONN_PROPERTIES) + 1; } else { pFirstEapInfo->pbClientConfigOrig = NULL; pFirstEapInfo->dwClientConfigOrigSize = 0; } //if typeid is 0, no user props are setup yet. if ( pFirstEntryUserProp->dwSize > sizeof(PEAP_ENTRY_USER_PROPERTIES)) { pFirstEapInfo->pbUserConfigOrig = pFirstEntryUserProp->bData; pFirstEapInfo->dwUserConfigOrigSize = pFirstEntryUserProp->dwSize - sizeof(PEAP_ENTRY_USER_PROPERTIES) + 1; } else { pFirstEapInfo->pbUserConfigOrig = NULL; pFirstEapInfo->dwUserConfigOrigSize = 0; } // // Invoke Identity UI for the first entry // and - NOTE we will have to chain this later. // and save it in the conn prop of each if ( pFirstEapInfo->lpwszIdentityUIPath ) { dwRetCode = PeapEapInfoInvokeIdentityUI ( hwndParent, pFirstEapInfo, pwszPhonebook, pwszEntry, pUserDataIn, dwSizeOfUserDataIn, ppwszIdentityOut, dwFlags ); if ( NO_ERROR == dwRetCode ) { // // Check to see if we have new user data // if ( pFirstEapInfo->pbUserConfigNew && pFirstEapInfo->dwNewUserConfigSize ) { // // redo the user prop blob // pUserPropNew = (PPEAP_USER_PROP) LocalAlloc ( LPTR, sizeof(PEAP_USER_PROP) + pFirstEapInfo->dwNewUserConfigSize ); if ( NULL == pUserPropNew ) { dwRetCode = ERROR_OUTOFMEMORY; goto LDone; } CopyMemory ( pUserPropNew, pUserProp, sizeof(PEAP_USER_PROP) ); pUserPropNew->UserProperties.dwVersion = 1; pUserPropNew->UserProperties.dwSize = sizeof(PEAP_ENTRY_USER_PROPERTIES) + pFirstEapInfo->dwNewUserConfigSize -1; pUserPropNew->dwSize = pUserPropNew->UserProperties.dwSize + sizeof(PEAP_USER_PROP) - sizeof(PEAP_ENTRY_USER_PROPERTIES); pUserPropNew->UserProperties.dwEapTypeId = pFirstEapInfo->dwTypeId; pUserPropNew->UserProperties.fUsingPeapDefault = 0; CopyMemory (pUserPropNew->UserProperties.bData, pFirstEapInfo->pbUserConfigNew, pFirstEapInfo->dwNewUserConfigSize ); *ppUserDataOut = (PBYTE)pUserPropNew; *pdwSizeOfUserDataOut = pUserPropNew->dwSize; pUserPropNew = NULL; } else { *ppUserDataOut = (PBYTE)pUserProp; *pdwSizeOfUserDataOut = pUserProp->dwSize; pUserProp = NULL; } } } else { //MAchine Auth if ( dwFlags & RAS_EAP_FLAG_MACHINE_AUTH) { //Send the identity back as domain\machine$ dwRetCode = GetLocalMachineName(&lpwszLocalMachineName ); if ( NO_ERROR != dwRetCode ) { EapTlsTrace("Failed to get computer name"); goto LDone; } if ( ! FFormatMachineIdentity1 ( lpwszLocalMachineName, ppwszIdentityOut ) ) { EapTlsTrace("Failed to format machine identity"); } goto LDone; } if ( dwFlags & RAS_EAP_FLAG_NON_INTERACTIVE ) { EapTlsTrace("Passed non interactive mode when interactive mode expected."); dwRetCode = ERROR_INTERACTIVE_MODE; goto LDone; } // // provide our default identity - You cannot save this identity or anything like that. // This is for the lame EAP methods that dont supply their own identity // ZeroMemory ( &DefaultCredDialog, sizeof(DefaultCredDialog) ); nRet = DialogBoxParam( GetResouceDLLHInstance(), MAKEINTRESOURCE(IDD_DIALOG_DEFAULT_CREDENTIALS), hwndParent, DefaultCredDialogProc, (LPARAM)&DefaultCredDialog); // EapTlsPinDialog.pUserProp may have been realloced if (-1 == nRet) { dwRetCode = GetLastError(); goto LDone; } else if (IDOK != nRet) { dwRetCode = ERROR_CANCELLED; goto LDone; } //CReate the new user prop blob pUserPropNew = (PPEAP_USER_PROP) LocalAlloc ( LPTR, sizeof(PEAP_USER_PROP) + sizeof( PEAP_DEFAULT_CREDENTIALS ) ); if ( NULL == pUserPropNew ) { dwRetCode = ERROR_OUTOFMEMORY; goto LDone; } CopyMemory ( pUserPropNew, pUserProp, sizeof(PEAP_USER_PROP) ); pUserPropNew->UserProperties.dwVersion = 1; pUserPropNew->UserProperties.dwSize = sizeof(PEAP_ENTRY_USER_PROPERTIES) + sizeof(PEAP_DEFAULT_CREDENTIALS) - 1; pUserPropNew->UserProperties.fUsingPeapDefault = 1; pUserPropNew->dwSize = pUserPropNew->UserProperties.dwSize + sizeof(PEAP_USER_PROP) - sizeof(PEAP_ENTRY_USER_PROPERTIES); pUserPropNew->UserProperties.dwEapTypeId = pFirstEapInfo->dwTypeId; CopyMemory (pUserPropNew->UserProperties.bData, &(DefaultCredDialog.PeapDefaultCredentials), sizeof(DefaultCredDialog.PeapDefaultCredentials) ); *ppUserDataOut = (PBYTE)pUserPropNew; *pdwSizeOfUserDataOut = pUserPropNew->dwSize; // // Now create the identity with uid and domain if any // dwRetCode = GetIdentityFromUserName ( DefaultCredDialog.PeapDefaultCredentials.wszUserName, DefaultCredDialog.PeapDefaultCredentials.wszDomain, ppwszIdentityOut ); if ( NO_ERROR != dwRetCode ) { goto LDone; } pUserPropNew = NULL; } LDone: LocalFree( lpwszLocalMachineName ); LocalFree(pConnProp); LocalFree(pUserProp); LocalFree(pUserPropNew); PeapEapInfoFreeList( pEapInfo ); return dwRetCode; } /* Returns: NO_ERROR: iff Success Notes: */ DWORD RasEapGetIdentity( IN DWORD dwEapTypeId, IN HWND hwndParent, IN DWORD dwFlags, IN const WCHAR* pwszPhonebook, IN const WCHAR* pwszEntry, IN BYTE* pConnectionDataIn, IN DWORD dwSizeOfConnectionDataIn, IN BYTE* pUserDataIn, IN DWORD dwSizeOfUserDataIn, OUT BYTE** ppUserDataOut, OUT DWORD* pdwSizeOfUserDataOut, OUT WCHAR** ppwszIdentityOut ) { DWORD dwErr = ERROR_INVALID_PARAMETER; if ( PPP_EAP_TLS == dwEapTypeId ) { dwErr = EapTlsInvokeIdentityUI( FALSE /* fServer */, FALSE /* fRouterConfig */, dwFlags, L"MY", pwszPhonebook, pwszEntry, hwndParent, pConnectionDataIn, dwSizeOfConnectionDataIn, pUserDataIn, dwSizeOfUserDataIn, ppUserDataOut, pdwSizeOfUserDataOut, ppwszIdentityOut); } #ifdef IMPL_PEAP else if ( PPP_EAP_PEAP == dwEapTypeId ) { dwErr = PeapGetIdentity(dwEapTypeId, hwndParent, dwFlags, pwszPhonebook, pwszEntry, pConnectionDataIn, dwSizeOfConnectionDataIn, pUserDataIn, dwSizeOfUserDataIn, ppUserDataOut, pdwSizeOfUserDataOut, ppwszIdentityOut ); } #endif return(dwErr); } /* Returns: Notes: Called to free memory. */ DWORD RasEapFreeMemory( IN BYTE* pMemory ) { LocalFree(pMemory); return(NO_ERROR); } #if 0 #if WINVER > 0x0500 /* Returns: Notes: API to create a connection Properties V1 Blob */ /* Returns: Notes: API to create a connection Properties V1 Blob */ DWORD RasEapCreateConnProp ( IN PEAPTLS_CONNPROP_ATTRIBUTE pAttr, IN PVOID * ppConnPropIn, IN DWORD * pdwConnPropSizeIn, OUT PVOID * ppConnPropOut, OUT DWORD * pdwConnPropSizeOut ) { DWORD dwRetCode = NO_ERROR; DWORD dwAllocBytes = 0; DWORD dwNumHashesOrig = 0; DWORD dwServerNamesLengthOrig = 0; PEAPTLS_CONNPROP_ATTRIBUTE pAttrInternal = pAttr; EAPTLS_CONN_PROPERTIES_V1 * pConnPropv1 = NULL; EAPTLS_CONN_PROPERTIES_V1 * pConnPropv1Orig = NULL; PEAPTLS_CONNPROP_ATTRIBUTE pAttrServerNames = NULL; PEAPTLS_CONNPROP_ATTRIBUTE pAttrHashes = NULL; EAPTLS_HASH sHash; DWORD i; if ( !pAttr || !ppConnPropOut ) { dwRetCode = ERROR_INVALID_PARAMETER; goto done; } *ppConnPropOut = NULL; // // Get the sizeof this allocation. // dwAllocBytes = sizeof(EAPTLS_CONN_PROPERTIES_V1); while ( pAttrInternal->ecaType != ecatMinimum ) { switch ( pAttrInternal->ecaType ) { case ecatMinimum: case ecatFlagRegistryCert: case ecatFlagScard: case ecatFlagValidateServer: case ecatFlagValidateName: case ecatFlagDiffUser: break; case ecatServerNames: dwAllocBytes += pAttrInternal->dwLength; break; case ecatRootHashes: dwAllocBytes += ( ( (pAttrInternal->dwLength)/MAX_HASH_SIZE) * sizeof(EAPTLS_HASH) ); break; default: dwRetCode = ERROR_INVALID_PARAMETER; goto done; } pAttrInternal ++; } pAttrInternal = pAttr; if (*ppConnPropIn == NULL) { pConnPropv1 = (EAPTLS_CONN_PROPERTIES_V1 *) LocalAlloc(LPTR, dwAllocBytes ); if ( NULL == pConnPropv1 ) { dwRetCode = GetLastError(); goto done; } } else { // Input struct with always be Version 0, convert internally to // Version 1 dwRetCode = ConnPropGetV1Struct ( ((EAPTLS_CONN_PROPERTIES *)(*ppConnPropIn)), &pConnPropv1Orig ); if ( NO_ERROR != dwRetCode ) { goto done; } if (pConnPropv1Orig->dwNumHashes) { dwAllocBytes += pConnPropv1Orig->dwNumHashes*sizeof(EAPTLS_HASH); } dwAllocBytes += wcslen ( (WCHAR *)( pConnPropv1Orig->bData + (pConnPropv1Orig->dwNumHashes * sizeof(EAPTLS_HASH)) )) * sizeof(WCHAR) + sizeof(WCHAR); pConnPropv1 = (EAPTLS_CONN_PROPERTIES_V1 *) LocalAlloc(LPTR, dwAllocBytes ); if ( NULL == pConnPropv1 ) { dwRetCode = GetLastError(); goto done; } } pConnPropv1->dwVersion = 1; pConnPropv1->dwSize = dwAllocBytes; // //Set the flags first // while ( pAttrInternal->ecaType != ecatMinimum ) { switch ( pAttrInternal->ecaType ) { case ecatFlagRegistryCert: pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_REGISTRY; break; case ecatFlagScard: pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_REGISTRY; break; case ecatFlagValidateServer: if ( *((BOOL *)(pAttrInternal->Value)) ) pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_NO_VALIDATE_CERT; else pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_NO_VALIDATE_CERT; break; case ecatFlagValidateName: if ( *((BOOL *)(pAttrInternal->Value)) ) pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_NO_VALIDATE_NAME; else pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_NO_VALIDATE_NAME; break; case ecatFlagDiffUser: if ( *((BOOL *)(pAttrInternal->Value)) ) pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_DIFF_USER; else pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_DIFF_USER; break; case ecatServerNames: pAttrServerNames = pAttrInternal; break; case ecatRootHashes: pAttrHashes = pAttrInternal; break; } pAttrInternal++; } dwNumHashesOrig = pConnPropv1Orig?pConnPropv1Orig->dwNumHashes:0; if ( dwNumHashesOrig ) { CopyMemory( pConnPropv1->bData, pConnPropv1Orig->bData, sizeof(EAPTLS_HASH)*dwNumHashesOrig ); pConnPropv1->dwNumHashes = dwNumHashesOrig; } if ( pAttrHashes ) { DWORD dwNumHashes = 0; dwNumHashes = (pAttrHashes->dwLength)/MAX_HASH_SIZE; for ( i = 0; i < dwNumHashes; i ++ ) { ZeroMemory( &sHash, sizeof(sHash) ); sHash.cbHash = MAX_HASH_SIZE; CopyMemory( sHash.pbHash, ((PBYTE)pAttrHashes->Value) + MAX_HASH_SIZE * i, MAX_HASH_SIZE ); CopyMemory( pConnPropv1->bData + sizeof(EAPTLS_HASH) * (pConnPropv1->dwNumHashes + i) , &sHash, sizeof(sHash) ); } pConnPropv1->dwNumHashes += dwNumHashes; } dwServerNamesLengthOrig = pConnPropv1Orig?(wcslen((WCHAR*)(pConnPropv1Orig->bData+sizeof(EAPTLS_HASH) * (pConnPropv1Orig->dwNumHashes)))*sizeof(WCHAR) + sizeof (WCHAR) ):0; if ( dwServerNamesLengthOrig ) { CopyMemory ( pConnPropv1->bData + sizeof(EAPTLS_HASH) * pConnPropv1->dwNumHashes, pConnPropv1Orig->bData+sizeof(EAPTLS_HASH) * pConnPropv1Orig->dwNumHashes, dwServerNamesLengthOrig ); } if ( pAttrServerNames ) { //Setup the server name CopyMemory ( pConnPropv1->bData + sizeof(EAPTLS_HASH) * pConnPropv1->dwNumHashes + dwServerNamesLengthOrig, pAttrServerNames->Value, pAttrServerNames->dwLength ); } dwRetCode = ConnPropGetV0Struct ( pConnPropv1, (EAPTLS_CONN_PROPERTIES ** )ppConnPropOut ); if ( NO_ERROR != dwRetCode ) { goto done; } *pdwConnPropSizeOut = ((EAPTLS_CONN_PROPERTIES * )*ppConnPropOut)->dwSize; done: LocalFree ( pConnPropv1 ); return dwRetCode; } #endif #endif ////////////////////////// all PEAP related stuff /////////////////////////////////////// TCHAR* ComboBox_GetPsz( IN HWND hwnd, IN INT nIndex ) /* Returns heap block containing the text contents of the 'nIndex'th item ** of combo box 'hwnd' or NULL. It is caller's responsibility to Free the ** returned string. */ { INT cch; TCHAR* psz; cch = ComboBox_GetLBTextLen( hwnd, nIndex ); if (cch < 0) return NULL; psz = LocalAlloc (LPTR, (cch + 1) * sizeof(TCHAR) ); if (psz) { *psz = TEXT('\0'); ComboBox_GetLBText( hwnd, nIndex, psz ); } return psz; } VOID ComboBox_AutoSizeDroppedWidth( IN HWND hwndLb ) /* Set the width of the drop-down list 'hwndLb' to the width of the ** longest item (or the width of the list box if that's wider). */ { HDC hdc; HFONT hfont; TCHAR* psz; SIZE size; DWORD cch; DWORD dxNew; DWORD i; hfont = (HFONT )SendMessage( hwndLb, WM_GETFONT, 0, 0 ); if (!hfont) return; hdc = GetDC( hwndLb ); if (!hdc) return; SelectObject( hdc, hfont ); dxNew = 0; for (i = 0; psz = ComboBox_GetPsz( hwndLb, i ); ++i) { cch = lstrlen( psz ); if (GetTextExtentPoint32( hdc, psz, cch, &size )) { if (dxNew < (DWORD )size.cx) dxNew = (DWORD )size.cx; } LocalFree( psz ); } ReleaseDC( hwndLb, hdc ); /* Allow for the spacing on left and right added by the control. */ dxNew += 6; /* Figure out if the vertical scrollbar will be displayed and, if so, ** allow for it's width. */ { RECT rectD; RECT rectU; DWORD dyItem; DWORD cItemsInDrop; DWORD cItemsInList; GetWindowRect( hwndLb, &rectU ); SendMessage( hwndLb, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM )&rectD ); dyItem = (DWORD)SendMessage( hwndLb, CB_GETITEMHEIGHT, 0, 0 ); cItemsInDrop = (rectD.bottom - rectU.bottom) / dyItem; cItemsInList = ComboBox_GetCount( hwndLb ); if (cItemsInDrop < cItemsInList) dxNew += GetSystemMetrics( SM_CXVSCROLL ); } SendMessage( hwndLb, CB_SETDROPPEDWIDTH, dxNew, 0 ); } VOID PeapEnableValidateNameControls( IN PPEAP_CONN_DIALOG pPeapConnDialog ) { BOOL fEnable; RTASSERT(NULL != pPeapConnDialog); fEnable = !(pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags & EAPTLS_CONN_FLAG_NO_VALIDATE_CERT); EnableWindow(pPeapConnDialog->hWndCheckValidateName, fEnable); EnableWindow(pPeapConnDialog->hWndStaticRootCaName, fEnable); EnableWindow(pPeapConnDialog->hWndListRootCaName, fEnable); fEnable = ( fEnable && !(pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags & EAPTLS_CONN_FLAG_NO_VALIDATE_NAME)); EnableWindow(pPeapConnDialog->hWndEditServerName, fEnable); } BOOL PeapConnInitDialog( IN HWND hWnd, IN LPARAM lParam ) { PPEAP_CONN_DIALOG pPeapConnDialog; LVCOLUMN lvColumn; LPWSTR lpwszServerName = NULL; DWORD dwCount = 0; PPEAP_EAP_INFO pEapInfo; DWORD dwSelItem = 0; PEAP_ENTRY_CONN_PROPERTIES UNALIGNED * pEntryProp; INT_PTR nIndex = 0; BOOL fCripplePeap = FALSE; SetWindowLongPtr(hWnd, DWLP_USER, lParam); pPeapConnDialog = (PPEAP_CONN_DIALOG)lParam; pPeapConnDialog->hWndCheckValidateCert = GetDlgItem(hWnd, IDC_CHECK_VALIDATE_CERT); pPeapConnDialog->hWndCheckValidateName = GetDlgItem(hWnd, IDC_CHECK_VALIDATE_NAME); pPeapConnDialog->hWndEditServerName = GetDlgItem(hWnd, IDC_EDIT_SERVER_NAME); pPeapConnDialog->hWndStaticRootCaName = GetDlgItem(hWnd, IDC_STATIC_ROOT_CA_NAME); pPeapConnDialog->hWndListRootCaName = GetDlgItem(hWnd, IDC_LIST_ROOT_CA_NAME); pPeapConnDialog->hWndComboPeapType = GetDlgItem(hWnd, IDC_COMBO_PEAP_TYPE); pPeapConnDialog->hWndButtonConfigure = GetDlgItem(hWnd, IDC_BUTTON_CONFIGURE); pPeapConnDialog->hWndCheckEnableFastReconnect = GetDlgItem(hWnd, IDC_CHECK_ENABLE_FAST_RECONNECT); //Set the style to set list boxes. ListView_SetExtendedListViewStyle ( pPeapConnDialog->hWndListRootCaName, ListView_GetExtendedListViewStyle(pPeapConnDialog->hWndListRootCaName) | LVS_EX_CHECKBOXES ); ZeroMemory ( &lvColumn, sizeof(lvColumn)); lvColumn.fmt = LVCFMT_LEFT; ListView_InsertColumn( pPeapConnDialog->hWndListRootCaName, 0, &lvColumn ); ListView_SetColumnWidth(pPeapConnDialog->hWndListRootCaName, 0, LVSCW_AUTOSIZE_USEHEADER ); // //Now we need to init the //list box with all the certs and selected cert InitListBox ( pPeapConnDialog->hWndListRootCaName, pPeapConnDialog->pCertList, pPeapConnDialog->pConnProp->EapTlsConnProp.dwNumHashes, pPeapConnDialog->ppSelCertList ); lpwszServerName = (LPWSTR )(pPeapConnDialog->pConnProp->EapTlsConnProp.bData + sizeof( EAPTLS_HASH ) * pPeapConnDialog->pConnProp->EapTlsConnProp.dwNumHashes); SetWindowText(pPeapConnDialog->hWndEditServerName, lpwszServerName ); if (pPeapConnDialog->fFlags & EAPTLS_CONN_DIALOG_FLAG_ROUTER) { pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags |= EAPTLS_CONN_FLAG_REGISTRY; } CheckDlgButton(hWnd, IDC_CHECK_VALIDATE_CERT, (pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags & EAPTLS_CONN_FLAG_NO_VALIDATE_CERT) ? BST_UNCHECKED : BST_CHECKED); CheckDlgButton(hWnd, IDC_CHECK_VALIDATE_NAME, (pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags & EAPTLS_CONN_FLAG_NO_VALIDATE_NAME) ? BST_UNCHECKED : BST_CHECKED); PeapEnableValidateNameControls(pPeapConnDialog); //NOTE: // For this version of PEAP the control is a combo box. But // it will change to list box and we need to change the // control to list and change the following code to // add only the ones that are applicable // // Check to see if PEAP is crippled. // { HKEY hKeyLM =0; RegConnectRegistry ( NULL, HKEY_LOCAL_MACHINE, &hKeyLM ); fCripplePeap = IsPeapCrippled ( hKeyLM ); RegCloseKey(hKeyLM); } // //Add all the PEAP eap type friendly names // pEapInfo = pPeapConnDialog->pEapInfo; dwCount = 0; while ( pEapInfo ) { if ( pEapInfo->dwTypeId == PPP_EAP_CHAP ) { pEapInfo = pEapInfo->pNext; continue; } nIndex = SendMessage(pPeapConnDialog->hWndComboPeapType, CB_ADDSTRING, 0, (LPARAM)pEapInfo->lpwszFriendlyName); SendMessage ( pPeapConnDialog->hWndComboPeapType, CB_SETITEMDATA, (WPARAM)nIndex, (LPARAM)pEapInfo ); ComboBox_AutoSizeDroppedWidth( pPeapConnDialog->hWndComboPeapType ); dwCount++; if ( pPeapConnDialog->pConnProp->dwNumPeapTypes ) { /* if ( pPeapConnDialog->pConnProp->EapTlsConnProp.dwSize == sizeof(EAPTLS_CONN_PROPERTIES_V1) ) { //This is a newly initialized structure. pEntryProp = (PEAP_ENTRY_CONN_PROPERTIES UNALIGNED *) (((BYTE UNALIGNED *)(pPeapConnDialog->pConnProp)) + sizeof(PEAP_CONN_PROP)); } else */ { pEntryProp = ( PEAP_ENTRY_CONN_PROPERTIES UNALIGNED *) ( (BYTE UNALIGNED *)pPeapConnDialog->pConnProp->EapTlsConnProp.bData + pPeapConnDialog->pConnProp->EapTlsConnProp.dwNumHashes * sizeof(EAPTLS_HASH) + wcslen(lpwszServerName) * sizeof(WCHAR) + sizeof(WCHAR)); } if ( pEntryProp->dwEapTypeId == pEapInfo->dwTypeId ) { pPeapConnDialog->pSelEapInfo = pEapInfo; pPeapConnDialog->pSelEapInfo->pbClientConfigOrig = pEntryProp->bData; pPeapConnDialog->pSelEapInfo->dwClientConfigOrigSize = pEntryProp->dwSize - sizeof(PEAP_ENTRY_CONN_PROPERTIES) + 1; } } pEapInfo = pEapInfo->pNext; } dwSelItem = 0; for ( nIndex = 0; nIndex < (INT_PTR)dwCount; nIndex ++ ) { pEapInfo = (PPEAP_EAP_INFO)SendMessage( pPeapConnDialog->hWndComboPeapType, CB_GETITEMDATA, (WPARAM)nIndex, (LPARAM)0L ); if ( pEapInfo == pPeapConnDialog->pSelEapInfo ) { dwSelItem = (DWORD)nIndex; break; } } SendMessage(pPeapConnDialog->hWndComboPeapType, CB_SETCURSEL, dwSelItem, 0); // // Hide/Show Fast reconnect based on if this is a // Wireless client or VPN client. // if ( pPeapConnDialog->fFlags & PEAP_CONN_DIALOG_FLAG_8021x ) { ShowWindow ( pPeapConnDialog->hWndCheckEnableFastReconnect, SW_SHOW ); //Check the box based on what the CheckDlgButton(hWnd, IDC_CHECK_ENABLE_FAST_RECONNECT, ( pPeapConnDialog->pConnProp->dwFlags & PEAP_CONN_FLAG_FAST_ROAMING) ? BST_CHECKED : BST_UNCHECKED ); } else { ShowWindow ( pPeapConnDialog->hWndCheckEnableFastReconnect, SW_HIDE ); } if ( pPeapConnDialog->pSelEapInfo->lpwszConfigUIPath ) { EnableWindow(pPeapConnDialog->hWndButtonConfigure, TRUE ); } else { // // There is no configuration option here. // EnableWindow(pPeapConnDialog->hWndButtonConfigure, FALSE ); } // // if this is to function in readonly mode, // disable the controls - set them in read only mode. return(FALSE); } /* Returns: TRUE: We prrocessed this message. FALSE: We did not prrocess this message. Notes: Response to the WM_COMMAND message (Config UI). */ BOOL PeapConnCommand( IN PPEAP_CONN_DIALOG pPeapConnDialog, IN WORD wNotifyCode, IN WORD wId, IN HWND hWndDlg, IN HWND hWndCtrl ) { DWORD dwNumChars; PPEAP_CONN_PROP pPeapConnProp; switch(wId) { case IDC_CHECK_VALIDATE_CERT: if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_VALIDATE_CERT)) { pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags &= ~EAPTLS_CONN_FLAG_NO_VALIDATE_CERT; pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags &= ~EAPTLS_CONN_FLAG_NO_VALIDATE_NAME; CheckDlgButton(hWndDlg, IDC_CHECK_VALIDATE_NAME, BST_CHECKED); } else { pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags |= EAPTLS_CONN_FLAG_NO_VALIDATE_CERT; pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags |= EAPTLS_CONN_FLAG_NO_VALIDATE_NAME; CheckDlgButton(hWndDlg, IDC_CHECK_VALIDATE_NAME, BST_UNCHECKED); } PeapEnableValidateNameControls(pPeapConnDialog); return(TRUE); case IDC_CHECK_VALIDATE_NAME: if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_VALIDATE_NAME)) { pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags &= ~EAPTLS_CONN_FLAG_NO_VALIDATE_NAME; } else { pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags |= EAPTLS_CONN_FLAG_NO_VALIDATE_NAME; } PeapEnableValidateNameControls(pPeapConnDialog); return(TRUE); case IDC_COMBO_PEAP_TYPE: if (CBN_SELCHANGE != wNotifyCode) { return(FALSE); // We will not process this message } //Fall Thru' case IDC_BUTTON_CONFIGURE: { INT nIndex = -1; nIndex = (INT)SendMessage ( pPeapConnDialog->hWndComboPeapType, CB_GETCURSEL, 0,0 ); if ( nIndex != -1 ) { // // Change the currently selected EAP Type. // pPeapConnDialog->pSelEapInfo = (PPEAP_EAP_INFO) SendMessage ( pPeapConnDialog->hWndComboPeapType, CB_GETITEMDATA, (WPARAM)nIndex, (LPARAM)0 ); if ( pPeapConnDialog->pSelEapInfo->lpwszConfigUIPath ) { EnableWindow(pPeapConnDialog->hWndButtonConfigure, TRUE ); if ( wId == IDC_BUTTON_CONFIGURE ) { // // Invoke the configure method for selected eap type and if no error is // returned, then set the new configuration // DWORD dwFlags = 0; if ( pPeapConnDialog->fFlags & EAPTLS_CONN_DIALOG_FLAG_ROUTER ) { dwFlags |= RAS_EAP_FLAG_ROUTER; } if ( pPeapConnDialog->fFlags & PEAP_CONN_DIALOG_FLAG_8021x ) { dwFlags |= RAS_EAP_FLAG_8021X_AUTH; } PeapEapInfoInvokeClientConfigUI ( hWndDlg, pPeapConnDialog->pSelEapInfo, dwFlags ); } } else { // // There is no configuration option here. // EnableWindow(pPeapConnDialog->hWndButtonConfigure, FALSE ); } } else { EnableWindow(pPeapConnDialog->hWndButtonConfigure, FALSE ); pPeapConnDialog->pSelEapInfo = NULL; } return TRUE; } case IDOK: { // Setup new PPEAP_CONN_PROP here. // EAPTLS_HASH * pHash = NULL; DWORD dwNumHash = 0; DWORD dwSelCount = 0; DWORD dwPeapConnBlobSize = 0; PEAP_ENTRY_CONN_PROPERTIES UNALIGNED * pEntryProp; EAPTLS_CERT_NODE ** ppSelCertList = NULL; WCHAR wszTitle[200] = {0}; WCHAR wszMessage[200] = {0}; if ( NULL == pPeapConnDialog->pSelEapInfo ) { // No item selected so cannot complete configuration // $TODO:show message LoadString ( GetHInstance(), IDS_CANT_CONFIGURE_SERVER_TITLE, wszTitle, sizeof(wszTitle)/sizeof(WCHAR) ); LoadString ( GetResouceDLLHInstance(), IDS_PEAP_NO_EAP_TYPE, wszMessage, sizeof(wszMessage)/sizeof(WCHAR) ); MessageBox ( GetFocus(), wszMessage, wszTitle, MB_OK|MB_ICONWARNING ); return TRUE; } CertListSelectedCount ( pPeapConnDialog->hWndListRootCaName, &dwSelCount ); if ( dwSelCount > 0 ) { ppSelCertList = (EAPTLS_CERT_NODE **)LocalAlloc(LPTR, sizeof(EAPTLS_CERT_NODE *) * dwSelCount ); if ( NULL == ppSelCertList ) { EapTlsTrace("LocalAlloc in Command failed and returned %d", GetLastError()); return TRUE; } pHash = (EAPTLS_HASH *)LocalAlloc(LPTR, sizeof(EAPTLS_HASH ) * dwSelCount ); if ( NULL == pHash ) { EapTlsTrace("LocalAlloc in Command failed and returned %d", GetLastError()); return TRUE; } CertListSelected( pPeapConnDialog->hWndListRootCaName, pPeapConnDialog->pCertList, ppSelCertList, pHash, dwSelCount ); } dwNumChars = GetWindowTextLength(pPeapConnDialog->hWndEditServerName); //Allocate memory for pPeapConnProp //Size of Peap conn prop includes // sizeof peap conn prop + // sizeof eaptls hashes of selected certs + // sizeof server name + // sizeof PEAP_ENTRY_CONN_PROPERTIES + // sizeof conn prop returned by the selected type. // dwPeapConnBlobSize = sizeof(PEAP_CONN_PROP) + sizeof(EAPTLS_HASH) * dwSelCount + dwNumChars * sizeof(WCHAR) + sizeof(WCHAR) + sizeof(PEAP_ENTRY_CONN_PROPERTIES ); if ( pPeapConnDialog->pSelEapInfo->pbNewClientConfig ) { dwPeapConnBlobSize += pPeapConnDialog->pSelEapInfo->dwNewClientConfigSize; } else { dwPeapConnBlobSize += pPeapConnDialog->pSelEapInfo->dwClientConfigOrigSize; } pPeapConnProp = (PPEAP_CONN_PROP)LocalAlloc( LPTR, dwPeapConnBlobSize ); if (NULL == pPeapConnProp) { EapTlsTrace("LocalAlloc in Command failed and returned %d", GetLastError()); } else { pPeapConnProp->dwVersion = 1; pPeapConnProp->dwSize = dwPeapConnBlobSize; pPeapConnProp->dwNumPeapTypes = 1; // // See if fast roaming is enabled or not. // if ( pPeapConnDialog->fFlags & PEAP_CONN_DIALOG_FLAG_8021x ) { if ( IsDlgButtonChecked ( hWndDlg, IDC_CHECK_ENABLE_FAST_RECONNECT ) == BST_CHECKED ) { pPeapConnProp->dwFlags |= PEAP_CONN_FLAG_FAST_ROAMING; } else { pPeapConnProp->dwFlags &= ~PEAP_CONN_FLAG_FAST_ROAMING; } } CopyMemory( &pPeapConnProp->EapTlsConnProp, &(pPeapConnDialog->pConnProp->EapTlsConnProp), sizeof(EAPTLS_CONN_PROPERTIES_V1) ); // //Size of EapTlsConnProp is sizeof (EAPTLS_CONN_PROP_V1) -1 ( for bdata) //+ sizeof(EAPTLS_HASH) * dwSelCount + sizeof( string) + one for null. // pPeapConnProp->EapTlsConnProp.dwSize = (sizeof(EAPTLS_CONN_PROPERTIES_V1) - 1) + sizeof(EAPTLS_HASH) * dwSelCount + dwNumChars * sizeof(WCHAR) + sizeof(WCHAR); CopyMemory ( pPeapConnProp->EapTlsConnProp.bData, pHash, sizeof(EAPTLS_HASH) * dwSelCount ); pPeapConnProp->EapTlsConnProp.dwVersion = 1; pPeapConnProp->EapTlsConnProp.dwNumHashes = dwSelCount; GetWindowText(pPeapConnDialog->hWndEditServerName, (LPWSTR)(pPeapConnProp->EapTlsConnProp.bData + sizeof(EAPTLS_HASH) * dwSelCount) , dwNumChars + 1); // // Now copy over the PEAP_ENTRY_CONN_PROPERTIES structure // pEntryProp = (PEAP_ENTRY_CONN_PROPERTIES UNALIGNED *) ((BYTE UNALIGNED *)pPeapConnProp->EapTlsConnProp.bData + sizeof(EAPTLS_HASH) * dwSelCount + dwNumChars * sizeof(WCHAR)+ sizeof(WCHAR)); pEntryProp->dwVersion = 1; pEntryProp->dwEapTypeId = pPeapConnDialog->pSelEapInfo->dwTypeId; pEntryProp->dwSize = sizeof(PEAP_ENTRY_CONN_PROPERTIES)-1; if ( pPeapConnDialog->pSelEapInfo->pbNewClientConfig ) { pEntryProp->dwSize += pPeapConnDialog->pSelEapInfo->dwNewClientConfigSize ; if ( pPeapConnDialog->pSelEapInfo->dwNewClientConfigSize ) { CopyMemory( pEntryProp->bData, pPeapConnDialog->pSelEapInfo->pbNewClientConfig, pPeapConnDialog->pSelEapInfo->dwNewClientConfigSize ); } } else { pEntryProp->dwSize += pPeapConnDialog->pSelEapInfo->dwClientConfigOrigSize; if ( pPeapConnDialog->pSelEapInfo->dwClientConfigOrigSize ) { CopyMemory( pEntryProp->bData, pPeapConnDialog->pSelEapInfo->pbClientConfigOrig, pPeapConnDialog->pSelEapInfo->dwClientConfigOrigSize ); } } LocalFree(pPeapConnDialog->pConnProp); if ( pPeapConnDialog->ppSelCertList ) LocalFree(pPeapConnDialog->ppSelCertList); pPeapConnDialog->ppSelCertList = ppSelCertList; pPeapConnDialog->pConnProp= pPeapConnProp; } } // Fall through case IDCANCEL: EndDialog(hWndDlg, wId); return(TRUE); default: return(FALSE); } } BOOL PeapConnNotify( PEAP_CONN_DIALOG *pPeapConnDialog, WPARAM wParam, LPARAM lParam, HWND hWnd ) { HCERTSTORE hCertStore = NULL; PCCERT_CONTEXT pCertContext = NULL; LPNMITEMACTIVATE lpnmItem; LVITEM lvItem; if ( wParam == IDC_LIST_ROOT_CA_NAME ) { lpnmItem = (LPNMITEMACTIVATE) lParam; if ( lpnmItem->hdr.code == NM_DBLCLK ) { ZeroMemory(&lvItem, sizeof(lvItem) ); lvItem.mask = LVIF_PARAM; lvItem.iItem = lpnmItem->iItem; ListView_GetItem(lpnmItem->hdr.hwndFrom, &lvItem); if ( NO_ERROR == GetSelCertContext( //pEaptlsConnDialog->pCertList, (EAPTLS_CERT_NODE*)(lvItem.lParam) , -1, &hCertStore, L"ROOT", &pCertContext ) ) { ShowCertDetails( hWnd, hCertStore, pCertContext ); CertFreeCertificateContext(pCertContext); CertCloseStore( hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ); return TRUE; } return TRUE; } } return FALSE; } /* Returns: Notes: Callback function used with the Config UI DialogBoxParam function. It processes messages sent to the dialog box. See the DialogProc documentation in MSDN. */ INT_PTR CALLBACK PeapConnDialogProc( IN HWND hWnd, IN UINT unMsg, IN WPARAM wParam, IN LPARAM lParam ) { PPEAP_CONN_DIALOG pPeapConnDialog; switch (unMsg) { case WM_INITDIALOG: return(PeapConnInitDialog(hWnd, lParam)); case WM_HELP: case WM_CONTEXTMENU: { ContextHelp(g_adwHelp, hWnd, unMsg, wParam, lParam); break; } case WM_NOTIFY: { pPeapConnDialog = (PPEAP_CONN_DIALOG)GetWindowLongPtr(hWnd, DWLP_USER); return PeapConnNotify( pPeapConnDialog, wParam, lParam, hWnd ); } case WM_COMMAND: pPeapConnDialog = (PPEAP_CONN_DIALOG)GetWindowLongPtr(hWnd, DWLP_USER); return(PeapConnCommand(pPeapConnDialog, HIWORD(wParam), LOWORD(wParam), hWnd, (HWND)lParam)); } return(FALSE); } VOID PeapDisplayCertInfo ( IN PPEAP_SERVER_CONFIG_DIALOG pServerConfigDialog ) { RTASSERT(NULL != pServerConfigDialog); // Erase old values first SetWindowText(pServerConfigDialog->hWndEditFriendlyName, L""); SetWindowText(pServerConfigDialog->hWndEditIssuer, L""); SetWindowText(pServerConfigDialog->hWndEditExpiration, L""); if (NULL != pServerConfigDialog->pSelCertList) { if (NULL != pServerConfigDialog->pSelCertList->pwszFriendlyName) { SetWindowText(pServerConfigDialog->hWndEditFriendlyName, pServerConfigDialog->pSelCertList->pwszFriendlyName); } if (NULL != pServerConfigDialog->pSelCertList->pwszIssuer) { SetWindowText(pServerConfigDialog->hWndEditIssuer, pServerConfigDialog->pSelCertList->pwszIssuer); } if (NULL != pServerConfigDialog->pSelCertList->pwszExpiration) { SetWindowText(pServerConfigDialog->hWndEditExpiration, pServerConfigDialog->pSelCertList->pwszExpiration); } } } #if 0 BOOL PeapServerInitDialog( IN HWND hWnd, IN LPARAM lParam ) { PPEAP_SERVER_CONFIG_DIALOG pPeapServerDialog; PPEAP_EAP_INFO pEapInfo; DWORD dwSelItem = 0; SetWindowLongPtr( hWnd, DWLP_USER, lParam); pPeapServerDialog = (PPEAP_SERVER_CONFIG_DIALOG)lParam; pPeapServerDialog ->hWndComboServerName = GetDlgItem(hWnd, IDC_COMBO_SERVER_NAME); pPeapServerDialog ->hWndEditFriendlyName= GetDlgItem(hWnd, IDC_EDIT_FRIENDLY_NAME); pPeapServerDialog ->hWndEditIssuer= GetDlgItem(hWnd, IDC_EDIT_ISSUER); pPeapServerDialog ->hWndEditExpiration= GetDlgItem(hWnd, IDC_EDIT_EXPIRATION); pPeapServerDialog ->hWndComboPeapType= GetDlgItem(hWnd, IDC_COMBO_PEAP_TYPE); pPeapServerDialog ->hWndBtnConfigure= GetDlgItem(hWnd, IDC_BUTTON_CONFIGURE); pPeapServerDialog->hEndEnableFastReconnect = GetDlgItem(hWnd, IDC_CHECK_ENABLE_FAST_RECONNECT ); InitComboBox(pPeapServerDialog ->hWndComboServerName, pPeapServerDialog ->pCertList, pPeapServerDialog ->pSelCertList ); CheckDlgButton(hWnd, IDC_CHECK_ENABLE_FAST_RECONNECT, ( pPeapServerDialog->pUserProp->dwFlags & PEAP_USER_FLAG_FAST_ROAMING) ? BST_CHECKED : BST_UNCHECKED); PeapDisplayCertInfo(pPeapServerDialog); //NOTE: // For this version of PEAP the control is a combo box. But // it will change to list box and we need to change the // control to list and change the following code to // add only the ones that are applicable // //Add all the PEAP eap type friendly names // pEapInfo = pPeapServerDialog->pEapInfo; while ( pEapInfo ) { INT_PTR nIndex = 0; nIndex = SendMessage( pPeapServerDialog->hWndComboPeapType, CB_ADDSTRING, 0, (LPARAM)pEapInfo->lpwszFriendlyName); SendMessage ( pPeapServerDialog->hWndComboPeapType, CB_SETITEMDATA, (WPARAM)nIndex, (LPARAM)pEapInfo ); if ( pPeapServerDialog->pSelEapInfo ) { if ( pPeapServerDialog->pSelEapInfo->dwTypeId == pEapInfo->dwTypeId ) { dwSelItem = (DWORD)nIndex; } } pEapInfo = pEapInfo->pNext; } SendMessage(pPeapServerDialog->hWndComboPeapType, CB_SETCURSEL, dwSelItem, 0); // // Set the state of configure button // if ( NULL == pPeapServerDialog->pSelEapInfo ) { pPeapServerDialog->pSelEapInfo = (PPEAP_EAP_INFO) SendMessage ( pPeapServerDialog->hWndComboPeapType, CB_GETITEMDATA, (WPARAM)dwSelItem, (LPARAM)0 ); } if ( !pPeapServerDialog->pSelEapInfo->lpwszConfigClsId ) { EnableWindow ( pPeapServerDialog->hWndBtnConfigure, FALSE ); } else { EnableWindow (pPeapServerDialog->hWndBtnConfigure, TRUE ); } return(FALSE); } /* Returns: TRUE: We prrocessed this message. FALSE: We did not prrocess this message. Notes: Response to the WM_COMMAND message (Config UI). */ BOOL PeapServerCommand( IN PPEAP_SERVER_CONFIG_DIALOG pPeapServerDialog, IN WORD wNotifyCode, IN WORD wId, IN HWND hWndDlg, IN HWND hWndCtrl ) { switch(wId) { case IDC_COMBO_SERVER_NAME: if (CBN_SELCHANGE != wNotifyCode) { return(FALSE); // We will not process this message } pPeapServerDialog->pSelCertList = (EAPTLS_CERT_NODE *) SendMessage ( hWndCtrl, CB_GETITEMDATA, SendMessage(hWndCtrl, CB_GETCURSEL, 0,0L ), 0L ); PeapDisplayCertInfo(pPeapServerDialog); return(TRUE); case IDC_COMBO_PEAP_TYPE: if (CBN_SELCHANGE != wNotifyCode) { return(FALSE); // We will not process this message } //Fall Through... case IDC_BUTTON_CONFIGURE: { INT nIndex = -1; nIndex = (INT)SendMessage ( pPeapServerDialog->hWndComboPeapType, CB_GETCURSEL, 0,0 ); if ( nIndex != -1 ) { // // Change the currently selected EAP Type. // pPeapServerDialog->pSelEapInfo = (PPEAP_EAP_INFO) SendMessage ( pPeapServerDialog->hWndComboPeapType, CB_GETITEMDATA, (WPARAM)nIndex, (LPARAM)0 ); if ( pPeapServerDialog->pSelEapInfo->lpwszConfigClsId ) { EnableWindow(pPeapServerDialog->hWndBtnConfigure, TRUE ); if ( wId == IDC_BUTTON_CONFIGURE ) { // // Invoke the configure method for selected eap type and if no error is // returned, then set the new configuration // PeapEapInfoInvokeServerConfigUI ( hWndDlg, pPeapServerDialog->pwszMachineName, pPeapServerDialog->pSelEapInfo ); } } else { // // There is no configuration option here. // EnableWindow(pPeapServerDialog->hWndBtnConfigure, FALSE ); } } else { EnableWindow(pPeapServerDialog->hWndBtnConfigure, FALSE ); pPeapServerDialog->pSelEapInfo = NULL; } return TRUE; } case IDOK: { // Setup new PPEAP_USER_PROP here. // EAPTLS_HASH * pHash = NULL; DWORD dwNumHash = 0; DWORD dwSelCount = 0; DWORD dwPeapConnBlobSize = 0; PPEAP_USER_PROP pUserProp = NULL; if ( NULL == pPeapServerDialog->pSelCertList ) { DisplayResourceError ( hWndDlg, IDS_PEAP_NO_SERVER_CERT ); return TRUE; } if ( !pPeapServerDialog->pSelCertList->pwszDisplayName ) { DisplayResourceError ( hWndDlg, IDS_PEAP_NO_SERVER_CERT ); return TRUE; } if ( !wcslen(pPeapServerDialog->pSelCertList->pwszDisplayName) ) { DisplayResourceError ( hWndDlg, IDS_PEAP_NO_SERVER_CERT ); return TRUE; } if ( NULL == pPeapServerDialog->pSelEapInfo ) { DisplayResourceError ( hWndDlg, IDS_PEAP_NO_EAP_TYPE ); return TRUE; } pUserProp = (PPEAP_USER_PROP)LocalAlloc(LPTR, sizeof(PEAP_USER_PROP)); if ( NULL == pUserProp ) { EapTlsTrace("LocalAlloc in Command failed and returned %d", GetLastError()); } else { pUserProp->dwVersion = 1; pUserProp->dwSize = sizeof(PEAP_USER_PROP); CopyMemory( &pUserProp->CertHash, &(pPeapServerDialog->pSelCertList->Hash), sizeof(pUserProp->CertHash) ); // // If Fast Roaming is enabled, then set it in our user prop struct. // if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_ENABLE_FAST_RECONNECT)) { pUserProp->dwFlags |= PEAP_USER_FLAG_FAST_ROAMING; } else { pUserProp->dwFlags &= ~PEAP_USER_FLAG_FAST_ROAMING; } pUserProp->UserProperties.dwVersion = 1; pUserProp->UserProperties.dwSize = sizeof(PEAP_ENTRY_USER_PROPERTIES ); pUserProp->UserProperties.dwEapTypeId = pPeapServerDialog->pSelEapInfo->dwTypeId; pPeapServerDialog->pNewUserProp = pUserProp; } } // Fall through case IDCANCEL: EndDialog(hWndDlg, wId); return(TRUE); default: return(FALSE); } } INT_PTR CALLBACK PeapServerDialogProc( IN HWND hWnd, IN UINT unMsg, IN WPARAM wParam, IN LPARAM lParam ) { PPEAP_SERVER_CONFIG_DIALOG pPeapServerDialog; switch (unMsg) { case WM_INITDIALOG: return(PeapServerInitDialog(hWnd, lParam)); case WM_HELP: case WM_CONTEXTMENU: { ContextHelp(g_adwHelp, hWnd, unMsg, wParam, lParam); break; } case WM_COMMAND: pPeapServerDialog = (PPEAP_SERVER_CONFIG_DIALOG)GetWindowLongPtr(hWnd, DWLP_USER); return(PeapServerCommand(pPeapServerDialog, HIWORD(wParam), LOWORD(wParam), hWnd, (HWND)lParam)); } return(FALSE); } #endif ///// //// Default credentials UI //// BOOL DefaultCredInitDialog( IN HWND hWnd, IN LPARAM lParam ) { PPEAP_DEFAULT_CRED_DIALOG pDefaultCredDialog; SetWindowLongPtr( hWnd, DWLP_USER, lParam); pDefaultCredDialog = (PPEAP_DEFAULT_CRED_DIALOG)lParam; pDefaultCredDialog->hWndUserName= GetDlgItem(hWnd, IDC_EDIT_USERNAME); pDefaultCredDialog->hWndPassword= GetDlgItem(hWnd, IDC_EDIT_PASSWORD); pDefaultCredDialog->hWndDomain= GetDlgItem(hWnd, IDC_EDIT_DOMAIN); SendMessage(pDefaultCredDialog->hWndUserName, EM_LIMITTEXT, UNLEN, 0L ); SendMessage(pDefaultCredDialog->hWndPassword, EM_LIMITTEXT, PWLEN, 0L ); SendMessage(pDefaultCredDialog->hWndDomain, EM_LIMITTEXT, DNLEN, 0L ); if ( pDefaultCredDialog->PeapDefaultCredentials.wszUserName[0] ) { SetWindowText( pDefaultCredDialog->hWndUserName, pDefaultCredDialog->PeapDefaultCredentials.wszUserName ); } if ( pDefaultCredDialog->PeapDefaultCredentials.wszPassword[0] ) { SetWindowText( pDefaultCredDialog->hWndPassword, pDefaultCredDialog->PeapDefaultCredentials.wszPassword ); } if ( pDefaultCredDialog->PeapDefaultCredentials.wszDomain[0] ) { SetWindowText( pDefaultCredDialog->hWndDomain, pDefaultCredDialog->PeapDefaultCredentials.wszDomain ); } return(FALSE); } /* Returns: TRUE: We prrocessed this message. FALSE: We did not prrocess this message. Notes: Response to the WM_COMMAND message (Config UI). */ BOOL DefaultCredCommand( IN PPEAP_DEFAULT_CRED_DIALOG pDefaultCredDialog, IN WORD wNotifyCode, IN WORD wId, IN HWND hWndDlg, IN HWND hWndCtrl ) { switch(wId) { case IDOK: // //grab info from the fields and set it in //the logon dialog structure // GetWindowText( pDefaultCredDialog->hWndUserName, pDefaultCredDialog->PeapDefaultCredentials.wszUserName, UNLEN+1 ); GetWindowText( pDefaultCredDialog->hWndPassword, pDefaultCredDialog->PeapDefaultCredentials.wszPassword, PWLEN+1 ); GetWindowText ( pDefaultCredDialog->hWndDomain, pDefaultCredDialog->PeapDefaultCredentials.wszDomain, DNLEN+1 ); // Fall through case IDCANCEL: EndDialog(hWndDlg, wId); return(TRUE); default: return(FALSE); } } INT_PTR CALLBACK DefaultCredDialogProc( IN HWND hWnd, IN UINT unMsg, IN WPARAM wParam, IN LPARAM lParam ) { PPEAP_DEFAULT_CRED_DIALOG pDefaultCredDialog; switch (unMsg) { case WM_INITDIALOG: return(DefaultCredInitDialog(hWnd, lParam)); case WM_HELP: case WM_CONTEXTMENU: { ContextHelp(g_adwHelp, hWnd, unMsg, wParam, lParam); break; } case WM_COMMAND: pDefaultCredDialog = (PPEAP_DEFAULT_CRED_DIALOG)GetWindowLongPtr(hWnd, DWLP_USER); return(DefaultCredCommand(pDefaultCredDialog, HIWORD(wParam), LOWORD(wParam), hWnd, (HWND)lParam)); } return(FALSE); }