Leaked source code of windows server 2003
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.

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