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.

595 lines
16 KiB

  1. // Copyright (c) 2000, Microsoft Corporation, all rights reserved
  2. //
  3. // IPSecPolicy.c
  4. // Remote Access Common Dialog APIs
  5. // IPSecPolicy dialogs
  6. //
  7. // 10/04/2000 Gang Zhao
  8. //
  9. #include "rasdlgp.h"
  10. #include <rasauth.h>
  11. #include <rrascfg.h>
  12. #include <ras.h>
  13. #include <mprapi.h>
  14. #include <mprerror.h>
  15. //----------------------------------------------------------------------------
  16. // Help maps
  17. //----------------------------------------------------------------------------
  18. static DWORD g_adwCiHelp[] =
  19. {
  20. CID_CI_CB_PresharedKey, HID_CI_CB_PresharedKey,
  21. CID_CI_ST_Key, HID_CI_EB_PSK,
  22. CID_CI_EB_PSK, HID_CI_EB_PSK,
  23. 0, 0
  24. };
  25. //----------------------------------------------------------------------------
  26. // Local datatypes
  27. //----------------------------------------------------------------------------
  28. typedef struct
  29. _CIARGS
  30. {
  31. EINFO * pEinfo;
  32. }
  33. CIARGS;
  34. typedef struct
  35. _CIINFO
  36. {
  37. //Caller's arguments to the dialog
  38. //
  39. CIARGS * pArgs;
  40. //Handles of this dialog and some of its controls
  41. //for PSK
  42. HWND hwndDlg;
  43. HWND hwndCbPresharedKey;
  44. HWND hwndStKey;
  45. HWND hwndEbPSK;
  46. //for User certs
  47. //
  48. HWND hwndCbUserCerts;
  49. //for specific certs
  50. //
  51. HWND hwndCbSpecificCerts;
  52. HWND hwndPbSelect;
  53. HWND hwndLbCertsList;
  54. }
  55. CIINFO;
  56. //-----------------------------------------------------------------------------
  57. // Local prototypes (alphabetically)
  58. //-----------------------------------------------------------------------------
  59. BOOL
  60. CiCommand(
  61. IN CIINFO* pInfo,
  62. IN WORD wNotification,
  63. IN WORD wId,
  64. IN HWND hwndCtrl );
  65. INT_PTR CALLBACK
  66. CiDlgProc(
  67. IN HWND hwnd,
  68. IN UINT unMsg,
  69. IN WPARAM wparam,
  70. IN LPARAM lparam );
  71. BOOL
  72. CiInit(
  73. IN HWND hwndDlg,
  74. IN CIARGS* pArgs );
  75. VOID
  76. CiTerm(
  77. IN HWND hwndDlg );
  78. BOOL
  79. CiSave(
  80. IN CIINFO* pInfo );
  81. //
  82. // Add new features for whistler bug 193987
  83. // Pop Up a Dialog box for IPSec Policy
  84. // currently just Pre-shared key/L2TP, and will have Certificates/L2TP in the future
  85. //
  86. BOOL
  87. IPSecPolicyDlg(
  88. IN HWND hwndOwner,
  89. IN OUT EINFO* pArgs )
  90. {
  91. INT_PTR nStatus;
  92. CIARGS args;
  93. TRACE( "IPSecPolicyDlg" );
  94. args.pEinfo = pArgs;
  95. nStatus =
  96. DialogBoxParam(
  97. g_hinstDll,
  98. MAKEINTRESOURCE( DID_CI_CustomIPSec ),
  99. hwndOwner,
  100. CiDlgProc,
  101. (LPARAM )&args );
  102. if (nStatus == -1)
  103. {
  104. ErrorDlg( hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
  105. nStatus = FALSE;
  106. }
  107. return (nStatus) ? TRUE : FALSE;
  108. }//end of IPSecPolicyDlg()
  109. INT_PTR CALLBACK
  110. CiDlgProc(
  111. IN HWND hwnd,
  112. IN UINT unMsg,
  113. IN WPARAM wparam,
  114. IN LPARAM lparam )
  115. // DialogProc callback for the Custom IPSecPolicy dialog. Parameters
  116. // and return value are as described for standard windows 'DialogProc's.
  117. //
  118. {
  119. #if 0
  120. TRACE4( "CiDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
  121. (DWORD )hwnd, (DWORD )unMsg, (DWORD )wparam, (DWORD )lparam );
  122. #endif
  123. switch (unMsg)
  124. {
  125. case WM_INITDIALOG:
  126. {
  127. return CiInit( hwnd, (CIARGS* )lparam );
  128. }
  129. case WM_HELP:
  130. case WM_CONTEXTMENU:
  131. {
  132. ContextHelp( g_adwCiHelp, hwnd, unMsg, wparam, lparam );
  133. break;
  134. }
  135. case WM_COMMAND:
  136. {
  137. CIINFO* pInfo = (CIINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  138. ASSERT( pInfo );
  139. return CiCommand(
  140. pInfo, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
  141. }
  142. case WM_DESTROY:
  143. {
  144. CiTerm( hwnd );
  145. break;
  146. }
  147. }
  148. return FALSE;
  149. }//end of CiDlgProc()
  150. BOOL
  151. CiInit(
  152. IN HWND hwndDlg,
  153. IN CIARGS* pArgs )
  154. // Called on WM_INITDIALOG. 'HwndDlg' is the handle of the phonebook
  155. // dialog window. 'PArgs' is caller's arguments as passed to the stub
  156. // API.
  157. //
  158. // Return false if focus was set, true otherwise, i.e. as defined for
  159. // WM_INITDIALOG.
  160. //
  161. {
  162. DWORD dwErr;
  163. DWORD dwAr;
  164. CIINFO* pInfo;
  165. TRACE( "CiInit" );
  166. // Allocate the dialog context block. Initialize minimally for proper
  167. // cleanup, then attach to the dialog window.
  168. //
  169. {
  170. pInfo = Malloc( sizeof(*pInfo) );
  171. if (!pInfo)
  172. {
  173. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
  174. EndDialog( hwndDlg, FALSE );
  175. return TRUE;
  176. }
  177. ZeroMemory( pInfo, sizeof(*pInfo) );
  178. pInfo->pArgs = pArgs;
  179. pInfo->hwndDlg = hwndDlg;
  180. SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pInfo );
  181. TRACE( "Context set" );
  182. }
  183. pInfo->hwndCbPresharedKey = GetDlgItem( hwndDlg, CID_CI_CB_PresharedKey );
  184. ASSERT(pInfo->hwndCbPresharedKey);
  185. pInfo->hwndStKey = GetDlgItem( hwndDlg, CID_CI_ST_Key );
  186. ASSERT(pInfo->hwndStKey);
  187. pInfo->hwndEbPSK = GetDlgItem( hwndDlg, CID_CI_EB_PSK );
  188. ASSERT(pInfo->hwndEbPSK);
  189. pInfo->hwndCbUserCerts = GetDlgItem( hwndDlg, CID_CI_CB_UserCerts );
  190. ASSERT(pInfo->hwndCbUserCerts);
  191. pInfo->hwndCbSpecificCerts = GetDlgItem( hwndDlg, CID_CI_CB_SpecificCerts );
  192. ASSERT(pInfo->hwndCbSpecificCerts);
  193. pInfo->hwndPbSelect = GetDlgItem( hwndDlg, CID_CI_PB_Select );
  194. ASSERT(pInfo->hwndPbSelect);
  195. pInfo->hwndLbCertsList = GetDlgItem( hwndDlg, CID_CI_LB_CertsList );
  196. ASSERT(pInfo->hwndLbCertsList);
  197. //Hide the User certs and Specific certs until the whistler server
  198. ShowWindow( pInfo->hwndCbUserCerts, SW_HIDE );
  199. ShowWindow( pInfo->hwndCbSpecificCerts, SW_HIDE );
  200. ShowWindow( pInfo->hwndPbSelect, SW_HIDE );
  201. ShowWindow( pInfo->hwndLbCertsList, SW_HIDE );
  202. // Fill the EAP packages listbox and select the previously identified
  203. // selection. The Properties button is disabled by default, but may
  204. // be enabled when the EAP list selection is set.
  205. //
  206. {
  207. BOOL fEnabled;
  208. fEnabled = !!((pArgs->pEinfo->pEntry->dwIpSecFlags)& AR_F_IpSecPSK) ;
  209. Button_SetCheck( pInfo->hwndCbPresharedKey, fEnabled );
  210. EnableWindow( pInfo->hwndStKey, fEnabled );
  211. EnableWindow( pInfo->hwndEbPSK, fEnabled );
  212. Edit_LimitText( pInfo->hwndEbPSK, PWLEN ); //Limit the length of PSK
  213. }
  214. //
  215. //Fill the Preshared Key in "*"s or just leave it bland if none
  216. //is saved previously
  217. //
  218. //for Demand Dial, use MprAdmin.... router functions
  219. //
  220. if (pArgs->pEinfo->fRouter)
  221. {
  222. if( !(pArgs->pEinfo->fPSKCached) )
  223. {
  224. // Initialize the interface-information structure.
  225. //
  226. DWORD dwErr;
  227. HANDLE hServer = NULL;
  228. HANDLE hInterface = NULL;
  229. WCHAR* pwszInterface = NULL;
  230. WCHAR pszComputer[512];
  231. MPR_INTERFACE_0 mi0;
  232. MPR_CREDENTIALSEX_1 * pMc1 = NULL;
  233. dwErr = NO_ERROR;
  234. do {
  235. dwErr = g_pMprAdminServerConnect(pArgs->pEinfo->pszRouter, &hServer);
  236. if (dwErr != NO_ERROR)
  237. {
  238. TRACE("CiInit: MprAdminServerConnect failed!");
  239. break;
  240. }
  241. ZeroMemory( &mi0, sizeof(mi0) );
  242. mi0.dwIfType = ROUTER_IF_TYPE_FULL_ROUTER;
  243. mi0.fEnabled = TRUE;
  244. pwszInterface = StrDupWFromT( pArgs->pEinfo->pEntry->pszEntryName );
  245. if (!pwszInterface)
  246. {
  247. TRACE("CiInit:pwszInterface conversion failed!");
  248. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  249. break;
  250. }
  251. lstrcpynW(
  252. mi0.wszInterfaceName,
  253. pwszInterface,
  254. MAX_INTERFACE_NAME_LEN+1 );
  255. // Get the interface handle
  256. //
  257. ASSERT( g_pMprAdminInterfaceGetHandle );
  258. dwErr = g_pMprAdminInterfaceGetHandle(
  259. hServer,
  260. pwszInterface,
  261. &hInterface,
  262. FALSE);
  263. if (dwErr)
  264. {
  265. TRACE1( "CiInit: MprAdminInterfaceGetHandle error %d", dwErr);
  266. break;
  267. }
  268. //Get the IPSec Policy keys(PSK for Whislter)
  269. //
  270. ASSERT( g_pMprAdminInterfaceGetCredentialsEx );
  271. dwErr = g_pMprAdminInterfaceGetCredentialsEx(
  272. hServer,
  273. hInterface,
  274. 1,
  275. (LPBYTE *)&pMc1 );
  276. if(dwErr)
  277. {
  278. TRACE1(
  279. "CiInit: MprAdminInterfaceGetCredentialsEx error %d", dwErr);
  280. break;
  281. }
  282. if ( !pMc1 )
  283. {
  284. TRACE(
  285. "CiInit: MprAdminInterfaceGetCredentialsEx returns invalid credential pointer!");
  286. dwErr = ERROR_CAN_NOT_COMPLETE;
  287. break;
  288. }
  289. else
  290. {
  291. if ( lstrlenA( pMc1->lpbCredentialsInfo ) >0 )
  292. {
  293. SetWindowText( pInfo->hwndEbPSK,TEXT("****************") );
  294. // Whistler bug 254385 encode password when not being used
  295. // Whistler bug 275526 NetVBL BVT Break: Routing BVT broken
  296. //
  297. ZeroMemory(
  298. pMc1->lpbCredentialsInfo,
  299. lstrlenA(pMc1->lpbCredentialsInfo) + 1 );
  300. }
  301. else
  302. {
  303. SetWindowText( pInfo->hwndEbPSK,TEXT("") );
  304. }
  305. ASSERT( g_pMprAdminBufferFree );
  306. g_pMprAdminBufferFree( pMc1 );
  307. }
  308. }
  309. while (FALSE) ;
  310. // Cleanup
  311. {
  312. // If some operation failed, restore the router to the
  313. // state it was previously in.
  314. if ( dwErr != NO_ERROR )
  315. {
  316. SetWindowText( pInfo->hwndEbPSK, TEXT("") );
  317. }
  318. // Close all handles, free all strings.
  319. if ( pwszInterface )
  320. {
  321. Free0( pwszInterface );
  322. }
  323. if (hServer)
  324. {
  325. g_pMprAdminServerDisconnect( hServer );
  326. }
  327. }
  328. }
  329. else
  330. {
  331. SetWindowText( pInfo->hwndEbPSK,TEXT("****************") );// pArgs->pEinfo->szPSK ); //
  332. }
  333. }
  334. else //retrieve the credentials with Ras functions
  335. {
  336. // Look up cached PSK, from RASMAN or EINFO
  337. //
  338. if( !(pArgs->pEinfo->fPSKCached) )
  339. {
  340. DWORD dwErrRc;
  341. RASCREDENTIALS rc;
  342. ZeroMemory( &rc, sizeof(rc) );
  343. rc.dwSize = sizeof(rc);
  344. rc.dwMask = RASCM_PreSharedKey;
  345. ASSERT( g_pRasGetCredentials );
  346. TRACE( "RasGetCredentials" );
  347. dwErrRc = g_pRasGetCredentials(
  348. pInfo->pArgs->pEinfo->pFile->pszPath,
  349. pInfo->pArgs->pEinfo->pEntry->pszEntryName,
  350. &rc );
  351. TRACE2( "RasGetCredentials=%d,m=%d", dwErrRc, rc.dwMask );
  352. if (dwErrRc == 0 && (rc.dwMask & RASCM_PreSharedKey) && ( lstrlen(rc.szPassword) > 0 ) )
  353. {
  354. SetWindowText( pInfo->hwndEbPSK, TEXT("****************") );
  355. }
  356. else
  357. {
  358. SetWindowText( pInfo->hwndEbPSK,TEXT("") );
  359. }
  360. // Whistler bug 254385 encode password when not being used
  361. //
  362. ZeroMemory( rc.szPassword, sizeof(rc.szPassword) );
  363. }
  364. else
  365. {
  366. SetWindowText( pInfo->hwndEbPSK,TEXT("****************") );// pArgs->pEinfo->szPSK ); //
  367. }
  368. }
  369. // Center dialog on the owner window.
  370. //
  371. CenterWindow( hwndDlg, GetParent( hwndDlg ) );
  372. // Add context help button to title bar.
  373. //
  374. AddContextHelpButton( hwndDlg );
  375. SetFocus( pInfo->hwndEbPSK );
  376. return TRUE;
  377. } //end of CiInit()
  378. BOOL
  379. CiCommand(
  380. IN CIINFO* pInfo,
  381. IN WORD wNotification,
  382. IN WORD wId,
  383. IN HWND hwndCtrl )
  384. // Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
  385. // is the notification code of the command. 'wId' is the control/menu
  386. // identifier of the command. 'HwndCtrl' is the control window handle of
  387. // the command.
  388. //
  389. // Returns true if processed message, false otherwise.
  390. //
  391. {
  392. TRACE3( "CiCommand(n=%d,i=%d,c=$%x)",
  393. (DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
  394. switch (wId)
  395. {
  396. case CID_CI_EB_PSK:
  397. {
  398. return TRUE;
  399. }
  400. case CID_CI_CB_PresharedKey:
  401. {
  402. BOOL fEnabled;
  403. fEnabled = Button_GetCheck( pInfo->hwndCbPresharedKey );
  404. EnableWindow( pInfo->hwndStKey, fEnabled );
  405. EnableWindow( pInfo->hwndEbPSK, fEnabled );
  406. }
  407. break;
  408. case IDOK:
  409. {
  410. if (CiSave( pInfo ))
  411. {
  412. EndDialog( pInfo->hwndDlg, TRUE );
  413. }
  414. return TRUE;
  415. }
  416. case IDCANCEL:
  417. {
  418. TRACE( "Cancel pressed" );
  419. EndDialog( pInfo->hwndDlg, FALSE );
  420. return TRUE;
  421. }
  422. }
  423. return FALSE;
  424. }//end of CiCommand()
  425. BOOL
  426. CiSave(
  427. IN CIINFO* pInfo )
  428. // Saves control contents to caller's PBENTRY argument. 'PInfo' is the
  429. // dialog context.
  430. //
  431. // Returns TRUE if successful or false if invalid combination of
  432. // selections was detected and reported.
  433. //
  434. {
  435. TCHAR szPSK[PWLEN + 1];
  436. BOOL fPskChecked = FALSE;
  437. fPskChecked = Button_GetCheck( pInfo->hwndCbPresharedKey );
  438. if ( fPskChecked )
  439. {
  440. GetWindowText( pInfo->hwndEbPSK, szPSK, PWLEN+1 );
  441. if ( lstrlen( szPSK ) == 0 )
  442. {
  443. MsgDlgUtil( pInfo->hwndDlg, SID_HavetoEnterPSK, NULL, g_hinstDll, SID_PopupTitle );
  444. return FALSE;
  445. }
  446. else if (!lstrcmp( szPSK, TEXT("****************")) ) //16 "*" means no change
  447. {
  448. ;
  449. }
  450. else //save PSK to EINFO and mark the fPSKCached
  451. {
  452. // Whistler bug 224074 use only lstrcpyn's to prevent
  453. // maliciousness
  454. //
  455. // Whistler bug 254385 encode password when not being used
  456. // Assumed password was not encoded by GetWindowText()
  457. //
  458. lstrcpyn(
  459. pInfo->pArgs->pEinfo->szPSK,
  460. szPSK,
  461. sizeof(pInfo->pArgs->pEinfo->szPSK) / sizeof(TCHAR) );
  462. EncodePassword( pInfo->pArgs->pEinfo->szPSK );
  463. pInfo->pArgs->pEinfo->fPSKCached = TRUE;
  464. }
  465. }
  466. else
  467. {
  468. // Whistler bug 224074 use only lstrcpyn's to prevent
  469. // maliciousness
  470. //
  471. lstrcpyn(
  472. pInfo->pArgs->pEinfo->szPSK,
  473. TEXT(""),
  474. sizeof(pInfo->pArgs->pEinfo->szPSK) / sizeof(TCHAR) );
  475. pInfo->pArgs->pEinfo->fPSKCached = FALSE;
  476. }
  477. // Whistler bug 254385 encode password when not being used
  478. //
  479. ZeroMemory( szPSK, sizeof(szPSK) );
  480. //Change the value of dwIpSecFlags only along with a valid operation
  481. //
  482. pInfo->pArgs->pEinfo->pEntry->dwIpSecFlags = fPskChecked?AR_F_IpSecPSK : 0;
  483. return TRUE;
  484. }//end of CiSave()
  485. VOID
  486. CiTerm(
  487. IN HWND hwndDlg )
  488. // Dialog termination. Releases the context block. 'HwndDlg' is the
  489. // handle of a dialog.
  490. //
  491. {
  492. CIINFO* pInfo;
  493. TRACE( "CiTerm" );
  494. pInfo = (CIINFO* )GetWindowLongPtr( hwndDlg, DWLP_USER );
  495. if (pInfo)
  496. {
  497. Free( pInfo );
  498. TRACE( "Context freed" );
  499. }
  500. }//end of CiTerm()