Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

5557 lines
158 KiB

  1. /*
  2. Copyright (c) 1997, Microsoft Corporation, all rights reserved
  3. Description:
  4. History:
  5. Nov 1997: Vijay Baliga created original version.
  6. */
  7. #include <nt.h> // Required by windows.h
  8. #include <ntrtl.h> // Required by windows.h
  9. #include <nturtl.h> // Required by windows.h
  10. #include <windows.h> // Win32 base API's
  11. #include <windowsx.h>
  12. #include <stdio.h> // For swprintf
  13. #include <rasauth.h> // Required by raseapif.h
  14. #include <rtutils.h> // For RTASSERT
  15. #include <rasman.h> // For EAPLOGONINFO
  16. #include <raserror.h> // For ERROR_NO_SMART_CARD_READER
  17. #include <eaptypeid.h>
  18. #include <commctrl.h>
  19. #if WINVER > 0x0500
  20. #include "wzcsapi.h"
  21. #endif
  22. #include <schannel.h>
  23. #define SECURITY_WIN32
  24. #include <security.h> // For GetUserNameExA, CredHandle
  25. #include <sspi.h> // For CredHandle
  26. #include <wincrypt.h>
  27. #include <eaptls.h>
  28. #include <resource.h>
  29. const DWORD g_adwHelp[] =
  30. {
  31. IDC_RADIO_USE_CARD, IDH_RADIO_USE_CARD,
  32. IDC_RADIO_USE_REGISTRY, IDH_RADIO_USE_REGISTRY,
  33. IDC_CHECK_VALIDATE_CERT, IDH_CHECK_VALIDATE_CERT,
  34. IDC_CHECK_VALIDATE_NAME, IDH_CHECK_VALIDATE_NAME,
  35. IDC_EDIT_SERVER_NAME, IDH_EDIT_SERVER_NAME,
  36. IDC_STATIC_ROOT_CA_NAME, IDH_COMBO_ROOT_CA_NAME,
  37. IDC_CHECK_DIFF_USER, IDH_CHECK_DIFF_USER,
  38. IDC_STATIC_DIFF_USER, IDH_EDIT_DIFF_USER,
  39. IDC_EDIT_DIFF_USER, IDH_EDIT_DIFF_USER,
  40. IDC_STATIC_PIN, IDH_EDIT_PIN,
  41. IDC_EDIT_PIN, IDH_EDIT_PIN,
  42. IDC_CHECK_SAVE_PIN, IDH_CHECK_SAVE_PIN,
  43. IDC_STATIC_SERVER_NAME, IDH_COMBO_SERVER_NAME,
  44. IDC_COMBO_SERVER_NAME, IDH_COMBO_SERVER_NAME,
  45. IDC_STATIC_USER_NAME, IDH_COMBO_USER_NAME,
  46. IDC_COMBO_USER_NAME, IDH_COMBO_USER_NAME,
  47. IDC_STATIC_FRIENDLY_NAME, IDH_EDIT_FRIENDLY_NAME,
  48. IDC_EDIT_FRIENDLY_NAME, IDH_EDIT_FRIENDLY_NAME,
  49. IDC_STATIC_ISSUER, IDH_EDIT_ISSUER,
  50. IDC_EDIT_ISSUER, IDH_EDIT_ISSUER,
  51. IDC_STATIC_EXPIRATION, IDH_EDIT_EXPIRATION,
  52. IDC_EDIT_EXPIRATION, IDH_EDIT_EXPIRATION,
  53. 0, 0
  54. };
  55. /*
  56. Returns:
  57. VOID
  58. Notes:
  59. Calls WinHelp to popup context sensitive help. padwMap is an array of
  60. control-ID help-ID pairs terminated with a 0,0 pair. unMsg is WM_HELP or
  61. WM_CONTEXTMENU indicating the message received requesting help. wParam and
  62. lParam are the parameters of the message received requesting help.
  63. */
  64. VOID
  65. ContextHelp(
  66. IN const DWORD* padwMap,
  67. IN HWND hWndDlg,
  68. IN UINT unMsg,
  69. IN WPARAM wParam,
  70. IN LPARAM lParam
  71. )
  72. {
  73. HWND hWnd;
  74. UINT unType;
  75. WCHAR* pwszHelpFile = NULL;
  76. HELPINFO* pHelpInfo;
  77. if (unMsg == WM_HELP)
  78. {
  79. pHelpInfo = (HELPINFO*) lParam;
  80. if (pHelpInfo->iContextType != HELPINFO_WINDOW)
  81. {
  82. goto LDone;
  83. }
  84. hWnd = pHelpInfo->hItemHandle;
  85. unType = HELP_WM_HELP;
  86. }
  87. else
  88. {
  89. // Standard Win95 method that produces a one-item "What's This?" menu
  90. // that user must click to get help.
  91. hWnd = (HWND) wParam;
  92. unType = HELP_CONTEXTMENU;
  93. };
  94. pwszHelpFile = WszFromId(GetHInstance(), IDS_HELPFILE);
  95. if (NULL == pwszHelpFile)
  96. {
  97. goto LDone;
  98. }
  99. WinHelp(hWnd, pwszHelpFile, unType, (ULONG_PTR)padwMap);
  100. LDone:
  101. LocalFree(pwszHelpFile);
  102. }
  103. VOID
  104. DisplayResourceError (
  105. IN HWND hwndParent,
  106. IN DWORD dwResourceId
  107. )
  108. {
  109. WCHAR* pwszTitle = NULL;
  110. WCHAR* pwszMessage = NULL;
  111. pwszTitle = WszFromId(GetHInstance(), IDS_CANT_CONFIGURE_SERVER_TITLE);
  112. //
  113. // Check to see which file the resource is to be loaded
  114. //
  115. switch ( dwResourceId )
  116. {
  117. case IDS_VALIDATE_SERVER_TITLE:
  118. case IDS_CANT_CONFIGURE_SERVER_TEXT:
  119. case IDS_CONNECT:
  120. case IDS_HELPFILE:
  121. case IDS_PEAP_NO_SERVER_CERT:
  122. pwszMessage = WszFromId(GetHInstance(), dwResourceId);
  123. default:
  124. pwszMessage = WszFromId(GetResouceDLLHInstance(), dwResourceId);
  125. }
  126. MessageBox(hwndParent,
  127. (pwszMessage != NULL)? pwszMessage : L"",
  128. (pwszTitle != NULL) ? pwszTitle : L"",
  129. MB_OK | MB_ICONERROR);
  130. LocalFree(pwszTitle);
  131. LocalFree(pwszMessage);
  132. }
  133. /*
  134. Returns:
  135. VOID
  136. Notes:
  137. Display the error message corresponding to dwErrNum. Used only on the server
  138. side.
  139. */
  140. VOID
  141. DisplayError(
  142. IN HWND hwndParent,
  143. IN DWORD dwErrNum
  144. )
  145. {
  146. WCHAR* pwszTitle = NULL;
  147. WCHAR* pwszMessageFormat = NULL;
  148. WCHAR* pwszMessage = NULL;
  149. DWORD dwErr;
  150. pwszTitle = WszFromId(GetHInstance(), IDS_CANT_CONFIGURE_SERVER_TITLE);
  151. dwErr = MprAdminGetErrorString(dwErrNum, &pwszMessage);
  152. if (NO_ERROR != dwErr)
  153. {
  154. pwszMessageFormat = WszFromId(GetHInstance(),
  155. IDS_CANT_CONFIGURE_SERVER_TEXT);
  156. if (NULL != pwszMessageFormat)
  157. {
  158. pwszMessage = LocalAlloc(LPTR, wcslen(pwszMessageFormat) + 20);
  159. if (NULL != pwszMessage)
  160. {
  161. swprintf(pwszMessage, pwszMessageFormat, dwErrNum);
  162. }
  163. }
  164. }
  165. MessageBox(hwndParent,
  166. (pwszMessage != NULL)? pwszMessage : L"",
  167. (pwszTitle != NULL) ? pwszTitle : L"",
  168. MB_OK | MB_ICONERROR);
  169. LocalFree(pwszTitle);
  170. LocalFree(pwszMessageFormat);
  171. LocalFree(pwszMessage);
  172. }
  173. /* List view of check boxes state indices.
  174. */
  175. #define SI_Unchecked 1
  176. #define SI_Checked 2
  177. #define SI_DisabledUnchecked 3
  178. #define SI_DisabledChecked 4
  179. #define LVXN_SETCHECK (LVN_LAST + 1)
  180. //
  181. //Work arounds for bugs in list ctrl...
  182. //
  183. BOOL
  184. ListView_GetCheck(
  185. IN HWND hwndLv,
  186. IN INT iItem )
  187. /* Returns true if the check box of item 'iItem' of listview of checkboxes
  188. ** 'hwndLv' is checked, false otherwise. This function works on disabled
  189. ** check boxes as well as enabled ones.
  190. */
  191. {
  192. UINT unState;
  193. unState = ListView_GetItemState( hwndLv, iItem, LVIS_STATEIMAGEMASK );
  194. return !!((unState == INDEXTOSTATEIMAGEMASK( SI_Checked )) ||
  195. (unState == INDEXTOSTATEIMAGEMASK( SI_DisabledChecked )));
  196. }
  197. BOOL
  198. ListView_IsCheckDisabled (
  199. IN HWND hwndLv,
  200. IN INT iItem)
  201. /* Returns true if the check box of item 'iItem' of listview of checkboxes
  202. ** 'hwndLv' is disabled, false otherwise.
  203. */
  204. {
  205. UINT unState;
  206. unState = ListView_GetItemState( hwndLv, iItem, LVIS_STATEIMAGEMASK );
  207. if ((unState == INDEXTOSTATEIMAGEMASK( SI_DisabledChecked )) ||
  208. (unState == INDEXTOSTATEIMAGEMASK( SI_DisabledUnchecked )))
  209. return TRUE;
  210. return FALSE;
  211. }
  212. VOID
  213. ListView_SetCheck(
  214. IN HWND hwndLv,
  215. IN INT iItem,
  216. IN BOOL fCheck )
  217. /* Sets the check mark on item 'iItem' of listview of checkboxes 'hwndLv'
  218. ** to checked if 'fCheck' is true or unchecked if false.
  219. */
  220. {
  221. NM_LISTVIEW nmlv;
  222. if (ListView_IsCheckDisabled(hwndLv, iItem))
  223. return;
  224. ListView_SetItemState( hwndLv, iItem,
  225. INDEXTOSTATEIMAGEMASK( (fCheck) ? SI_Checked : SI_Unchecked ),
  226. LVIS_STATEIMAGEMASK );
  227. nmlv.hdr.code = LVXN_SETCHECK;
  228. nmlv.hdr.hwndFrom = hwndLv;
  229. nmlv.iItem = iItem;
  230. FORWARD_WM_NOTIFY(
  231. GetParent(hwndLv), GetDlgCtrlID(hwndLv), &nmlv, SendMessage
  232. );
  233. }
  234. /*
  235. Returns:
  236. FALSE (prevent Windows from setting the default keyboard focus).
  237. Notes:
  238. Response to the WM_INITDIALOG message.
  239. */
  240. BOOL
  241. PinInitDialog(
  242. IN HWND hWnd,
  243. IN LPARAM lParam
  244. )
  245. {
  246. EAPTLS_PIN_DIALOG* pEapTlsPinDialog;
  247. EAPTLS_USER_PROPERTIES* pUserProp;
  248. WCHAR* pwszTitleFormat = NULL;
  249. WCHAR* pwszTitle = NULL;
  250. WCHAR* pwszIdentity = NULL;
  251. SetWindowLongPtr(hWnd, DWLP_USER, lParam);
  252. pEapTlsPinDialog = (EAPTLS_PIN_DIALOG*)lParam;
  253. pUserProp = pEapTlsPinDialog->pUserProp;
  254. pEapTlsPinDialog->hWndStaticDiffUser =
  255. GetDlgItem(hWnd, IDC_STATIC_DIFF_USER);
  256. pEapTlsPinDialog->hWndEditDiffUser =
  257. GetDlgItem(hWnd, IDC_EDIT_DIFF_USER);
  258. pEapTlsPinDialog->hWndStaticPin =
  259. GetDlgItem(hWnd, IDC_STATIC_PIN);
  260. pEapTlsPinDialog->hWndEditPin =
  261. GetDlgItem(hWnd, IDC_EDIT_PIN);
  262. if (pUserProp->pwszDiffUser[0])
  263. {
  264. SetWindowText(pEapTlsPinDialog->hWndEditDiffUser,
  265. pUserProp->pwszDiffUser);
  266. }
  267. if (pUserProp->pwszPin[0])
  268. {
  269. SetWindowText(pEapTlsPinDialog->hWndEditPin, pUserProp->pwszPin);
  270. ZeroMemory(pUserProp->pwszPin,
  271. wcslen(pUserProp->pwszPin) * sizeof(WCHAR));
  272. }
  273. if (!(pEapTlsPinDialog->fFlags & EAPTLS_PIN_DIALOG_FLAG_DIFF_USER))
  274. {
  275. EnableWindow(pEapTlsPinDialog->hWndStaticDiffUser, FALSE);
  276. EnableWindow(pEapTlsPinDialog->hWndEditDiffUser, FALSE);
  277. }
  278. if (pUserProp->fFlags & EAPTLS_USER_FLAG_SAVE_PIN)
  279. {
  280. CheckDlgButton(hWnd, IDC_CHECK_SAVE_PIN, BST_CHECKED);
  281. }
  282. // Bug 428871 implies that SavePin must not be allowed.
  283. ShowWindow(GetDlgItem(hWnd, IDC_CHECK_SAVE_PIN), SW_HIDE);
  284. SetFocus(pEapTlsPinDialog->hWndEditPin);
  285. {
  286. // Set the title
  287. pwszTitleFormat = WszFromId(GetHInstance(), IDS_CONNECT);
  288. if (NULL != pwszTitleFormat)
  289. {
  290. pwszTitle = LocalAlloc(LPTR,
  291. (wcslen(pwszTitleFormat) +
  292. wcslen(pEapTlsPinDialog->pwszEntry)) *
  293. sizeof(WCHAR));
  294. if (NULL != pwszTitle)
  295. {
  296. swprintf(pwszTitle, pwszTitleFormat,
  297. pEapTlsPinDialog->pwszEntry);
  298. SetWindowText(hWnd, pwszTitle);
  299. }
  300. }
  301. }
  302. LocalFree(pwszTitleFormat);
  303. LocalFree(pwszTitle);
  304. return(FALSE);
  305. }
  306. void ValidatePIN ( IN EAPTLS_PIN_DIALOG* pEapTlsPinDialog )
  307. {
  308. pEapTlsPinDialog->dwRetCode =
  309. AssociatePinWithCertificate( pEapTlsPinDialog->pCertContext,
  310. pEapTlsPinDialog->pUserProp,
  311. FALSE,
  312. TRUE
  313. );
  314. return;
  315. }
  316. /*
  317. Returns:
  318. TRUE: We prrocessed this message.
  319. FALSE: We did not prrocess this message.
  320. Notes:
  321. Response to the WM_COMMAND message.
  322. */
  323. BOOL
  324. PinCommand(
  325. IN EAPTLS_PIN_DIALOG* pEapTlsPinDialog,
  326. IN WORD wNotifyCode,
  327. IN WORD wId,
  328. IN HWND hWndDlg,
  329. IN HWND hWndCtrl
  330. )
  331. {
  332. DWORD dwNumChars;
  333. DWORD dwNameLength;
  334. DWORD dwPinLength;
  335. DWORD dwSize;
  336. EAPTLS_USER_PROPERTIES* pUserProp;
  337. switch(wId)
  338. {
  339. case IDOK:
  340. dwNameLength = GetWindowTextLength(
  341. pEapTlsPinDialog->hWndEditDiffUser);
  342. dwPinLength = GetWindowTextLength(
  343. pEapTlsPinDialog->hWndEditPin);
  344. // There is already one character in awszString.
  345. // Add the number of characters in DiffUser...
  346. dwNumChars = dwNameLength;
  347. // Add the number of characters in PIN...
  348. dwNumChars += dwPinLength;
  349. // Add one more for a terminating NULL. Use the extra character in
  350. // awszString for the other terminating NULL.
  351. dwNumChars += 1;
  352. dwSize = sizeof(EAPTLS_USER_PROPERTIES) + dwNumChars*sizeof(WCHAR);
  353. pUserProp = LocalAlloc(LPTR, dwSize);
  354. if (NULL == pUserProp)
  355. {
  356. EapTlsTrace("LocalAlloc in Command failed and returned %d",
  357. GetLastError());
  358. }
  359. else
  360. {
  361. CopyMemory(pUserProp, pEapTlsPinDialog->pUserProp,
  362. sizeof(EAPTLS_USER_PROPERTIES));
  363. pUserProp->dwSize = dwSize;
  364. pUserProp->pwszDiffUser = pUserProp->awszString;
  365. GetWindowText(pEapTlsPinDialog->hWndEditDiffUser,
  366. pUserProp->pwszDiffUser,
  367. dwNameLength + 1);
  368. pUserProp->dwPinOffset = dwNameLength + 1;
  369. pUserProp->pwszPin = pUserProp->awszString +
  370. pUserProp->dwPinOffset;
  371. GetWindowText(pEapTlsPinDialog->hWndEditPin,
  372. pUserProp->pwszPin,
  373. dwPinLength + 1);
  374. LocalFree(pEapTlsPinDialog->pUserProp);
  375. pEapTlsPinDialog->pUserProp = pUserProp;
  376. }
  377. if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_SAVE_PIN))
  378. {
  379. pEapTlsPinDialog->pUserProp->fFlags |= EAPTLS_USER_FLAG_SAVE_PIN;
  380. }
  381. else
  382. {
  383. pEapTlsPinDialog->pUserProp->fFlags &= ~EAPTLS_USER_FLAG_SAVE_PIN;
  384. }
  385. //
  386. //Check if valid PIN has been entered and set the error code in pEapTlsPinDialog
  387. //
  388. ValidatePIN ( pEapTlsPinDialog);
  389. // Fall through
  390. case IDCANCEL:
  391. EndDialog(hWndDlg, wId);
  392. return(TRUE);
  393. default:
  394. return(FALSE);
  395. }
  396. }
  397. /*
  398. Returns:
  399. Notes:
  400. Callback function used with the DialogBoxParam function. It processes
  401. messages sent to the dialog box. See the DialogProc documentation in MSDN.
  402. */
  403. INT_PTR CALLBACK
  404. PinDialogProc(
  405. IN HWND hWnd,
  406. IN UINT unMsg,
  407. IN WPARAM wParam,
  408. IN LPARAM lParam
  409. )
  410. {
  411. EAPTLS_PIN_DIALOG* pEapTlsPinDialog;
  412. switch (unMsg)
  413. {
  414. case WM_INITDIALOG:
  415. return(PinInitDialog(hWnd, lParam));
  416. case WM_HELP:
  417. case WM_CONTEXTMENU:
  418. {
  419. ContextHelp(g_adwHelp, hWnd, unMsg, wParam, lParam);
  420. break;
  421. }
  422. case WM_COMMAND:
  423. pEapTlsPinDialog = (EAPTLS_PIN_DIALOG*)GetWindowLongPtr(hWnd, DWLP_USER);
  424. return(PinCommand(pEapTlsPinDialog, HIWORD(wParam), LOWORD(wParam),
  425. hWnd, (HWND)lParam));
  426. }
  427. return(FALSE);
  428. }
  429. /*
  430. ** Smart card and cert store accessing status dialog
  431. */
  432. INT_PTR CALLBACK
  433. StatusDialogProc(
  434. IN HWND hWnd,
  435. IN UINT unMsg,
  436. IN WPARAM wParam,
  437. IN LPARAM lParam
  438. )
  439. {
  440. switch (unMsg)
  441. {
  442. case WM_INITDIALOG:
  443. {
  444. ShowWindow(GetDlgItem(hWnd, IDC_BITMAP_SCARD),
  445. SW_SHOW
  446. );
  447. ShowWindow(GetDlgItem(hWnd, IDC_STATUS_SCARD),
  448. SW_SHOW
  449. );
  450. return TRUE;
  451. }
  452. }
  453. return FALSE;
  454. }
  455. /*
  456. Returns:
  457. VOID
  458. Notes:
  459. Enables or disables the controls in the "Validate server name" group.
  460. */
  461. VOID
  462. EnableValidateNameControls(
  463. IN EAPTLS_CONN_DIALOG* pEapTlsConnDialog
  464. )
  465. {
  466. BOOL fEnable;
  467. RTASSERT(NULL != pEapTlsConnDialog);
  468. fEnable = !(pEapTlsConnDialog->pConnPropv1->fFlags &
  469. EAPTLS_CONN_FLAG_NO_VALIDATE_CERT);
  470. EnableWindow(pEapTlsConnDialog->hWndCheckValidateName, fEnable);
  471. EnableWindow(pEapTlsConnDialog->hWndStaticRootCaName, fEnable);
  472. EnableWindow(pEapTlsConnDialog->hWndListRootCaName, fEnable);
  473. fEnable = ( fEnable
  474. && !(pEapTlsConnDialog->pConnPropv1->fFlags &
  475. EAPTLS_CONN_FLAG_NO_VALIDATE_NAME));
  476. EnableWindow(pEapTlsConnDialog->hWndEditServerName, fEnable);
  477. fEnable = pEapTlsConnDialog->pConnPropv1->fFlags
  478. & EAPTLS_CONN_FLAG_REGISTRY;
  479. EnableWindow( pEapTlsConnDialog->hWndCheckUseSimpleSel, fEnable );
  480. }
  481. /*
  482. Returns:
  483. VOID
  484. Notes:
  485. Displays the cert information
  486. */
  487. VOID
  488. DisplayCertInfo(
  489. IN EAPTLS_USER_DIALOG* pEapTlsUserDialog
  490. )
  491. {
  492. RTASSERT(NULL != pEapTlsUserDialog);
  493. // Erase old values first
  494. SetWindowText(pEapTlsUserDialog->hWndEditFriendlyName, L"");
  495. SetWindowText(pEapTlsUserDialog->hWndEditIssuer, L"");
  496. SetWindowText(pEapTlsUserDialog->hWndEditExpiration, L"");
  497. SetWindowText(pEapTlsUserDialog->hWndEditDiffUser, L"");
  498. if (NULL != pEapTlsUserDialog->pCert)
  499. {
  500. if (NULL != pEapTlsUserDialog->pCert->pwszFriendlyName)
  501. {
  502. SetWindowText(pEapTlsUserDialog->hWndEditFriendlyName,
  503. pEapTlsUserDialog->pCert->pwszFriendlyName);
  504. }
  505. if (NULL != pEapTlsUserDialog->pCert->pwszIssuer)
  506. {
  507. SetWindowText(pEapTlsUserDialog->hWndEditIssuer,
  508. pEapTlsUserDialog->pCert->pwszIssuer);
  509. }
  510. if (NULL != pEapTlsUserDialog->pCert->pwszExpiration)
  511. {
  512. SetWindowText(pEapTlsUserDialog->hWndEditExpiration,
  513. pEapTlsUserDialog->pCert->pwszExpiration);
  514. }
  515. if ( (NULL != pEapTlsUserDialog->pCert->pwszDisplayName)
  516. && (NULL != pEapTlsUserDialog->hWndEditDiffUser)
  517. && (EAPTLS_USER_DIALOG_FLAG_DIFF_USER & pEapTlsUserDialog->fFlags))
  518. {
  519. SetWindowText(pEapTlsUserDialog->hWndEditDiffUser,
  520. pEapTlsUserDialog->pCert->pwszDisplayName);
  521. }
  522. }
  523. }
  524. VOID InitComboBoxFromGroup (
  525. IN HWND hWnd,
  526. IN PEAPTLS_GROUPED_CERT_NODES pGroupList,
  527. IN EAPTLS_CERT_NODE* pCert //Selected certificate
  528. )
  529. {
  530. DWORD dwIndex;
  531. DWORD dwItemIndex;
  532. WCHAR* pwszDisplayName;
  533. PEAPTLS_GROUPED_CERT_NODES pGListTemp = pGroupList;
  534. SendMessage(hWnd, CB_RESETCONTENT, 0, 0);
  535. dwIndex = 0;
  536. dwItemIndex = 0;
  537. while (NULL != pGListTemp)
  538. {
  539. pwszDisplayName = pGListTemp->pwszDisplayName;
  540. if (NULL == pwszDisplayName)
  541. {
  542. pwszDisplayName = L" ";
  543. }
  544. SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)pwszDisplayName);
  545. if (pGListTemp->pMostRecentCert == pCert)
  546. {
  547. dwItemIndex = dwIndex;
  548. }
  549. pGListTemp = pGListTemp->pNext;
  550. dwIndex++;
  551. }
  552. SendMessage(hWnd, CB_SETCURSEL, dwItemIndex, 0);
  553. }
  554. /*
  555. Returns:
  556. VOID
  557. Notes:
  558. Initializes a combo box
  559. */
  560. VOID
  561. InitComboBox(
  562. IN HWND hWnd,
  563. IN EAPTLS_CERT_NODE* pCertList,
  564. IN EAPTLS_CERT_NODE* pCert
  565. )
  566. {
  567. DWORD dwIndex;
  568. DWORD dwItemIndex;
  569. WCHAR* pwszDisplayName;
  570. SendMessage(hWnd, CB_RESETCONTENT, 0, 0);
  571. dwIndex = 0;
  572. dwItemIndex = 0;
  573. while (NULL != pCertList)
  574. {
  575. pwszDisplayName = pCertList->pwszDisplayName;
  576. if (NULL == pwszDisplayName)
  577. {
  578. pwszDisplayName = L" ";
  579. }
  580. SendMessage(hWnd, CB_ADDSTRING, 0, (LPARAM)pwszDisplayName);
  581. SendMessage(hWnd, CB_SETITEMDATA, (WORD)dwIndex, (LPARAM)pCertList);
  582. if (pCertList == pCert)
  583. {
  584. dwItemIndex = dwIndex;
  585. }
  586. pCertList = pCertList->pNext;
  587. dwIndex++;
  588. }
  589. SendMessage(hWnd, CB_SETCURSEL, dwItemIndex, 0);
  590. }
  591. /*
  592. Returns:
  593. VOID
  594. Notes:
  595. Initializes a List box with selected certs
  596. */
  597. VOID InitListBox ( IN HWND hWnd,
  598. IN EAPTLS_CERT_NODE * pCertList,
  599. IN DWORD dwNumSelCerts,
  600. IN EAPTLS_CERT_NODE ** ppSelectedCertList
  601. )
  602. {
  603. int nIndex = 0;
  604. int nNewIndex = 0;
  605. DWORD dw = 0;
  606. WCHAR* pwszDisplayName;
  607. LVITEM lvItem;
  608. ListView_DeleteAllItems(hWnd);
  609. while (NULL != pCertList)
  610. {
  611. pwszDisplayName = pCertList->pwszDisplayName;
  612. if (NULL == pwszDisplayName)
  613. {
  614. pCertList = pCertList->pNext;
  615. continue;
  616. }
  617. ZeroMemory(&lvItem, sizeof(lvItem));
  618. lvItem.mask = LVIF_TEXT|LVIF_PARAM;
  619. lvItem.pszText = pwszDisplayName;
  620. lvItem.iItem = nIndex;
  621. lvItem.lParam = (LPARAM)pCertList;
  622. nNewIndex = ListView_InsertItem ( hWnd, &lvItem );
  623. for ( dw = 0; dw < dwNumSelCerts; dw ++ )
  624. {
  625. if ( pCertList == *(ppSelectedCertList+dw) )
  626. {
  627. ListView_SetCheckState(hWnd, nNewIndex,TRUE);
  628. }
  629. }
  630. nIndex++;
  631. pCertList = pCertList->pNext;
  632. }
  633. ListView_SetItemState( hWnd,
  634. 0,
  635. LVIS_FOCUSED|LVIS_SELECTED,
  636. LVIS_FOCUSED|LVIS_SELECTED
  637. );
  638. }
  639. VOID CertListSelectedCount ( HWND hWndCtrl,
  640. DWORD * pdwSelCertCount )
  641. {
  642. DWORD dwItemIndex = 0;
  643. DWORD dwItemCount = 0;
  644. dwItemCount = ListView_GetItemCount(hWndCtrl);
  645. *pdwSelCertCount = 0;
  646. for ( dwItemIndex = 0; dwItemIndex < dwItemCount; dwItemIndex ++ )
  647. {
  648. if ( ListView_GetCheckState(hWndCtrl, dwItemIndex) )
  649. {
  650. (*pdwSelCertCount) ++;
  651. }
  652. }
  653. }
  654. VOID
  655. CertListSelected(
  656. IN HWND hWndCtrl, //Handle to the list box
  657. IN EAPTLS_CERT_NODE* pCertList, //List of certs in the listbox
  658. IN OUT EAPTLS_CERT_NODE** ppSelCertList, //List of selected
  659. IN OUT EAPTLS_HASH* pHash, //List of Hash
  660. IN DWORD dwNumHash //Number of Items in the list
  661. )
  662. {
  663. DWORD dwItemIndex = 0;
  664. DWORD dwItemCount = ListView_GetItemCount(hWndCtrl);
  665. DWORD dwCertIndex = 0;
  666. LVITEM lvitem;
  667. if (NULL == pCertList)
  668. {
  669. return;
  670. }
  671. //Skip the one with null display name...
  672. pCertList = pCertList->pNext;
  673. //
  674. //Need to do two iterations on the list box.
  675. //I am sure there is a better way of doing this but
  676. //I just dont know...
  677. //
  678. for ( dwItemIndex = 0; dwItemIndex < dwItemCount; dwItemIndex ++ )
  679. {
  680. if ( ListView_GetCheckState(hWndCtrl, dwItemIndex) )
  681. {
  682. ZeroMemory( &lvitem, sizeof(lvitem) );
  683. lvitem.mask = LVIF_PARAM;
  684. lvitem.iItem = dwItemIndex;
  685. ListView_GetItem(hWndCtrl, &lvitem);
  686. *(ppSelCertList + dwCertIndex ) = (EAPTLS_CERT_NODE *)lvitem.lParam;
  687. CopyMemory ( pHash + dwCertIndex,
  688. &(((EAPTLS_CERT_NODE *)lvitem.lParam)->Hash),
  689. sizeof(EAPTLS_HASH)
  690. );
  691. dwCertIndex ++;
  692. }
  693. }
  694. }
  695. /*
  696. Returns:
  697. VOID
  698. Notes:
  699. hWndCtrl is the HWND of a combo box. pCertList is the associated list of
  700. certs. *ppCert will ultimately point to the cert that was selected. Its
  701. hash will be stored in *pHash.
  702. */
  703. VOID
  704. CertSelected(
  705. IN HWND hWndCtrl,
  706. IN EAPTLS_CERT_NODE* pCertList,
  707. IN EAPTLS_CERT_NODE** ppCert,
  708. IN EAPTLS_HASH* pHash
  709. )
  710. {
  711. LONG_PTR lIndex;
  712. LRESULT lrItemIndex;
  713. if (NULL == pCertList)
  714. {
  715. return;
  716. }
  717. if ( NULL == hWndCtrl )
  718. {
  719. lrItemIndex = 0;
  720. }
  721. else
  722. {
  723. lrItemIndex = SendMessage(hWndCtrl, CB_GETCURSEL, 0, 0);
  724. }
  725. for (lIndex = 0; lIndex != lrItemIndex; lIndex++)
  726. {
  727. pCertList = pCertList->pNext;
  728. }
  729. *ppCert = pCertList;
  730. CopyMemory(pHash, &(pCertList->Hash), sizeof(EAPTLS_HASH));
  731. }
  732. VOID
  733. GroupCertSelected(
  734. IN HWND hWndCtrl,
  735. IN PEAPTLS_GROUPED_CERT_NODES pGroupList,
  736. IN EAPTLS_CERT_NODE** ppCert,
  737. IN EAPTLS_HASH* pHash
  738. )
  739. {
  740. LONG_PTR lIndex;
  741. LRESULT lrItemIndex;
  742. PEAPTLS_GROUPED_CERT_NODES pGList = pGroupList;
  743. if (NULL == pGList)
  744. {
  745. return;
  746. }
  747. if ( NULL == hWndCtrl )
  748. {
  749. lrItemIndex = 0;
  750. }
  751. else
  752. {
  753. lrItemIndex = SendMessage(hWndCtrl, CB_GETCURSEL, 0, 0);
  754. }
  755. //
  756. // This is really a very bogus way of doing things...
  757. // We can setup a itemdata for this in the control itself...
  758. //
  759. for (lIndex = 0; lIndex != lrItemIndex; lIndex++)
  760. {
  761. pGList = pGList ->pNext;
  762. }
  763. *ppCert = pGList->pMostRecentCert;
  764. CopyMemory(pHash, &(pGList ->pMostRecentCert->Hash), sizeof(EAPTLS_HASH));
  765. }
  766. /*
  767. Returns:
  768. FALSE (prevent Windows from setting the default keyboard focus).
  769. Notes:
  770. Response to the WM_INITDIALOG message.
  771. */
  772. BOOL
  773. UserInitDialog(
  774. IN HWND hWnd,
  775. IN LPARAM lParam
  776. )
  777. {
  778. EAPTLS_USER_DIALOG* pEapTlsUserDialog;
  779. WCHAR* pwszTitleFormat = NULL;
  780. WCHAR* pwszTitle = NULL;
  781. SetWindowLongPtr(hWnd, DWLP_USER, lParam);
  782. pEapTlsUserDialog = (EAPTLS_USER_DIALOG*)lParam;
  783. BringWindowToTop(hWnd);
  784. pEapTlsUserDialog->hWndComboUserName =
  785. GetDlgItem(hWnd, IDC_COMBO_USER_NAME);
  786. if (NULL == pEapTlsUserDialog->hWndComboUserName)
  787. {
  788. // We must be showing the server's cert selection dialog
  789. pEapTlsUserDialog->hWndComboUserName =
  790. GetDlgItem(hWnd, IDC_COMBO_SERVER_NAME);
  791. }
  792. pEapTlsUserDialog->hWndBtnViewCert =
  793. GetDlgItem(hWnd, IDC_BUTTON_VIEW_CERTIFICATE );
  794. pEapTlsUserDialog->hWndEditFriendlyName =
  795. GetDlgItem(hWnd, IDC_EDIT_FRIENDLY_NAME);
  796. pEapTlsUserDialog->hWndEditIssuer =
  797. GetDlgItem(hWnd, IDC_EDIT_ISSUER);
  798. pEapTlsUserDialog->hWndEditExpiration =
  799. GetDlgItem(hWnd, IDC_EDIT_EXPIRATION);
  800. pEapTlsUserDialog->hWndStaticDiffUser =
  801. GetDlgItem(hWnd, IDC_STATIC_DIFF_USER);
  802. pEapTlsUserDialog->hWndEditDiffUser =
  803. GetDlgItem(hWnd, IDC_EDIT_DIFF_USER);
  804. if ( pEapTlsUserDialog->fFlags & EAPTLS_USER_DIALOG_FLAG_USE_SIMPLE_CERTSEL
  805. )
  806. {
  807. InitComboBoxFromGroup(pEapTlsUserDialog->hWndComboUserName,
  808. pEapTlsUserDialog->pGroupedList,
  809. pEapTlsUserDialog->pCert);
  810. }
  811. else
  812. {
  813. InitComboBox(pEapTlsUserDialog->hWndComboUserName,
  814. pEapTlsUserDialog->pCertList,
  815. pEapTlsUserDialog->pCert);
  816. }
  817. if ( (NULL != pEapTlsUserDialog->hWndEditDiffUser)
  818. && (!(pEapTlsUserDialog->fFlags & EAPTLS_USER_DIALOG_FLAG_DIFF_USER)))
  819. {
  820. ShowWindow(pEapTlsUserDialog->hWndStaticDiffUser, SW_HIDE);
  821. ShowWindow(pEapTlsUserDialog->hWndEditDiffUser, SW_HIDE);
  822. }
  823. DisplayCertInfo(pEapTlsUserDialog);
  824. if (pEapTlsUserDialog->pUserProp->pwszDiffUser[0])
  825. {
  826. SetWindowText(pEapTlsUserDialog->hWndEditDiffUser,
  827. pEapTlsUserDialog->pUserProp->pwszDiffUser);
  828. }
  829. SetFocus(pEapTlsUserDialog->hWndComboUserName);
  830. if (pEapTlsUserDialog->fFlags & EAPTLS_USER_DIALOG_FLAG_DIFF_TITLE)
  831. {
  832. // Set the title
  833. pwszTitleFormat = WszFromId(GetHInstance(), IDS_CONNECT);
  834. if (NULL != pwszTitleFormat)
  835. {
  836. pwszTitle = LocalAlloc(LPTR,
  837. (wcslen(pwszTitleFormat) +
  838. wcslen(pEapTlsUserDialog->pwszEntry)) *
  839. sizeof(WCHAR));
  840. if (NULL != pwszTitle)
  841. {
  842. HWND hWndDuplicate = NULL;
  843. DWORD dwThreadProcessId = 0;
  844. DWORD dwRetCode = NO_ERROR;
  845. swprintf(pwszTitle, pwszTitleFormat,
  846. pEapTlsUserDialog->pwszEntry);
  847. if ((hWndDuplicate = FindWindow (NULL, pwszTitle)) != NULL)
  848. {
  849. GetWindowThreadProcessId (hWndDuplicate, &dwThreadProcessId);
  850. if ((GetCurrentProcessId ()) == dwThreadProcessId)
  851. {
  852. // Kill current dialog since old one may be in use
  853. if (!PostMessage (hWnd, WM_DESTROY, 0, 0))
  854. {
  855. dwRetCode = GetLastError ();
  856. EapTlsTrace("PostMessage failed with error %ld", dwRetCode);
  857. }
  858. goto LDone;
  859. }
  860. else
  861. {
  862. EapTlsTrace("Matching Window does not have same process id");
  863. }
  864. }
  865. else
  866. {
  867. EapTlsTrace ("FindWindow could not find matching window");
  868. }
  869. SetWindowText(hWnd, pwszTitle);
  870. }
  871. }
  872. }
  873. LDone:
  874. LocalFree(pwszTitleFormat);
  875. LocalFree(pwszTitle);
  876. return(FALSE);
  877. }
  878. /*
  879. Returns:
  880. TRUE: We prrocessed this message.
  881. FALSE: We did not prrocess this message.
  882. Notes:
  883. Response to the WM_COMMAND message.
  884. */
  885. BOOL
  886. UserCommand(
  887. IN EAPTLS_USER_DIALOG* pEapTlsUserDialog,
  888. IN WORD wNotifyCode,
  889. IN WORD wId,
  890. IN HWND hWndDlg,
  891. IN HWND hWndCtrl
  892. )
  893. {
  894. DWORD dwNumChars;
  895. DWORD dwTextLength;
  896. DWORD dwSize;
  897. EAPTLS_USER_PROPERTIES* pUserProp;
  898. HCERTSTORE hCertStore;
  899. PCCERT_CONTEXT pCertContext = NULL;
  900. switch(wId)
  901. {
  902. case IDC_BUTTON_VIEW_CERTIFICATE:
  903. {
  904. WCHAR szError[256];
  905. WCHAR szTitle[512] = {0};
  906. CRYPT_HASH_BLOB chb;
  907. GetWindowText(hWndDlg, szTitle, 511 );
  908. //
  909. // Show the certificate details here
  910. //
  911. if ( pEapTlsUserDialog->pCert )
  912. {
  913. //There is a selected cert - show details.
  914. hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,
  915. 0,
  916. 0,
  917. CERT_STORE_READONLY_FLAG |
  918. ((pEapTlsUserDialog->fIdentity) ?
  919. CERT_SYSTEM_STORE_CURRENT_USER:
  920. CERT_SYSTEM_STORE_LOCAL_MACHINE
  921. ),
  922. pEapTlsUserDialog->pwszStoreName
  923. );
  924. LoadString( GetResouceDLLHInstance(), IDS_NO_CERT_DETAILS,
  925. szError, 255);
  926. if ( !hCertStore )
  927. {
  928. MessageBox ( hWndDlg,
  929. szError,
  930. szTitle,
  931. MB_OK|MB_ICONSTOP
  932. );
  933. return(TRUE);
  934. }
  935. chb.cbData = pEapTlsUserDialog->pCert->Hash.cbHash;
  936. chb.pbData = pEapTlsUserDialog->pCert->Hash.pbHash;
  937. pCertContext = CertFindCertificateInStore(
  938. hCertStore,
  939. 0,
  940. 0,
  941. CERT_FIND_HASH,
  942. &chb,
  943. 0);
  944. if ( NULL == pCertContext )
  945. {
  946. MessageBox ( hWndDlg,
  947. szError,
  948. szTitle,
  949. MB_OK|MB_ICONSTOP
  950. );
  951. if ( hCertStore )
  952. CertCloseStore( hCertStore, CERT_CLOSE_STORE_FORCE_FLAG );
  953. return(TRUE);
  954. }
  955. //
  956. // Show Cert detail
  957. //
  958. ShowCertDetails ( hWndDlg, hCertStore, pCertContext );
  959. if ( pCertContext )
  960. CertFreeCertificateContext(pCertContext);
  961. if ( hCertStore )
  962. CertCloseStore( hCertStore, CERT_CLOSE_STORE_FORCE_FLAG );
  963. }
  964. return(TRUE);
  965. }
  966. case IDC_COMBO_USER_NAME:
  967. case IDC_COMBO_SERVER_NAME:
  968. if (CBN_SELCHANGE != wNotifyCode)
  969. {
  970. return(FALSE); // We will not process this message
  971. }
  972. if ( pEapTlsUserDialog->fFlags & EAPTLS_USER_DIALOG_FLAG_USE_SIMPLE_CERTSEL
  973. )
  974. {
  975. GroupCertSelected(hWndCtrl, pEapTlsUserDialog->pGroupedList,
  976. &(pEapTlsUserDialog->pCert), &(pEapTlsUserDialog->pUserProp->Hash));
  977. }
  978. else
  979. {
  980. CertSelected(hWndCtrl, pEapTlsUserDialog->pCertList,
  981. &(pEapTlsUserDialog->pCert), &(pEapTlsUserDialog->pUserProp->Hash));
  982. }
  983. DisplayCertInfo(pEapTlsUserDialog);
  984. return(TRUE);
  985. case IDOK:
  986. if ( pEapTlsUserDialog->fFlags & EAPTLS_USER_DIALOG_FLAG_USE_SIMPLE_CERTSEL
  987. )
  988. {
  989. GroupCertSelected(pEapTlsUserDialog->hWndComboUserName, pEapTlsUserDialog->pGroupedList,
  990. &(pEapTlsUserDialog->pCert), &(pEapTlsUserDialog->pUserProp->Hash));
  991. }
  992. else
  993. {
  994. CertSelected(pEapTlsUserDialog->hWndComboUserName, pEapTlsUserDialog->pCertList,
  995. &(pEapTlsUserDialog->pCert), &(pEapTlsUserDialog->pUserProp->Hash));
  996. }
  997. if (NULL != pEapTlsUserDialog->hWndEditDiffUser)
  998. {
  999. dwTextLength = GetWindowTextLength(
  1000. pEapTlsUserDialog->hWndEditDiffUser);
  1001. // There is already one character in awszString.
  1002. // Add the number of characters in DiffUser...
  1003. dwNumChars = dwTextLength;
  1004. // Add the number of characters in PIN...
  1005. dwNumChars += wcslen(pEapTlsUserDialog->pUserProp->pwszPin);
  1006. // Add one more for a terminating NULL. Use the extra character in
  1007. // awszString for the other terminating NULL.
  1008. dwNumChars += 1;
  1009. dwSize = sizeof(EAPTLS_USER_PROPERTIES) + dwNumChars*sizeof(WCHAR);
  1010. pUserProp = LocalAlloc(LPTR, dwSize);
  1011. if (NULL == pUserProp)
  1012. {
  1013. EapTlsTrace("LocalAlloc in Command failed and returned %d",
  1014. GetLastError());
  1015. }
  1016. else
  1017. {
  1018. CopyMemory(pUserProp, pEapTlsUserDialog->pUserProp,
  1019. sizeof(EAPTLS_USER_PROPERTIES));
  1020. pUserProp->dwSize = dwSize;
  1021. pUserProp->pwszDiffUser = pUserProp->awszString;
  1022. GetWindowText(pEapTlsUserDialog->hWndEditDiffUser,
  1023. pUserProp->pwszDiffUser,
  1024. dwTextLength + 1);
  1025. pUserProp->dwPinOffset = dwTextLength + 1;
  1026. pUserProp->pwszPin = pUserProp->awszString +
  1027. pUserProp->dwPinOffset;
  1028. wcscpy(pUserProp->pwszPin,
  1029. pEapTlsUserDialog->pUserProp->pwszPin);
  1030. ZeroMemory(pEapTlsUserDialog->pUserProp,
  1031. pEapTlsUserDialog->pUserProp->dwSize);
  1032. LocalFree(pEapTlsUserDialog->pUserProp);
  1033. pEapTlsUserDialog->pUserProp = pUserProp;
  1034. }
  1035. }
  1036. // Fall through
  1037. case IDCANCEL:
  1038. EndDialog(hWndDlg, wId);
  1039. return(TRUE);
  1040. default:
  1041. return(FALSE);
  1042. }
  1043. }
  1044. /*
  1045. Returns:
  1046. Notes:
  1047. Callback function used with the DialogBoxParam function. It processes
  1048. messages sent to the dialog box. See the DialogProc documentation in MSDN.
  1049. */
  1050. INT_PTR CALLBACK
  1051. UserDialogProc(
  1052. IN HWND hWnd,
  1053. IN UINT unMsg,
  1054. IN WPARAM wParam,
  1055. IN LPARAM lParam
  1056. )
  1057. {
  1058. EAPTLS_USER_DIALOG* pEapTlsUserDialog;
  1059. switch (unMsg)
  1060. {
  1061. case WM_INITDIALOG:
  1062. return(UserInitDialog(hWnd, lParam));
  1063. case WM_HELP:
  1064. case WM_CONTEXTMENU:
  1065. {
  1066. ContextHelp(g_adwHelp, hWnd, unMsg, wParam, lParam);
  1067. break;
  1068. }
  1069. case WM_COMMAND:
  1070. pEapTlsUserDialog = (EAPTLS_USER_DIALOG*)GetWindowLongPtr(hWnd, DWLP_USER);
  1071. return(UserCommand(pEapTlsUserDialog, HIWORD(wParam), LOWORD(wParam),
  1072. hWnd, (HWND)lParam));
  1073. case WM_DESTROY:
  1074. EndDialog(hWnd, IDCANCEL);
  1075. break;
  1076. }
  1077. return(FALSE);
  1078. }
  1079. VOID CenterWindow(HWND hWnd, HWND hWndParent, BOOL bRightTop)
  1080. {
  1081. RECT rcWndParent,
  1082. rcWnd;
  1083. // Get the window rect for the parent window.
  1084. //
  1085. if (hWndParent == NULL)
  1086. GetWindowRect(GetDesktopWindow(), &rcWndParent);
  1087. else
  1088. GetWindowRect(hWndParent, &rcWndParent);
  1089. // Get the window rect for the window to be centered.
  1090. //
  1091. GetWindowRect(hWnd, &rcWnd);
  1092. // Now center the window.
  1093. //
  1094. if (bRightTop)
  1095. {
  1096. SetWindowPos(hWnd, HWND_TOPMOST,
  1097. rcWndParent.right - (rcWnd.right - rcWnd.left) - 5,
  1098. GetSystemMetrics(SM_CYCAPTION) * 2,
  1099. 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
  1100. }
  1101. else
  1102. {
  1103. SetWindowPos(hWnd, NULL,
  1104. rcWndParent.left + (rcWndParent.right - rcWndParent.left - (rcWnd.right - rcWnd.left)) / 2,
  1105. rcWndParent.top + (rcWndParent.bottom - rcWndParent.top - (rcWnd.bottom - rcWnd.top)) / 2,
  1106. 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
  1107. }
  1108. }
  1109. void DeleteGroupedList(PEAPTLS_GROUPED_CERT_NODES pList)
  1110. {
  1111. PEAPTLS_GROUPED_CERT_NODES pTemp = NULL;
  1112. while ( pList )
  1113. {
  1114. pTemp = pList->pNext;
  1115. LocalFree(pList);
  1116. pList = pTemp;
  1117. }
  1118. }
  1119. DWORD
  1120. GroupCertificates ( EAPTLS_USER_DIALOG * pEapTlsUserDialog )
  1121. {
  1122. DWORD dwRetCode = NO_ERROR;
  1123. PEAPTLS_GROUPED_CERT_NODES pGroupList = NULL;
  1124. PEAPTLS_GROUPED_CERT_NODES pGroupListTemp = NULL;
  1125. EAPTLS_CERT_NODE* pCertList = pEapTlsUserDialog->pCertList;
  1126. EAPTLS_CERT_NODE* pSelCert = NULL;
  1127. BOOL fItemProcessed;
  1128. EapTlsTrace("GroupCertificates");
  1129. //
  1130. // This second pass to do grouping is not really required but
  1131. // is good in case we add
  1132. // something more to the groups later
  1133. //
  1134. while ( pCertList )
  1135. {
  1136. pGroupListTemp = pGroupList;
  1137. fItemProcessed = FALSE;
  1138. while ( pGroupListTemp )
  1139. {
  1140. if ( pCertList->pwszDisplayName &&
  1141. pGroupListTemp->pwszDisplayName &&
  1142. ! wcscmp( pCertList->pwszDisplayName,
  1143. pGroupListTemp->pwszDisplayName
  1144. )
  1145. )
  1146. {
  1147. //
  1148. // Found the group. Now check to see
  1149. // if the new cert is more current than
  1150. // the one we have in the group. If so,
  1151. //
  1152. if ( ! pGroupListTemp->pMostRecentCert )
  1153. {
  1154. pGroupListTemp->pMostRecentCert = pCertList;
  1155. fItemProcessed = TRUE;
  1156. break;
  1157. }
  1158. else
  1159. {
  1160. if ( CompareFileTime ( &(pGroupListTemp->pMostRecentCert->IssueDate),
  1161. &(pCertList->IssueDate)
  1162. ) < 0
  1163. )
  1164. {
  1165. pGroupListTemp->pMostRecentCert = pCertList;
  1166. }
  1167. //Or else drop the item.
  1168. fItemProcessed = TRUE;
  1169. break;
  1170. }
  1171. }
  1172. pGroupListTemp = pGroupListTemp->pNext;
  1173. }
  1174. if ( !fItemProcessed && pCertList->pwszDisplayName)
  1175. {
  1176. //
  1177. // need to create a new group
  1178. //
  1179. pGroupListTemp = (PEAPTLS_GROUPED_CERT_NODES)LocalAlloc(LPTR, sizeof(EAPTLS_GROUPED_CERT_NODES));
  1180. if ( NULL == pGroupListTemp )
  1181. {
  1182. dwRetCode = ERROR_OUTOFMEMORY;
  1183. goto LDone;
  1184. }
  1185. pGroupListTemp->pNext = pGroupList;
  1186. pGroupListTemp->pwszDisplayName = pCertList->pwszDisplayName;
  1187. pGroupListTemp->pMostRecentCert = pCertList;
  1188. pGroupList = pGroupListTemp;
  1189. }
  1190. pCertList = pCertList->pNext;
  1191. }
  1192. //
  1193. // now that we have grouped all the certs, check to see if
  1194. // the cert previously used is in the list. If so,
  1195. //
  1196. pGroupListTemp = pGroupList;
  1197. while ( pGroupListTemp )
  1198. {
  1199. if ( pEapTlsUserDialog->pCert == pGroupListTemp->pMostRecentCert )
  1200. {
  1201. pSelCert = pEapTlsUserDialog->pCert;
  1202. break;
  1203. }
  1204. pGroupListTemp = pGroupListTemp->pNext;
  1205. }
  1206. pEapTlsUserDialog->pGroupedList = pGroupList ;
  1207. pGroupList = NULL;
  1208. if ( NULL == pSelCert )
  1209. {
  1210. //
  1211. // Selected cert is not in the group.
  1212. //
  1213. pEapTlsUserDialog->pCert = pEapTlsUserDialog->pGroupedList->pMostRecentCert;
  1214. }
  1215. LDone:
  1216. DeleteGroupedList( pGroupList );
  1217. return dwRetCode;
  1218. }
  1219. /*
  1220. Returns:
  1221. Notes:
  1222. ppwszIdentity can be NULL.
  1223. Break up this ugly function.
  1224. */
  1225. DWORD
  1226. GetCertInfo(
  1227. IN BOOL fServer,
  1228. IN BOOL fRouterConfig,
  1229. IN DWORD dwFlags,
  1230. IN const WCHAR* pwszPhonebook,
  1231. IN const WCHAR* pwszEntry,
  1232. IN HWND hwndParent,
  1233. IN WCHAR* pwszStoreName,
  1234. IN EAPTLS_CONN_PROPERTIES_V1* pConnProp,
  1235. IN OUT EAPTLS_USER_PROPERTIES** ppUserProp,
  1236. OUT WCHAR** ppwszIdentity
  1237. )
  1238. {
  1239. INT_PTR nRet;
  1240. HCERTSTORE hCertStore = NULL;
  1241. CRYPT_HASH_BLOB HashBlob;
  1242. PCCERT_CONTEXT pCertContext = NULL;
  1243. DWORD dwCertFlags;
  1244. BOOL fRouter;
  1245. BOOL fDiffUser = FALSE;
  1246. BOOL fGotIdentity = FALSE;
  1247. WCHAR* pwszIdentity = NULL;
  1248. WCHAR* pwszTemp;
  1249. DWORD dwNumChars;
  1250. BOOL fLogon;
  1251. EAPTLS_USER_DIALOG EapTlsUserDialog;
  1252. EAPTLS_PIN_DIALOG EapTlsPinDialog;
  1253. EAPTLS_USER_PROPERTIES* pUserProp = NULL;
  1254. EAPTLS_USER_PROPERTIES* pUserPropTemp;
  1255. RASCREDENTIALS RasCredentials;
  1256. DWORD dwErr = NO_ERROR;
  1257. DWORD dwNumCerts = 0;
  1258. HWND hWndStatus = NULL;
  1259. RTASSERT(NULL != pwszStoreName);
  1260. RTASSERT(NULL != pConnProp);
  1261. RTASSERT(NULL != ppUserProp);
  1262. RTASSERT(NULL != *ppUserProp);
  1263. // ppwszIdentity can be NULL.
  1264. fRouter = dwFlags & RAS_EAP_FLAG_ROUTER;
  1265. fLogon = dwFlags & RAS_EAP_FLAG_LOGON;
  1266. EapTlsTrace("GetCertInfo");
  1267. pUserProp = *ppUserProp;
  1268. ZeroMemory(&EapTlsUserDialog, sizeof(EapTlsUserDialog));
  1269. ZeroMemory(&EapTlsPinDialog, sizeof(EapTlsPinDialog));
  1270. if (EAPTLS_CONN_FLAG_DIFF_USER & pConnProp->fFlags)
  1271. {
  1272. fDiffUser = TRUE;
  1273. EapTlsUserDialog.fFlags |= EAPTLS_USER_DIALOG_FLAG_DIFF_USER;
  1274. EapTlsPinDialog.fFlags |= EAPTLS_PIN_DIALOG_FLAG_DIFF_USER;
  1275. }
  1276. EapTlsUserDialog.pwszEntry = pwszEntry;
  1277. EapTlsPinDialog.pwszEntry = pwszEntry;
  1278. if ( fServer
  1279. || fRouter
  1280. || dwFlags & RAS_EAP_FLAG_MACHINE_AUTH //if this is a machine cert authentication
  1281. )
  1282. {
  1283. dwCertFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE;
  1284. }
  1285. else
  1286. {
  1287. dwCertFlags = CERT_SYSTEM_STORE_CURRENT_USER;
  1288. EapTlsUserDialog.fFlags |= EAPTLS_USER_DIALOG_FLAG_DIFF_TITLE;
  1289. }
  1290. //Use simple cert selection logic
  1291. if ( pConnProp->fFlags & EAPTLS_CONN_FLAG_SIMPLE_CERT_SEL )
  1292. {
  1293. EapTlsUserDialog.fFlags |= EAPTLS_USER_DIALOG_FLAG_USE_SIMPLE_CERTSEL;
  1294. }
  1295. if (fLogon)
  1296. {
  1297. if (pConnProp->fFlags & EAPTLS_CONN_FLAG_REGISTRY)
  1298. {
  1299. dwErr = ERROR_NO_REG_CERT_AT_LOGON;
  1300. goto LDone;
  1301. }
  1302. else
  1303. {
  1304. EapTlsPinDialog.fFlags |= EAPTLS_PIN_DIALOG_FLAG_LOGON;
  1305. }
  1306. }
  1307. if ( fRouter )
  1308. {
  1309. EapTlsPinDialog.fFlags |= EAPTLS_PIN_DIALOG_FLAG_ROUTER;
  1310. }
  1311. if ( !fServer
  1312. && !(pConnProp->fFlags & EAPTLS_CONN_FLAG_REGISTRY))
  1313. {
  1314. //this is smart card stuff
  1315. BOOL fCredentialsFound = FALSE;
  1316. BOOL fGotAllInfo = FALSE;
  1317. if ( dwFlags & RAS_EAP_FLAG_MACHINE_AUTH )
  1318. {
  1319. //
  1320. // Machine auth requested along with
  1321. // smart card auth so return an interactive
  1322. // mode error.
  1323. //
  1324. dwErr = ERROR_INTERACTIVE_MODE;
  1325. goto LDone;
  1326. }
  1327. hWndStatus = CreateDialogParam (GetResouceDLLHInstance(),
  1328. MAKEINTRESOURCE(IDD_SCARD_STATUS),
  1329. hwndParent,
  1330. StatusDialogProc,
  1331. 1
  1332. );
  1333. if ( NULL != hWndStatus )
  1334. {
  1335. CenterWindow(hWndStatus, NULL, FALSE);
  1336. ShowWindow(hWndStatus, SW_SHOW);
  1337. UpdateWindow(hWndStatus);
  1338. }
  1339. if (!FSmartCardReaderInstalled())
  1340. {
  1341. dwErr = ERROR_NO_SMART_CARD_READER;
  1342. goto LDone;
  1343. }
  1344. if (pUserProp->fFlags & EAPTLS_USER_FLAG_SAVE_PIN)
  1345. {
  1346. ZeroMemory(&RasCredentials, sizeof(RasCredentials));
  1347. RasCredentials.dwSize = sizeof(RasCredentials);
  1348. RasCredentials.dwMask = RASCM_Password;
  1349. dwErr = RasGetCredentials(pwszPhonebook, pwszEntry,
  1350. &RasCredentials);
  1351. if ( (dwErr == NO_ERROR)
  1352. && (RasCredentials.dwMask & RASCM_Password))
  1353. {
  1354. fCredentialsFound = TRUE;
  1355. }
  1356. else
  1357. {
  1358. pUserProp->fFlags &= ~EAPTLS_USER_FLAG_SAVE_PIN;
  1359. }
  1360. dwErr = NO_ERROR;
  1361. }
  1362. if ( fCredentialsFound
  1363. && ( !fDiffUser
  1364. || (0 != pUserProp->pwszDiffUser[0])))
  1365. {
  1366. fGotAllInfo = TRUE;
  1367. }
  1368. if ( !fGotAllInfo
  1369. && (dwFlags & RAS_EAP_FLAG_NON_INTERACTIVE))
  1370. {
  1371. dwErr = ERROR_INTERACTIVE_MODE;
  1372. goto LDone;
  1373. }
  1374. dwErr = GetCertFromCard(&pCertContext);
  1375. if (NO_ERROR != dwErr)
  1376. {
  1377. goto LDone;
  1378. }
  1379. //Check the time validity of the certificate
  1380. //got from the card
  1381. if ( !FCheckTimeValidity( pCertContext) )
  1382. {
  1383. dwErr = CERT_E_EXPIRED;
  1384. goto LDone;
  1385. }
  1386. pUserProp->Hash.cbHash = MAX_HASH_SIZE;
  1387. if (!CertGetCertificateContextProperty(pCertContext,
  1388. CERT_HASH_PROP_ID, pUserProp->Hash.pbHash,
  1389. &(pUserProp->Hash.cbHash)))
  1390. {
  1391. dwErr = GetLastError();
  1392. EapTlsTrace("CertGetCertificateContextProperty failed and "
  1393. "returned 0x%x", dwErr);
  1394. goto LDone;
  1395. }
  1396. EapTlsPinDialog.pUserProp = pUserProp;
  1397. if ( !fDiffUser
  1398. || (0 == pUserProp->pwszDiffUser[0]))
  1399. {
  1400. if (!FCertToStr(pCertContext, 0, fRouter, &pwszIdentity))
  1401. {
  1402. dwErr = E_FAIL;
  1403. goto LDone;
  1404. }
  1405. dwErr = AllocUserDataWithNewIdentity(pUserProp, pwszIdentity,
  1406. &pUserPropTemp);
  1407. LocalFree(pwszIdentity);
  1408. pwszIdentity = NULL;
  1409. if (NO_ERROR != dwErr)
  1410. {
  1411. goto LDone;
  1412. }
  1413. LocalFree(pUserProp);
  1414. EapTlsPinDialog.pUserProp = pUserProp = *ppUserProp = pUserPropTemp;
  1415. }
  1416. if (fCredentialsFound)
  1417. {
  1418. dwErr = AllocUserDataWithNewPin(
  1419. pUserProp,
  1420. (PBYTE)RasCredentials.szPassword,
  1421. lstrlen(RasCredentials.szPassword),
  1422. &pUserPropTemp);
  1423. if (NO_ERROR != dwErr)
  1424. {
  1425. goto LDone;
  1426. }
  1427. LocalFree(pUserProp);
  1428. EapTlsPinDialog.pUserProp = pUserProp = *ppUserProp = pUserPropTemp;
  1429. }
  1430. EapTlsPinDialog.pCertContext = pCertContext;
  1431. if ( !fGotAllInfo
  1432. || (dwFlags & RAS_EAP_FLAG_PREVIEW))
  1433. {
  1434. if ( NULL != hWndStatus )
  1435. {
  1436. DestroyWindow(hWndStatus);
  1437. hWndStatus = NULL;
  1438. }
  1439. nRet = DialogBoxParam(
  1440. GetHInstance(),
  1441. MAKEINTRESOURCE(IDD_USERNAME_PIN_UI),
  1442. hwndParent,
  1443. PinDialogProc,
  1444. (LPARAM)&EapTlsPinDialog);
  1445. // EapTlsPinDialog.pUserProp may have been realloced
  1446. pUserProp = *ppUserProp = EapTlsPinDialog.pUserProp;
  1447. if (-1 == nRet)
  1448. {
  1449. dwErr = GetLastError();
  1450. goto LDone;
  1451. }
  1452. else if (IDOK != nRet)
  1453. {
  1454. dwErr = ERROR_CANCELLED;
  1455. goto LDone;
  1456. }
  1457. ZeroMemory(&RasCredentials, sizeof(RasCredentials));
  1458. RasCredentials.dwSize = sizeof(RasCredentials);
  1459. RasCredentials.dwMask = RASCM_Password;
  1460. if (EapTlsPinDialog.pUserProp->fFlags & EAPTLS_USER_FLAG_SAVE_PIN)
  1461. {
  1462. wcscpy(RasCredentials.szPassword,
  1463. EapTlsPinDialog.pUserProp->pwszPin);
  1464. RasSetCredentials(pwszPhonebook, pwszEntry, &RasCredentials,
  1465. FALSE /* fClearCredentials */);
  1466. }
  1467. else
  1468. {
  1469. RasSetCredentials(pwszPhonebook, pwszEntry, &RasCredentials,
  1470. TRUE /* fClearCredentials */);
  1471. }
  1472. }
  1473. EncodePin(EapTlsPinDialog.pUserProp);
  1474. pwszIdentity = LocalAlloc(LPTR,
  1475. (wcslen(pUserProp->pwszDiffUser) + 1) * sizeof(WCHAR));
  1476. if (NULL == pwszIdentity)
  1477. {
  1478. dwErr = GetLastError();
  1479. EapTlsTrace("LocalAlloc failed and returned %d", dwErr);
  1480. goto LDone;
  1481. }
  1482. wcscpy(pwszIdentity, pUserProp->pwszDiffUser);
  1483. if (NULL != ppwszIdentity)
  1484. {
  1485. *ppwszIdentity = pwszIdentity;
  1486. pwszIdentity = NULL;
  1487. }
  1488. if (!fDiffUser)
  1489. {
  1490. pUserProp->pwszDiffUser[0] = 0;
  1491. }
  1492. if ( EapTlsPinDialog.dwRetCode != NO_ERROR )
  1493. dwErr = EapTlsPinDialog.dwRetCode ;
  1494. goto LDone;
  1495. }
  1496. dwCertFlags |= CERT_STORE_READONLY_FLAG;
  1497. hCertStore = CertOpenStore(
  1498. CERT_STORE_PROV_SYSTEM_W,
  1499. X509_ASN_ENCODING,
  1500. 0,
  1501. dwCertFlags,
  1502. pwszStoreName);
  1503. if (NULL == hCertStore)
  1504. {
  1505. dwErr = GetLastError();
  1506. EapTlsTrace("CertOpenStore failed and returned 0x%x", dwErr);
  1507. goto LDone;
  1508. }
  1509. if ( ( dwFlags & RAS_EAP_FLAG_MACHINE_AUTH) )
  1510. {
  1511. //if this is not machine authentication
  1512. //This is propably not the best way to do things.
  1513. //We should provide a way in which
  1514. //Get the default machine certificate and
  1515. //populate the out data structures...
  1516. dwErr = GetDefaultClientMachineCert(hCertStore, &pCertContext );
  1517. if ( NO_ERROR == dwErr )
  1518. {
  1519. EapTlsTrace("Got the default Machine Cert");
  1520. pUserProp->Hash.cbHash = MAX_HASH_SIZE;
  1521. if (!CertGetCertificateContextProperty(pCertContext,
  1522. CERT_HASH_PROP_ID, pUserProp->Hash.pbHash,
  1523. &(pUserProp->Hash.cbHash)))
  1524. {
  1525. dwErr = GetLastError();
  1526. EapTlsTrace("CertGetCertificateContextProperty failed and "
  1527. "returned 0x%x", dwErr);
  1528. }
  1529. pUserProp->pwszDiffUser[0] = 0;
  1530. if ( FMachineAuthCertToStr(pCertContext, &pwszIdentity))
  1531. {
  1532. //format the identity in the domain\machinename format.
  1533. FFormatMachineIdentity1 (pwszIdentity, ppwszIdentity );
  1534. pwszIdentity = NULL;
  1535. }
  1536. else
  1537. {
  1538. //if not possible get it from the subject field
  1539. if ( FCertToStr(pCertContext, 0, TRUE, &pwszIdentity))
  1540. {
  1541. //format the identity in the domain\machinename format.
  1542. FFormatMachineIdentity1 (pwszIdentity, ppwszIdentity );
  1543. pwszIdentity = NULL;
  1544. }
  1545. }
  1546. *ppUserProp = pUserProp;
  1547. }
  1548. goto LDone;
  1549. }
  1550. HashBlob.cbData = pUserProp->Hash.cbHash;
  1551. HashBlob.pbData = pUserProp->Hash.pbHash;
  1552. pCertContext = CertFindCertificateInStore(hCertStore, X509_ASN_ENCODING,
  1553. 0, CERT_FIND_HASH, &HashBlob, NULL);
  1554. if ( (NULL == pCertContext)
  1555. || ( fDiffUser
  1556. && (0 == pUserProp->pwszDiffUser[0])))
  1557. {
  1558. // We don't have complete information. Note that for registry certs,
  1559. // pwszDiffUser is not a different dialog.
  1560. if (fServer)
  1561. {
  1562. dwErr = GetDefaultMachineCert(hCertStore, &pCertContext);
  1563. if (NO_ERROR == dwErr)
  1564. {
  1565. pUserProp->Hash.cbHash = MAX_HASH_SIZE;
  1566. if (!CertGetCertificateContextProperty(pCertContext,
  1567. CERT_HASH_PROP_ID, pUserProp->Hash.pbHash,
  1568. &(pUserProp->Hash.cbHash)))
  1569. {
  1570. dwErr = GetLastError();
  1571. EapTlsTrace("CertGetCertificateContextProperty failed and "
  1572. "returned 0x%x", dwErr);
  1573. }
  1574. }
  1575. dwErr = NO_ERROR;
  1576. }
  1577. }
  1578. else
  1579. {
  1580. if ( !fServer
  1581. && !fRouterConfig
  1582. && !(dwFlags & RAS_EAP_FLAG_PREVIEW)
  1583. && !(FCheckSCardCertAndCanOpenSilentContext ( pCertContext ))
  1584. )
  1585. {
  1586. fGotIdentity = FALSE;
  1587. if (!fDiffUser)
  1588. {
  1589. pUserProp->pwszDiffUser[0] = 0;
  1590. }
  1591. if ( fDiffUser
  1592. && (pUserProp->pwszDiffUser[0]))
  1593. {
  1594. pwszIdentity = LocalAlloc(LPTR,
  1595. (wcslen(pUserProp->pwszDiffUser)+1) * sizeof(WCHAR));;
  1596. if (NULL == pwszIdentity)
  1597. {
  1598. dwErr = GetLastError();
  1599. EapTlsTrace("LocalAlloc failed and returned %d", dwErr);
  1600. goto LDone;
  1601. }
  1602. wcscpy(pwszIdentity, pUserProp->pwszDiffUser);
  1603. EapTlsTrace("(saved) Sending EAP identity %ws", pwszIdentity);
  1604. fGotIdentity = TRUE;
  1605. }
  1606. else if (FCertToStr(pCertContext, 0, fRouter, &pwszIdentity))
  1607. {
  1608. EapTlsTrace("(saved) The name in the certificate is: %ws",
  1609. pwszIdentity);
  1610. fGotIdentity = TRUE;
  1611. }
  1612. if (fGotIdentity)
  1613. {
  1614. RTASSERT(NULL != ppwszIdentity);
  1615. *ppwszIdentity = pwszIdentity;
  1616. pwszIdentity = NULL;
  1617. goto LDone;
  1618. }
  1619. }
  1620. }
  1621. EapTlsUserDialog.pUserProp = pUserProp;
  1622. CreateCertList( fServer,
  1623. fRouter,
  1624. FALSE /* fRoot */,
  1625. &(EapTlsUserDialog.pCertList),
  1626. &(EapTlsUserDialog.pCert),
  1627. 1,
  1628. &(EapTlsUserDialog.pUserProp->Hash),
  1629. pwszStoreName);
  1630. if (NULL == EapTlsUserDialog.pCertList)
  1631. {
  1632. dwErr = ERROR_NO_EAPTLS_CERTIFICATE;
  1633. if (fServer || fRouter)
  1634. {
  1635. if (dwFlags & RAS_EAP_FLAG_NON_INTERACTIVE)
  1636. {
  1637. dwErr = ERROR_INTERACTIVE_MODE;
  1638. goto LDone;
  1639. }
  1640. DisplayError(hwndParent, dwErr);
  1641. }
  1642. goto LDone;
  1643. }
  1644. else
  1645. {
  1646. if ( NULL == EapTlsUserDialog.pCert )
  1647. {
  1648. EapTlsUserDialog.pCert = EapTlsUserDialog.pCertList;
  1649. }
  1650. EapTlsUserDialog.pwszStoreName = pwszStoreName;
  1651. if ( !fServer && !fRouter )
  1652. {
  1653. // if this is a client - not a server and not a router
  1654. // There are more than one certificates or the user has
  1655. // chosen to provide different identity
  1656. //
  1657. if ( EapTlsUserDialog.pCertList->pNext || EapTlsUserDialog.fFlags & EAPTLS_USER_DIALOG_FLAG_DIFF_USER )
  1658. {
  1659. if (dwFlags & RAS_EAP_FLAG_NON_INTERACTIVE)
  1660. {
  1661. dwErr = ERROR_INTERACTIVE_MODE;
  1662. goto LDone;
  1663. }
  1664. //
  1665. // Group Certs for the client UI
  1666. //
  1667. if ( !fServer )
  1668. {
  1669. if ( EapTlsUserDialog.fFlags & EAPTLS_USER_DIALOG_FLAG_USE_SIMPLE_CERTSEL )
  1670. {
  1671. //
  1672. // Grouping is done only if it is specified in
  1673. // the connection properties
  1674. //
  1675. dwErr = GroupCertificates (&EapTlsUserDialog);
  1676. if ( NO_ERROR != dwErr )
  1677. {
  1678. EapTlsTrace("Error grouping certificates. 0x%x", dwErr );
  1679. goto LDone;
  1680. }
  1681. }
  1682. //
  1683. // Now check to see if we have only one group
  1684. //
  1685. if ( EapTlsUserDialog.fFlags & EAPTLS_USER_DIALOG_FLAG_USE_SIMPLE_CERTSEL &&
  1686. !(EapTlsUserDialog.fFlags & EAPTLS_USER_DIALOG_FLAG_DIFF_USER ) &&
  1687. !(EapTlsUserDialog.pGroupedList->pNext)
  1688. )
  1689. {
  1690. //
  1691. // only one group. So select the cert and use it
  1692. //
  1693. CertSelected(NULL,
  1694. EapTlsUserDialog.pCertList,
  1695. &(EapTlsUserDialog.pGroupedList->pMostRecentCert),
  1696. &(EapTlsUserDialog.pUserProp->Hash)
  1697. );
  1698. }
  1699. else
  1700. {
  1701. EapTlsUserDialog.fIdentity = TRUE;
  1702. nRet = DialogBoxParam(
  1703. GetResouceDLLHInstance(),
  1704. MAKEINTRESOURCE(IDD_IDENTITY_UI),
  1705. hwndParent,
  1706. UserDialogProc,
  1707. (LPARAM)&EapTlsUserDialog);
  1708. if (-1 == nRet)
  1709. {
  1710. dwErr = GetLastError();
  1711. goto LDone;
  1712. }
  1713. else if (IDOK != nRet)
  1714. {
  1715. dwErr = ERROR_CANCELLED;
  1716. goto LDone;
  1717. }
  1718. }
  1719. }
  1720. else
  1721. {
  1722. //
  1723. // No server side code on XPSP1 to save on resources
  1724. //
  1725. #if 0
  1726. nRet = DialogBoxParam(
  1727. GetHInstance(),
  1728. MAKEINTRESOURCE(IDD_SERVER_UI),
  1729. hwndParent,
  1730. UserDialogProc,
  1731. (LPARAM)&EapTlsUserDialog);
  1732. if (-1 == nRet)
  1733. {
  1734. dwErr = GetLastError();
  1735. goto LDone;
  1736. }
  1737. else if (IDOK != nRet)
  1738. {
  1739. dwErr = ERROR_CANCELLED;
  1740. goto LDone;
  1741. }
  1742. #endif
  1743. }
  1744. // EapTlsUserDialog.pUserProp may have been realloced
  1745. pUserProp = *ppUserProp = EapTlsUserDialog.pUserProp;
  1746. }
  1747. else
  1748. {
  1749. //
  1750. // There is only one relevant certificate so auto select it.
  1751. //
  1752. CertSelected(NULL, EapTlsUserDialog.pCertList,
  1753. &(EapTlsUserDialog.pCert), &(EapTlsUserDialog.pUserProp->Hash));
  1754. }
  1755. }
  1756. else
  1757. {
  1758. if (dwFlags & RAS_EAP_FLAG_NON_INTERACTIVE)
  1759. {
  1760. dwErr = ERROR_INTERACTIVE_MODE;
  1761. goto LDone;
  1762. }
  1763. if ( EapTlsUserDialog.fFlags & EAPTLS_USER_DIALOG_FLAG_USE_SIMPLE_CERTSEL )
  1764. {
  1765. //
  1766. // Grouping is done only if it is specified in
  1767. // the connection properties
  1768. //
  1769. dwErr = GroupCertificates (&EapTlsUserDialog);
  1770. if ( NO_ERROR != dwErr )
  1771. {
  1772. EapTlsTrace("Error grouping certificates. 0x%x", dwErr );
  1773. goto LDone;
  1774. }
  1775. }
  1776. //
  1777. // No server side UI on the client for XPSP1 to save on resources
  1778. //
  1779. nRet = DialogBoxParam(
  1780. GetResouceDLLHInstance(),
  1781. MAKEINTRESOURCE(IDD_IDENTITY_UI),
  1782. hwndParent,
  1783. UserDialogProc,
  1784. (LPARAM)&EapTlsUserDialog);
  1785. #if 0
  1786. nRet = DialogBoxParam(
  1787. GetHInstance(),
  1788. MAKEINTRESOURCE(fServer ? IDD_SERVER_UI : IDD_IDENTITY_UI),
  1789. hwndParent,
  1790. UserDialogProc,
  1791. (LPARAM)&EapTlsUserDialog);
  1792. #endif
  1793. // EapTlsUserDialog.pUserProp may have been realloced
  1794. pUserProp = *ppUserProp = EapTlsUserDialog.pUserProp;
  1795. if (-1 == nRet)
  1796. {
  1797. dwErr = GetLastError();
  1798. goto LDone;
  1799. }
  1800. else if (IDOK != nRet)
  1801. {
  1802. dwErr = ERROR_CANCELLED;
  1803. goto LDone;
  1804. }
  1805. }
  1806. }
  1807. if (NULL != EapTlsUserDialog.pCert)
  1808. {
  1809. if ( fDiffUser
  1810. && (0 != EapTlsUserDialog.pUserProp->pwszDiffUser[0]))
  1811. {
  1812. pwszTemp = EapTlsUserDialog.pUserProp->pwszDiffUser;
  1813. }
  1814. else
  1815. {
  1816. pwszTemp = EapTlsUserDialog.pCert->pwszDisplayName;
  1817. }
  1818. pwszIdentity = LocalAlloc(LPTR, (wcslen(pwszTemp) + 1)*sizeof(WCHAR));
  1819. if (NULL == pwszIdentity)
  1820. {
  1821. dwErr = GetLastError();
  1822. EapTlsTrace("LocalAlloc failed and returned %d", dwErr);
  1823. goto LDone;
  1824. }
  1825. wcscpy(pwszIdentity, pwszTemp);
  1826. if (NULL != ppwszIdentity)
  1827. {
  1828. *ppwszIdentity = pwszIdentity;
  1829. pwszIdentity = NULL;
  1830. }
  1831. }
  1832. LDone:
  1833. if ( NULL != hWndStatus )
  1834. {
  1835. DestroyWindow(hWndStatus);
  1836. hWndStatus = NULL;
  1837. }
  1838. if (NULL != pCertContext)
  1839. {
  1840. CertFreeCertificateContext(pCertContext);
  1841. // Always returns TRUE;
  1842. }
  1843. if (NULL != hCertStore)
  1844. {
  1845. if (!CertCloseStore(hCertStore, 0))
  1846. {
  1847. EapTlsTrace("CertCloseStore failed and returned 0x%x",
  1848. GetLastError());
  1849. }
  1850. }
  1851. if ( pwszIdentity )
  1852. LocalFree(pwszIdentity);
  1853. FreeCertList(EapTlsUserDialog.pCertList);
  1854. ZeroMemory(&RasCredentials, sizeof(RasCredentials));
  1855. return(dwErr);
  1856. }
  1857. /*
  1858. Returns:
  1859. FALSE (prevent Windows from setting the default keyboard focus).
  1860. Notes:
  1861. Response to the WM_INITDIALOG message (Config UI).
  1862. */
  1863. BOOL
  1864. ConnInitDialog(
  1865. IN HWND hWnd,
  1866. IN LPARAM lParam
  1867. )
  1868. {
  1869. EAPTLS_CONN_DIALOG* pEapTlsConnDialog;
  1870. LVCOLUMN lvColumn;
  1871. SetWindowLongPtr(hWnd, DWLP_USER, lParam);
  1872. pEapTlsConnDialog = (EAPTLS_CONN_DIALOG*)lParam;
  1873. pEapTlsConnDialog->hWndRadioUseCard =
  1874. GetDlgItem(hWnd, IDC_RADIO_USE_CARD);
  1875. pEapTlsConnDialog->hWndRadioUseRegistry =
  1876. GetDlgItem(hWnd, IDC_RADIO_USE_REGISTRY);
  1877. pEapTlsConnDialog->hWndCheckValidateCert =
  1878. GetDlgItem(hWnd, IDC_CHECK_VALIDATE_CERT);
  1879. pEapTlsConnDialog->hWndCheckValidateName =
  1880. GetDlgItem(hWnd, IDC_CHECK_VALIDATE_NAME);
  1881. pEapTlsConnDialog->hWndEditServerName =
  1882. GetDlgItem(hWnd, IDC_EDIT_SERVER_NAME);
  1883. pEapTlsConnDialog->hWndStaticRootCaName =
  1884. GetDlgItem(hWnd, IDC_STATIC_ROOT_CA_NAME);
  1885. //pEapTlsConnDialog->hWndComboRootCaName =
  1886. // GetDlgItem(hWnd, IDC_COMBO_ROOT_CA_NAME);
  1887. pEapTlsConnDialog->hWndListRootCaName =
  1888. GetDlgItem(hWnd, IDC_LIST_ROOT_CA_NAME);
  1889. pEapTlsConnDialog->hWndCheckDiffUser =
  1890. GetDlgItem(hWnd, IDC_CHECK_DIFF_USER);
  1891. pEapTlsConnDialog->hWndCheckUseSimpleSel =
  1892. GetDlgItem(hWnd, IDC_CHECK_USE_SIMPLE_CERT_SEL);
  1893. pEapTlsConnDialog->hWndViewCertDetails =
  1894. GetDlgItem(hWnd, IDC_BUTTON_VIEW_CERTIFICATE);
  1895. //Set the style to set list boxes.
  1896. ListView_SetExtendedListViewStyle
  1897. ( pEapTlsConnDialog->hWndListRootCaName,
  1898. ListView_GetExtendedListViewStyle(pEapTlsConnDialog->hWndListRootCaName) | LVS_EX_CHECKBOXES
  1899. );
  1900. ZeroMemory ( &lvColumn, sizeof(lvColumn));
  1901. lvColumn.fmt = LVCFMT_LEFT;
  1902. ListView_InsertColumn( pEapTlsConnDialog->hWndListRootCaName,
  1903. 0,
  1904. &lvColumn
  1905. );
  1906. ListView_SetColumnWidth(pEapTlsConnDialog->hWndListRootCaName,
  1907. 0,
  1908. LVSCW_AUTOSIZE_USEHEADER
  1909. );
  1910. //
  1911. //Now we need to init the
  1912. //list box with all the certs and selected cert
  1913. InitListBox ( pEapTlsConnDialog->hWndListRootCaName,
  1914. pEapTlsConnDialog->pCertList,
  1915. pEapTlsConnDialog->pConnPropv1->dwNumHashes,
  1916. pEapTlsConnDialog->ppSelCertList
  1917. );
  1918. SetWindowText(pEapTlsConnDialog->hWndEditServerName,
  1919. (LPWSTR )(pEapTlsConnDialog->pConnPropv1->bData + sizeof( EAPTLS_HASH ) * pEapTlsConnDialog->pConnPropv1->dwNumHashes)
  1920. );
  1921. if (pEapTlsConnDialog->fFlags & EAPTLS_CONN_DIALOG_FLAG_ROUTER)
  1922. {
  1923. pEapTlsConnDialog->pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_REGISTRY;
  1924. EnableWindow(pEapTlsConnDialog->hWndRadioUseCard, FALSE);
  1925. }
  1926. CheckRadioButton(hWnd, IDC_RADIO_USE_CARD, IDC_RADIO_USE_REGISTRY,
  1927. (pEapTlsConnDialog->pConnPropv1->fFlags & EAPTLS_CONN_FLAG_REGISTRY) ?
  1928. IDC_RADIO_USE_REGISTRY : IDC_RADIO_USE_CARD);
  1929. CheckDlgButton(hWnd, IDC_CHECK_VALIDATE_CERT,
  1930. (pEapTlsConnDialog->pConnPropv1->fFlags &
  1931. EAPTLS_CONN_FLAG_NO_VALIDATE_CERT) ?
  1932. BST_UNCHECKED : BST_CHECKED);
  1933. CheckDlgButton(hWnd, IDC_CHECK_VALIDATE_NAME,
  1934. (pEapTlsConnDialog->pConnPropv1->fFlags &
  1935. EAPTLS_CONN_FLAG_NO_VALIDATE_NAME) ?
  1936. BST_UNCHECKED : BST_CHECKED);
  1937. CheckDlgButton(hWnd, IDC_CHECK_DIFF_USER,
  1938. (pEapTlsConnDialog->pConnPropv1->fFlags &
  1939. EAPTLS_CONN_FLAG_DIFF_USER) ?
  1940. BST_CHECKED : BST_UNCHECKED);
  1941. CheckDlgButton(hWnd, IDC_CHECK_USE_SIMPLE_CERT_SEL,
  1942. (pEapTlsConnDialog->pConnPropv1->fFlags &
  1943. EAPTLS_CONN_FLAG_SIMPLE_CERT_SEL) ?
  1944. BST_CHECKED : BST_UNCHECKED);
  1945. EnableValidateNameControls(pEapTlsConnDialog);
  1946. //
  1947. // Check to see if we are in readonly mode
  1948. // If so, disable the OK button and
  1949. // make the dialog go into readonly mode
  1950. //
  1951. return(FALSE);
  1952. }
  1953. DWORD GetSelCertContext(EAPTLS_CERT_NODE* pCertList,
  1954. int nIndex,
  1955. HCERTSTORE * phCertStore,
  1956. LPWSTR pwszStoreName,
  1957. PCCERT_CONTEXT * ppCertContext
  1958. )
  1959. {
  1960. PCCERT_CONTEXT pCertContext = NULL;
  1961. EAPTLS_CERT_NODE * pTemp = pCertList;
  1962. DWORD dwErr= NO_ERROR;
  1963. HCERTSTORE hStore = NULL;
  1964. CRYPT_HASH_BLOB chb;
  1965. if ( nIndex >= 0 )
  1966. {
  1967. pTemp = pTemp->pNext;
  1968. while ( nIndex && pTemp )
  1969. {
  1970. pTemp = pTemp->pNext;
  1971. nIndex --;
  1972. }
  1973. }
  1974. if ( pTemp )
  1975. {
  1976. *phCertStore = CertOpenStore (CERT_STORE_PROV_SYSTEM,
  1977. 0,
  1978. 0,
  1979. CERT_STORE_READONLY_FLAG |CERT_SYSTEM_STORE_CURRENT_USER,
  1980. pwszStoreName
  1981. );
  1982. if ( !*phCertStore )
  1983. {
  1984. dwErr = GetLastError();
  1985. goto LDone;
  1986. }
  1987. chb.cbData = pTemp->Hash.cbHash;
  1988. chb.pbData = pTemp->Hash.pbHash;
  1989. pCertContext = CertFindCertificateInStore(
  1990. *phCertStore,
  1991. 0,
  1992. 0,
  1993. CERT_FIND_HASH,
  1994. &chb,
  1995. 0);
  1996. if ( NULL == pCertContext )
  1997. {
  1998. dwErr = GetLastError();
  1999. }
  2000. }
  2001. else
  2002. {
  2003. dwErr = ERROR_NOT_FOUND;
  2004. goto LDone;
  2005. }
  2006. *ppCertContext = pCertContext;
  2007. LDone:
  2008. if ( NO_ERROR != dwErr )
  2009. {
  2010. if ( pCertContext )
  2011. CertFreeCertificateContext(pCertContext);
  2012. if ( *phCertStore )
  2013. CertCloseStore( *phCertStore, CERT_CLOSE_STORE_FORCE_FLAG );
  2014. }
  2015. return dwErr;
  2016. }
  2017. /*
  2018. Returns:
  2019. TRUE: We prrocessed this message.
  2020. FALSE: We did not prrocess this message.
  2021. Notes:
  2022. Response to the WM_COMMAND message (Config UI).
  2023. */
  2024. BOOL
  2025. ConnCommand(
  2026. IN EAPTLS_CONN_DIALOG* pEapTlsConnDialog,
  2027. IN WORD wNotifyCode,
  2028. IN WORD wId,
  2029. IN HWND hWndDlg,
  2030. IN HWND hWndCtrl
  2031. )
  2032. {
  2033. DWORD dwNumChars;
  2034. EAPTLS_CONN_PROPERTIES_V1 * pConnProp;
  2035. switch(wId)
  2036. {
  2037. case IDC_RADIO_USE_CARD:
  2038. pEapTlsConnDialog->pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_REGISTRY;
  2039. pEapTlsConnDialog->pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_SIMPLE_CERT_SEL;
  2040. EnableValidateNameControls(pEapTlsConnDialog);
  2041. return(TRUE);
  2042. case IDC_RADIO_USE_REGISTRY:
  2043. pEapTlsConnDialog->pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_REGISTRY;
  2044. pEapTlsConnDialog->pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_SIMPLE_CERT_SEL;
  2045. CheckDlgButton(hWndDlg, IDC_CHECK_USE_SIMPLE_CERT_SEL, BST_CHECKED);
  2046. EnableValidateNameControls(pEapTlsConnDialog);
  2047. return(TRUE);
  2048. case IDC_CHECK_USE_SIMPLE_CERT_SEL:
  2049. if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_USE_SIMPLE_CERT_SEL))
  2050. {
  2051. pEapTlsConnDialog->pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_SIMPLE_CERT_SEL;
  2052. }
  2053. else
  2054. {
  2055. pEapTlsConnDialog->pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_SIMPLE_CERT_SEL;
  2056. }
  2057. return TRUE;
  2058. case IDC_CHECK_VALIDATE_CERT:
  2059. if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_VALIDATE_CERT))
  2060. {
  2061. pEapTlsConnDialog->pConnPropv1->fFlags &=
  2062. ~EAPTLS_CONN_FLAG_NO_VALIDATE_CERT;
  2063. pEapTlsConnDialog->pConnPropv1->fFlags &=
  2064. ~EAPTLS_CONN_FLAG_NO_VALIDATE_NAME;
  2065. CheckDlgButton(hWndDlg, IDC_CHECK_VALIDATE_NAME, BST_CHECKED);
  2066. }
  2067. else
  2068. {
  2069. pEapTlsConnDialog->pConnPropv1->fFlags |=
  2070. EAPTLS_CONN_FLAG_NO_VALIDATE_CERT;
  2071. pEapTlsConnDialog->pConnPropv1->fFlags |=
  2072. EAPTLS_CONN_FLAG_NO_VALIDATE_NAME;
  2073. CheckDlgButton(hWndDlg, IDC_CHECK_VALIDATE_NAME, BST_UNCHECKED);
  2074. }
  2075. EnableValidateNameControls(pEapTlsConnDialog);
  2076. return(TRUE);
  2077. case IDC_CHECK_VALIDATE_NAME:
  2078. if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_VALIDATE_NAME))
  2079. {
  2080. pEapTlsConnDialog->pConnPropv1->fFlags &=
  2081. ~EAPTLS_CONN_FLAG_NO_VALIDATE_NAME;
  2082. }
  2083. else
  2084. {
  2085. pEapTlsConnDialog->pConnPropv1->fFlags |=
  2086. EAPTLS_CONN_FLAG_NO_VALIDATE_NAME;
  2087. }
  2088. EnableValidateNameControls(pEapTlsConnDialog);
  2089. return(TRUE);
  2090. case IDC_CHECK_DIFF_USER:
  2091. if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_DIFF_USER))
  2092. {
  2093. pEapTlsConnDialog->pConnPropv1->fFlags |=
  2094. EAPTLS_CONN_FLAG_DIFF_USER;
  2095. }
  2096. else
  2097. {
  2098. pEapTlsConnDialog->pConnPropv1->fFlags &=
  2099. ~EAPTLS_CONN_FLAG_DIFF_USER;
  2100. }
  2101. return(TRUE);
  2102. case IDC_BUTTON_VIEW_CERTIFICATE:
  2103. {
  2104. //Show cert details here
  2105. INT nIndex = -1;
  2106. HCERTSTORE hCertStore = NULL;
  2107. PCCERT_CONTEXT pCertContext = NULL;
  2108. LVITEM lvItem;
  2109. nIndex = ListView_GetNextItem(pEapTlsConnDialog->hWndListRootCaName,
  2110. -1,
  2111. LVNI_SELECTED
  2112. );
  2113. if ( nIndex >= 0 )
  2114. {
  2115. ZeroMemory( &lvItem, sizeof(lvItem) );
  2116. lvItem.iItem = nIndex;
  2117. lvItem.mask = LVIF_PARAM;
  2118. ListView_GetItem ( pEapTlsConnDialog->hWndListRootCaName,
  2119. &lvItem
  2120. );
  2121. if ( NO_ERROR == GetSelCertContext( (EAPTLS_CERT_NODE*)(lvItem.lParam),
  2122. -1,
  2123. &hCertStore,
  2124. L"ROOT",
  2125. &pCertContext
  2126. )
  2127. )
  2128. {
  2129. ShowCertDetails( hWndDlg, hCertStore, pCertContext );
  2130. CertFreeCertificateContext(pCertContext);
  2131. CertCloseStore( hCertStore, CERT_CLOSE_STORE_FORCE_FLAG );
  2132. }
  2133. }
  2134. }
  2135. return TRUE;
  2136. case IDOK:
  2137. {
  2138. EAPTLS_HASH * pHash = NULL;
  2139. DWORD dwNumHash = 0;
  2140. DWORD dwSelCount = 0;
  2141. EAPTLS_CERT_NODE ** ppSelCertList = NULL;
  2142. WCHAR wszTitle[200] = {0};
  2143. WCHAR wszMessage[200] = {0};
  2144. CertListSelectedCount ( pEapTlsConnDialog->hWndListRootCaName, &dwSelCount );
  2145. if ( pEapTlsConnDialog->fFlags & EAPTLS_CONN_DIALOG_FLAG_ROUTER)
  2146. {
  2147. //
  2148. // If we are a router,
  2149. // check to see if Validate Server certificate is selected
  2150. // and no cert is selected.
  2151. // Also, check to see if server name is checked and no server's
  2152. // are entered.
  2153. //
  2154. if ( !( pEapTlsConnDialog->pConnPropv1->fFlags & EAPTLS_CONN_FLAG_NO_VALIDATE_CERT) &&
  2155. 0 == dwSelCount )
  2156. {
  2157. LoadString ( GetHInstance(),
  2158. IDS_CANT_CONFIGURE_SERVER_TITLE,
  2159. wszTitle, sizeof(wszTitle)/sizeof(WCHAR)
  2160. );
  2161. LoadString ( GetResouceDLLHInstance(),
  2162. IDS_NO_ROOT_CERT,
  2163. wszMessage, sizeof(wszMessage)/sizeof(WCHAR)
  2164. );
  2165. MessageBox ( GetFocus(), wszMessage, wszTitle, MB_OK|MB_ICONWARNING );
  2166. return TRUE;
  2167. }
  2168. if ( !( pEapTlsConnDialog->pConnPropv1->fFlags & EAPTLS_CONN_FLAG_NO_VALIDATE_NAME) &&
  2169. !GetWindowTextLength(pEapTlsConnDialog->hWndEditServerName) )
  2170. {
  2171. //
  2172. // Nothing entered in server name field
  2173. //
  2174. LoadString ( GetHInstance(),
  2175. IDS_CANT_CONFIGURE_SERVER_TITLE,
  2176. wszTitle, sizeof(wszTitle)/sizeof(WCHAR)
  2177. );
  2178. LoadString ( GetResouceDLLHInstance(),
  2179. IDS_NO_SERVER_NAME,
  2180. wszMessage, sizeof(wszMessage)/sizeof(WCHAR)
  2181. );
  2182. MessageBox ( GetFocus(), wszMessage, wszTitle, MB_OK|MB_ICONWARNING );
  2183. return TRUE;
  2184. }
  2185. }
  2186. if ( dwSelCount > 0 )
  2187. {
  2188. ppSelCertList = (EAPTLS_CERT_NODE **)LocalAlloc(LPTR, sizeof(EAPTLS_CERT_NODE *) * dwSelCount );
  2189. if ( NULL == ppSelCertList )
  2190. {
  2191. EapTlsTrace("LocalAlloc in Command failed and returned %d",
  2192. GetLastError());
  2193. return TRUE;
  2194. }
  2195. pHash = (EAPTLS_HASH *)LocalAlloc(LPTR, sizeof(EAPTLS_HASH ) * dwSelCount );
  2196. if ( NULL == pHash )
  2197. {
  2198. EapTlsTrace("LocalAlloc in Command failed and returned %d",
  2199. GetLastError());
  2200. return TRUE;
  2201. }
  2202. CertListSelected( pEapTlsConnDialog->hWndListRootCaName,
  2203. pEapTlsConnDialog->pCertList,
  2204. ppSelCertList,
  2205. pHash,
  2206. dwSelCount
  2207. );
  2208. }
  2209. dwNumChars = GetWindowTextLength(pEapTlsConnDialog->hWndEditServerName);
  2210. pConnProp = LocalAlloc( LPTR,
  2211. sizeof(EAPTLS_CONN_PROPERTIES_V1) +
  2212. sizeof(EAPTLS_HASH) * dwSelCount +
  2213. dwNumChars * sizeof(WCHAR) + sizeof(WCHAR) //one for null.
  2214. );
  2215. if (NULL == pConnProp)
  2216. {
  2217. EapTlsTrace("LocalAlloc in Command failed and returned %d",
  2218. GetLastError());
  2219. }
  2220. else
  2221. {
  2222. CopyMemory( pConnProp,
  2223. pEapTlsConnDialog->pConnPropv1,
  2224. sizeof(EAPTLS_CONN_PROPERTIES_V1)
  2225. );
  2226. pConnProp->dwSize = sizeof(EAPTLS_CONN_PROPERTIES_V1) +
  2227. sizeof(EAPTLS_HASH) * dwSelCount +
  2228. dwNumChars * sizeof(WCHAR);
  2229. CopyMemory ( pConnProp->bData,
  2230. pHash,
  2231. sizeof(EAPTLS_HASH) * dwSelCount
  2232. );
  2233. pConnProp->dwNumHashes = dwSelCount;
  2234. GetWindowText(pEapTlsConnDialog->hWndEditServerName,
  2235. (LPWSTR)(pConnProp->bData + sizeof(EAPTLS_HASH) * dwSelCount) ,
  2236. dwNumChars + 1);
  2237. LocalFree(pEapTlsConnDialog->pConnPropv1);
  2238. if ( pEapTlsConnDialog->ppSelCertList )
  2239. LocalFree(pEapTlsConnDialog->ppSelCertList);
  2240. pEapTlsConnDialog->ppSelCertList = ppSelCertList;
  2241. pEapTlsConnDialog->pConnPropv1 = pConnProp;
  2242. }
  2243. }
  2244. // Fall through
  2245. case IDCANCEL:
  2246. EndDialog(hWndDlg, wId);
  2247. return(TRUE);
  2248. default:
  2249. return(FALSE);
  2250. }
  2251. }
  2252. BOOL ConnNotify( EAPTLS_CONN_DIALOG *pEaptlsConnDialog,
  2253. WPARAM wParam,
  2254. LPARAM lParam,
  2255. HWND hWnd
  2256. )
  2257. {
  2258. HCERTSTORE hCertStore = NULL;
  2259. PCCERT_CONTEXT pCertContext = NULL;
  2260. LPNMITEMACTIVATE lpnmItem;
  2261. LVITEM lvItem;
  2262. if ( wParam == IDC_LIST_ROOT_CA_NAME )
  2263. {
  2264. lpnmItem = (LPNMITEMACTIVATE) lParam;
  2265. if ( lpnmItem->hdr.code == NM_DBLCLK )
  2266. {
  2267. ZeroMemory(&lvItem, sizeof(lvItem) );
  2268. lvItem.mask = LVIF_PARAM;
  2269. lvItem.iItem = lpnmItem->iItem;
  2270. ListView_GetItem(lpnmItem->hdr.hwndFrom, &lvItem);
  2271. if ( NO_ERROR == GetSelCertContext( //pEaptlsConnDialog->pCertList,
  2272. (EAPTLS_CERT_NODE*)(lvItem.lParam) ,
  2273. -1,
  2274. &hCertStore,
  2275. L"ROOT",
  2276. &pCertContext
  2277. )
  2278. )
  2279. {
  2280. ShowCertDetails( hWnd, hCertStore, pCertContext );
  2281. CertFreeCertificateContext(pCertContext);
  2282. CertCloseStore( hCertStore, CERT_CLOSE_STORE_FORCE_FLAG );
  2283. return TRUE;
  2284. }
  2285. return TRUE;
  2286. }
  2287. }
  2288. return FALSE;
  2289. }
  2290. /*
  2291. Returns:
  2292. Notes:
  2293. Callback function used with the Config UI DialogBoxParam function. It
  2294. processes messages sent to the dialog box. See the DialogProc documentation
  2295. in MSDN.
  2296. */
  2297. INT_PTR CALLBACK
  2298. ConnDialogProc(
  2299. IN HWND hWnd,
  2300. IN UINT unMsg,
  2301. IN WPARAM wParam,
  2302. IN LPARAM lParam
  2303. )
  2304. {
  2305. EAPTLS_CONN_DIALOG* pEapTlsConnDialog;
  2306. switch (unMsg)
  2307. {
  2308. case WM_INITDIALOG:
  2309. return(ConnInitDialog(hWnd, lParam));
  2310. case WM_HELP:
  2311. case WM_CONTEXTMENU:
  2312. {
  2313. ContextHelp(g_adwHelp, hWnd, unMsg, wParam, lParam);
  2314. break;
  2315. }
  2316. case WM_NOTIFY:
  2317. {
  2318. pEapTlsConnDialog = (EAPTLS_CONN_DIALOG*)GetWindowLongPtr(hWnd, DWLP_USER);
  2319. return ConnNotify( pEapTlsConnDialog,
  2320. wParam,
  2321. lParam,
  2322. hWnd
  2323. );
  2324. }
  2325. case WM_COMMAND:
  2326. pEapTlsConnDialog = (EAPTLS_CONN_DIALOG*)GetWindowLongPtr(hWnd, DWLP_USER);
  2327. return(ConnCommand(pEapTlsConnDialog, HIWORD(wParam), LOWORD(wParam),
  2328. hWnd, (HWND)lParam));
  2329. }
  2330. return(FALSE);
  2331. }
  2332. DWORD
  2333. RasEapTlsInvokeConfigUI(
  2334. IN DWORD dwEapTypeId,
  2335. IN HWND hwndParent,
  2336. IN DWORD dwFlags,
  2337. IN BYTE* pConnectionDataIn,
  2338. IN DWORD dwSizeOfConnectionDataIn,
  2339. OUT BYTE** ppConnectionDataOut,
  2340. OUT DWORD* pdwSizeOfConnectionDataOut
  2341. )
  2342. {
  2343. DWORD dwErr = NO_ERROR;
  2344. BOOL fRouter = FALSE;
  2345. INT_PTR nRet;
  2346. EAPTLS_CONN_DIALOG EapTlsConnDialog;
  2347. RTASSERT(NULL != ppConnectionDataOut);
  2348. RTASSERT(NULL != pdwSizeOfConnectionDataOut);
  2349. EapTlsInitialize2(TRUE, TRUE /* fUI */);
  2350. *ppConnectionDataOut = NULL;
  2351. *pdwSizeOfConnectionDataOut = 0;
  2352. ZeroMemory(&EapTlsConnDialog, sizeof(EAPTLS_CONN_DIALOG));
  2353. if (dwFlags & RAS_EAP_FLAG_ROUTER)
  2354. {
  2355. fRouter = TRUE;
  2356. EapTlsConnDialog.fFlags = EAPTLS_CONN_DIALOG_FLAG_ROUTER;
  2357. }
  2358. #if 0
  2359. if ( dwFlags & RAS_EAP_FLAG_READ_ONLY_UI )
  2360. {
  2361. EapTlsConnDialog.fFlags |= EAPTLS_CONN_DIALOG_FLAG_READONLY;
  2362. }
  2363. #endif
  2364. dwErr = ReadConnectionData( ( dwFlags & RAS_EAP_FLAG_8021X_AUTH ),
  2365. pConnectionDataIn,
  2366. dwSizeOfConnectionDataIn,
  2367. &(EapTlsConnDialog.pConnProp)
  2368. );
  2369. if (NO_ERROR != dwErr)
  2370. {
  2371. goto LDone;
  2372. }
  2373. dwErr = ConnPropGetV1Struct ( EapTlsConnDialog.pConnProp, &(EapTlsConnDialog.pConnPropv1) );
  2374. if ( NO_ERROR != dwErr )
  2375. {
  2376. goto LDone;
  2377. }
  2378. //
  2379. //if there are certificates that need to be selected, allocate
  2380. //memory upfront for them
  2381. //
  2382. if ( EapTlsConnDialog.pConnPropv1->dwNumHashes )
  2383. {
  2384. EapTlsConnDialog.ppSelCertList = (EAPTLS_CERT_NODE **)LocalAlloc(LPTR, sizeof(EAPTLS_CERT_NODE *) * EapTlsConnDialog.pConnPropv1->dwNumHashes );
  2385. if ( NULL == EapTlsConnDialog.ppSelCertList )
  2386. {
  2387. dwErr = GetLastError();
  2388. EapTlsTrace("LocalAlloc failed and returned %d",
  2389. dwErr);
  2390. goto LDone;
  2391. }
  2392. }
  2393. CreateCertList( FALSE /* fServer */,
  2394. fRouter,
  2395. TRUE /* fRoot */,
  2396. &(EapTlsConnDialog.pCertList), //lined list of all certs in the store.
  2397. EapTlsConnDialog.ppSelCertList, //list of selected certificates - null if nothing's in the list
  2398. EapTlsConnDialog.pConnPropv1->dwNumHashes,
  2399. (EAPTLS_HASH*)(EapTlsConnDialog.pConnPropv1->bData),
  2400. L"ROOT"
  2401. );
  2402. nRet = DialogBoxParam(
  2403. GetResouceDLLHInstance(),
  2404. MAKEINTRESOURCE(IDD_CONFIG_UI),
  2405. hwndParent,
  2406. ConnDialogProc,
  2407. (LPARAM)&EapTlsConnDialog);
  2408. if (-1 == nRet)
  2409. {
  2410. dwErr = GetLastError();
  2411. goto LDone;
  2412. }
  2413. else if (IDOK != nRet)
  2414. {
  2415. dwErr = ERROR_CANCELLED;
  2416. goto LDone;
  2417. }
  2418. //
  2419. //Convert the connpropv1 back to connpropv0 + extra cludge
  2420. //here
  2421. //
  2422. RTASSERT(NULL != EapTlsConnDialog.pConnPropv1);
  2423. dwErr = ConnPropGetV0Struct ( EapTlsConnDialog.pConnPropv1, (EAPTLS_CONN_PROPERTIES ** )ppConnectionDataOut );
  2424. if ( NO_ERROR != dwErr )
  2425. {
  2426. goto LDone;
  2427. }
  2428. *pdwSizeOfConnectionDataOut = ((EAPTLS_CONN_PROPERTIES * )*ppConnectionDataOut)->dwSize;
  2429. LDone:
  2430. EapTlsInitialize2(FALSE, TRUE /* fUI */);
  2431. FreeCertList(EapTlsConnDialog.pCertList);
  2432. if ( EapTlsConnDialog.ppSelCertList )
  2433. {
  2434. LocalFree( EapTlsConnDialog.ppSelCertList );
  2435. EapTlsConnDialog.ppSelCertList = NULL;
  2436. }
  2437. LocalFree( EapTlsConnDialog.pConnProp );
  2438. LocalFree( EapTlsConnDialog.pConnPropv1 );
  2439. return dwErr;
  2440. }
  2441. DWORD
  2442. RasEapPeapInvokeConfigUI(
  2443. IN DWORD dwEapTypeId,
  2444. IN HWND hwndParent,
  2445. IN DWORD dwFlags,
  2446. IN BYTE* pConnectionDataIn,
  2447. IN DWORD dwSizeOfConnectionDataIn,
  2448. OUT BYTE** ppConnectionDataOut,
  2449. OUT DWORD* pdwSizeOfConnectionDataOut
  2450. )
  2451. {
  2452. DWORD dwRetCode = NO_ERROR;
  2453. PEAP_CONN_DIALOG PeapConnDialog;
  2454. BOOL fRouter = FALSE;
  2455. INT_PTR nRet;
  2456. //
  2457. // Do the following here:
  2458. //
  2459. // Get a list of Root Certs:
  2460. // Get the list of all the eaptypes registered for PEAP:
  2461. // and set in in the GUI
  2462. //
  2463. EapTlsInitialize2(TRUE, TRUE /* fUI */);
  2464. *ppConnectionDataOut = NULL;
  2465. *pdwSizeOfConnectionDataOut = 0;
  2466. ZeroMemory(&PeapConnDialog, sizeof(PEAP_CONN_DIALOG));
  2467. if (dwFlags & RAS_EAP_FLAG_ROUTER)
  2468. {
  2469. fRouter = TRUE;
  2470. PeapConnDialog.fFlags = PEAP_CONN_DIALOG_FLAG_ROUTER;
  2471. }
  2472. if ( dwFlags & RAS_EAP_FLAG_8021X_AUTH )
  2473. {
  2474. PeapConnDialog.fFlags |= PEAP_CONN_DIALOG_FLAG_8021x;
  2475. }
  2476. dwRetCode = PeapReadConnectionData(( dwFlags & RAS_EAP_FLAG_8021X_AUTH ),
  2477. pConnectionDataIn, dwSizeOfConnectionDataIn,
  2478. &(PeapConnDialog.pConnProp));
  2479. if (NO_ERROR != dwRetCode)
  2480. {
  2481. goto LDone;
  2482. }
  2483. //
  2484. //if there are certificates that need to be selected, allocate
  2485. //memory upfront for them
  2486. //
  2487. if ( PeapConnDialog.pConnProp->EapTlsConnProp.dwNumHashes )
  2488. {
  2489. PeapConnDialog.ppSelCertList = (EAPTLS_CERT_NODE **)LocalAlloc(LPTR,
  2490. sizeof(EAPTLS_CERT_NODE *) * PeapConnDialog.pConnProp->EapTlsConnProp.dwNumHashes );
  2491. if ( NULL == PeapConnDialog.ppSelCertList )
  2492. {
  2493. dwRetCode = GetLastError();
  2494. EapTlsTrace("LocalAlloc failed and returned %d",
  2495. dwRetCode);
  2496. goto LDone;
  2497. }
  2498. }
  2499. CreateCertList( FALSE /* fServer */,
  2500. fRouter,
  2501. TRUE /* fRoot */,
  2502. &(PeapConnDialog.pCertList), //lined list of all certs in the store.
  2503. PeapConnDialog.ppSelCertList, //list of selected certificates - null if nothing's in the list
  2504. PeapConnDialog.pConnProp->EapTlsConnProp.dwNumHashes,
  2505. (EAPTLS_HASH*)(PeapConnDialog.pConnProp->EapTlsConnProp.bData),
  2506. L"ROOT"
  2507. );
  2508. //
  2509. // Create a list of all Eap Types here
  2510. //
  2511. dwRetCode = PeapEapInfoGetList ( NULL, &(PeapConnDialog.pEapInfo) );
  2512. if ( NO_ERROR != dwRetCode )
  2513. {
  2514. EapTlsTrace("Error Creating list of PEAP EapTypes");
  2515. goto LDone;
  2516. }
  2517. // Setup the conn props for each of the eaptypes from our PeapConnprop
  2518. // in
  2519. dwRetCode = PeapEapInfoSetConnData ( PeapConnDialog.pEapInfo,
  2520. PeapConnDialog.pConnProp );
  2521. nRet = DialogBoxParam(
  2522. GetResouceDLLHInstance(),
  2523. MAKEINTRESOURCE(IDD_PEAP_CONFIG_UI),
  2524. hwndParent,
  2525. PeapConnDialogProc,
  2526. (LPARAM)&PeapConnDialog);
  2527. if (-1 == nRet)
  2528. {
  2529. dwRetCode = GetLastError();
  2530. goto LDone;
  2531. }
  2532. else if (IDOK != nRet)
  2533. {
  2534. dwRetCode = ERROR_CANCELLED;
  2535. goto LDone;
  2536. }
  2537. //
  2538. //Convert the connpropv1 back to connpropv0 + extra cludge
  2539. //here
  2540. //
  2541. RTASSERT(NULL != PeapConnDialog.pConnProp);
  2542. *ppConnectionDataOut = (PBYTE)PeapConnDialog.pConnProp;
  2543. *pdwSizeOfConnectionDataOut = PeapConnDialog.pConnProp->dwSize;
  2544. PeapConnDialog.pConnProp = NULL;
  2545. LDone:
  2546. EapTlsInitialize2(FALSE, TRUE /* fUI */);
  2547. FreeCertList(PeapConnDialog.pCertList);
  2548. if ( PeapConnDialog.ppSelCertList )
  2549. {
  2550. LocalFree( PeapConnDialog.ppSelCertList );
  2551. PeapConnDialog.ppSelCertList = NULL;
  2552. }
  2553. PeapEapInfoFreeList ( PeapConnDialog.pEapInfo );
  2554. LocalFree( PeapConnDialog.pConnProp );
  2555. return dwRetCode;
  2556. }
  2557. /*
  2558. Returns:
  2559. Notes:
  2560. Called to get the EAP-TLS properties for a connection.
  2561. */
  2562. DWORD
  2563. RasEapInvokeConfigUI(
  2564. IN DWORD dwEapTypeId,
  2565. IN HWND hwndParent,
  2566. IN DWORD dwFlags,
  2567. IN BYTE* pConnectionDataIn,
  2568. IN DWORD dwSizeOfConnectionDataIn,
  2569. OUT BYTE** ppConnectionDataOut,
  2570. OUT DWORD* pdwSizeOfConnectionDataOut
  2571. )
  2572. {
  2573. DWORD dwErr = ERROR_INVALID_PARAMETER;
  2574. //
  2575. // This is invoked in case of client configuration
  2576. //
  2577. if ( PPP_EAP_TLS == dwEapTypeId )
  2578. {
  2579. dwErr = RasEapTlsInvokeConfigUI(
  2580. dwEapTypeId,
  2581. hwndParent,
  2582. dwFlags,
  2583. pConnectionDataIn,
  2584. dwSizeOfConnectionDataIn,
  2585. ppConnectionDataOut,
  2586. pdwSizeOfConnectionDataOut
  2587. );
  2588. }
  2589. #ifdef IMPL_PEAP
  2590. else
  2591. {
  2592. //Invoke the client config UI
  2593. dwErr = RasEapPeapInvokeConfigUI(
  2594. dwEapTypeId,
  2595. hwndParent,
  2596. dwFlags,
  2597. pConnectionDataIn,
  2598. dwSizeOfConnectionDataIn,
  2599. ppConnectionDataOut,
  2600. pdwSizeOfConnectionDataOut
  2601. );
  2602. }
  2603. #endif
  2604. return(dwErr);
  2605. }
  2606. /*
  2607. Returns:
  2608. Notes:
  2609. pConnectionDataIn, pUserDataIn, and ppwszIdentity may be NULL.
  2610. */
  2611. DWORD
  2612. EapTlsInvokeIdentityUI(
  2613. IN BOOL fServer,
  2614. IN BOOL fRouterConfig,
  2615. IN DWORD dwFlags,
  2616. IN WCHAR* pwszStoreName,
  2617. IN const WCHAR* pwszPhonebook,
  2618. IN const WCHAR* pwszEntry,
  2619. IN HWND hwndParent,
  2620. IN BYTE* pConnectionDataIn,
  2621. IN DWORD dwSizeOfConnectionDataIn,
  2622. IN BYTE* pUserDataIn,
  2623. IN DWORD dwSizeOfUserDataIn,
  2624. OUT BYTE** ppUserDataOut,
  2625. OUT DWORD* pdwSizeOfUserDataOut,
  2626. OUT WCHAR** ppwszIdentity
  2627. )
  2628. {
  2629. DWORD dwErr = NO_ERROR;
  2630. EAPTLS_USER_PROPERTIES* pUserProp = NULL;
  2631. EAPTLS_CONN_PROPERTIES* pConnProp = NULL;
  2632. EAPTLS_CONN_PROPERTIES_V1 * pConnPropv1 = NULL;
  2633. WCHAR* pwszIdentity = NULL;
  2634. PBYTE pbEncPIN = NULL;
  2635. DWORD cbEncPIN = 0;
  2636. RTASSERT(NULL != pwszStoreName);
  2637. RTASSERT(NULL != ppUserDataOut);
  2638. RTASSERT(NULL != pdwSizeOfUserDataOut);
  2639. // pConnectionDataIn, pUserDataIn, and ppwszIdentity may be NULL.
  2640. EapTlsInitialize2(TRUE, TRUE /* fUI */);
  2641. EapTlsTrace("EapTlsInvokeIdentityUI");
  2642. *ppUserDataOut = NULL;
  2643. *pdwSizeOfUserDataOut = 0;
  2644. if (NULL != ppwszIdentity)
  2645. {
  2646. *ppwszIdentity = NULL;
  2647. }
  2648. dwErr = ReadConnectionData( ( dwFlags & RAS_EAP_FLAG_8021X_AUTH ),
  2649. pConnectionDataIn,
  2650. dwSizeOfConnectionDataIn,
  2651. &pConnProp);
  2652. if (NO_ERROR != dwErr)
  2653. {
  2654. goto LDone;
  2655. }
  2656. dwErr = ConnPropGetV1Struct ( pConnProp, &pConnPropv1 );
  2657. if ( NO_ERROR != dwErr )
  2658. {
  2659. goto LDone;
  2660. }
  2661. dwErr = ReadUserData(pUserDataIn, dwSizeOfUserDataIn, &pUserProp);
  2662. if (NO_ERROR != dwErr)
  2663. {
  2664. goto LDone;
  2665. }
  2666. if ( !(dwFlags & RAS_EAP_FLAG_LOGON)
  2667. || (NULL == pUserDataIn))
  2668. {
  2669. dwErr = GetCertInfo(fServer, fRouterConfig, dwFlags, pwszPhonebook,
  2670. pwszEntry, hwndParent, pwszStoreName, pConnPropv1, &pUserProp,
  2671. ppwszIdentity);
  2672. if (NO_ERROR != dwErr)
  2673. {
  2674. #if WINVER > 0x0500
  2675. if ( dwErr == SCARD_E_CANCELLED || dwErr == SCARD_W_CANCELLED_BY_USER )
  2676. {
  2677. dwErr = ERROR_READING_SCARD;
  2678. }
  2679. #endif
  2680. goto LDone;
  2681. }
  2682. if ( (!fServer) &&
  2683. ( dwFlags & RAS_EAP_FLAG_8021X_AUTH ) &&
  2684. !(pConnProp->fFlags & EAPTLS_CONN_FLAG_REGISTRY)
  2685. )
  2686. {
  2687. //
  2688. // Encrypt PIN and send it back
  2689. //
  2690. dwErr = EncryptData ( (PBYTE)pUserProp->pwszPin,
  2691. lstrlen(pUserProp->pwszPin) * sizeof(WCHAR),
  2692. &pbEncPIN,
  2693. &cbEncPIN
  2694. );
  2695. if ( NO_ERROR != dwErr )
  2696. {
  2697. goto LDone;
  2698. }
  2699. dwErr = AllocUserDataWithNewPin(pUserProp, pbEncPIN, cbEncPIN, &pUserProp);
  2700. }
  2701. *ppUserDataOut = (BYTE*)(pUserProp);
  2702. *pdwSizeOfUserDataOut = pUserProp->dwSize;
  2703. pUserProp = NULL;
  2704. goto LDone;
  2705. }
  2706. else
  2707. {
  2708. if (EAPTLS_CONN_FLAG_REGISTRY & pConnProp->fFlags)
  2709. {
  2710. dwErr = ERROR_NO_REG_CERT_AT_LOGON;
  2711. goto LDone;
  2712. }
  2713. if (EAPTLS_CONN_FLAG_DIFF_USER & pConnProp->fFlags)
  2714. {
  2715. dwErr = ERROR_NO_DIFF_USER_AT_LOGON;
  2716. goto LDone;
  2717. }
  2718. dwErr = GetIdentityFromLogonInfo(pUserDataIn, dwSizeOfUserDataIn,
  2719. &pwszIdentity);
  2720. if (NO_ERROR != dwErr)
  2721. {
  2722. goto LDone;
  2723. }
  2724. if (NULL != ppwszIdentity)
  2725. {
  2726. *ppwszIdentity = pwszIdentity;
  2727. pwszIdentity = NULL;
  2728. }
  2729. }
  2730. LDone:
  2731. EapTlsInitialize2(FALSE, TRUE /* fUI */);
  2732. LocalFree(pwszIdentity);
  2733. LocalFree(pUserProp);
  2734. LocalFree(pConnProp);
  2735. LocalFree(pConnPropv1);
  2736. LocalFree(pbEncPIN);
  2737. return(dwErr);
  2738. }
  2739. DWORD
  2740. PeapInvokeServerConfigUI ( IN HWND hWnd,
  2741. IN WCHAR * pwszMachineName
  2742. )
  2743. {
  2744. //
  2745. // Since this is the client side code only for xpsp1, we remove
  2746. // serve side resources.
  2747. //
  2748. return ERROR_CALL_NOT_IMPLEMENTED;
  2749. #if 0
  2750. WCHAR awszStoreName[MAX_COMPUTERNAME_LENGTH + 10 + 1];
  2751. DWORD dwStrLen;
  2752. BYTE* pUserDataOut = NULL;
  2753. DWORD dwSizeOfUserDataOut;
  2754. BOOL fLocal = FALSE;
  2755. PEAP_SERVER_CONFIG_DIALOG ServerConfigDialog;
  2756. PPEAP_ENTRY_USER_PROPERTIES pEntryProp = NULL;
  2757. INT_PTR nRet = -1;
  2758. DWORD dwErr = NO_ERROR;
  2759. EapTlsInitialize2(TRUE, TRUE /* fUI */);
  2760. ZeroMemory ( &ServerConfigDialog, sizeof(ServerConfigDialog));
  2761. if (0 == *pwszMachineName)
  2762. {
  2763. fLocal = TRUE;
  2764. }
  2765. ServerConfigDialog.pwszMachineName = pwszMachineName;
  2766. wcscpy(awszStoreName, L"\\\\");
  2767. wcsncat(awszStoreName, pwszMachineName, MAX_COMPUTERNAME_LENGTH);
  2768. dwErr = PeapServerConfigDataIO(TRUE /* fRead */, fLocal ? NULL : awszStoreName,
  2769. (BYTE**)&( ServerConfigDialog.pUserProp), 0);
  2770. if (NO_ERROR != dwErr)
  2771. {
  2772. goto LDone;
  2773. }
  2774. //
  2775. // Create cert list to display and then show the server config UI.
  2776. //
  2777. dwStrLen = wcslen(awszStoreName);
  2778. wcsncat(awszStoreName, L"\\MY", wcslen(L"\\MY") );
  2779. CreateCertList( TRUE,
  2780. FALSE, /*fRouter */
  2781. TRUE /* fRoot */,
  2782. &(ServerConfigDialog.pCertList),
  2783. &(ServerConfigDialog.pSelCertList),
  2784. 1,
  2785. &(ServerConfigDialog.pUserProp->CertHash),
  2786. fLocal ? L"MY": awszStoreName);
  2787. wcsncat(awszStoreName, L"\\MY", wcslen(L"\\MY"));
  2788. awszStoreName[dwStrLen] = 0; // Get rid of the \MY
  2789. //
  2790. // Create list of All EAP Types allowed
  2791. //
  2792. dwErr = PeapEapInfoGetList ( pwszMachineName, &(ServerConfigDialog.pEapInfo) );
  2793. if ( NO_ERROR != dwErr )
  2794. {
  2795. goto LDone;
  2796. }
  2797. //
  2798. // From the user info get the selected PEAP Type if any
  2799. //
  2800. dwErr = PeapGetFirstEntryUserProp ( ServerConfigDialog.pUserProp,
  2801. &pEntryProp
  2802. );
  2803. if ( NO_ERROR == dwErr )
  2804. {
  2805. // Set the selected EAP type
  2806. //
  2807. PeapEapInfoFindListNode ( pEntryProp->dwEapTypeId,
  2808. ServerConfigDialog.pEapInfo,
  2809. &(ServerConfigDialog.pSelEapInfo)
  2810. );
  2811. }
  2812. //
  2813. // Invoke the config UI.
  2814. //
  2815. nRet = DialogBoxParam(
  2816. GetResouceDLLHInstance(),
  2817. MAKEINTRESOURCE(IDD_PEAP_SERVER_UI),
  2818. hWnd,
  2819. PeapServerDialogProc,
  2820. (LPARAM)&ServerConfigDialog);
  2821. if (-1 == nRet)
  2822. {
  2823. dwErr = GetLastError();
  2824. goto LDone;
  2825. }
  2826. else if (IDOK != nRet)
  2827. {
  2828. dwErr = ERROR_CANCELLED;
  2829. goto LDone;
  2830. }
  2831. if ( ServerConfigDialog.pNewUserProp )
  2832. {
  2833. dwErr = PeapServerConfigDataIO(FALSE /* fRead */, fLocal ? NULL : awszStoreName,
  2834. (PBYTE *) &(ServerConfigDialog.pNewUserProp), sizeof(PEAP_USER_PROP));
  2835. }
  2836. LDone:
  2837. // Ignore errors
  2838. RasEapFreeMemory(pUserDataOut);
  2839. LocalFree(ServerConfigDialog.pNewUserProp );
  2840. LocalFree(ServerConfigDialog.pUserProp );
  2841. PeapEapInfoFreeList ( ServerConfigDialog.pEapInfo );
  2842. EapTlsInitialize2(FALSE, TRUE /* fUI */);
  2843. return dwErr;
  2844. #endif
  2845. }
  2846. /*
  2847. Returns:
  2848. NO_ERROR: iff Success
  2849. Notes:
  2850. Congigure EAP-TLS for the RAS server.
  2851. */
  2852. DWORD
  2853. InvokeServerConfigUI(
  2854. IN HWND hWnd,
  2855. IN WCHAR* pwszMachineName
  2856. )
  2857. {
  2858. #define MAX_STORE_NAME_LENGTH MAX_COMPUTERNAME_LENGTH + 10
  2859. WCHAR awszStoreName[MAX_STORE_NAME_LENGTH + 1];
  2860. DWORD dwStrLen;
  2861. EAPTLS_USER_PROPERTIES* pUserProp = NULL;
  2862. BYTE* pUserDataOut = NULL;
  2863. DWORD dwSizeOfUserDataOut;
  2864. BOOL fLocal = FALSE;
  2865. DWORD dwErr = NO_ERROR;
  2866. if (0 == *pwszMachineName)
  2867. {
  2868. fLocal = TRUE;
  2869. }
  2870. wcscpy(awszStoreName, L"\\\\");
  2871. wcsncat(awszStoreName, pwszMachineName, MAX_COMPUTERNAME_LENGTH);
  2872. dwErr = ServerConfigDataIO(TRUE /* fRead */, fLocal ? NULL : awszStoreName,
  2873. (BYTE**)&pUserProp, 0);
  2874. if (NO_ERROR != dwErr)
  2875. {
  2876. goto LDone;
  2877. }
  2878. dwStrLen = wcslen(awszStoreName);
  2879. wcsncat(awszStoreName, L"\\MY", wcslen(L"\\MY"));
  2880. dwErr = EapTlsInvokeIdentityUI(
  2881. TRUE /* fServer */,
  2882. FALSE /* fRouterConfig */,
  2883. 0 /* dwFlags */,
  2884. fLocal ? L"MY" : awszStoreName,
  2885. L"" /* pwszPhonebook */,
  2886. L"" /* pwszEntry */,
  2887. hWnd,
  2888. NULL /* pConnectionDataIn */,
  2889. 0 /* dwSizeOfConnectionDataIn */,
  2890. (BYTE*)pUserProp,
  2891. pUserProp->dwSize,
  2892. &pUserDataOut,
  2893. &dwSizeOfUserDataOut,
  2894. NULL /* pszIdentity */);
  2895. if (NO_ERROR != dwErr)
  2896. {
  2897. goto LDone;
  2898. }
  2899. awszStoreName[dwStrLen] = 0; // Get rid of the \MY
  2900. dwErr = ServerConfigDataIO(FALSE /* fRead */, fLocal ? NULL : awszStoreName,
  2901. &pUserDataOut, dwSizeOfUserDataOut);
  2902. LDone:
  2903. // Ignore errors
  2904. RasEapFreeMemory(pUserDataOut);
  2905. LocalFree(pUserProp);
  2906. return(dwErr);
  2907. }
  2908. DWORD
  2909. PeapGetIdentity(
  2910. IN DWORD dwEapTypeId,
  2911. IN HWND hwndParent,
  2912. IN DWORD dwFlags,
  2913. IN const WCHAR* pwszPhonebook,
  2914. IN const WCHAR* pwszEntry,
  2915. IN BYTE* pConnectionDataIn,
  2916. IN DWORD dwSizeOfConnectionDataIn,
  2917. IN BYTE* pUserDataIn,
  2918. IN DWORD dwSizeOfUserDataIn,
  2919. OUT BYTE** ppUserDataOut,
  2920. OUT DWORD* pdwSizeOfUserDataOut,
  2921. OUT WCHAR** ppwszIdentityOut
  2922. )
  2923. {
  2924. DWORD dwRetCode = NO_ERROR;
  2925. PPEAP_CONN_PROP pConnProp = NULL;
  2926. PPEAP_USER_PROP pUserProp = NULL;
  2927. PPEAP_USER_PROP pUserPropNew = NULL;
  2928. PPEAP_EAP_INFO pEapInfo = NULL;
  2929. PPEAP_EAP_INFO pFirstEapInfo = NULL;
  2930. PEAP_ENTRY_CONN_PROPERTIES UNALIGNED * pFirstEntryConnProp = NULL;
  2931. PEAP_ENTRY_USER_PROPERTIES UNALIGNED * pFirstEntryUserProp = NULL;
  2932. PEAP_DEFAULT_CRED_DIALOG DefaultCredDialog;
  2933. INT_PTR nRet;
  2934. LPWSTR lpwszLocalMachineName = NULL;
  2935. //
  2936. // Since PEAP itself does not have any client identity of its own,
  2937. // check the first configured eap type and call it's get identity
  2938. // entry point. If we dont have any eaptype configured, it is an
  2939. // error condition.
  2940. //
  2941. dwRetCode = PeapReadConnectionData( ( dwFlags & RAS_EAP_FLAG_8021X_AUTH ),
  2942. pConnectionDataIn,
  2943. dwSizeOfConnectionDataIn,
  2944. &pConnProp
  2945. );
  2946. if ( NO_ERROR != dwRetCode )
  2947. {
  2948. goto LDone;
  2949. }
  2950. dwRetCode = PeapReadUserData ( pUserDataIn,
  2951. dwSizeOfUserDataIn,
  2952. &pUserProp
  2953. );
  2954. if ( NO_ERROR != dwRetCode )
  2955. {
  2956. goto LDone;
  2957. }
  2958. //
  2959. // This is probably not a very good thing. Modify PeapReadConnectionData to
  2960. // put in the default of first eap type that it finds...
  2961. // For now we have the only one - mschap v2 so may not be an issue...
  2962. //
  2963. if ( !pConnProp->dwNumPeapTypes )
  2964. {
  2965. dwRetCode = ERROR_PROTOCOL_NOT_CONFIGURED;
  2966. goto LDone;
  2967. }
  2968. //
  2969. // Check to see if the conn prop and user prop are mismatched. If so, we need to get the
  2970. // User props all over again
  2971. //
  2972. // Now invoke the first EAP method configured ( in this release, the only EAP )
  2973. // method and get the config info from it...
  2974. //
  2975. dwRetCode = PeapEapInfoGetList ( NULL, &pEapInfo);
  2976. if ( NO_ERROR != dwRetCode )
  2977. {
  2978. goto LDone;
  2979. }
  2980. //
  2981. // If we have come this far, we have at least one configured eaptype in
  2982. // PEAP. So, get the entry properties for it.
  2983. //
  2984. dwRetCode = PeapGetFirstEntryConnProp ( pConnProp,
  2985. &pFirstEntryConnProp
  2986. );
  2987. if ( NO_ERROR != dwRetCode )
  2988. {
  2989. goto LDone;
  2990. }
  2991. dwRetCode = PeapGetFirstEntryUserProp ( pUserProp,
  2992. &pFirstEntryUserProp
  2993. );
  2994. if ( NO_ERROR != dwRetCode )
  2995. {
  2996. goto LDone;
  2997. }
  2998. dwRetCode = PeapEapInfoFindListNode ( pFirstEntryConnProp->dwEapTypeId,
  2999. pEapInfo,
  3000. &pFirstEapInfo
  3001. );
  3002. if ( NO_ERROR != dwRetCode )
  3003. {
  3004. goto LDone;
  3005. }
  3006. if ( pFirstEntryConnProp->dwEapTypeId != pFirstEntryUserProp->dwEapTypeId )
  3007. {
  3008. //
  3009. // We have mismatched user prop and conn prop. So Reset the USer Prop Structure
  3010. //
  3011. LocalFree ( pUserProp );
  3012. dwRetCode = PeapReDoUserData (pFirstEntryConnProp->dwEapTypeId,
  3013. &pUserProp
  3014. );
  3015. if ( NO_ERROR != dwRetCode )
  3016. {
  3017. goto LDone;
  3018. }
  3019. dwRetCode = PeapGetFirstEntryUserProp ( pUserProp,
  3020. &pFirstEntryUserProp
  3021. );
  3022. if ( NO_ERROR != dwRetCode )
  3023. {
  3024. goto LDone;
  3025. }
  3026. }
  3027. if ( pFirstEntryConnProp->dwSize > sizeof(PEAP_ENTRY_CONN_PROPERTIES))
  3028. {
  3029. pFirstEapInfo->pbClientConfigOrig = pFirstEntryConnProp->bData;
  3030. pFirstEapInfo->dwClientConfigOrigSize = pFirstEntryConnProp->dwSize - sizeof(PEAP_ENTRY_CONN_PROPERTIES) + 1;
  3031. }
  3032. else
  3033. {
  3034. pFirstEapInfo->pbClientConfigOrig = NULL;
  3035. pFirstEapInfo->dwClientConfigOrigSize = 0;
  3036. }
  3037. //if typeid is 0, no user props are setup yet.
  3038. if ( pFirstEntryUserProp->dwSize > sizeof(PEAP_ENTRY_USER_PROPERTIES))
  3039. {
  3040. pFirstEapInfo->pbUserConfigOrig = pFirstEntryUserProp->bData;
  3041. pFirstEapInfo->dwUserConfigOrigSize = pFirstEntryUserProp->dwSize - sizeof(PEAP_ENTRY_USER_PROPERTIES) + 1;
  3042. }
  3043. else
  3044. {
  3045. pFirstEapInfo->pbUserConfigOrig = NULL;
  3046. pFirstEapInfo->dwUserConfigOrigSize = 0;
  3047. }
  3048. //
  3049. // Invoke Identity UI for the first entry
  3050. // and - NOTE we will have to chain this later.
  3051. // and save it in the conn prop of each
  3052. if ( pFirstEapInfo->lpwszIdentityUIPath )
  3053. {
  3054. dwRetCode = PeapEapInfoInvokeIdentityUI ( hwndParent,
  3055. pFirstEapInfo,
  3056. pwszPhonebook,
  3057. pwszEntry,
  3058. pUserDataIn,
  3059. dwSizeOfUserDataIn,
  3060. ppwszIdentityOut,
  3061. dwFlags
  3062. );
  3063. if ( NO_ERROR == dwRetCode )
  3064. {
  3065. //
  3066. // Check to see if we have new user data
  3067. //
  3068. if ( pFirstEapInfo->pbUserConfigNew && pFirstEapInfo->dwNewUserConfigSize )
  3069. {
  3070. //
  3071. // redo the user prop blob
  3072. //
  3073. pUserPropNew = (PPEAP_USER_PROP)
  3074. LocalAlloc ( LPTR, sizeof(PEAP_USER_PROP) + pFirstEapInfo->dwNewUserConfigSize );
  3075. if ( NULL == pUserPropNew )
  3076. {
  3077. dwRetCode = ERROR_OUTOFMEMORY;
  3078. goto LDone;
  3079. }
  3080. CopyMemory ( pUserPropNew, pUserProp, sizeof(PEAP_USER_PROP) );
  3081. pUserPropNew->UserProperties.dwVersion = 1;
  3082. pUserPropNew->UserProperties.dwSize = sizeof(PEAP_ENTRY_USER_PROPERTIES) +
  3083. pFirstEapInfo->dwNewUserConfigSize -1;
  3084. pUserPropNew->dwSize = pUserPropNew->UserProperties.dwSize +
  3085. sizeof(PEAP_USER_PROP) - sizeof(PEAP_ENTRY_USER_PROPERTIES);
  3086. pUserPropNew->UserProperties.dwEapTypeId = pFirstEapInfo->dwTypeId;
  3087. pUserPropNew->UserProperties.fUsingPeapDefault = 0;
  3088. CopyMemory (pUserPropNew->UserProperties.bData,
  3089. pFirstEapInfo->pbUserConfigNew,
  3090. pFirstEapInfo->dwNewUserConfigSize
  3091. );
  3092. *ppUserDataOut = (PBYTE)pUserPropNew;
  3093. *pdwSizeOfUserDataOut = pUserPropNew->dwSize;
  3094. pUserPropNew = NULL;
  3095. }
  3096. else
  3097. {
  3098. *ppUserDataOut = (PBYTE)pUserProp;
  3099. *pdwSizeOfUserDataOut = pUserProp->dwSize;
  3100. pUserProp = NULL;
  3101. }
  3102. }
  3103. }
  3104. else
  3105. {
  3106. //MAchine Auth
  3107. if ( dwFlags & RAS_EAP_FLAG_MACHINE_AUTH)
  3108. {
  3109. //Send the identity back as domain\machine$
  3110. dwRetCode = GetLocalMachineName(&lpwszLocalMachineName );
  3111. if ( NO_ERROR != dwRetCode )
  3112. {
  3113. EapTlsTrace("Failed to get computer name");
  3114. goto LDone;
  3115. }
  3116. if ( ! FFormatMachineIdentity1 ( lpwszLocalMachineName,
  3117. ppwszIdentityOut )
  3118. )
  3119. {
  3120. EapTlsTrace("Failed to format machine identity");
  3121. }
  3122. goto LDone;
  3123. }
  3124. if ( dwFlags & RAS_EAP_FLAG_NON_INTERACTIVE )
  3125. {
  3126. EapTlsTrace("Passed non interactive mode when interactive mode expected.");
  3127. dwRetCode = ERROR_INTERACTIVE_MODE;
  3128. goto LDone;
  3129. }
  3130. //
  3131. // provide our default identity - You cannot save this identity or anything like that.
  3132. // This is for the lame EAP methods that dont supply their own identity
  3133. //
  3134. ZeroMemory ( &DefaultCredDialog, sizeof(DefaultCredDialog) );
  3135. nRet = DialogBoxParam(
  3136. GetResouceDLLHInstance(),
  3137. MAKEINTRESOURCE(IDD_DIALOG_DEFAULT_CREDENTIALS),
  3138. hwndParent,
  3139. DefaultCredDialogProc,
  3140. (LPARAM)&DefaultCredDialog);
  3141. // EapTlsPinDialog.pUserProp may have been realloced
  3142. if (-1 == nRet)
  3143. {
  3144. dwRetCode = GetLastError();
  3145. goto LDone;
  3146. }
  3147. else if (IDOK != nRet)
  3148. {
  3149. dwRetCode = ERROR_CANCELLED;
  3150. goto LDone;
  3151. }
  3152. //CReate the new user prop blob
  3153. pUserPropNew = (PPEAP_USER_PROP)
  3154. LocalAlloc ( LPTR,
  3155. sizeof(PEAP_USER_PROP) + sizeof( PEAP_DEFAULT_CREDENTIALS ) );
  3156. if ( NULL == pUserPropNew )
  3157. {
  3158. dwRetCode = ERROR_OUTOFMEMORY;
  3159. goto LDone;
  3160. }
  3161. CopyMemory ( pUserPropNew, pUserProp, sizeof(PEAP_USER_PROP) );
  3162. pUserPropNew->UserProperties.dwVersion = 1;
  3163. pUserPropNew->UserProperties.dwSize = sizeof(PEAP_ENTRY_USER_PROPERTIES) +
  3164. sizeof(PEAP_DEFAULT_CREDENTIALS) - 1;
  3165. pUserPropNew->UserProperties.fUsingPeapDefault = 1;
  3166. pUserPropNew->dwSize = pUserPropNew->UserProperties.dwSize +
  3167. sizeof(PEAP_USER_PROP) - sizeof(PEAP_ENTRY_USER_PROPERTIES);
  3168. pUserPropNew->UserProperties.dwEapTypeId = pFirstEapInfo->dwTypeId;
  3169. CopyMemory (pUserPropNew->UserProperties.bData,
  3170. &(DefaultCredDialog.PeapDefaultCredentials),
  3171. sizeof(DefaultCredDialog.PeapDefaultCredentials)
  3172. );
  3173. *ppUserDataOut = (PBYTE)pUserPropNew;
  3174. *pdwSizeOfUserDataOut = pUserPropNew->dwSize;
  3175. //
  3176. // Now create the identity with uid and domain if any
  3177. //
  3178. dwRetCode = GetIdentityFromUserName (
  3179. DefaultCredDialog.PeapDefaultCredentials.wszUserName,
  3180. DefaultCredDialog.PeapDefaultCredentials.wszDomain,
  3181. ppwszIdentityOut
  3182. );
  3183. if ( NO_ERROR != dwRetCode )
  3184. {
  3185. goto LDone;
  3186. }
  3187. pUserPropNew = NULL;
  3188. }
  3189. LDone:
  3190. LocalFree( lpwszLocalMachineName );
  3191. LocalFree(pConnProp);
  3192. LocalFree(pUserProp);
  3193. LocalFree(pUserPropNew);
  3194. PeapEapInfoFreeList( pEapInfo );
  3195. return dwRetCode;
  3196. }
  3197. /*
  3198. Returns:
  3199. NO_ERROR: iff Success
  3200. Notes:
  3201. */
  3202. DWORD
  3203. RasEapGetIdentity(
  3204. IN DWORD dwEapTypeId,
  3205. IN HWND hwndParent,
  3206. IN DWORD dwFlags,
  3207. IN const WCHAR* pwszPhonebook,
  3208. IN const WCHAR* pwszEntry,
  3209. IN BYTE* pConnectionDataIn,
  3210. IN DWORD dwSizeOfConnectionDataIn,
  3211. IN BYTE* pUserDataIn,
  3212. IN DWORD dwSizeOfUserDataIn,
  3213. OUT BYTE** ppUserDataOut,
  3214. OUT DWORD* pdwSizeOfUserDataOut,
  3215. OUT WCHAR** ppwszIdentityOut
  3216. )
  3217. {
  3218. DWORD dwErr = ERROR_INVALID_PARAMETER;
  3219. if ( PPP_EAP_TLS == dwEapTypeId )
  3220. {
  3221. dwErr = EapTlsInvokeIdentityUI(
  3222. FALSE /* fServer */,
  3223. FALSE /* fRouterConfig */,
  3224. dwFlags,
  3225. L"MY",
  3226. pwszPhonebook,
  3227. pwszEntry,
  3228. hwndParent,
  3229. pConnectionDataIn,
  3230. dwSizeOfConnectionDataIn,
  3231. pUserDataIn,
  3232. dwSizeOfUserDataIn,
  3233. ppUserDataOut,
  3234. pdwSizeOfUserDataOut,
  3235. ppwszIdentityOut);
  3236. }
  3237. #ifdef IMPL_PEAP
  3238. else if ( PPP_EAP_PEAP == dwEapTypeId )
  3239. {
  3240. dwErr = PeapGetIdentity(dwEapTypeId,
  3241. hwndParent,
  3242. dwFlags,
  3243. pwszPhonebook,
  3244. pwszEntry,
  3245. pConnectionDataIn,
  3246. dwSizeOfConnectionDataIn,
  3247. pUserDataIn,
  3248. dwSizeOfUserDataIn,
  3249. ppUserDataOut,
  3250. pdwSizeOfUserDataOut,
  3251. ppwszIdentityOut
  3252. );
  3253. }
  3254. #endif
  3255. return(dwErr);
  3256. }
  3257. /*
  3258. Returns:
  3259. Notes:
  3260. Called to free memory.
  3261. */
  3262. DWORD
  3263. RasEapFreeMemory(
  3264. IN BYTE* pMemory
  3265. )
  3266. {
  3267. LocalFree(pMemory);
  3268. return(NO_ERROR);
  3269. }
  3270. #if 0
  3271. #if WINVER > 0x0500
  3272. /*
  3273. Returns:
  3274. Notes:
  3275. API to create a connection Properties V1 Blob
  3276. */
  3277. /*
  3278. Returns:
  3279. Notes:
  3280. API to create a connection Properties V1 Blob
  3281. */
  3282. DWORD
  3283. RasEapCreateConnProp
  3284. (
  3285. IN PEAPTLS_CONNPROP_ATTRIBUTE pAttr,
  3286. IN PVOID * ppConnPropIn,
  3287. IN DWORD * pdwConnPropSizeIn,
  3288. OUT PVOID * ppConnPropOut,
  3289. OUT DWORD * pdwConnPropSizeOut
  3290. )
  3291. {
  3292. DWORD dwRetCode = NO_ERROR;
  3293. DWORD dwAllocBytes = 0;
  3294. DWORD dwNumHashesOrig = 0;
  3295. DWORD dwServerNamesLengthOrig = 0;
  3296. PEAPTLS_CONNPROP_ATTRIBUTE pAttrInternal = pAttr;
  3297. EAPTLS_CONN_PROPERTIES_V1 * pConnPropv1 = NULL;
  3298. EAPTLS_CONN_PROPERTIES_V1 * pConnPropv1Orig = NULL;
  3299. PEAPTLS_CONNPROP_ATTRIBUTE pAttrServerNames = NULL;
  3300. PEAPTLS_CONNPROP_ATTRIBUTE pAttrHashes = NULL;
  3301. EAPTLS_HASH sHash;
  3302. DWORD i;
  3303. if ( !pAttr || !ppConnPropOut )
  3304. {
  3305. dwRetCode = ERROR_INVALID_PARAMETER;
  3306. goto done;
  3307. }
  3308. *ppConnPropOut = NULL;
  3309. //
  3310. // Get the sizeof this allocation.
  3311. //
  3312. dwAllocBytes = sizeof(EAPTLS_CONN_PROPERTIES_V1);
  3313. while ( pAttrInternal->ecaType != ecatMinimum )
  3314. {
  3315. switch ( pAttrInternal->ecaType )
  3316. {
  3317. case ecatMinimum:
  3318. case ecatFlagRegistryCert:
  3319. case ecatFlagScard:
  3320. case ecatFlagValidateServer:
  3321. case ecatFlagValidateName:
  3322. case ecatFlagDiffUser:
  3323. break;
  3324. case ecatServerNames:
  3325. dwAllocBytes += pAttrInternal->dwLength;
  3326. break;
  3327. case ecatRootHashes:
  3328. dwAllocBytes += ( ( (pAttrInternal->dwLength)/MAX_HASH_SIZE) * sizeof(EAPTLS_HASH) );
  3329. break;
  3330. default:
  3331. dwRetCode = ERROR_INVALID_PARAMETER;
  3332. goto done;
  3333. }
  3334. pAttrInternal ++;
  3335. }
  3336. pAttrInternal = pAttr;
  3337. if (*ppConnPropIn == NULL)
  3338. {
  3339. pConnPropv1 = (EAPTLS_CONN_PROPERTIES_V1 *) LocalAlloc(LPTR, dwAllocBytes );
  3340. if ( NULL == pConnPropv1 )
  3341. {
  3342. dwRetCode = GetLastError();
  3343. goto done;
  3344. }
  3345. }
  3346. else
  3347. {
  3348. // Input struct with always be Version 0, convert internally to
  3349. // Version 1
  3350. dwRetCode = ConnPropGetV1Struct ( ((EAPTLS_CONN_PROPERTIES *)(*ppConnPropIn)), &pConnPropv1Orig );
  3351. if ( NO_ERROR != dwRetCode )
  3352. {
  3353. goto done;
  3354. }
  3355. if (pConnPropv1Orig->dwNumHashes)
  3356. {
  3357. dwAllocBytes += pConnPropv1Orig->dwNumHashes*sizeof(EAPTLS_HASH);
  3358. }
  3359. dwAllocBytes += wcslen ( (WCHAR *)( pConnPropv1Orig->bData + (pConnPropv1Orig->dwNumHashes * sizeof(EAPTLS_HASH)) )) * sizeof(WCHAR) + sizeof(WCHAR);
  3360. pConnPropv1 = (EAPTLS_CONN_PROPERTIES_V1 *) LocalAlloc(LPTR, dwAllocBytes );
  3361. if ( NULL == pConnPropv1 )
  3362. {
  3363. dwRetCode = GetLastError();
  3364. goto done;
  3365. }
  3366. }
  3367. pConnPropv1->dwVersion = 1;
  3368. pConnPropv1->dwSize = dwAllocBytes;
  3369. //
  3370. //Set the flags first
  3371. //
  3372. while ( pAttrInternal->ecaType != ecatMinimum )
  3373. {
  3374. switch ( pAttrInternal->ecaType )
  3375. {
  3376. case ecatFlagRegistryCert:
  3377. pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_REGISTRY;
  3378. break;
  3379. case ecatFlagScard:
  3380. pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_REGISTRY;
  3381. break;
  3382. case ecatFlagValidateServer:
  3383. if ( *((BOOL *)(pAttrInternal->Value)) )
  3384. pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_NO_VALIDATE_CERT;
  3385. else
  3386. pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_NO_VALIDATE_CERT;
  3387. break;
  3388. case ecatFlagValidateName:
  3389. if ( *((BOOL *)(pAttrInternal->Value)) )
  3390. pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_NO_VALIDATE_NAME;
  3391. else
  3392. pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_NO_VALIDATE_NAME;
  3393. break;
  3394. case ecatFlagDiffUser:
  3395. if ( *((BOOL *)(pAttrInternal->Value)) )
  3396. pConnPropv1->fFlags &= ~EAPTLS_CONN_FLAG_DIFF_USER;
  3397. else
  3398. pConnPropv1->fFlags |= EAPTLS_CONN_FLAG_DIFF_USER;
  3399. break;
  3400. case ecatServerNames:
  3401. pAttrServerNames = pAttrInternal;
  3402. break;
  3403. case ecatRootHashes:
  3404. pAttrHashes = pAttrInternal;
  3405. break;
  3406. }
  3407. pAttrInternal++;
  3408. }
  3409. dwNumHashesOrig = pConnPropv1Orig?pConnPropv1Orig->dwNumHashes:0;
  3410. if ( dwNumHashesOrig )
  3411. {
  3412. CopyMemory( pConnPropv1->bData, pConnPropv1Orig->bData, sizeof(EAPTLS_HASH)*dwNumHashesOrig );
  3413. pConnPropv1->dwNumHashes = dwNumHashesOrig;
  3414. }
  3415. if ( pAttrHashes )
  3416. {
  3417. DWORD dwNumHashes = 0;
  3418. dwNumHashes = (pAttrHashes->dwLength)/MAX_HASH_SIZE;
  3419. for ( i = 0; i < dwNumHashes; i ++ )
  3420. {
  3421. ZeroMemory( &sHash, sizeof(sHash) );
  3422. sHash.cbHash = MAX_HASH_SIZE;
  3423. CopyMemory( sHash.pbHash, ((PBYTE)pAttrHashes->Value) + MAX_HASH_SIZE * i, MAX_HASH_SIZE );
  3424. CopyMemory( pConnPropv1->bData + sizeof(EAPTLS_HASH) * (pConnPropv1->dwNumHashes + i) , &sHash, sizeof(sHash) );
  3425. }
  3426. pConnPropv1->dwNumHashes += dwNumHashes;
  3427. }
  3428. dwServerNamesLengthOrig = pConnPropv1Orig?(wcslen((WCHAR*)(pConnPropv1Orig->bData+sizeof(EAPTLS_HASH) * (pConnPropv1Orig->dwNumHashes)))*sizeof(WCHAR) + sizeof (WCHAR) ):0;
  3429. if ( dwServerNamesLengthOrig )
  3430. {
  3431. CopyMemory ( pConnPropv1->bData + sizeof(EAPTLS_HASH) * pConnPropv1->dwNumHashes,
  3432. pConnPropv1Orig->bData+sizeof(EAPTLS_HASH) * pConnPropv1Orig->dwNumHashes,
  3433. dwServerNamesLengthOrig
  3434. );
  3435. }
  3436. if ( pAttrServerNames )
  3437. {
  3438. //Setup the server name
  3439. CopyMemory ( pConnPropv1->bData + sizeof(EAPTLS_HASH) * pConnPropv1->dwNumHashes + dwServerNamesLengthOrig,
  3440. pAttrServerNames->Value,
  3441. pAttrServerNames->dwLength
  3442. );
  3443. }
  3444. dwRetCode = ConnPropGetV0Struct ( pConnPropv1, (EAPTLS_CONN_PROPERTIES ** )ppConnPropOut );
  3445. if ( NO_ERROR != dwRetCode )
  3446. {
  3447. goto done;
  3448. }
  3449. *pdwConnPropSizeOut = ((EAPTLS_CONN_PROPERTIES * )*ppConnPropOut)->dwSize;
  3450. done:
  3451. LocalFree ( pConnPropv1 );
  3452. return dwRetCode;
  3453. }
  3454. #endif
  3455. #endif
  3456. ////////////////////////// all PEAP related stuff ///////////////////////////////////////
  3457. TCHAR*
  3458. ComboBox_GetPsz(
  3459. IN HWND hwnd,
  3460. IN INT nIndex )
  3461. /* Returns heap block containing the text contents of the 'nIndex'th item
  3462. ** of combo box 'hwnd' or NULL. It is caller's responsibility to Free the
  3463. ** returned string.
  3464. */
  3465. {
  3466. INT cch;
  3467. TCHAR* psz;
  3468. cch = ComboBox_GetLBTextLen( hwnd, nIndex );
  3469. if (cch < 0)
  3470. return NULL;
  3471. psz = LocalAlloc (LPTR, (cch + 1) * sizeof(TCHAR) );
  3472. if (psz)
  3473. {
  3474. *psz = TEXT('\0');
  3475. ComboBox_GetLBText( hwnd, nIndex, psz );
  3476. }
  3477. return psz;
  3478. }
  3479. VOID
  3480. ComboBox_AutoSizeDroppedWidth(
  3481. IN HWND hwndLb )
  3482. /* Set the width of the drop-down list 'hwndLb' to the width of the
  3483. ** longest item (or the width of the list box if that's wider).
  3484. */
  3485. {
  3486. HDC hdc;
  3487. HFONT hfont;
  3488. TCHAR* psz;
  3489. SIZE size;
  3490. DWORD cch;
  3491. DWORD dxNew;
  3492. DWORD i;
  3493. hfont = (HFONT )SendMessage( hwndLb, WM_GETFONT, 0, 0 );
  3494. if (!hfont)
  3495. return;
  3496. hdc = GetDC( hwndLb );
  3497. if (!hdc)
  3498. return;
  3499. SelectObject( hdc, hfont );
  3500. dxNew = 0;
  3501. for (i = 0; psz = ComboBox_GetPsz( hwndLb, i ); ++i)
  3502. {
  3503. cch = lstrlen( psz );
  3504. if (GetTextExtentPoint32( hdc, psz, cch, &size ))
  3505. {
  3506. if (dxNew < (DWORD )size.cx)
  3507. dxNew = (DWORD )size.cx;
  3508. }
  3509. LocalFree( psz );
  3510. }
  3511. ReleaseDC( hwndLb, hdc );
  3512. /* Allow for the spacing on left and right added by the control.
  3513. */
  3514. dxNew += 6;
  3515. /* Figure out if the vertical scrollbar will be displayed and, if so,
  3516. ** allow for it's width.
  3517. */
  3518. {
  3519. RECT rectD;
  3520. RECT rectU;
  3521. DWORD dyItem;
  3522. DWORD cItemsInDrop;
  3523. DWORD cItemsInList;
  3524. GetWindowRect( hwndLb, &rectU );
  3525. SendMessage( hwndLb, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM )&rectD );
  3526. dyItem = (DWORD)SendMessage( hwndLb, CB_GETITEMHEIGHT, 0, 0 );
  3527. cItemsInDrop = (rectD.bottom - rectU.bottom) / dyItem;
  3528. cItemsInList = ComboBox_GetCount( hwndLb );
  3529. if (cItemsInDrop < cItemsInList)
  3530. dxNew += GetSystemMetrics( SM_CXVSCROLL );
  3531. }
  3532. SendMessage( hwndLb, CB_SETDROPPEDWIDTH, dxNew, 0 );
  3533. }
  3534. VOID
  3535. PeapEnableValidateNameControls(
  3536. IN PPEAP_CONN_DIALOG pPeapConnDialog
  3537. )
  3538. {
  3539. BOOL fEnable;
  3540. RTASSERT(NULL != pPeapConnDialog);
  3541. fEnable = !(pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags &
  3542. EAPTLS_CONN_FLAG_NO_VALIDATE_CERT);
  3543. EnableWindow(pPeapConnDialog->hWndCheckValidateName, fEnable);
  3544. EnableWindow(pPeapConnDialog->hWndStaticRootCaName, fEnable);
  3545. EnableWindow(pPeapConnDialog->hWndListRootCaName, fEnable);
  3546. fEnable = ( fEnable
  3547. && !(pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags &
  3548. EAPTLS_CONN_FLAG_NO_VALIDATE_NAME));
  3549. EnableWindow(pPeapConnDialog->hWndEditServerName, fEnable);
  3550. }
  3551. BOOL
  3552. PeapConnInitDialog(
  3553. IN HWND hWnd,
  3554. IN LPARAM lParam
  3555. )
  3556. {
  3557. PPEAP_CONN_DIALOG pPeapConnDialog;
  3558. LVCOLUMN lvColumn;
  3559. LPWSTR lpwszServerName = NULL;
  3560. DWORD dwCount = 0;
  3561. PPEAP_EAP_INFO pEapInfo;
  3562. DWORD dwSelItem = 0;
  3563. PEAP_ENTRY_CONN_PROPERTIES UNALIGNED * pEntryProp;
  3564. INT_PTR nIndex = 0;
  3565. BOOL fCripplePeap = FALSE;
  3566. SetWindowLongPtr(hWnd, DWLP_USER, lParam);
  3567. pPeapConnDialog = (PPEAP_CONN_DIALOG)lParam;
  3568. pPeapConnDialog->hWndCheckValidateCert =
  3569. GetDlgItem(hWnd, IDC_CHECK_VALIDATE_CERT);
  3570. pPeapConnDialog->hWndCheckValidateName =
  3571. GetDlgItem(hWnd, IDC_CHECK_VALIDATE_NAME);
  3572. pPeapConnDialog->hWndEditServerName =
  3573. GetDlgItem(hWnd, IDC_EDIT_SERVER_NAME);
  3574. pPeapConnDialog->hWndStaticRootCaName =
  3575. GetDlgItem(hWnd, IDC_STATIC_ROOT_CA_NAME);
  3576. pPeapConnDialog->hWndListRootCaName =
  3577. GetDlgItem(hWnd, IDC_LIST_ROOT_CA_NAME);
  3578. pPeapConnDialog->hWndComboPeapType =
  3579. GetDlgItem(hWnd, IDC_COMBO_PEAP_TYPE);
  3580. pPeapConnDialog->hWndButtonConfigure =
  3581. GetDlgItem(hWnd, IDC_BUTTON_CONFIGURE);
  3582. pPeapConnDialog->hWndCheckEnableFastReconnect =
  3583. GetDlgItem(hWnd, IDC_CHECK_ENABLE_FAST_RECONNECT);
  3584. //Set the style to set list boxes.
  3585. ListView_SetExtendedListViewStyle
  3586. ( pPeapConnDialog->hWndListRootCaName,
  3587. ListView_GetExtendedListViewStyle(pPeapConnDialog->hWndListRootCaName) | LVS_EX_CHECKBOXES
  3588. );
  3589. ZeroMemory ( &lvColumn, sizeof(lvColumn));
  3590. lvColumn.fmt = LVCFMT_LEFT;
  3591. ListView_InsertColumn( pPeapConnDialog->hWndListRootCaName,
  3592. 0,
  3593. &lvColumn
  3594. );
  3595. ListView_SetColumnWidth(pPeapConnDialog->hWndListRootCaName,
  3596. 0,
  3597. LVSCW_AUTOSIZE_USEHEADER
  3598. );
  3599. //
  3600. //Now we need to init the
  3601. //list box with all the certs and selected cert
  3602. InitListBox ( pPeapConnDialog->hWndListRootCaName,
  3603. pPeapConnDialog->pCertList,
  3604. pPeapConnDialog->pConnProp->EapTlsConnProp.dwNumHashes,
  3605. pPeapConnDialog->ppSelCertList
  3606. );
  3607. lpwszServerName =
  3608. (LPWSTR )(pPeapConnDialog->pConnProp->EapTlsConnProp.bData +
  3609. sizeof( EAPTLS_HASH ) * pPeapConnDialog->pConnProp->EapTlsConnProp.dwNumHashes);
  3610. SetWindowText(pPeapConnDialog->hWndEditServerName,
  3611. lpwszServerName
  3612. );
  3613. if (pPeapConnDialog->fFlags & EAPTLS_CONN_DIALOG_FLAG_ROUTER)
  3614. {
  3615. pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags |= EAPTLS_CONN_FLAG_REGISTRY;
  3616. }
  3617. CheckDlgButton(hWnd, IDC_CHECK_VALIDATE_CERT,
  3618. (pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags &
  3619. EAPTLS_CONN_FLAG_NO_VALIDATE_CERT) ?
  3620. BST_UNCHECKED : BST_CHECKED);
  3621. CheckDlgButton(hWnd, IDC_CHECK_VALIDATE_NAME,
  3622. (pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags &
  3623. EAPTLS_CONN_FLAG_NO_VALIDATE_NAME) ?
  3624. BST_UNCHECKED : BST_CHECKED);
  3625. PeapEnableValidateNameControls(pPeapConnDialog);
  3626. //NOTE:
  3627. // For this version of PEAP the control is a combo box. But
  3628. // it will change to list box and we need to change the
  3629. // control to list and change the following code to
  3630. // add only the ones that are applicable
  3631. //
  3632. // Check to see if PEAP is crippled.
  3633. //
  3634. {
  3635. HKEY hKeyLM =0;
  3636. RegConnectRegistry ( NULL,
  3637. HKEY_LOCAL_MACHINE,
  3638. &hKeyLM
  3639. );
  3640. fCripplePeap = IsPeapCrippled ( hKeyLM );
  3641. RegCloseKey(hKeyLM);
  3642. }
  3643. //
  3644. //Add all the PEAP eap type friendly names
  3645. //
  3646. pEapInfo = pPeapConnDialog->pEapInfo;
  3647. dwCount = 0;
  3648. while ( pEapInfo )
  3649. {
  3650. if ( pEapInfo->dwTypeId == PPP_EAP_CHAP )
  3651. {
  3652. pEapInfo = pEapInfo->pNext;
  3653. continue;
  3654. }
  3655. nIndex = SendMessage(pPeapConnDialog->hWndComboPeapType,
  3656. CB_ADDSTRING,
  3657. 0,
  3658. (LPARAM)pEapInfo->lpwszFriendlyName);
  3659. SendMessage ( pPeapConnDialog->hWndComboPeapType,
  3660. CB_SETITEMDATA,
  3661. (WPARAM)nIndex,
  3662. (LPARAM)pEapInfo
  3663. );
  3664. ComboBox_AutoSizeDroppedWidth( pPeapConnDialog->hWndComboPeapType );
  3665. dwCount++;
  3666. if ( pPeapConnDialog->pConnProp->dwNumPeapTypes )
  3667. {
  3668. /*
  3669. if ( pPeapConnDialog->pConnProp->EapTlsConnProp.dwSize == sizeof(EAPTLS_CONN_PROPERTIES_V1) )
  3670. {
  3671. //This is a newly initialized structure.
  3672. pEntryProp = (PEAP_ENTRY_CONN_PROPERTIES UNALIGNED *)
  3673. (((BYTE UNALIGNED *)(pPeapConnDialog->pConnProp)) + sizeof(PEAP_CONN_PROP));
  3674. }
  3675. else
  3676. */
  3677. {
  3678. pEntryProp = ( PEAP_ENTRY_CONN_PROPERTIES UNALIGNED *)
  3679. ( (BYTE UNALIGNED *)pPeapConnDialog->pConnProp->EapTlsConnProp.bData
  3680. + pPeapConnDialog->pConnProp->EapTlsConnProp.dwNumHashes * sizeof(EAPTLS_HASH) +
  3681. wcslen(lpwszServerName) * sizeof(WCHAR) + sizeof(WCHAR));
  3682. }
  3683. if ( pEntryProp->dwEapTypeId == pEapInfo->dwTypeId )
  3684. {
  3685. pPeapConnDialog->pSelEapInfo = pEapInfo;
  3686. pPeapConnDialog->pSelEapInfo->pbClientConfigOrig =
  3687. pEntryProp->bData;
  3688. pPeapConnDialog->pSelEapInfo->dwClientConfigOrigSize =
  3689. pEntryProp->dwSize - sizeof(PEAP_ENTRY_CONN_PROPERTIES) + 1;
  3690. }
  3691. }
  3692. pEapInfo = pEapInfo->pNext;
  3693. }
  3694. dwSelItem = 0;
  3695. for ( nIndex = 0; nIndex < (INT_PTR)dwCount; nIndex ++ )
  3696. {
  3697. pEapInfo = (PPEAP_EAP_INFO)SendMessage( pPeapConnDialog->hWndComboPeapType,
  3698. CB_GETITEMDATA,
  3699. (WPARAM)nIndex,
  3700. (LPARAM)0L
  3701. );
  3702. if ( pEapInfo == pPeapConnDialog->pSelEapInfo )
  3703. {
  3704. dwSelItem = (DWORD)nIndex;
  3705. break;
  3706. }
  3707. }
  3708. SendMessage(pPeapConnDialog->hWndComboPeapType, CB_SETCURSEL, dwSelItem, 0);
  3709. //
  3710. // Hide/Show Fast reconnect based on if this is a
  3711. // Wireless client or VPN client.
  3712. //
  3713. if ( pPeapConnDialog->fFlags & PEAP_CONN_DIALOG_FLAG_8021x )
  3714. {
  3715. ShowWindow ( pPeapConnDialog->hWndCheckEnableFastReconnect,
  3716. SW_SHOW
  3717. );
  3718. //Check the box based on what the
  3719. CheckDlgButton(hWnd, IDC_CHECK_ENABLE_FAST_RECONNECT,
  3720. ( pPeapConnDialog->pConnProp->dwFlags &
  3721. PEAP_CONN_FLAG_FAST_ROAMING) ?
  3722. BST_CHECKED : BST_UNCHECKED
  3723. );
  3724. }
  3725. else
  3726. {
  3727. ShowWindow ( pPeapConnDialog->hWndCheckEnableFastReconnect,
  3728. SW_HIDE
  3729. );
  3730. }
  3731. if ( pPeapConnDialog->pSelEapInfo->lpwszConfigUIPath )
  3732. {
  3733. EnableWindow(pPeapConnDialog->hWndButtonConfigure, TRUE );
  3734. }
  3735. else
  3736. {
  3737. //
  3738. // There is no configuration option here.
  3739. //
  3740. EnableWindow(pPeapConnDialog->hWndButtonConfigure, FALSE );
  3741. }
  3742. //
  3743. // if this is to function in readonly mode,
  3744. // disable the controls - set them in read only mode.
  3745. return(FALSE);
  3746. }
  3747. /*
  3748. Returns:
  3749. TRUE: We prrocessed this message.
  3750. FALSE: We did not prrocess this message.
  3751. Notes:
  3752. Response to the WM_COMMAND message (Config UI).
  3753. */
  3754. BOOL
  3755. PeapConnCommand(
  3756. IN PPEAP_CONN_DIALOG pPeapConnDialog,
  3757. IN WORD wNotifyCode,
  3758. IN WORD wId,
  3759. IN HWND hWndDlg,
  3760. IN HWND hWndCtrl
  3761. )
  3762. {
  3763. DWORD dwNumChars;
  3764. PPEAP_CONN_PROP pPeapConnProp;
  3765. switch(wId)
  3766. {
  3767. case IDC_CHECK_VALIDATE_CERT:
  3768. if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_VALIDATE_CERT))
  3769. {
  3770. pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags &=
  3771. ~EAPTLS_CONN_FLAG_NO_VALIDATE_CERT;
  3772. pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags &=
  3773. ~EAPTLS_CONN_FLAG_NO_VALIDATE_NAME;
  3774. CheckDlgButton(hWndDlg, IDC_CHECK_VALIDATE_NAME, BST_CHECKED);
  3775. }
  3776. else
  3777. {
  3778. pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags |=
  3779. EAPTLS_CONN_FLAG_NO_VALIDATE_CERT;
  3780. pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags |=
  3781. EAPTLS_CONN_FLAG_NO_VALIDATE_NAME;
  3782. CheckDlgButton(hWndDlg, IDC_CHECK_VALIDATE_NAME, BST_UNCHECKED);
  3783. }
  3784. PeapEnableValidateNameControls(pPeapConnDialog);
  3785. return(TRUE);
  3786. case IDC_CHECK_VALIDATE_NAME:
  3787. if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_VALIDATE_NAME))
  3788. {
  3789. pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags &=
  3790. ~EAPTLS_CONN_FLAG_NO_VALIDATE_NAME;
  3791. }
  3792. else
  3793. {
  3794. pPeapConnDialog->pConnProp->EapTlsConnProp.fFlags |=
  3795. EAPTLS_CONN_FLAG_NO_VALIDATE_NAME;
  3796. }
  3797. PeapEnableValidateNameControls(pPeapConnDialog);
  3798. return(TRUE);
  3799. case IDC_COMBO_PEAP_TYPE:
  3800. if (CBN_SELCHANGE != wNotifyCode)
  3801. {
  3802. return(FALSE); // We will not process this message
  3803. }
  3804. //Fall Thru'
  3805. case IDC_BUTTON_CONFIGURE:
  3806. {
  3807. INT nIndex = -1;
  3808. nIndex = (INT)SendMessage ( pPeapConnDialog->hWndComboPeapType,
  3809. CB_GETCURSEL,
  3810. 0,0
  3811. );
  3812. if ( nIndex != -1 )
  3813. {
  3814. //
  3815. // Change the currently selected EAP Type.
  3816. //
  3817. pPeapConnDialog->pSelEapInfo = (PPEAP_EAP_INFO)
  3818. SendMessage ( pPeapConnDialog->hWndComboPeapType,
  3819. CB_GETITEMDATA,
  3820. (WPARAM)nIndex,
  3821. (LPARAM)0
  3822. );
  3823. if ( pPeapConnDialog->pSelEapInfo->lpwszConfigUIPath )
  3824. {
  3825. EnableWindow(pPeapConnDialog->hWndButtonConfigure, TRUE );
  3826. if ( wId == IDC_BUTTON_CONFIGURE )
  3827. {
  3828. //
  3829. // Invoke the configure method for selected eap type and if no error is
  3830. // returned, then set the new configuration
  3831. //
  3832. DWORD dwFlags = 0;
  3833. if ( pPeapConnDialog->fFlags & EAPTLS_CONN_DIALOG_FLAG_ROUTER )
  3834. {
  3835. dwFlags |= RAS_EAP_FLAG_ROUTER;
  3836. }
  3837. if ( pPeapConnDialog->fFlags & PEAP_CONN_DIALOG_FLAG_8021x )
  3838. {
  3839. dwFlags |= RAS_EAP_FLAG_8021X_AUTH;
  3840. }
  3841. PeapEapInfoInvokeClientConfigUI ( hWndDlg,
  3842. pPeapConnDialog->pSelEapInfo,
  3843. dwFlags
  3844. );
  3845. }
  3846. }
  3847. else
  3848. {
  3849. //
  3850. // There is no configuration option here.
  3851. //
  3852. EnableWindow(pPeapConnDialog->hWndButtonConfigure, FALSE );
  3853. }
  3854. }
  3855. else
  3856. {
  3857. EnableWindow(pPeapConnDialog->hWndButtonConfigure, FALSE );
  3858. pPeapConnDialog->pSelEapInfo = NULL;
  3859. }
  3860. return TRUE;
  3861. }
  3862. case IDOK:
  3863. {
  3864. // Setup new PPEAP_CONN_PROP here.
  3865. //
  3866. EAPTLS_HASH * pHash = NULL;
  3867. DWORD dwNumHash = 0;
  3868. DWORD dwSelCount = 0;
  3869. DWORD dwPeapConnBlobSize = 0;
  3870. PEAP_ENTRY_CONN_PROPERTIES UNALIGNED * pEntryProp;
  3871. EAPTLS_CERT_NODE ** ppSelCertList = NULL;
  3872. WCHAR wszTitle[200] = {0};
  3873. WCHAR wszMessage[200] = {0};
  3874. if ( NULL == pPeapConnDialog->pSelEapInfo )
  3875. {
  3876. // No item selected so cannot complete configuration
  3877. // $TODO:show message
  3878. LoadString ( GetHInstance(),
  3879. IDS_CANT_CONFIGURE_SERVER_TITLE,
  3880. wszTitle, sizeof(wszTitle)/sizeof(WCHAR)
  3881. );
  3882. LoadString ( GetResouceDLLHInstance(),
  3883. IDS_PEAP_NO_EAP_TYPE,
  3884. wszMessage, sizeof(wszMessage)/sizeof(WCHAR)
  3885. );
  3886. MessageBox ( GetFocus(), wszMessage, wszTitle, MB_OK|MB_ICONWARNING );
  3887. return TRUE;
  3888. }
  3889. CertListSelectedCount ( pPeapConnDialog->hWndListRootCaName, &dwSelCount );
  3890. if ( dwSelCount > 0 )
  3891. {
  3892. ppSelCertList = (EAPTLS_CERT_NODE **)LocalAlloc(LPTR, sizeof(EAPTLS_CERT_NODE *) * dwSelCount );
  3893. if ( NULL == ppSelCertList )
  3894. {
  3895. EapTlsTrace("LocalAlloc in Command failed and returned %d",
  3896. GetLastError());
  3897. return TRUE;
  3898. }
  3899. pHash = (EAPTLS_HASH *)LocalAlloc(LPTR, sizeof(EAPTLS_HASH ) * dwSelCount );
  3900. if ( NULL == pHash )
  3901. {
  3902. EapTlsTrace("LocalAlloc in Command failed and returned %d",
  3903. GetLastError());
  3904. return TRUE;
  3905. }
  3906. CertListSelected( pPeapConnDialog->hWndListRootCaName,
  3907. pPeapConnDialog->pCertList,
  3908. ppSelCertList,
  3909. pHash,
  3910. dwSelCount
  3911. );
  3912. }
  3913. dwNumChars = GetWindowTextLength(pPeapConnDialog->hWndEditServerName);
  3914. //Allocate memory for pPeapConnProp
  3915. //Size of Peap conn prop includes
  3916. // sizeof peap conn prop +
  3917. // sizeof eaptls hashes of selected certs +
  3918. // sizeof server name +
  3919. // sizeof PEAP_ENTRY_CONN_PROPERTIES +
  3920. // sizeof conn prop returned by the selected type.
  3921. //
  3922. dwPeapConnBlobSize = sizeof(PEAP_CONN_PROP) + sizeof(EAPTLS_HASH) * dwSelCount +
  3923. dwNumChars * sizeof(WCHAR) + sizeof(WCHAR) +
  3924. sizeof(PEAP_ENTRY_CONN_PROPERTIES );
  3925. if ( pPeapConnDialog->pSelEapInfo->pbNewClientConfig )
  3926. {
  3927. dwPeapConnBlobSize += pPeapConnDialog->pSelEapInfo->dwNewClientConfigSize;
  3928. }
  3929. else
  3930. {
  3931. dwPeapConnBlobSize += pPeapConnDialog->pSelEapInfo->dwClientConfigOrigSize;
  3932. }
  3933. pPeapConnProp = (PPEAP_CONN_PROP)LocalAlloc( LPTR, dwPeapConnBlobSize );
  3934. if (NULL == pPeapConnProp)
  3935. {
  3936. EapTlsTrace("LocalAlloc in Command failed and returned %d",
  3937. GetLastError());
  3938. }
  3939. else
  3940. {
  3941. pPeapConnProp->dwVersion = 1;
  3942. pPeapConnProp->dwSize = dwPeapConnBlobSize;
  3943. pPeapConnProp->dwNumPeapTypes = 1;
  3944. //
  3945. // See if fast roaming is enabled or not.
  3946. //
  3947. if ( pPeapConnDialog->fFlags & PEAP_CONN_DIALOG_FLAG_8021x )
  3948. {
  3949. if ( IsDlgButtonChecked ( hWndDlg,
  3950. IDC_CHECK_ENABLE_FAST_RECONNECT
  3951. ) == BST_CHECKED
  3952. )
  3953. {
  3954. pPeapConnProp->dwFlags |= PEAP_CONN_FLAG_FAST_ROAMING;
  3955. }
  3956. else
  3957. {
  3958. pPeapConnProp->dwFlags &= ~PEAP_CONN_FLAG_FAST_ROAMING;
  3959. }
  3960. }
  3961. CopyMemory( &pPeapConnProp->EapTlsConnProp,
  3962. &(pPeapConnDialog->pConnProp->EapTlsConnProp),
  3963. sizeof(EAPTLS_CONN_PROPERTIES_V1)
  3964. );
  3965. //
  3966. //Size of EapTlsConnProp is sizeof (EAPTLS_CONN_PROP_V1) -1 ( for bdata)
  3967. //+ sizeof(EAPTLS_HASH) * dwSelCount + sizeof( string) + one for null.
  3968. //
  3969. pPeapConnProp->EapTlsConnProp.dwSize = (sizeof(EAPTLS_CONN_PROPERTIES_V1) - 1) +
  3970. sizeof(EAPTLS_HASH) * dwSelCount +
  3971. dwNumChars * sizeof(WCHAR) + sizeof(WCHAR);
  3972. CopyMemory ( pPeapConnProp->EapTlsConnProp.bData,
  3973. pHash,
  3974. sizeof(EAPTLS_HASH) * dwSelCount
  3975. );
  3976. pPeapConnProp->EapTlsConnProp.dwVersion = 1;
  3977. pPeapConnProp->EapTlsConnProp.dwNumHashes = dwSelCount;
  3978. GetWindowText(pPeapConnDialog->hWndEditServerName,
  3979. (LPWSTR)(pPeapConnProp->EapTlsConnProp.bData + sizeof(EAPTLS_HASH) * dwSelCount) ,
  3980. dwNumChars + 1);
  3981. //
  3982. // Now copy over the PEAP_ENTRY_CONN_PROPERTIES structure
  3983. //
  3984. pEntryProp = (PEAP_ENTRY_CONN_PROPERTIES UNALIGNED *)
  3985. ((BYTE UNALIGNED *)pPeapConnProp->EapTlsConnProp.bData + sizeof(EAPTLS_HASH) * dwSelCount
  3986. + dwNumChars * sizeof(WCHAR)+ sizeof(WCHAR));
  3987. pEntryProp->dwVersion = 1;
  3988. pEntryProp->dwEapTypeId = pPeapConnDialog->pSelEapInfo->dwTypeId;
  3989. pEntryProp->dwSize = sizeof(PEAP_ENTRY_CONN_PROPERTIES)-1;
  3990. if ( pPeapConnDialog->pSelEapInfo->pbNewClientConfig )
  3991. {
  3992. pEntryProp->dwSize += pPeapConnDialog->pSelEapInfo->dwNewClientConfigSize ;
  3993. if ( pPeapConnDialog->pSelEapInfo->dwNewClientConfigSize )
  3994. {
  3995. CopyMemory( pEntryProp->bData,
  3996. pPeapConnDialog->pSelEapInfo->pbNewClientConfig,
  3997. pPeapConnDialog->pSelEapInfo->dwNewClientConfigSize
  3998. );
  3999. }
  4000. }
  4001. else
  4002. {
  4003. pEntryProp->dwSize += pPeapConnDialog->pSelEapInfo->dwClientConfigOrigSize;
  4004. if ( pPeapConnDialog->pSelEapInfo->dwClientConfigOrigSize )
  4005. {
  4006. CopyMemory( pEntryProp->bData,
  4007. pPeapConnDialog->pSelEapInfo->pbClientConfigOrig,
  4008. pPeapConnDialog->pSelEapInfo->dwClientConfigOrigSize
  4009. );
  4010. }
  4011. }
  4012. LocalFree(pPeapConnDialog->pConnProp);
  4013. if ( pPeapConnDialog->ppSelCertList )
  4014. LocalFree(pPeapConnDialog->ppSelCertList);
  4015. pPeapConnDialog->ppSelCertList = ppSelCertList;
  4016. pPeapConnDialog->pConnProp= pPeapConnProp;
  4017. }
  4018. }
  4019. // Fall through
  4020. case IDCANCEL:
  4021. EndDialog(hWndDlg, wId);
  4022. return(TRUE);
  4023. default:
  4024. return(FALSE);
  4025. }
  4026. }
  4027. BOOL PeapConnNotify( PEAP_CONN_DIALOG *pPeapConnDialog,
  4028. WPARAM wParam,
  4029. LPARAM lParam,
  4030. HWND hWnd
  4031. )
  4032. {
  4033. HCERTSTORE hCertStore = NULL;
  4034. PCCERT_CONTEXT pCertContext = NULL;
  4035. LPNMITEMACTIVATE lpnmItem;
  4036. LVITEM lvItem;
  4037. if ( wParam == IDC_LIST_ROOT_CA_NAME )
  4038. {
  4039. lpnmItem = (LPNMITEMACTIVATE) lParam;
  4040. if ( lpnmItem->hdr.code == NM_DBLCLK )
  4041. {
  4042. ZeroMemory(&lvItem, sizeof(lvItem) );
  4043. lvItem.mask = LVIF_PARAM;
  4044. lvItem.iItem = lpnmItem->iItem;
  4045. ListView_GetItem(lpnmItem->hdr.hwndFrom, &lvItem);
  4046. if ( NO_ERROR == GetSelCertContext( //pEaptlsConnDialog->pCertList,
  4047. (EAPTLS_CERT_NODE*)(lvItem.lParam) ,
  4048. -1,
  4049. &hCertStore,
  4050. L"ROOT",
  4051. &pCertContext
  4052. )
  4053. )
  4054. {
  4055. ShowCertDetails( hWnd, hCertStore, pCertContext );
  4056. CertFreeCertificateContext(pCertContext);
  4057. CertCloseStore( hCertStore, CERT_CLOSE_STORE_FORCE_FLAG );
  4058. return TRUE;
  4059. }
  4060. return TRUE;
  4061. }
  4062. }
  4063. return FALSE;
  4064. }
  4065. /*
  4066. Returns:
  4067. Notes:
  4068. Callback function used with the Config UI DialogBoxParam function. It
  4069. processes messages sent to the dialog box. See the DialogProc documentation
  4070. in MSDN.
  4071. */
  4072. INT_PTR CALLBACK
  4073. PeapConnDialogProc(
  4074. IN HWND hWnd,
  4075. IN UINT unMsg,
  4076. IN WPARAM wParam,
  4077. IN LPARAM lParam
  4078. )
  4079. {
  4080. PPEAP_CONN_DIALOG pPeapConnDialog;
  4081. switch (unMsg)
  4082. {
  4083. case WM_INITDIALOG:
  4084. return(PeapConnInitDialog(hWnd, lParam));
  4085. case WM_HELP:
  4086. case WM_CONTEXTMENU:
  4087. {
  4088. ContextHelp(g_adwHelp, hWnd, unMsg, wParam, lParam);
  4089. break;
  4090. }
  4091. case WM_NOTIFY:
  4092. {
  4093. pPeapConnDialog = (PPEAP_CONN_DIALOG)GetWindowLongPtr(hWnd, DWLP_USER);
  4094. return PeapConnNotify( pPeapConnDialog,
  4095. wParam,
  4096. lParam,
  4097. hWnd
  4098. );
  4099. }
  4100. case WM_COMMAND:
  4101. pPeapConnDialog = (PPEAP_CONN_DIALOG)GetWindowLongPtr(hWnd, DWLP_USER);
  4102. return(PeapConnCommand(pPeapConnDialog, HIWORD(wParam), LOWORD(wParam),
  4103. hWnd, (HWND)lParam));
  4104. }
  4105. return(FALSE);
  4106. }
  4107. VOID
  4108. PeapDisplayCertInfo (
  4109. IN PPEAP_SERVER_CONFIG_DIALOG pServerConfigDialog
  4110. )
  4111. {
  4112. RTASSERT(NULL != pServerConfigDialog);
  4113. // Erase old values first
  4114. SetWindowText(pServerConfigDialog->hWndEditFriendlyName, L"");
  4115. SetWindowText(pServerConfigDialog->hWndEditIssuer, L"");
  4116. SetWindowText(pServerConfigDialog->hWndEditExpiration, L"");
  4117. if (NULL != pServerConfigDialog->pSelCertList)
  4118. {
  4119. if (NULL != pServerConfigDialog->pSelCertList->pwszFriendlyName)
  4120. {
  4121. SetWindowText(pServerConfigDialog->hWndEditFriendlyName,
  4122. pServerConfigDialog->pSelCertList->pwszFriendlyName);
  4123. }
  4124. if (NULL != pServerConfigDialog->pSelCertList->pwszIssuer)
  4125. {
  4126. SetWindowText(pServerConfigDialog->hWndEditIssuer,
  4127. pServerConfigDialog->pSelCertList->pwszIssuer);
  4128. }
  4129. if (NULL != pServerConfigDialog->pSelCertList->pwszExpiration)
  4130. {
  4131. SetWindowText(pServerConfigDialog->hWndEditExpiration,
  4132. pServerConfigDialog->pSelCertList->pwszExpiration);
  4133. }
  4134. }
  4135. }
  4136. #if 0
  4137. BOOL
  4138. PeapServerInitDialog(
  4139. IN HWND hWnd,
  4140. IN LPARAM lParam
  4141. )
  4142. {
  4143. PPEAP_SERVER_CONFIG_DIALOG pPeapServerDialog;
  4144. PPEAP_EAP_INFO pEapInfo;
  4145. DWORD dwSelItem = 0;
  4146. SetWindowLongPtr( hWnd, DWLP_USER, lParam);
  4147. pPeapServerDialog = (PPEAP_SERVER_CONFIG_DIALOG)lParam;
  4148. pPeapServerDialog ->hWndComboServerName =
  4149. GetDlgItem(hWnd, IDC_COMBO_SERVER_NAME);
  4150. pPeapServerDialog ->hWndEditFriendlyName=
  4151. GetDlgItem(hWnd, IDC_EDIT_FRIENDLY_NAME);
  4152. pPeapServerDialog ->hWndEditIssuer=
  4153. GetDlgItem(hWnd, IDC_EDIT_ISSUER);
  4154. pPeapServerDialog ->hWndEditExpiration=
  4155. GetDlgItem(hWnd, IDC_EDIT_EXPIRATION);
  4156. pPeapServerDialog ->hWndComboPeapType=
  4157. GetDlgItem(hWnd, IDC_COMBO_PEAP_TYPE);
  4158. pPeapServerDialog ->hWndBtnConfigure=
  4159. GetDlgItem(hWnd, IDC_BUTTON_CONFIGURE);
  4160. pPeapServerDialog->hEndEnableFastReconnect =
  4161. GetDlgItem(hWnd, IDC_CHECK_ENABLE_FAST_RECONNECT );
  4162. InitComboBox(pPeapServerDialog ->hWndComboServerName,
  4163. pPeapServerDialog ->pCertList,
  4164. pPeapServerDialog ->pSelCertList
  4165. );
  4166. CheckDlgButton(hWnd, IDC_CHECK_ENABLE_FAST_RECONNECT,
  4167. ( pPeapServerDialog->pUserProp->dwFlags &
  4168. PEAP_USER_FLAG_FAST_ROAMING) ?
  4169. BST_CHECKED : BST_UNCHECKED);
  4170. PeapDisplayCertInfo(pPeapServerDialog);
  4171. //NOTE:
  4172. // For this version of PEAP the control is a combo box. But
  4173. // it will change to list box and we need to change the
  4174. // control to list and change the following code to
  4175. // add only the ones that are applicable
  4176. //
  4177. //Add all the PEAP eap type friendly names
  4178. //
  4179. pEapInfo = pPeapServerDialog->pEapInfo;
  4180. while ( pEapInfo )
  4181. {
  4182. INT_PTR nIndex = 0;
  4183. nIndex = SendMessage( pPeapServerDialog->hWndComboPeapType,
  4184. CB_ADDSTRING,
  4185. 0,
  4186. (LPARAM)pEapInfo->lpwszFriendlyName);
  4187. SendMessage ( pPeapServerDialog->hWndComboPeapType,
  4188. CB_SETITEMDATA,
  4189. (WPARAM)nIndex,
  4190. (LPARAM)pEapInfo
  4191. );
  4192. if ( pPeapServerDialog->pSelEapInfo )
  4193. {
  4194. if ( pPeapServerDialog->pSelEapInfo->dwTypeId == pEapInfo->dwTypeId )
  4195. {
  4196. dwSelItem = (DWORD)nIndex;
  4197. }
  4198. }
  4199. pEapInfo = pEapInfo->pNext;
  4200. }
  4201. SendMessage(pPeapServerDialog->hWndComboPeapType, CB_SETCURSEL, dwSelItem, 0);
  4202. //
  4203. // Set the state of configure button
  4204. //
  4205. if ( NULL == pPeapServerDialog->pSelEapInfo )
  4206. {
  4207. pPeapServerDialog->pSelEapInfo = (PPEAP_EAP_INFO)
  4208. SendMessage ( pPeapServerDialog->hWndComboPeapType,
  4209. CB_GETITEMDATA,
  4210. (WPARAM)dwSelItem,
  4211. (LPARAM)0
  4212. );
  4213. }
  4214. if ( !pPeapServerDialog->pSelEapInfo->lpwszConfigClsId )
  4215. {
  4216. EnableWindow ( pPeapServerDialog->hWndBtnConfigure, FALSE );
  4217. }
  4218. else
  4219. {
  4220. EnableWindow (pPeapServerDialog->hWndBtnConfigure, TRUE );
  4221. }
  4222. return(FALSE);
  4223. }
  4224. /*
  4225. Returns:
  4226. TRUE: We prrocessed this message.
  4227. FALSE: We did not prrocess this message.
  4228. Notes:
  4229. Response to the WM_COMMAND message (Config UI).
  4230. */
  4231. BOOL
  4232. PeapServerCommand(
  4233. IN PPEAP_SERVER_CONFIG_DIALOG pPeapServerDialog,
  4234. IN WORD wNotifyCode,
  4235. IN WORD wId,
  4236. IN HWND hWndDlg,
  4237. IN HWND hWndCtrl
  4238. )
  4239. {
  4240. switch(wId)
  4241. {
  4242. case IDC_COMBO_SERVER_NAME:
  4243. if (CBN_SELCHANGE != wNotifyCode)
  4244. {
  4245. return(FALSE); // We will not process this message
  4246. }
  4247. pPeapServerDialog->pSelCertList = (EAPTLS_CERT_NODE *)
  4248. SendMessage ( hWndCtrl,
  4249. CB_GETITEMDATA,
  4250. SendMessage(hWndCtrl,
  4251. CB_GETCURSEL,
  4252. 0,0L
  4253. ),
  4254. 0L
  4255. );
  4256. PeapDisplayCertInfo(pPeapServerDialog);
  4257. return(TRUE);
  4258. case IDC_COMBO_PEAP_TYPE:
  4259. if (CBN_SELCHANGE != wNotifyCode)
  4260. {
  4261. return(FALSE); // We will not process this message
  4262. }
  4263. //Fall Through...
  4264. case IDC_BUTTON_CONFIGURE:
  4265. {
  4266. INT nIndex = -1;
  4267. nIndex = (INT)SendMessage ( pPeapServerDialog->hWndComboPeapType,
  4268. CB_GETCURSEL,
  4269. 0,0
  4270. );
  4271. if ( nIndex != -1 )
  4272. {
  4273. //
  4274. // Change the currently selected EAP Type.
  4275. //
  4276. pPeapServerDialog->pSelEapInfo = (PPEAP_EAP_INFO)
  4277. SendMessage ( pPeapServerDialog->hWndComboPeapType,
  4278. CB_GETITEMDATA,
  4279. (WPARAM)nIndex,
  4280. (LPARAM)0
  4281. );
  4282. if ( pPeapServerDialog->pSelEapInfo->lpwszConfigClsId )
  4283. {
  4284. EnableWindow(pPeapServerDialog->hWndBtnConfigure, TRUE );
  4285. if ( wId == IDC_BUTTON_CONFIGURE )
  4286. {
  4287. //
  4288. // Invoke the configure method for selected eap type and if no error is
  4289. // returned, then set the new configuration
  4290. //
  4291. PeapEapInfoInvokeServerConfigUI ( hWndDlg,
  4292. pPeapServerDialog->pwszMachineName,
  4293. pPeapServerDialog->pSelEapInfo
  4294. );
  4295. }
  4296. }
  4297. else
  4298. {
  4299. //
  4300. // There is no configuration option here.
  4301. //
  4302. EnableWindow(pPeapServerDialog->hWndBtnConfigure, FALSE );
  4303. }
  4304. }
  4305. else
  4306. {
  4307. EnableWindow(pPeapServerDialog->hWndBtnConfigure, FALSE );
  4308. pPeapServerDialog->pSelEapInfo = NULL;
  4309. }
  4310. return TRUE;
  4311. }
  4312. case IDOK:
  4313. {
  4314. // Setup new PPEAP_USER_PROP here.
  4315. //
  4316. EAPTLS_HASH * pHash = NULL;
  4317. DWORD dwNumHash = 0;
  4318. DWORD dwSelCount = 0;
  4319. DWORD dwPeapConnBlobSize = 0;
  4320. PPEAP_USER_PROP pUserProp = NULL;
  4321. if ( NULL == pPeapServerDialog->pSelCertList )
  4322. {
  4323. DisplayResourceError ( hWndDlg, IDS_PEAP_NO_SERVER_CERT );
  4324. return TRUE;
  4325. }
  4326. if ( !pPeapServerDialog->pSelCertList->pwszDisplayName )
  4327. {
  4328. DisplayResourceError ( hWndDlg, IDS_PEAP_NO_SERVER_CERT );
  4329. return TRUE;
  4330. }
  4331. if ( !wcslen(pPeapServerDialog->pSelCertList->pwszDisplayName) )
  4332. {
  4333. DisplayResourceError ( hWndDlg, IDS_PEAP_NO_SERVER_CERT );
  4334. return TRUE;
  4335. }
  4336. if ( NULL == pPeapServerDialog->pSelEapInfo )
  4337. {
  4338. DisplayResourceError ( hWndDlg, IDS_PEAP_NO_EAP_TYPE );
  4339. return TRUE;
  4340. }
  4341. pUserProp = (PPEAP_USER_PROP)LocalAlloc(LPTR, sizeof(PEAP_USER_PROP));
  4342. if ( NULL == pUserProp )
  4343. {
  4344. EapTlsTrace("LocalAlloc in Command failed and returned %d",
  4345. GetLastError());
  4346. }
  4347. else
  4348. {
  4349. pUserProp->dwVersion = 1;
  4350. pUserProp->dwSize = sizeof(PEAP_USER_PROP);
  4351. CopyMemory( &pUserProp->CertHash,
  4352. &(pPeapServerDialog->pSelCertList->Hash),
  4353. sizeof(pUserProp->CertHash)
  4354. );
  4355. //
  4356. // If Fast Roaming is enabled, then set it in our user prop struct.
  4357. //
  4358. if (BST_CHECKED == IsDlgButtonChecked(hWndDlg, IDC_CHECK_ENABLE_FAST_RECONNECT))
  4359. {
  4360. pUserProp->dwFlags |= PEAP_USER_FLAG_FAST_ROAMING;
  4361. }
  4362. else
  4363. {
  4364. pUserProp->dwFlags &= ~PEAP_USER_FLAG_FAST_ROAMING;
  4365. }
  4366. pUserProp->UserProperties.dwVersion = 1;
  4367. pUserProp->UserProperties.dwSize = sizeof(PEAP_ENTRY_USER_PROPERTIES );
  4368. pUserProp->UserProperties.dwEapTypeId = pPeapServerDialog->pSelEapInfo->dwTypeId;
  4369. pPeapServerDialog->pNewUserProp = pUserProp;
  4370. }
  4371. }
  4372. // Fall through
  4373. case IDCANCEL:
  4374. EndDialog(hWndDlg, wId);
  4375. return(TRUE);
  4376. default:
  4377. return(FALSE);
  4378. }
  4379. }
  4380. INT_PTR CALLBACK
  4381. PeapServerDialogProc(
  4382. IN HWND hWnd,
  4383. IN UINT unMsg,
  4384. IN WPARAM wParam,
  4385. IN LPARAM lParam
  4386. )
  4387. {
  4388. PPEAP_SERVER_CONFIG_DIALOG pPeapServerDialog;
  4389. switch (unMsg)
  4390. {
  4391. case WM_INITDIALOG:
  4392. return(PeapServerInitDialog(hWnd, lParam));
  4393. case WM_HELP:
  4394. case WM_CONTEXTMENU:
  4395. {
  4396. ContextHelp(g_adwHelp, hWnd, unMsg, wParam, lParam);
  4397. break;
  4398. }
  4399. case WM_COMMAND:
  4400. pPeapServerDialog = (PPEAP_SERVER_CONFIG_DIALOG)GetWindowLongPtr(hWnd, DWLP_USER);
  4401. return(PeapServerCommand(pPeapServerDialog, HIWORD(wParam), LOWORD(wParam),
  4402. hWnd, (HWND)lParam));
  4403. }
  4404. return(FALSE);
  4405. }
  4406. #endif
  4407. /////
  4408. //// Default credentials UI
  4409. ////
  4410. BOOL
  4411. DefaultCredInitDialog(
  4412. IN HWND hWnd,
  4413. IN LPARAM lParam
  4414. )
  4415. {
  4416. PPEAP_DEFAULT_CRED_DIALOG pDefaultCredDialog;
  4417. SetWindowLongPtr( hWnd, DWLP_USER, lParam);
  4418. pDefaultCredDialog = (PPEAP_DEFAULT_CRED_DIALOG)lParam;
  4419. pDefaultCredDialog->hWndUserName=
  4420. GetDlgItem(hWnd, IDC_EDIT_USERNAME);
  4421. pDefaultCredDialog->hWndPassword=
  4422. GetDlgItem(hWnd, IDC_EDIT_PASSWORD);
  4423. pDefaultCredDialog->hWndDomain=
  4424. GetDlgItem(hWnd, IDC_EDIT_DOMAIN);
  4425. SendMessage(pDefaultCredDialog->hWndUserName,
  4426. EM_LIMITTEXT,
  4427. UNLEN,
  4428. 0L
  4429. );
  4430. SendMessage(pDefaultCredDialog->hWndPassword,
  4431. EM_LIMITTEXT,
  4432. PWLEN,
  4433. 0L
  4434. );
  4435. SendMessage(pDefaultCredDialog->hWndDomain,
  4436. EM_LIMITTEXT,
  4437. DNLEN,
  4438. 0L
  4439. );
  4440. if ( pDefaultCredDialog->PeapDefaultCredentials.wszUserName[0] )
  4441. {
  4442. SetWindowText( pDefaultCredDialog->hWndUserName,
  4443. pDefaultCredDialog->PeapDefaultCredentials.wszUserName
  4444. );
  4445. }
  4446. if ( pDefaultCredDialog->PeapDefaultCredentials.wszPassword[0] )
  4447. {
  4448. SetWindowText( pDefaultCredDialog->hWndPassword,
  4449. pDefaultCredDialog->PeapDefaultCredentials.wszPassword
  4450. );
  4451. }
  4452. if ( pDefaultCredDialog->PeapDefaultCredentials.wszDomain[0] )
  4453. {
  4454. SetWindowText( pDefaultCredDialog->hWndDomain,
  4455. pDefaultCredDialog->PeapDefaultCredentials.wszDomain
  4456. );
  4457. }
  4458. return(FALSE);
  4459. }
  4460. /*
  4461. Returns:
  4462. TRUE: We prrocessed this message.
  4463. FALSE: We did not prrocess this message.
  4464. Notes:
  4465. Response to the WM_COMMAND message (Config UI).
  4466. */
  4467. BOOL
  4468. DefaultCredCommand(
  4469. IN PPEAP_DEFAULT_CRED_DIALOG pDefaultCredDialog,
  4470. IN WORD wNotifyCode,
  4471. IN WORD wId,
  4472. IN HWND hWndDlg,
  4473. IN HWND hWndCtrl
  4474. )
  4475. {
  4476. switch(wId)
  4477. {
  4478. case IDOK:
  4479. //
  4480. //grab info from the fields and set it in
  4481. //the logon dialog structure
  4482. //
  4483. GetWindowText( pDefaultCredDialog->hWndUserName,
  4484. pDefaultCredDialog->PeapDefaultCredentials.wszUserName,
  4485. UNLEN+1
  4486. );
  4487. GetWindowText( pDefaultCredDialog->hWndPassword,
  4488. pDefaultCredDialog->PeapDefaultCredentials.wszPassword,
  4489. PWLEN+1
  4490. );
  4491. GetWindowText ( pDefaultCredDialog->hWndDomain,
  4492. pDefaultCredDialog->PeapDefaultCredentials.wszDomain,
  4493. DNLEN+1
  4494. );
  4495. // Fall through
  4496. case IDCANCEL:
  4497. EndDialog(hWndDlg, wId);
  4498. return(TRUE);
  4499. default:
  4500. return(FALSE);
  4501. }
  4502. }
  4503. INT_PTR CALLBACK
  4504. DefaultCredDialogProc(
  4505. IN HWND hWnd,
  4506. IN UINT unMsg,
  4507. IN WPARAM wParam,
  4508. IN LPARAM lParam
  4509. )
  4510. {
  4511. PPEAP_DEFAULT_CRED_DIALOG pDefaultCredDialog;
  4512. switch (unMsg)
  4513. {
  4514. case WM_INITDIALOG:
  4515. return(DefaultCredInitDialog(hWnd, lParam));
  4516. case WM_HELP:
  4517. case WM_CONTEXTMENU:
  4518. {
  4519. ContextHelp(g_adwHelp, hWnd, unMsg, wParam, lParam);
  4520. break;
  4521. }
  4522. case WM_COMMAND:
  4523. pDefaultCredDialog = (PPEAP_DEFAULT_CRED_DIALOG)GetWindowLongPtr(hWnd, DWLP_USER);
  4524. return(DefaultCredCommand(pDefaultCredDialog, HIWORD(wParam), LOWORD(wParam),
  4525. hWnd, (HWND)lParam));
  4526. }
  4527. return(FALSE);
  4528. }