|
|
/*
Copyright (c) 1997, Microsoft Corporation, all rights reserved
Description:
History: Nov 1997: Vijay Baliga created original version.
*/
#include <nt.h> // Required by windows.h
#include <ntrtl.h> // Required by windows.h
#include <nturtl.h> // Required by windows.h
#include <windows.h> // Win32 base API's
#include <windowsx.h>
#include <stdio.h> // For swprintf
#include <rasauth.h> // Required by raseapif.h
#include <rtutils.h> // For RTASSERT
#include <rasman.h> // For EAPLOGONINFO
#include <raserror.h> // For ERROR_NO_SMART_CARD_READER
#include <eaptypeid.h>
#include <commctrl.h>
#if WINVER > 0x0500
#include "wzcsapi.h"
#endif
#include <schannel.h>
#define SECURITY_WIN32
#include <security.h> // For GetUserNameExA, CredHandle
#include <sspi.h> // For CredHandle
#include <wincrypt.h>
#include <eaptls.h>
#include <resource.h>
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); }
|