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.

597 lines
17 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 = NO_ERROR;
  163. CIINFO* pInfo = NULL;
  164. TRACE( "CiInit" );
  165. // Allocate the dialog context block. Initialize minimally for proper
  166. // cleanup, then attach to the dialog window.
  167. //
  168. {
  169. pInfo = Malloc( sizeof(*pInfo) );
  170. if (!pInfo)
  171. {
  172. ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
  173. EndDialog( hwndDlg, FALSE );
  174. return TRUE;
  175. }
  176. ZeroMemory( pInfo, sizeof(*pInfo) );
  177. pInfo->pArgs = pArgs;
  178. pInfo->hwndDlg = hwndDlg;
  179. SetWindowLongPtr( hwndDlg, DWLP_USER, (ULONG_PTR )pInfo );
  180. TRACE( "Context set" );
  181. }
  182. pInfo->hwndCbPresharedKey = GetDlgItem( hwndDlg, CID_CI_CB_PresharedKey );
  183. ASSERT(pInfo->hwndCbPresharedKey);
  184. pInfo->hwndStKey = GetDlgItem( hwndDlg, CID_CI_ST_Key );
  185. ASSERT(pInfo->hwndStKey);
  186. pInfo->hwndEbPSK = GetDlgItem( hwndDlg, CID_CI_EB_PSK );
  187. ASSERT(pInfo->hwndEbPSK);
  188. pInfo->hwndCbUserCerts = GetDlgItem( hwndDlg, CID_CI_CB_UserCerts );
  189. ASSERT(pInfo->hwndCbUserCerts);
  190. pInfo->hwndCbSpecificCerts = GetDlgItem( hwndDlg, CID_CI_CB_SpecificCerts );
  191. ASSERT(pInfo->hwndCbSpecificCerts);
  192. pInfo->hwndPbSelect = GetDlgItem( hwndDlg, CID_CI_PB_Select );
  193. ASSERT(pInfo->hwndPbSelect);
  194. pInfo->hwndLbCertsList = GetDlgItem( hwndDlg, CID_CI_LB_CertsList );
  195. ASSERT(pInfo->hwndLbCertsList);
  196. //Hide the User certs and Specific certs until the whistler server
  197. ShowWindow( pInfo->hwndCbUserCerts, SW_HIDE );
  198. ShowWindow( pInfo->hwndCbSpecificCerts, SW_HIDE );
  199. ShowWindow( pInfo->hwndPbSelect, SW_HIDE );
  200. ShowWindow( pInfo->hwndLbCertsList, SW_HIDE );
  201. // Fill the EAP packages listbox and select the previously identified
  202. // selection. The Properties button is disabled by default, but may
  203. // be enabled when the EAP list selection is set.
  204. //
  205. {
  206. BOOL fEnabled;
  207. fEnabled = !!((pArgs->pEinfo->pEntry->dwIpSecFlags)& AR_F_IpSecPSK) ;
  208. Button_SetCheck( pInfo->hwndCbPresharedKey, fEnabled );
  209. EnableWindow( pInfo->hwndStKey, fEnabled );
  210. EnableWindow( pInfo->hwndEbPSK, fEnabled );
  211. // For whistler bug 432771 gangz
  212. // Limit the length of PSK to be 255
  213. //
  214. Edit_LimitText( pInfo->hwndEbPSK, PWLEN-1 );
  215. }
  216. //
  217. //Fill the Preshared Key in "*"s or just leave it bland if none
  218. //is saved previously
  219. //
  220. //for Demand Dial, use MprAdmin.... router functions
  221. //
  222. if (pArgs->pEinfo->fRouter)
  223. {
  224. if( !(pArgs->pEinfo->fPSKCached) )
  225. {
  226. // Initialize the interface-information structure.
  227. //
  228. // For whistler 522872
  229. HANDLE hServer = NULL;
  230. HANDLE hInterface = NULL;
  231. WCHAR* pwszInterface = NULL;
  232. WCHAR pszComputer[512];
  233. MPR_INTERFACE_0 mi0;
  234. MPR_CREDENTIALSEX_1 * pMc1 = NULL;
  235. do {
  236. dwErr = g_pMprAdminServerConnect(pArgs->pEinfo->pszRouter, &hServer);
  237. if (dwErr != NO_ERROR)
  238. {
  239. TRACE("CiInit: MprAdminServerConnect failed!");
  240. break;
  241. }
  242. ZeroMemory( &mi0, sizeof(mi0) );
  243. mi0.dwIfType = ROUTER_IF_TYPE_FULL_ROUTER;
  244. mi0.fEnabled = TRUE;
  245. pwszInterface = StrDupWFromT( pArgs->pEinfo->pEntry->pszEntryName );
  246. if (!pwszInterface)
  247. {
  248. TRACE("CiInit:pwszInterface conversion failed!");
  249. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  250. break;
  251. }
  252. lstrcpynW(
  253. mi0.wszInterfaceName,
  254. pwszInterface,
  255. MAX_INTERFACE_NAME_LEN+1 );
  256. // Get the interface handle
  257. //
  258. ASSERT( g_pMprAdminInterfaceGetHandle );
  259. dwErr = g_pMprAdminInterfaceGetHandle(
  260. hServer,
  261. pwszInterface,
  262. &hInterface,
  263. FALSE);
  264. if (dwErr)
  265. {
  266. TRACE1( "CiInit: MprAdminInterfaceGetHandle error %d", dwErr);
  267. break;
  268. }
  269. //Get the IPSec Policy keys(PSK for Whislter)
  270. //
  271. ASSERT( g_pMprAdminInterfaceGetCredentialsEx );
  272. dwErr = g_pMprAdminInterfaceGetCredentialsEx(
  273. hServer,
  274. hInterface,
  275. 1,
  276. (LPBYTE *)&pMc1 );
  277. if(dwErr)
  278. {
  279. TRACE1(
  280. "CiInit: MprAdminInterfaceGetCredentialsEx error %d", dwErr);
  281. break;
  282. }
  283. if ( !pMc1 )
  284. {
  285. TRACE(
  286. "CiInit: MprAdminInterfaceGetCredentialsEx returns invalid credential pointer!");
  287. dwErr = ERROR_CAN_NOT_COMPLETE;
  288. break;
  289. }
  290. else
  291. {
  292. if ( lstrlenA( pMc1->lpbCredentialsInfo ) >0 )
  293. {
  294. SetWindowText( pInfo->hwndEbPSK,TEXT("****************") );
  295. // Whistler bug 254385 encode password when not being used
  296. // Whistler bug 275526 NetVBL BVT Break: Routing BVT broken
  297. //
  298. ZeroMemory(
  299. pMc1->lpbCredentialsInfo,
  300. lstrlenA(pMc1->lpbCredentialsInfo) + 1 );
  301. }
  302. else
  303. {
  304. SetWindowText( pInfo->hwndEbPSK,TEXT("") );
  305. }
  306. ASSERT( g_pMprAdminBufferFree );
  307. g_pMprAdminBufferFree( pMc1 );
  308. }
  309. }
  310. while (FALSE) ;
  311. // Cleanup
  312. {
  313. // If some operation failed, restore the router to the
  314. // state it was previously in.
  315. if ( dwErr != NO_ERROR )
  316. {
  317. SetWindowText( pInfo->hwndEbPSK, TEXT("") );
  318. }
  319. // Close all handles, free all strings.
  320. if ( pwszInterface )
  321. {
  322. Free0( pwszInterface );
  323. }
  324. if (hServer)
  325. {
  326. g_pMprAdminServerDisconnect( hServer );
  327. }
  328. }
  329. }
  330. else
  331. {
  332. SetWindowText( pInfo->hwndEbPSK,TEXT("****************") );// pArgs->pEinfo->szPSK ); //
  333. }
  334. }
  335. else //retrieve the credentials with Ras functions
  336. {
  337. // Look up cached PSK, from RASMAN or EINFO
  338. //
  339. if( !(pArgs->pEinfo->fPSKCached) )
  340. {
  341. DWORD dwErrRc;
  342. RASCREDENTIALS rc;
  343. ZeroMemory( &rc, sizeof(rc) );
  344. rc.dwSize = sizeof(rc);
  345. rc.dwMask = RASCM_PreSharedKey;
  346. ASSERT( g_pRasGetCredentials );
  347. TRACE( "RasGetCredentials" );
  348. dwErrRc = g_pRasGetCredentials(
  349. pInfo->pArgs->pEinfo->pFile->pszPath,
  350. pInfo->pArgs->pEinfo->pEntry->pszEntryName,
  351. &rc );
  352. TRACE2( "RasGetCredentials=%d,m=%d", dwErrRc, rc.dwMask );
  353. if (dwErrRc == 0 && (rc.dwMask & RASCM_PreSharedKey) && ( lstrlen(rc.szPassword) > 0 ) )
  354. {
  355. SetWindowText( pInfo->hwndEbPSK, TEXT("****************") );
  356. }
  357. else
  358. {
  359. SetWindowText( pInfo->hwndEbPSK,TEXT("") );
  360. }
  361. // Whistler bug 254385 encode password when not being used
  362. //
  363. RtlSecureZeroMemory( rc.szPassword, sizeof(rc.szPassword) );
  364. }
  365. else
  366. {
  367. SetWindowText( pInfo->hwndEbPSK,TEXT("****************") );// pArgs->pEinfo->szPSK ); //
  368. }
  369. }
  370. // Center dialog on the owner window.
  371. //
  372. CenterWindow( hwndDlg, GetParent( hwndDlg ) );
  373. // Add context help button to title bar.
  374. //
  375. AddContextHelpButton( hwndDlg );
  376. SetFocus( pInfo->hwndEbPSK );
  377. return TRUE;
  378. } //end of CiInit()
  379. BOOL
  380. CiCommand(
  381. IN CIINFO* pInfo,
  382. IN WORD wNotification,
  383. IN WORD wId,
  384. IN HWND hwndCtrl )
  385. // Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
  386. // is the notification code of the command. 'wId' is the control/menu
  387. // identifier of the command. 'HwndCtrl' is the control window handle of
  388. // the command.
  389. //
  390. // Returns true if processed message, false otherwise.
  391. //
  392. {
  393. TRACE3( "CiCommand(n=%d,i=%d,c=$%x)",
  394. (DWORD )wNotification, (DWORD )wId, (ULONG_PTR )hwndCtrl );
  395. switch (wId)
  396. {
  397. case CID_CI_EB_PSK:
  398. {
  399. return TRUE;
  400. }
  401. case CID_CI_CB_PresharedKey:
  402. {
  403. BOOL fEnabled;
  404. fEnabled = Button_GetCheck( pInfo->hwndCbPresharedKey );
  405. EnableWindow( pInfo->hwndStKey, fEnabled );
  406. EnableWindow( pInfo->hwndEbPSK, fEnabled );
  407. }
  408. break;
  409. case IDOK:
  410. {
  411. if (CiSave( pInfo ))
  412. {
  413. EndDialog( pInfo->hwndDlg, TRUE );
  414. }
  415. return TRUE;
  416. }
  417. case IDCANCEL:
  418. {
  419. TRACE( "Cancel pressed" );
  420. EndDialog( pInfo->hwndDlg, FALSE );
  421. return TRUE;
  422. }
  423. }
  424. return FALSE;
  425. }//end of CiCommand()
  426. BOOL
  427. CiSave(
  428. IN CIINFO* pInfo )
  429. // Saves control contents to caller's PBENTRY argument. 'PInfo' is the
  430. // dialog context.
  431. //
  432. // Returns TRUE if successful or false if invalid combination of
  433. // selections was detected and reported.
  434. //
  435. {
  436. TCHAR szPSK[PWLEN + 1];
  437. BOOL fPskChecked = FALSE;
  438. fPskChecked = Button_GetCheck( pInfo->hwndCbPresharedKey );
  439. if ( fPskChecked )
  440. {
  441. GetWindowText( pInfo->hwndEbPSK, szPSK, PWLEN+1 );
  442. if ( lstrlen( szPSK ) == 0 )
  443. {
  444. MsgDlgUtil( pInfo->hwndDlg, SID_HavetoEnterPSK, NULL, g_hinstDll, SID_PopupTitle );
  445. return FALSE;
  446. }
  447. else if (!lstrcmp( szPSK, TEXT("****************")) ) //16 "*" means no change
  448. {
  449. ;
  450. }
  451. else //save PSK to EINFO and mark the fPSKCached
  452. {
  453. // Whistler bug 224074 use only lstrcpyn's to prevent
  454. // maliciousness
  455. //
  456. // Whistler bug 254385 encode password when not being used
  457. // Assumed password was not encoded by GetWindowText()
  458. //
  459. lstrcpyn(
  460. pInfo->pArgs->pEinfo->szPSK,
  461. szPSK,
  462. sizeof(pInfo->pArgs->pEinfo->szPSK) / sizeof(TCHAR) );
  463. EncodePassword( pInfo->pArgs->pEinfo->szPSK );
  464. pInfo->pArgs->pEinfo->fPSKCached = TRUE;
  465. }
  466. }
  467. else
  468. {
  469. // Whistler bug 224074 use only lstrcpyn's to prevent
  470. // maliciousness
  471. //
  472. lstrcpyn(
  473. pInfo->pArgs->pEinfo->szPSK,
  474. TEXT(""),
  475. sizeof(pInfo->pArgs->pEinfo->szPSK) / sizeof(TCHAR) );
  476. pInfo->pArgs->pEinfo->fPSKCached = FALSE;
  477. }
  478. // Whistler bug 254385 encode password when not being used
  479. //
  480. RtlSecureZeroMemory( szPSK, sizeof(szPSK) );
  481. //Change the value of dwIpSecFlags only along with a valid operation
  482. //
  483. pInfo->pArgs->pEinfo->pEntry->dwIpSecFlags = fPskChecked?AR_F_IpSecPSK : 0;
  484. return TRUE;
  485. }//end of CiSave()
  486. VOID
  487. CiTerm(
  488. IN HWND hwndDlg )
  489. // Dialog termination. Releases the context block. 'HwndDlg' is the
  490. // handle of a dialog.
  491. //
  492. {
  493. CIINFO* pInfo;
  494. TRACE( "CiTerm" );
  495. pInfo = (CIINFO* )GetWindowLongPtr( hwndDlg, DWLP_USER );
  496. if (pInfo)
  497. {
  498. Free( pInfo );
  499. TRACE( "Context freed" );
  500. }
  501. }//end of CiTerm()