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

1245 lines
32 KiB

  1. // Copyright (c) 1997, Microsoft Corporation, all rights reserved
  2. //
  3. // security.c
  4. // Remote Access Common Dialog APIs
  5. // Security dialogs
  6. //
  7. // 11/06/97 Steve Cobb
  8. //
  9. #include "rasdlgp.h"
  10. #include <rasauth.h>
  11. #include <rrascfg.h>
  12. const IID IID_IEAPProviderConfig = {0x66A2DB19,
  13. 0xD706,
  14. 0x11D0,
  15. {0xA3,0x7B,0x00,0xC0,0x4F,0xC9,0xDA,0x04}};
  16. //----------------------------------------------------------------------------
  17. // Help maps
  18. //----------------------------------------------------------------------------
  19. static DWORD g_adwCaHelp[] =
  20. {
  21. CID_CA_ST_Encryption, HID_CA_LB_Encryption,
  22. CID_CA_LB_Encryption, HID_CA_LB_Encryption,
  23. CID_CA_GB_LogonSecurity, HID_CA_GB_LogonSecurity,
  24. CID_CA_RB_Eap, HID_CA_RB_Eap,
  25. CID_CA_LB_EapPackages, HID_CA_LB_EapPackages,
  26. CID_CA_PB_Properties, HID_CA_PB_Properties,
  27. CID_CA_RB_AllowedProtocols, HID_CA_RB_AllowedProtocols,
  28. CID_CA_CB_Pap, HID_CA_CB_Pap,
  29. CID_CA_CB_Spap, HID_CA_CB_Spap,
  30. CID_CA_CB_Chap, HID_CA_CB_Chap,
  31. CID_CA_CB_MsChap, HID_CA_CB_MsChap,
  32. CID_CA_CB_W95MsChap, HID_CA_CB_W95MsChap,
  33. CID_CA_CB_MsChap2, HID_CA_CB_MsChap2,
  34. CID_CA_CB_UseWindowsPw, HID_CA_CB_UseWindowsPw,
  35. 0, 0
  36. };
  37. //----------------------------------------------------------------------------
  38. // Local datatypes
  39. //----------------------------------------------------------------------------
  40. // Custom authentication dialog argument block.
  41. //
  42. typedef struct
  43. _CAARGS
  44. {
  45. PBENTRY* pEntry;
  46. BOOL fStrongEncryption;
  47. // Set if we have been called via RouterEntryDlg.
  48. //
  49. BOOL fRouter;
  50. // Set if pszRouter is an NT4 steelhead machine. Valid only
  51. // if fRouter is true.
  52. //
  53. BOOL fNt4Router;
  54. // The name of the server in "\\server" form or NULL if none (or if
  55. // 'fRouter' is not set).
  56. //
  57. TCHAR* pszRouter;
  58. }
  59. CAARGS;
  60. // Custom authentication dialog context block.
  61. //
  62. typedef struct
  63. _CAINFO
  64. {
  65. // Caller's arguments to the dialog.
  66. //
  67. CAARGS* pArgs;
  68. // Handle of this dialog and some of it's controls.
  69. //
  70. HWND hwndDlg;
  71. HWND hwndLbEncryption;
  72. HWND hwndRbEap;
  73. HWND hwndLbEapPackages;
  74. HWND hwndPbProperties;
  75. HWND hwndRbAllowedProtocols;
  76. HWND hwndCbPap;
  77. HWND hwndCbSpap;
  78. HWND hwndCbChap;
  79. HWND hwndCbMsChap;
  80. HWND hwndCbW95MsChap;
  81. HWND hwndCbMsChap2;
  82. HWND hwndCbUseWindowsPw;
  83. // List of EAPCFGs read from the registry, with the originally selected
  84. // node for use in consistency tests later.
  85. //
  86. DTLLIST* pListEapcfgs;
  87. DTLNODE* pOriginalEapcfgNode;
  88. // "Restore" states for controls that may be disabled with
  89. // EnableCbWithRestore or EnableLbWithRestore routines.
  90. //
  91. DWORD iLbEapPackages;
  92. BOOL fPap;
  93. BOOL fSpap;
  94. BOOL fChap;
  95. BOOL fMsChap;
  96. BOOL fW95MsChap;
  97. BOOL fMsChap2;
  98. BOOL fUseWindowsPw;
  99. }
  100. CAINFO;
  101. //-----------------------------------------------------------------------------
  102. // Local prototypes (alphabetically)
  103. //-----------------------------------------------------------------------------
  104. VOID
  105. CaCbToggle(
  106. IN CAINFO* pInfo,
  107. IN HWND hwndCb );
  108. BOOL
  109. CaCommand(
  110. IN CAINFO* pInfo,
  111. IN WORD wNotification,
  112. IN WORD wId,
  113. IN HWND hwndCtrl );
  114. INT_PTR CALLBACK
  115. CaDlgProc(
  116. IN HWND hwnd,
  117. IN UINT unMsg,
  118. IN WPARAM wparam,
  119. IN LPARAM lparam );
  120. BOOL
  121. CaInit(
  122. IN HWND hwndDlg,
  123. IN CAARGS* pArgs );
  124. VOID
  125. CaLbEapPackagesSelChange(
  126. IN CAINFO* pInfo );
  127. VOID
  128. CaPropertiesLocal(
  129. IN CAINFO* pInfo );
  130. VOID
  131. CaPropertiesRemote(
  132. IN CAINFO* pInfo );
  133. VOID
  134. CaRbToggle(
  135. IN CAINFO* pInfo,
  136. IN BOOL fEapSelected );
  137. BOOL
  138. CaSave(
  139. IN CAINFO* pInfo );
  140. VOID
  141. CaTerm(
  142. IN HWND hwndDlg );
  143. //----------------------------------------------------------------------------
  144. // Advanced Security dialog routines
  145. // Listed alphabetically following entrypoint and dialog proc
  146. //----------------------------------------------------------------------------
  147. BOOL
  148. AdvancedSecurityDlg(
  149. IN HWND hwndOwner,
  150. IN OUT EINFO* pArgs )
  151. // Popup a dialog to select advanced security options for phonebook entry
  152. // represented by 'pArgs'. 'HwndOwner' is the owning window.
  153. //
  154. // Returns true if user pressed OK and succeeded or false on Cancel or
  155. // error. If successful, the new configuration is written to the
  156. // appropriate 'pArgs->pEntry' fields. The routine assumes that these same
  157. // 'pEntry' fields contain the desired defaults on entry.
  158. //
  159. {
  160. INT_PTR nStatus;
  161. CAARGS args;
  162. TRACE( "AdvSecurityDlg" );
  163. args.pEntry = pArgs->pEntry;
  164. args.fStrongEncryption = pArgs->fStrongEncryption;
  165. args.fRouter = pArgs->fRouter;
  166. args.fNt4Router = pArgs->fNt4Router;
  167. args.pszRouter = pArgs->pszRouter;
  168. nStatus =
  169. DialogBoxParam(
  170. g_hinstDll,
  171. MAKEINTRESOURCE( DID_CA_CustomAuth ),
  172. hwndOwner,
  173. CaDlgProc,
  174. (LPARAM )&args );
  175. if (nStatus == -1)
  176. {
  177. ErrorDlg( hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
  178. nStatus = FALSE;
  179. }
  180. return (nStatus) ? TRUE : FALSE;
  181. }
  182. INT_PTR CALLBACK
  183. CaDlgProc(
  184. IN HWND hwnd,
  185. IN UINT unMsg,
  186. IN WPARAM wparam,
  187. IN LPARAM lparam )
  188. // DialogProc callback for the Custom Authentication dialog. Parameters
  189. // and return value are as described for standard windows 'DialogProc's.
  190. //
  191. {
  192. #if 0
  193. TRACE4( "CaDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  194. (DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
  195. #endif
  196. switch (unMsg)
  197. {
  198. case WM_INITDIALOG:
  199. {
  200. return CaInit( hwnd, (CAARGS* )lparam );
  201. }
  202. case WM_HELP:
  203. case WM_CONTEXTMENU:
  204. {
  205. ContextHelp( g_adwCaHelp, hwnd, unMsg, wparam, lparam );
  206. break;
  207. }
  208. case WM_COMMAND:
  209. {
  210. CAINFO* pInfo = (CAINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  211. ASSERT( pInfo );
  212. return CaCommand(
  213. pInfo, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
  214. }
  215. case WM_DESTROY:
  216. {
  217. CaTerm( hwnd );
  218. break;
  219. }
  220. }
  221. return FALSE;
  222. }
  223. BOOL
  224. CaCommand(
  225. IN CAINFO* pInfo,
  226. IN WORD wNotification,
  227. IN WORD wId,
  228. IN HWND hwndCtrl )
  229. // Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
  230. // is the notification code of the command. 'wId' is the control/menu
  231. // identifier of the command. 'HwndCtrl' is the control window handle of
  232. // the command.
  233. //
  234. // Returns true if processed message, false otherwise.
  235. //
  236. {
  237. TRACE3( "CaCommand(n=%d,i=%d,c=$%x)",
  238. (DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
  239. switch (wId)
  240. {
  241. case CID_CA_RB_Eap:
  242. case CID_CA_RB_AllowedProtocols:
  243. {
  244. switch (wNotification)
  245. {
  246. case BN_CLICKED:
  247. {
  248. CaRbToggle( pInfo, (wId == CID_CA_RB_Eap) );
  249. return TRUE;
  250. }
  251. }
  252. break;
  253. }
  254. case CID_CA_LB_EapPackages:
  255. {
  256. CaLbEapPackagesSelChange( pInfo );
  257. return TRUE;
  258. }
  259. case CID_CA_PB_Properties:
  260. {
  261. if ( ( pInfo->pArgs->fRouter )
  262. && ( !pInfo->pArgs->fNt4Router )
  263. && ( pInfo->pArgs->pszRouter )
  264. && ( pInfo->pArgs->pszRouter[0] ) )
  265. {
  266. CaPropertiesRemote( pInfo );
  267. }
  268. else
  269. {
  270. CaPropertiesLocal( pInfo );
  271. }
  272. return TRUE;
  273. }
  274. case CID_CA_CB_Pap:
  275. case CID_CA_CB_Spap:
  276. case CID_CA_CB_Chap:
  277. case CID_CA_CB_MsChap:
  278. case CID_CA_CB_W95MsChap:
  279. case CID_CA_CB_MsChap2:
  280. {
  281. CaCbToggle( pInfo, hwndCtrl );
  282. return TRUE;
  283. }
  284. case IDOK:
  285. {
  286. if (CaSave( pInfo ))
  287. {
  288. EndDialog( pInfo->hwndDlg, TRUE );
  289. }
  290. return TRUE;
  291. }
  292. case IDCANCEL:
  293. {
  294. TRACE( "Cancel pressed" );
  295. EndDialog( pInfo->hwndDlg, FALSE );
  296. return TRUE;
  297. }
  298. }
  299. return FALSE;
  300. }
  301. VOID
  302. CaCbToggle(
  303. IN CAINFO* pInfo,
  304. IN HWND hwndCb )
  305. // Called when one of the 6 authentication protocol check boxes is toggled
  306. // and/or the toggle processing should be performed. 'HwndCb' is the
  307. // window handle of the toggled checkbox or NULL if none. 'PInfo' is the
  308. // dialog context.
  309. //
  310. {
  311. BOOL fMsChap;
  312. BOOL fW95MsChap;
  313. BOOL fMsChap2;
  314. fMsChap = Button_GetCheck( pInfo->hwndCbMsChap );
  315. EnableCbWithRestore(
  316. pInfo->hwndCbW95MsChap,
  317. fMsChap,
  318. FALSE,
  319. &pInfo->fW95MsChap );
  320. if (IsWindowEnabled( pInfo->hwndCbW95MsChap ))
  321. {
  322. fW95MsChap = Button_GetCheck( pInfo->hwndCbW95MsChap );
  323. }
  324. else
  325. {
  326. fW95MsChap = FALSE;
  327. }
  328. fMsChap2 = Button_GetCheck( pInfo->hwndCbMsChap2 );
  329. EnableCbWithRestore(
  330. pInfo->hwndCbUseWindowsPw,
  331. fMsChap || fW95MsChap || fMsChap2,
  332. FALSE,
  333. &pInfo->fUseWindowsPw );
  334. }
  335. BOOL
  336. CaInit(
  337. IN HWND hwndDlg,
  338. IN CAARGS* pArgs )
  339. // Called on WM_INITDIALOG. 'HwndDlg' is the handle of the phonebook
  340. // dialog window. 'PArgs' is caller's arguments as passed to the stub
  341. // API.
  342. //
  343. // Return false if focus was set, true otherwise, i.e. as defined for
  344. // WM_INITDIALOG.
  345. //
  346. {
  347. DWORD dwErr;
  348. DWORD dwAr;
  349. CAINFO* pInfo;
  350. PBENTRY* pEntry;
  351. TRACE( "CaInit" );
  352. // Allocate the dialog context block. Initialize minimally for proper
  353. // cleanup, then attach to the dialog window.
  354. //
  355. {
  356. pInfo = Malloc( sizeof(*pInfo) );
  357. if (!pInfo)
  358. {
  359. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
  360. EndDialog( hwndDlg, FALSE );
  361. return TRUE;
  362. }
  363. ZeroMemory( pInfo, sizeof(*pInfo) );
  364. pInfo->pArgs = pArgs;
  365. pInfo->hwndDlg = hwndDlg;
  366. SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pInfo );
  367. TRACE( "Context set" );
  368. }
  369. pEntry = pArgs->pEntry;
  370. pInfo->hwndLbEncryption = GetDlgItem( hwndDlg, CID_CA_LB_Encryption );
  371. ASSERT( pInfo->hwndLbEncryption );
  372. pInfo->hwndRbEap = GetDlgItem( hwndDlg, CID_CA_RB_Eap );
  373. ASSERT( pInfo->hwndRbEap );
  374. pInfo->hwndLbEapPackages = GetDlgItem( hwndDlg, CID_CA_LB_EapPackages );
  375. ASSERT( pInfo->hwndLbEapPackages );
  376. pInfo->hwndPbProperties = GetDlgItem( hwndDlg, CID_CA_PB_Properties );
  377. ASSERT( pInfo->hwndPbProperties );
  378. pInfo->hwndRbAllowedProtocols =
  379. GetDlgItem( hwndDlg, CID_CA_RB_AllowedProtocols );
  380. ASSERT( pInfo->hwndRbAllowedProtocols );
  381. pInfo->hwndCbPap = GetDlgItem( hwndDlg, CID_CA_CB_Pap );
  382. ASSERT( pInfo->hwndCbPap );
  383. pInfo->hwndCbSpap = GetDlgItem( hwndDlg, CID_CA_CB_Spap );
  384. ASSERT( pInfo->hwndCbSpap );
  385. pInfo->hwndCbChap = GetDlgItem( hwndDlg, CID_CA_CB_Chap );
  386. ASSERT( pInfo->hwndCbChap );
  387. pInfo->hwndCbMsChap = GetDlgItem( hwndDlg, CID_CA_CB_MsChap );
  388. ASSERT( pInfo->hwndCbMsChap );
  389. pInfo->hwndCbW95MsChap = GetDlgItem( hwndDlg, CID_CA_CB_W95MsChap );
  390. ASSERT( pInfo->hwndCbW95MsChap );
  391. pInfo->hwndCbMsChap2 = GetDlgItem( hwndDlg, CID_CA_CB_MsChap2 );
  392. ASSERT( pInfo->hwndCbMsChap2 );
  393. pInfo->hwndCbUseWindowsPw = GetDlgItem( hwndDlg, CID_CA_CB_UseWindowsPw );
  394. ASSERT( pInfo->hwndCbUseWindowsPw );
  395. // Initialize the encryption list.
  396. //
  397. {
  398. LBTABLEITEM* pItem;
  399. INT i;
  400. static LBTABLEITEM aItems[] =
  401. {
  402. SID_DE_None, DE_None,
  403. SID_DE_IfPossible, DE_IfPossible,
  404. SID_DE_Require, DE_Require,
  405. SID_DE_RequireMax, DE_RequireMax,
  406. 0, 0
  407. };
  408. static LBTABLEITEM aItemsExport[] =
  409. {
  410. SID_DE_None, DE_None,
  411. SID_DE_IfPossible, DE_IfPossible,
  412. SID_DE_Require, DE_Require,
  413. 0, 0
  414. };
  415. // Warn user if entry is configured for strong encryption and none is
  416. // available on the machine. (See bug 289692)
  417. //
  418. if (pEntry->dwDataEncryption == DE_RequireMax
  419. && !pArgs->fStrongEncryption)
  420. {
  421. MsgDlg( pInfo->hwndDlg, SID_NoStrongEncryption, NULL );
  422. pEntry->dwDataEncryption = DE_Require;
  423. }
  424. for (pItem = (pArgs->fStrongEncryption) ? aItems : aItemsExport, i = 0;
  425. pItem->sidItem;
  426. ++pItem, ++i)
  427. {
  428. ComboBox_AddItemFromId(
  429. g_hinstDll, pInfo->hwndLbEncryption,
  430. pItem->sidItem, (VOID* )UlongToPtr(pItem->dwData));
  431. if (pEntry->dwDataEncryption == pItem->dwData)
  432. {
  433. ComboBox_SetCurSel( pInfo->hwndLbEncryption, i );
  434. }
  435. }
  436. }
  437. // Initialize EAP package list.
  438. //
  439. {
  440. DTLNODE* pNode;
  441. TCHAR* pszEncEnabled;
  442. // Read the EAPCFG information from the registry and find the node
  443. // selected in the entry, or the default, if none.
  444. //
  445. if ( ( pInfo->pArgs->fRouter )
  446. && ( !pInfo->pArgs->fNt4Router )
  447. && ( pInfo->pArgs->pszRouter )
  448. && ( pInfo->pArgs->pszRouter[0] ) )
  449. {
  450. pInfo->pListEapcfgs = ReadEapcfgList( pInfo->pArgs->pszRouter );
  451. }
  452. else
  453. {
  454. pInfo->pListEapcfgs = ReadEapcfgList( NULL );
  455. }
  456. if (pInfo->pListEapcfgs)
  457. {
  458. DTLNODE* pNodeEap;
  459. DWORD cbData = 0;
  460. PBYTE pbData = NULL;
  461. DWORD dwkey = pEntry->dwCustomAuthKey;
  462. for (pNodeEap = DtlGetFirstNode(pInfo->pListEapcfgs);
  463. pNodeEap;
  464. pNodeEap = DtlGetNextNode(pNodeEap))
  465. {
  466. EAPCFG* pEapcfg = (EAPCFG* )DtlGetData(pNodeEap);
  467. ASSERT( pEapcfg );
  468. pEntry->dwCustomAuthKey = pEapcfg->dwKey;
  469. if(NO_ERROR == DwGetCustomAuthData(
  470. pEntry,
  471. &cbData,
  472. &pbData)
  473. && (cbData > 0)
  474. && (pbData))
  475. {
  476. VOID *pData = Malloc(cbData);
  477. if(pData)
  478. {
  479. CopyMemory(pData,
  480. pbData,
  481. cbData);
  482. Free0(pEapcfg->pData);
  483. pEapcfg->pData = pData;
  484. pEapcfg->cbData = cbData;
  485. }
  486. }
  487. }
  488. pEntry->dwCustomAuthKey = dwkey;
  489. if (pEntry->dwCustomAuthKey == (DWORD )-1)
  490. {
  491. pNode = DtlGetFirstNode( pInfo->pListEapcfgs );
  492. }
  493. else
  494. {
  495. pNode = EapcfgNodeFromKey(
  496. pInfo->pListEapcfgs, pEntry->dwCustomAuthKey );
  497. }
  498. pInfo->pOriginalEapcfgNode = pNode;
  499. }
  500. // Fill the EAP packages listbox and select the previously identified
  501. // selection. The Properties button is disabled by default, but may
  502. // be enabled when the EAP list selection is set.
  503. //
  504. EnableWindow( pInfo->hwndPbProperties, FALSE );
  505. pszEncEnabled = PszFromId( g_hinstDll, SID_EncEnabled );
  506. if (pszEncEnabled)
  507. {
  508. for (pNode = DtlGetFirstNode( pInfo->pListEapcfgs );
  509. pNode;
  510. pNode = DtlGetNextNode( pNode ))
  511. {
  512. DWORD cb;
  513. EAPCFG* pEapcfg;
  514. INT i;
  515. TCHAR* pszBuf;
  516. pEapcfg = (EAPCFG* )DtlGetData( pNode );
  517. ASSERT( pEapcfg );
  518. ASSERT( pEapcfg->pszFriendlyName );
  519. // Whistler bug 224074 use only lstrcpyn's to prevent
  520. // maliciousness
  521. //
  522. cb = lstrlen( pEapcfg->pszFriendlyName ) +
  523. lstrlen( pszEncEnabled ) + 1;
  524. pszBuf = Malloc( cb * sizeof(TCHAR) );
  525. if (!pszBuf)
  526. {
  527. continue;
  528. }
  529. // Whistler bug 224074 use only lstrcpyn's to prevent
  530. // maliciousness
  531. //
  532. lstrcpyn( pszBuf, pEapcfg->pszFriendlyName, cb );
  533. if (pEapcfg->fProvidesMppeKeys)
  534. {
  535. lstrcat( pszBuf, pszEncEnabled );
  536. }
  537. i = ComboBox_AddItem(
  538. pInfo->hwndLbEapPackages, pszBuf, pNode );
  539. if (pNode == pInfo->pOriginalEapcfgNode)
  540. {
  541. ComboBox_SetCurSelNotify( pInfo->hwndLbEapPackages, i );
  542. }
  543. Free( pszBuf );
  544. }
  545. Free0( pszEncEnabled );
  546. ComboBox_AutoSizeDroppedWidth( pInfo->hwndLbEapPackages );
  547. }
  548. }
  549. // Set initial check box settings. The values may be changed when the
  550. // radio button handling does it's enabling/disabling.
  551. //
  552. dwAr = pEntry->dwAuthRestrictions;
  553. Button_SetCheck( pInfo->hwndCbPap, !!(dwAr & AR_F_AuthPAP) );
  554. Button_SetCheck( pInfo->hwndCbSpap, !!(dwAr & AR_F_AuthSPAP) );
  555. Button_SetCheck( pInfo->hwndCbChap, !!(dwAr & AR_F_AuthMD5CHAP) );
  556. Button_SetCheck( pInfo->hwndCbMsChap, !!(dwAr & AR_F_AuthMSCHAP) );
  557. Button_SetCheck( pInfo->hwndCbW95MsChap, !!(dwAr & AR_F_AuthW95MSCHAP) );
  558. Button_SetCheck( pInfo->hwndCbMsChap2, !!(dwAr & AR_F_AuthMSCHAP2) );
  559. if (!pInfo->pArgs->fRouter)
  560. {
  561. pInfo->fUseWindowsPw = pEntry->fAutoLogon;
  562. Button_SetCheck( pInfo->hwndCbUseWindowsPw, pInfo->fUseWindowsPw );
  563. }
  564. else
  565. {
  566. pInfo->fUseWindowsPw = FALSE;
  567. Button_SetCheck( pInfo->hwndCbUseWindowsPw, FALSE );
  568. EnableWindow( pInfo->hwndCbUseWindowsPw, FALSE );
  569. ShowWindow( pInfo->hwndCbUseWindowsPw, FALSE );
  570. }
  571. // Set the appropriate radio button which triggers appropriate
  572. // enabling/disabling.
  573. //
  574. {
  575. HWND hwndRb;
  576. if (dwAr & AR_F_AuthEAP)
  577. {
  578. hwndRb = pInfo->hwndRbEap;
  579. }
  580. else
  581. {
  582. hwndRb = pInfo->hwndRbAllowedProtocols;
  583. }
  584. SendMessage( hwndRb, BM_CLICK, 0, 0 );
  585. }
  586. // Center dialog on the owner window.
  587. //
  588. CenterWindow( hwndDlg, GetParent( hwndDlg ) );
  589. // Add context help button to title bar.
  590. //
  591. AddContextHelpButton( hwndDlg );
  592. SetFocus( pInfo->hwndLbEncryption );
  593. return TRUE;
  594. }
  595. VOID
  596. CaLbEapPackagesSelChange(
  597. IN CAINFO* pInfo )
  598. // Called when the EAP list selection changes. 'PInfo' is the dialog
  599. // context.
  600. //
  601. {
  602. EAPCFG* pEapcfg;
  603. INT iSel;
  604. // Get the EAPCFG information for the selected EAP package.
  605. //
  606. pEapcfg = NULL;
  607. iSel = ComboBox_GetCurSel( pInfo->hwndLbEapPackages );
  608. if (iSel >= 0)
  609. {
  610. DTLNODE* pNode;
  611. pNode =
  612. (DTLNODE* )ComboBox_GetItemDataPtr(
  613. pInfo->hwndLbEapPackages, iSel );
  614. if (pNode)
  615. {
  616. pEapcfg = (EAPCFG* )DtlGetData( pNode );
  617. }
  618. }
  619. // Enable the Properties button if the selected package has a
  620. // configuration entrypoint.
  621. //
  622. EnableWindow(
  623. pInfo->hwndPbProperties, (pEapcfg && !!(pEapcfg->pszConfigDll)) );
  624. }
  625. VOID
  626. CaPropertiesLocal(
  627. IN CAINFO* pInfo )
  628. // Called when the EAP properties button is pressed. Call the
  629. // configuration DLL to popup the properties of the package. 'PInfo' is
  630. // the dialog context.
  631. //
  632. {
  633. DWORD dwErr;
  634. DTLNODE* pNode;
  635. EAPCFG* pEapcfg;
  636. RASEAPINVOKECONFIGUI pInvokeConfigUi;
  637. RASEAPFREE pFreeConfigUIData;
  638. HINSTANCE h;
  639. BYTE* pConnectionData;
  640. DWORD cbConnectionData;
  641. // Look up the selected package configuration and load the associated
  642. // configuration DLL.
  643. //
  644. pNode = (DTLNODE* )ComboBox_GetItemDataPtr(
  645. pInfo->hwndLbEapPackages,
  646. ComboBox_GetCurSel( pInfo->hwndLbEapPackages ) );
  647. ASSERT( pNode );
  648. if(NULL == pNode)
  649. {
  650. return;
  651. }
  652. pEapcfg = (EAPCFG* )DtlGetData( pNode );
  653. ASSERT( pEapcfg );
  654. h = NULL;
  655. if (!(h = LoadLibrary( pEapcfg->pszConfigDll ))
  656. || !(pInvokeConfigUi =
  657. (RASEAPINVOKECONFIGUI )GetProcAddress(
  658. h, "RasEapInvokeConfigUI" ))
  659. || !(pFreeConfigUIData =
  660. (RASEAPFREE) GetProcAddress(
  661. h, "RasEapFreeMemory" )))
  662. {
  663. MsgDlg( pInfo->hwndDlg, SID_CannotLoadConfigDll, NULL );
  664. if (h)
  665. {
  666. FreeLibrary( h );
  667. }
  668. return;
  669. }
  670. // Call the configuration DLL to popup it's custom configuration UI.
  671. //
  672. pConnectionData = NULL;
  673. cbConnectionData = 0;
  674. dwErr = pInvokeConfigUi(
  675. pEapcfg->dwKey, pInfo->hwndDlg,
  676. pInfo->pArgs->fRouter ? RAS_EAP_FLAG_ROUTER : 0,
  677. pEapcfg->pData,
  678. pEapcfg->cbData,
  679. &pConnectionData, &cbConnectionData
  680. );
  681. if (dwErr != 0)
  682. {
  683. if (dwErr != ERROR_CANCELLED)
  684. MsgDlg( pInfo->hwndDlg, SID_ConfigDllApiFailed, NULL );
  685. FreeLibrary( h );
  686. return;
  687. }
  688. // Store the configuration information returned in the package descriptor.
  689. //
  690. Free( pEapcfg->pData );
  691. pEapcfg->pData = NULL;
  692. pEapcfg->cbData = 0;
  693. if (pConnectionData)
  694. {
  695. if (cbConnectionData > 0)
  696. {
  697. // Copy it into the eap node
  698. pEapcfg->pData = Malloc( cbConnectionData );
  699. if (pEapcfg->pData)
  700. {
  701. CopyMemory( pEapcfg->pData, pConnectionData, cbConnectionData );
  702. pEapcfg->cbData = cbConnectionData;
  703. }
  704. }
  705. }
  706. pFreeConfigUIData( pConnectionData );
  707. // Note any "force user to configure" requirement on the package has been
  708. // satisfied.
  709. //
  710. pEapcfg->fConfigDllCalled = TRUE;
  711. FreeLibrary( h );
  712. }
  713. VOID
  714. CaPropertiesRemote(
  715. IN CAINFO* pInfo )
  716. // Called when the EAP properties button is pressed. Call the
  717. // configuration DLL to popup the properties of the package. 'PInfo' is
  718. // the dialog context.
  719. //
  720. {
  721. DWORD dwErr;
  722. HRESULT hr;
  723. DTLNODE* pNode;
  724. EAPCFG* pEapcfg;
  725. BOOL fComInitialized = FALSE;
  726. BYTE* pConnectionData = NULL;
  727. DWORD cbConnectionData = 0;
  728. IEAPProviderConfig* pEapProv = NULL;
  729. ULONG_PTR uConnectionParam;
  730. BOOL fInitialized = FALSE;
  731. pNode = (DTLNODE* )ComboBox_GetItemDataPtr(
  732. pInfo->hwndLbEapPackages,
  733. ComboBox_GetCurSel( pInfo->hwndLbEapPackages ) );
  734. ASSERT( pNode );
  735. if(NULL == pNode)
  736. {
  737. goto LDone;
  738. }
  739. pEapcfg = (EAPCFG* )DtlGetData( pNode );
  740. ASSERT( pEapcfg );
  741. hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
  742. if ( RPC_E_CHANGED_MODE == hr )
  743. {
  744. hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
  745. }
  746. if ( ( S_OK != hr )
  747. && ( S_FALSE != hr ) )
  748. {
  749. goto LDone;
  750. }
  751. fComInitialized = TRUE;
  752. hr = CoCreateInstance(
  753. &(pEapcfg->guidConfigCLSID),
  754. NULL,
  755. CLSCTX_SERVER,
  756. &IID_IEAPProviderConfig,
  757. (PVOID*)&pEapProv
  758. );
  759. if ( FAILED( hr ) )
  760. {
  761. pEapProv = NULL;
  762. goto LDone;
  763. }
  764. // Call the configuration DLL to popup it's custom configuration UI.
  765. //
  766. hr = IEAPProviderConfig_Initialize(
  767. pEapProv,
  768. pInfo->pArgs->pszRouter,
  769. pEapcfg->dwKey,
  770. &uConnectionParam );
  771. if ( FAILED( hr ) )
  772. {
  773. goto LDone;
  774. }
  775. fInitialized = TRUE;
  776. hr = IEAPProviderConfig_RouterInvokeConfigUI(
  777. pEapProv,
  778. pEapcfg->dwKey,
  779. uConnectionParam,
  780. pInfo->hwndDlg,
  781. RAS_EAP_FLAG_ROUTER,
  782. pEapcfg->pData,
  783. pEapcfg->cbData,
  784. &pConnectionData,
  785. &cbConnectionData );
  786. if ( FAILED( hr ) )
  787. {
  788. // if (dwErr != ERROR_CANCELLED)
  789. // MsgDlg( pInfo->hwndDlg, SID_ConfigDllApiFailed, NULL );
  790. goto LDone;
  791. }
  792. // Store the configuration information returned in the package descriptor.
  793. //
  794. Free( pEapcfg->pData );
  795. pEapcfg->pData = NULL;
  796. pEapcfg->cbData = 0;
  797. if (pConnectionData)
  798. {
  799. if (cbConnectionData > 0)
  800. {
  801. // Copy it into the eap node
  802. pEapcfg->pData = Malloc( cbConnectionData );
  803. if (pEapcfg->pData)
  804. {
  805. CopyMemory( pEapcfg->pData, pConnectionData, cbConnectionData );
  806. pEapcfg->cbData = cbConnectionData;
  807. }
  808. }
  809. }
  810. // Note any "force user to configure" requirement on the package has been
  811. // satisfied.
  812. //
  813. pEapcfg->fConfigDllCalled = TRUE;
  814. LDone:
  815. if ( NULL != pConnectionData )
  816. {
  817. CoTaskMemFree( pConnectionData );
  818. }
  819. if ( fInitialized )
  820. {
  821. IEAPProviderConfig_Uninitialize(
  822. pEapProv,
  823. pEapcfg->dwKey,
  824. uConnectionParam );
  825. }
  826. if ( NULL != pEapProv )
  827. {
  828. IEAPProviderConfig_Release(pEapProv);
  829. }
  830. if ( fComInitialized )
  831. {
  832. CoUninitialize();
  833. }
  834. }
  835. VOID
  836. CaRbToggle(
  837. IN CAINFO* pInfo,
  838. IN BOOL fEapSelected )
  839. // Called when the radio button setting is toggled. 'FEapSelected' is set
  840. // if the EAP option was selected, clear if the "Allowed protocols" option
  841. // was selected. 'PInfo' is the dialog context.
  842. //
  843. {
  844. EnableLbWithRestore(
  845. pInfo->hwndLbEapPackages, fEapSelected, &pInfo->iLbEapPackages );
  846. EnableCbWithRestore(
  847. pInfo->hwndCbPap, !fEapSelected, FALSE, &pInfo->fPap );
  848. EnableCbWithRestore(
  849. pInfo->hwndCbSpap, !fEapSelected, FALSE, &pInfo->fSpap );
  850. EnableCbWithRestore(
  851. pInfo->hwndCbChap, !fEapSelected, FALSE, &pInfo->fChap );
  852. EnableCbWithRestore(
  853. pInfo->hwndCbMsChap, !fEapSelected, FALSE, &pInfo->fMsChap );
  854. EnableCbWithRestore(
  855. pInfo->hwndCbW95MsChap, !fEapSelected, FALSE, &pInfo->fW95MsChap );
  856. EnableCbWithRestore(
  857. pInfo->hwndCbMsChap2, !fEapSelected, FALSE, &pInfo->fMsChap2 );
  858. if (fEapSelected)
  859. {
  860. EnableCbWithRestore(
  861. pInfo->hwndCbUseWindowsPw, FALSE, FALSE, &pInfo->fUseWindowsPw );
  862. }
  863. else
  864. {
  865. CaCbToggle( pInfo, NULL );
  866. }
  867. }
  868. BOOL
  869. CaSave(
  870. IN CAINFO* pInfo )
  871. // Saves control contents to caller's PBENTRY argument. 'PInfo' is the
  872. // dialog context.
  873. //
  874. // Returns TRUE if successful or false if invalid combination of
  875. // selections was detected and reported.
  876. //
  877. {
  878. DWORD dwDe;
  879. PBENTRY* pEntry;
  880. DTLNODE* pNodeEap;
  881. DWORD dwEapKey;
  882. pEntry = pInfo->pArgs->pEntry;
  883. dwDe =
  884. (DWORD )ComboBox_GetItemData(
  885. pInfo->hwndLbEncryption,
  886. ComboBox_GetCurSel( pInfo->hwndLbEncryption ) );
  887. if (Button_GetCheck( pInfo->hwndRbEap ))
  888. {
  889. DTLNODE* pNode;
  890. EAPCFG* pEapcfg;
  891. pNode = (DTLNODE* )ComboBox_GetItemDataPtr(
  892. pInfo->hwndLbEapPackages,
  893. ComboBox_GetCurSel( pInfo->hwndLbEapPackages ) );
  894. ASSERT( pNode );
  895. if(NULL == pNode)
  896. {
  897. return FALSE;
  898. }
  899. pEapcfg = (EAPCFG* )DtlGetData( pNode );
  900. ASSERT( pEapcfg );
  901. // Tell user about required EAP configuration, if applicable.
  902. //
  903. if (pNode != pInfo->pOriginalEapcfgNode
  904. && pEapcfg->fForceConfig
  905. && !pEapcfg->fConfigDllCalled)
  906. {
  907. MsgDlg(
  908. pInfo->hwndDlg, SID_CustomAuthConfigRequired, NULL );
  909. ASSERT( IsWindowEnabled( pInfo->hwndPbProperties ) );
  910. SetFocus( pInfo->hwndPbProperties );
  911. return FALSE;
  912. }
  913. // Tell user EAP doesn't support encryption, if it doesn't and he
  914. // chose encryption. This check doesn't apply to L2TP which does not
  915. // use MPPE.
  916. //
  917. if (!(pEntry->dwType == RASET_Vpn
  918. && pEntry->dwVpnStrategy == VS_L2tpOnly)
  919. && (dwDe != DE_None && !pEapcfg->fProvidesMppeKeys))
  920. {
  921. MsgDlg( pInfo->hwndDlg, SID_NeedEapKeys, NULL );
  922. return FALSE;
  923. }
  924. // Save settings.
  925. //
  926. pEntry->dwDataEncryption = dwDe;
  927. pEntry->dwAuthRestrictions = AR_F_AuthCustom | AR_F_AuthEAP;
  928. pEntry->fAutoLogon = FALSE;
  929. dwEapKey = pEapcfg->dwKey;
  930. }
  931. else
  932. {
  933. DWORD dwAr;
  934. if (dwDe != DE_None
  935. && dwDe != DE_IfPossible
  936. && !(pEntry->dwType == RASET_Vpn
  937. && pEntry->dwVpnStrategy == VS_L2tpOnly)
  938. && !(Button_GetCheck( pInfo->hwndCbMsChap )
  939. || Button_GetCheck( pInfo->hwndCbW95MsChap )
  940. || Button_GetCheck( pInfo->hwndCbMsChap2 )))
  941. {
  942. MsgDlg( pInfo->hwndDlg, SID_MsChapRequired, NULL );
  943. return FALSE;
  944. }
  945. dwAr = AR_F_AuthCustom;
  946. if (Button_GetCheck( pInfo->hwndCbPap ))
  947. {
  948. dwAr |= AR_F_AuthPAP;
  949. }
  950. if (Button_GetCheck( pInfo->hwndCbSpap ))
  951. {
  952. dwAr |= AR_F_AuthSPAP;
  953. }
  954. if (Button_GetCheck( pInfo->hwndCbChap ))
  955. {
  956. dwAr |= AR_F_AuthMD5CHAP;
  957. }
  958. if (Button_GetCheck( pInfo->hwndCbMsChap ))
  959. {
  960. dwAr |= AR_F_AuthMSCHAP;
  961. }
  962. if (IsWindowEnabled( pInfo->hwndCbW95MsChap )
  963. && Button_GetCheck( pInfo->hwndCbW95MsChap ))
  964. {
  965. dwAr |= AR_F_AuthW95MSCHAP;
  966. }
  967. if (Button_GetCheck( pInfo->hwndCbMsChap2 ))
  968. {
  969. dwAr |= AR_F_AuthMSCHAP2;
  970. }
  971. if (dwDe != DE_None
  972. && !(pEntry->dwType == RASET_Vpn
  973. && pEntry->dwVpnStrategy == VS_L2tpOnly)
  974. && (dwAr & (AR_F_AuthPAP | AR_F_AuthSPAP | AR_F_AuthMD5CHAP)))
  975. {
  976. MSGARGS msgargs;
  977. ZeroMemory( &msgargs, sizeof(msgargs) );
  978. msgargs.dwFlags = MB_YESNO | MB_DEFBUTTON2 | MB_ICONINFORMATION;
  979. if (MsgDlg(
  980. pInfo->hwndDlg, SID_OptionalAuthQuery, &msgargs) == IDNO)
  981. {
  982. Button_SetCheck( pInfo->hwndCbPap, FALSE );
  983. Button_SetCheck( pInfo->hwndCbSpap, FALSE );
  984. Button_SetCheck( pInfo->hwndCbChap, FALSE );
  985. return FALSE;
  986. }
  987. }
  988. if (dwAr == AR_F_AuthCustom)
  989. {
  990. MsgDlg( pInfo->hwndDlg, SID_NoAuthChecked, NULL );
  991. return FALSE;
  992. }
  993. // Save settings.
  994. //
  995. pEntry->dwAuthRestrictions = dwAr;
  996. pEntry->dwDataEncryption = dwDe;
  997. if (IsWindowEnabled( pInfo->hwndCbUseWindowsPw ))
  998. {
  999. pEntry->fAutoLogon = Button_GetCheck( pInfo->hwndCbUseWindowsPw );
  1000. }
  1001. else
  1002. {
  1003. pEntry->fAutoLogon = FALSE;
  1004. }
  1005. dwEapKey = pEntry->dwCustomAuthKey;
  1006. }
  1007. for (pNodeEap = DtlGetFirstNode(pInfo->pListEapcfgs);
  1008. pNodeEap;
  1009. pNodeEap = DtlGetNextNode(pNodeEap))
  1010. {
  1011. EAPCFG* pcfg = (EAPCFG* )DtlGetData(pNodeEap);
  1012. ASSERT( pcfg );
  1013. pEntry->dwCustomAuthKey = pcfg->dwKey;
  1014. (VOID) DwSetCustomAuthData(
  1015. pEntry,
  1016. pcfg->cbData,
  1017. pcfg->pData);
  1018. Free0(pcfg->pData);
  1019. pcfg->pData = NULL;
  1020. }
  1021. pEntry->dwCustomAuthKey = dwEapKey;
  1022. return TRUE;
  1023. }
  1024. VOID
  1025. CaTerm(
  1026. IN HWND hwndDlg )
  1027. // Dialog termination. Releases the context block. 'HwndDlg' is the
  1028. // handle of a dialog.
  1029. //
  1030. {
  1031. CAINFO* pInfo;
  1032. TRACE( "CaTerm" );
  1033. pInfo = (CAINFO* )GetWindowLongPtr( hwndDlg, DWLP_USER );
  1034. if (pInfo)
  1035. {
  1036. if (pInfo->pListEapcfgs)
  1037. {
  1038. DtlDestroyList( pInfo->pListEapcfgs, DestroyEapcfgNode );
  1039. }
  1040. Free( pInfo );
  1041. TRACE( "Context freed" );
  1042. }
  1043. }