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.

1314 lines
35 KiB

  1. /*++
  2. Copyright (c) 2000, Microsoft Corporation
  3. Module Name:
  4. eluser.c
  5. Abstract:
  6. The module deals with functions related to user interaction, user logon
  7. Revision History:
  8. sachins, Apr 22 2001, Created
  9. --*/
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. #define cszEapKeyRas TEXT("Software\\Microsoft\\RAS EAP\\UserEapInfo")
  13. #define cszEapValue TEXT("EapInfo")
  14. static const DWORD g_adMD5Help[] =
  15. {
  16. 0, 0
  17. };
  18. //
  19. // ElGetUserIdentityDlgWorker
  20. //
  21. // Description:
  22. //
  23. // Function called to fetch identity of the user, via UI if required
  24. //
  25. // Arguments:
  26. //
  27. // Return values:
  28. //
  29. //
  30. DWORD
  31. ElGetUserIdentityDlgWorker (
  32. IN WCHAR *pwszConnectionName,
  33. IN VOID *pvContext
  34. )
  35. {
  36. DTLLIST *pListEaps = NULL;
  37. DTLNODE *pEapcfgNode = NULL;
  38. EAPCFG *pEapcfg = NULL;
  39. CHAR *pszIdentity = NULL;
  40. BYTE *pUserDataOut = NULL;
  41. DWORD dwSizeOfUserDataOut = 0;
  42. LPWSTR lpwszIdentity = NULL;
  43. HWND hwndOwner = NULL;
  44. PBYTE pbUserIn = NULL;
  45. DWORD cbData = 0;
  46. DWORD dwInSize = 0;
  47. PBYTE pbAuthData = NULL;
  48. HANDLE hLib = NULL;
  49. RASEAPFREE pFreeFunc = NULL;
  50. RASEAPGETIDENTITY pIdenFunc = NULL;
  51. EAPOL_EAP_UI_CONTEXT *pEAPUIContext = NULL;
  52. EAPOLUI_RESP EapolUIResp;
  53. DWORD dwEapTypeToBeUsed = 0;
  54. BOOLEAN fSendResponse = FALSE;
  55. BOOLEAN fVerifyPhase = FALSE;
  56. DWORD dwRetCode1= NO_ERROR;
  57. DWORD dwRetCode = NO_ERROR;
  58. do
  59. {
  60. if (pvContext == NULL)
  61. {
  62. dwRetCode = ERROR_INVALID_PARAMETER;
  63. return dwRetCode;
  64. }
  65. pEAPUIContext = (EAPOL_EAP_UI_CONTEXT *)pvContext;
  66. if (pwszConnectionName == NULL)
  67. {
  68. fVerifyPhase = TRUE;
  69. }
  70. pListEaps = ReadEapcfgList (0);
  71. if (pListEaps == NULL)
  72. {
  73. dwRetCode = ERROR_CAN_NOT_COMPLETE;
  74. break;
  75. }
  76. pEapcfgNode = EapcfgNodeFromKey (
  77. pListEaps,
  78. pEAPUIContext->dwEapTypeId
  79. );
  80. if (pEapcfgNode == NULL)
  81. {
  82. dwRetCode = ERROR_CAN_NOT_COMPLETE;
  83. break;
  84. }
  85. pEapcfg = (EAPCFG*) DtlGetData (pEapcfgNode);
  86. // Get the size of the user blob
  87. if ((dwRetCode = WZCGetEapUserInfo (
  88. pEAPUIContext->wszGUID,
  89. pEAPUIContext->dwEapTypeId,
  90. pEAPUIContext->dwSizeOfSSID,
  91. pEAPUIContext->bSSID,
  92. NULL,
  93. &dwInSize
  94. )) != NO_ERROR)
  95. {
  96. if (dwRetCode == ERROR_INSUFFICIENT_BUFFER)
  97. {
  98. if (dwInSize <= 0)
  99. {
  100. // No blob stored in the registry
  101. // Continue processing
  102. TRACE0 (USER, "ElGetUserIdentityDlgWorker: NULL sized user data");
  103. pbUserIn = NULL;
  104. }
  105. else
  106. {
  107. // Allocate memory to hold the blob
  108. pbUserIn = MALLOC (dwInSize);
  109. if (pbUserIn == NULL)
  110. {
  111. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  112. TRACE0 (USER, "ElGetUserIdentityDlgWorker: Error in memory allocation for User data");
  113. break;
  114. }
  115. if ((dwRetCode = WZCGetEapUserInfo (
  116. pEAPUIContext->wszGUID,
  117. pEAPUIContext->dwEapTypeId,
  118. pEAPUIContext->dwSizeOfSSID,
  119. pEAPUIContext->bSSID,
  120. pbUserIn,
  121. &dwInSize
  122. )) != NO_ERROR)
  123. {
  124. TRACE1 (USER, "ElGetUserIdentityDlgWorker: WZCGetEapUserInfo failed with %ld",
  125. dwRetCode);
  126. break;
  127. }
  128. }
  129. }
  130. else
  131. {
  132. // User info may not have been created till now
  133. // which is valid condition to proceed
  134. if (dwRetCode != ERROR_FILE_NOT_FOUND)
  135. {
  136. TRACE1 (USER, "ElGetUserIdentityDlgWorker: WZCGetEapUserInfo size estimation failed with error %ld",
  137. dwRetCode);
  138. break;
  139. }
  140. else
  141. {
  142. dwRetCode = NO_ERROR;
  143. }
  144. }
  145. }
  146. // In verification phase, if NULL user size, wait for onballoonclick
  147. // before showing balloon
  148. #if 0
  149. if (fVerifyPhase)
  150. {
  151. if ((pbUserIn == NULL) && (dwInSize == 0))
  152. {
  153. dwRetCode = ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION;
  154. break;
  155. }
  156. }
  157. #endif
  158. hLib = LoadLibrary (pEapcfg->pszIdentityDll);
  159. if (hLib == NULL)
  160. {
  161. dwRetCode = GetLastError ();
  162. break;
  163. }
  164. pIdenFunc = (RASEAPGETIDENTITY)GetProcAddress(hLib,
  165. "RasEapGetIdentity");
  166. pFreeFunc = (RASEAPFREE)GetProcAddress(hLib, "RasEapFreeMemory");
  167. if ((pFreeFunc == NULL) || (pIdenFunc == NULL))
  168. {
  169. TRACE0 (USER, "ElGetUserIdentityDlgWorker: pIdenFunc or pFreeFunc does not exist in the EAP implementation");
  170. dwRetCode = ERROR_CAN_NOT_COMPLETE;
  171. break;
  172. }
  173. // Get the size of the EAP blob
  174. if ((dwRetCode = WZCEapolGetCustomAuthData (
  175. NULL,
  176. pEAPUIContext->wszGUID,
  177. pEAPUIContext->dwEapTypeId,
  178. pEAPUIContext->dwSizeOfSSID,
  179. pEAPUIContext->bSSID,
  180. NULL,
  181. &cbData
  182. )) != NO_ERROR)
  183. {
  184. if (dwRetCode == ERROR_BUFFER_TOO_SMALL)
  185. {
  186. if (cbData == 0)
  187. {
  188. // No EAP blob stored in the registry
  189. TRACE0 (USER, "ElGetUserIdentityDlgWorker: NULL sized EAP blob");
  190. pbAuthData = NULL;
  191. // Every port should have connection data !!!
  192. // dwRetCode = ERROR_CAN_NOT_COMPLETE;
  193. // break;
  194. }
  195. else
  196. {
  197. // Allocate memory to hold the blob
  198. pbAuthData = MALLOC (cbData);
  199. if (pbAuthData == NULL)
  200. {
  201. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  202. TRACE0 (USER, "ElGetUserIdentityDlgWorker: Error in memory allocation for EAP blob");
  203. break;
  204. }
  205. if ((dwRetCode = WZCEapolGetCustomAuthData (
  206. NULL,
  207. pEAPUIContext->wszGUID,
  208. pEAPUIContext->dwEapTypeId,
  209. pEAPUIContext->dwSizeOfSSID,
  210. pEAPUIContext->bSSID,
  211. pbAuthData,
  212. &cbData
  213. )) != NO_ERROR)
  214. {
  215. TRACE1 (USER, "ElGetUserIdentityDlgWorker: ElGetCustomAuthData failed with %ld",
  216. dwRetCode);
  217. break;
  218. }
  219. }
  220. }
  221. else
  222. {
  223. // CustomAuthData for "Default" is always created for an
  224. // interface when EAPOL starts up
  225. TRACE1 (USER, "ElGetUserIdentityDlgWorker: ElGetCustomAuthData size estimation failed with error %ld",
  226. dwRetCode);
  227. break;
  228. }
  229. }
  230. // Get handle to desktop window
  231. hwndOwner = GetDesktopWindow ();
  232. dwEapTypeToBeUsed = pEAPUIContext->dwEapTypeId;
  233. if (pIdenFunc)
  234. if ((dwRetCode = (*(pIdenFunc))(
  235. dwEapTypeToBeUsed,
  236. fVerifyPhase?NULL:hwndOwner, // hwndOwner
  237. (fVerifyPhase?RAS_EAP_FLAG_NON_INTERACTIVE:0)
  238. | RAS_EAP_FLAG_8021X_AUTH, // dwFlags
  239. NULL, // lpszPhonebook
  240. pwszConnectionName, // lpszEntry
  241. pbAuthData, // Connection data
  242. cbData, // Count of pbAuthData
  243. pbUserIn, // User data for port
  244. dwInSize, // Size of user data
  245. &pUserDataOut,
  246. &dwSizeOfUserDataOut,
  247. &lpwszIdentity
  248. )) != NO_ERROR)
  249. {
  250. TRACE1 (USER, "ElGetUserIdentityDlgWorker: Error in calling GetIdentity = %ld",
  251. dwRetCode);
  252. if (fVerifyPhase)
  253. {
  254. // If interactive mode is required, return error accordingly
  255. if (dwRetCode == ERROR_INTERACTIVE_MODE)
  256. {
  257. dwRetCode = ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION;
  258. break;
  259. }
  260. }
  261. break;
  262. }
  263. if (lpwszIdentity != NULL)
  264. {
  265. pszIdentity = MALLOC (wcslen(lpwszIdentity)*sizeof(CHAR) + sizeof(CHAR));
  266. if (pszIdentity == NULL)
  267. {
  268. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  269. TRACE0 (USER, "ElGetUserIdentityDlgWorker: MALLOC failed for pszIdentity");
  270. break;
  271. }
  272. if (0 == WideCharToMultiByte (
  273. CP_ACP,
  274. 0,
  275. lpwszIdentity,
  276. -1,
  277. pszIdentity,
  278. wcslen(lpwszIdentity)*sizeof(CHAR)+sizeof(CHAR),
  279. NULL,
  280. NULL ))
  281. {
  282. dwRetCode = GetLastError();
  283. TRACE2 (USER, "ElGetUserIdentityDlgWorker: WideCharToMultiByte (%ws) failed: %ld",
  284. lpwszIdentity, dwRetCode);
  285. break;
  286. }
  287. TRACE1 (USER, "ElGetUserIdentityDlgWorker: Got identity = %s",
  288. pszIdentity);
  289. }
  290. }
  291. while (FALSE);
  292. // Create UI Response for Service
  293. ZeroMemory ((VOID *)&EapolUIResp, sizeof (EapolUIResp));
  294. if (pszIdentity)
  295. {
  296. EapolUIResp.rdData0.dwDataLen = strlen (pszIdentity);
  297. }
  298. else
  299. {
  300. EapolUIResp.rdData0.dwDataLen = 0;
  301. }
  302. EapolUIResp.rdData0.pData = pszIdentity;
  303. if ((dwSizeOfUserDataOut != 0) && (pUserDataOut != NULL))
  304. {
  305. EapolUIResp.rdData1.dwDataLen = dwSizeOfUserDataOut;
  306. EapolUIResp.rdData1.pData = pUserDataOut;
  307. }
  308. if ((cbData != 0) && (pbAuthData != NULL))
  309. {
  310. EapolUIResp.rdData2.dwDataLen = cbData;
  311. EapolUIResp.rdData2.pData = pbAuthData;
  312. }
  313. if (dwRetCode == NO_ERROR)
  314. {
  315. fSendResponse = TRUE;
  316. }
  317. else
  318. {
  319. // Send out GUEST identity if no certificate available
  320. // Do not fill out any identity information
  321. if ((dwRetCode == ERROR_NO_EAPTLS_CERTIFICATE) &&
  322. (IS_GUEST_AUTH_ENABLED(pEAPUIContext->dwEapFlags)))
  323. {
  324. // Reset error, since guest identity can be sent in
  325. // absence of certificate
  326. fSendResponse = TRUE;
  327. dwRetCode = NO_ERROR;
  328. TRACE0 (USER, "ElGetUserIdentityDlgWorker: Sending guest identity");
  329. }
  330. else
  331. {
  332. if ((dwRetCode != ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION) &&
  333. (dwRetCode != ERROR_NO_EAPTLS_CERTIFICATE) &&
  334. (dwRetCode != ERROR_NO_SMART_CARD_READER))
  335. {
  336. pEAPUIContext->dwRetCode = dwRetCode;
  337. fSendResponse = TRUE;
  338. }
  339. }
  340. }
  341. // Don't send out response during verification phase, if user-interaction
  342. // is required
  343. if ((dwRetCode != ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION) &&
  344. (dwRetCode != ERROR_NO_EAPTLS_CERTIFICATE) &&
  345. (dwRetCode != ERROR_NO_SMART_CARD_READER) &&
  346. fSendResponse)
  347. {
  348. if ((dwRetCode = WZCEapolUIResponse (
  349. NULL,
  350. *pEAPUIContext,
  351. EapolUIResp
  352. )) != NO_ERROR)
  353. {
  354. TRACE1 (USER, "ElGetUserIdentityDlgWorker: WZCEapolUIResponse failed with error %ld",
  355. dwRetCode);
  356. }
  357. }
  358. if (pbUserIn != NULL)
  359. {
  360. FREE (pbUserIn);
  361. }
  362. if (pbAuthData != NULL)
  363. {
  364. FREE (pbAuthData);
  365. }
  366. if (pszIdentity != NULL)
  367. {
  368. FREE (pszIdentity);
  369. }
  370. if (pFreeFunc != NULL)
  371. {
  372. if (lpwszIdentity != NULL)
  373. {
  374. if (( dwRetCode1 = (*(pFreeFunc)) ((BYTE *)lpwszIdentity)) != NO_ERROR)
  375. {
  376. TRACE1 (USER, "ElGetUserIdentityDlgWorker: Error in pFreeFunc = %ld",
  377. dwRetCode1);
  378. }
  379. }
  380. if (pUserDataOut != NULL)
  381. {
  382. if (( dwRetCode1 = (*(pFreeFunc)) ((BYTE *)pUserDataOut)) != NO_ERROR)
  383. {
  384. TRACE1 (USER, "ElGetUserIdentityDlgWorker: Error in pFreeFunc = %ld",
  385. dwRetCode1);
  386. }
  387. }
  388. }
  389. if (pListEaps != NULL)
  390. {
  391. DtlDestroyList(pListEaps, NULL);
  392. }
  393. if (hLib != NULL)
  394. {
  395. FreeLibrary (hLib);
  396. }
  397. return dwRetCode;
  398. }
  399. //
  400. // ElGetUserNamePasswordDlgWorker
  401. //
  402. // Description:
  403. //
  404. // Function called to fetch username/password credentials for the user using
  405. // UI dialog
  406. //
  407. // Arguments:
  408. //
  409. // Return values:
  410. // NO_ERROR - success
  411. // non-zero - error
  412. //
  413. DWORD
  414. ElGetUserNamePasswordDlgWorker (
  415. IN WCHAR *pwszConnectionName,
  416. IN VOID *pvContext
  417. )
  418. {
  419. HANDLE hUserToken = NULL;
  420. DWORD dwInSize = 0;
  421. HWND hwndOwner = NULL;
  422. EAPOLMD5UI *pEapolMD5UI = NULL;
  423. EAPOL_EAP_UI_CONTEXT *pEAPUIContext = NULL;
  424. EAPOLUI_RESP EapolUIResp;
  425. BOOLEAN fSendResponse = FALSE;
  426. DWORD dwRetCode = NO_ERROR;
  427. do
  428. {
  429. TRACE0 (USER, "ElGetUserNamePasswordDlgWorker entered");
  430. if (pvContext == NULL)
  431. {
  432. dwRetCode = ERROR_INVALID_PARAMETER;
  433. return dwRetCode;
  434. }
  435. pEAPUIContext = (EAPOL_EAP_UI_CONTEXT *)pvContext;
  436. pEapolMD5UI = MALLOC (sizeof (EAPOLMD5UI));
  437. if (pEapolMD5UI == NULL)
  438. {
  439. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  440. TRACE0 (USER, "ElGetUserNamePasswordDlgWorker: MALLOC failed for pEapolMD5UI");
  441. break;
  442. }
  443. pEapolMD5UI->pwszFriendlyName =
  444. MALLOC ((wcslen(pwszConnectionName)+1)*sizeof(WCHAR));
  445. if (pEapolMD5UI->pwszFriendlyName == NULL)
  446. {
  447. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  448. TRACE0 (USER, "ElGetUserNamePasswordDlgWorker: MALLOC failed for pEapolMD5UI->pwszFriendlyName");
  449. break;
  450. }
  451. wcscpy (pEapolMD5UI->pwszFriendlyName, pwszConnectionName);
  452. // Call the user dialog for obtaining the username and password
  453. if ((dwRetCode = ElUserDlg (hwndOwner, pEapolMD5UI)) != NO_ERROR)
  454. {
  455. TRACE0 (USER, "ElGetUserNamePasswordDlgWorker: ElUserDlg failed");
  456. break;
  457. }
  458. } while (FALSE);
  459. // Create UI Response for Service
  460. ZeroMemory ((VOID *)&EapolUIResp, sizeof (EapolUIResp));
  461. if (dwRetCode == NO_ERROR)
  462. {
  463. if (pEapolMD5UI->pszIdentity)
  464. {
  465. EapolUIResp.rdData0.dwDataLen = strlen (pEapolMD5UI->pszIdentity);
  466. fSendResponse = TRUE;
  467. }
  468. else
  469. {
  470. EapolUIResp.rdData0.dwDataLen = 0;
  471. // Send out NULL identity independent of guest auth setting
  472. // if (IS_GUEST_AUTH_ENABLED(pEAPUIContext->dwEapFlags))
  473. {
  474. fSendResponse = TRUE;
  475. }
  476. }
  477. EapolUIResp.rdData0.pData = pEapolMD5UI->pszIdentity;
  478. EapolUIResp.rdData1.dwDataLen = pEapolMD5UI->PasswordBlob.cbData;
  479. EapolUIResp.rdData1.pData = pEapolMD5UI->PasswordBlob.pbData;
  480. }
  481. else
  482. {
  483. pEAPUIContext->dwRetCode = dwRetCode;
  484. fSendResponse = TRUE;
  485. }
  486. if (fSendResponse)
  487. {
  488. if ((dwRetCode = WZCEapolUIResponse (
  489. NULL,
  490. *pEAPUIContext,
  491. EapolUIResp
  492. )) != NO_ERROR)
  493. {
  494. TRACE1 (USER, "ElGetUserNamePasswordWorker: WZCEapolUIResponse failed with error %ld",
  495. dwRetCode);
  496. }
  497. }
  498. if (pEapolMD5UI != NULL)
  499. {
  500. if (pEapolMD5UI->pwszFriendlyName != NULL)
  501. {
  502. FREE (pEapolMD5UI->pwszFriendlyName);
  503. }
  504. if (pEapolMD5UI->pszIdentity != NULL)
  505. {
  506. FREE (pEapolMD5UI->pszIdentity);
  507. }
  508. if (pEapolMD5UI->pwszPassword != NULL)
  509. {
  510. FREE (pEapolMD5UI->pwszPassword);
  511. }
  512. if (pEapolMD5UI->PasswordBlob.pbData != NULL)
  513. {
  514. FREE (pEapolMD5UI->PasswordBlob.pbData);
  515. }
  516. FREE (pEapolMD5UI);
  517. }
  518. TRACE1 (USER, "ElGetUserNamePasswordDlgWorker completed with error %ld", dwRetCode);
  519. return dwRetCode;
  520. }
  521. //
  522. // ElUserDlg
  523. //
  524. // Description:
  525. //
  526. // Function called to pop-up dialog box to user to enter username, password,
  527. // domainname etc.
  528. //
  529. // Arguments:
  530. // hwndOwner - handle to user desktop
  531. // pEapolMD5UI -
  532. //
  533. // Return values:
  534. // NO_ERROR - success
  535. // non-zero - error
  536. //
  537. DWORD
  538. ElUserDlg (
  539. IN HWND hwndOwner,
  540. IN EAPOLMD5UI *pEapolMD5UI
  541. )
  542. {
  543. USERDLGARGS args;
  544. DWORD dwRetCode = NO_ERROR;
  545. TRACE0 (USER, "ElUserDlg: Entered");
  546. args.pEapolMD5UI = pEapolMD5UI;
  547. if ( DialogBoxParam (
  548. GetModuleHandle(cszModuleName),
  549. MAKEINTRESOURCE (DID_DR_DialerUD),
  550. hwndOwner,
  551. ElUserDlgProc,
  552. (LPARAM)&args ) == -1)
  553. {
  554. dwRetCode = GetLastError ();
  555. TRACE1 (USER, "ElUserDlg: DialogBoxParam failed with error %ld",
  556. dwRetCode);
  557. }
  558. return dwRetCode;
  559. }
  560. //
  561. // ElUserDlgProc
  562. //
  563. // Description:
  564. //
  565. // Function handling all events for username/password/... dialog box
  566. //
  567. // Arguments:
  568. // hwnd -
  569. // unMsg -
  570. // wparam -
  571. // lparam -
  572. //
  573. // Return values:
  574. // NO_ERROR - success
  575. // non-zero - error
  576. //
  577. INT_PTR
  578. ElUserDlgProc (
  579. IN HWND hwnd,
  580. IN UINT unMsg,
  581. IN WPARAM wparam,
  582. IN LPARAM lparam )
  583. {
  584. switch (unMsg)
  585. {
  586. case WM_INITDIALOG:
  587. {
  588. return ElUserDlgInit( hwnd, (USERDLGARGS* )lparam );
  589. break;
  590. }
  591. case WM_HELP:
  592. case WM_CONTEXTMENU:
  593. {
  594. // ElContextHelp ( g_adMD5Help, hwnd, unMsg, wparam, lparam );
  595. break;
  596. }
  597. case WM_COMMAND:
  598. {
  599. USERDLGINFO* pInfo = (USERDLGINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  600. ASSERT( pInfo );
  601. return ElUserDlgCommand (
  602. pInfo, HIWORD(wparam), LOWORD(wparam), (HWND)lparam );
  603. break;
  604. }
  605. case WM_DESTROY:
  606. {
  607. USERDLGINFO* pInfo = (USERDLGINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
  608. ElUserDlgTerm (hwnd, pInfo);
  609. break;
  610. }
  611. }
  612. return FALSE;
  613. }
  614. //
  615. // ElUserDlgInit
  616. //
  617. // Description:
  618. //
  619. // Function initializing UI dialog
  620. //
  621. // Arguments:
  622. // hwndDlg -
  623. // pArgs -
  624. //
  625. // Return values:
  626. // TRUE -
  627. // FALSE -
  628. //
  629. BOOL
  630. ElUserDlgInit (
  631. IN HWND hwndDlg,
  632. IN USERDLGARGS *pArgs
  633. )
  634. {
  635. USERDLGINFO *pInfo = NULL;
  636. DWORD dwRetCode = NO_ERROR;
  637. TRACE0 (USER, "ElUserDlgInit entered");
  638. do
  639. {
  640. pInfo = MALLOC (sizeof (USERDLGINFO));
  641. if (pInfo == NULL)
  642. {
  643. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  644. TRACE0 (USER, "ElUserDlgInit: MALLOC failed for pInfo");
  645. break;
  646. }
  647. pInfo->pArgs = pArgs;
  648. pInfo->hwndDlg = hwndDlg;
  649. SetWindowLongPtr (hwndDlg, DWLP_USER, (ULONG_PTR)pInfo);
  650. #if 0
  651. if (!SetWindowLongPtr (hwndDlg, DWLP_USER, (ULONG_PTR)pInfo))
  652. {
  653. dwRetCode = GetLastError ();
  654. TRACE1 (USER, "ElUserDlgInit: SetWindowLongPtr failed with error %ld",
  655. dwRetCode);
  656. break;
  657. }
  658. #endif
  659. TRACE0 (USER, "ElUserDlgInit: Context Set");
  660. //
  661. // Set the title
  662. //
  663. if (pArgs->pEapolMD5UI->pwszFriendlyName)
  664. {
  665. if (!SetWindowText (hwndDlg, pArgs->pEapolMD5UI->pwszFriendlyName))
  666. {
  667. dwRetCode = GetLastError ();
  668. TRACE1 (USER, "ElUserDlgInit: SetWindowText failed with error %ld",
  669. dwRetCode);
  670. break;
  671. }
  672. }
  673. else
  674. {
  675. if (!SetWindowText (hwndDlg, L""))
  676. {
  677. dwRetCode = GetLastError ();
  678. TRACE1 (USER, "ElUserDlgInit: SetWindowText - NULL failed with error %ld",
  679. dwRetCode);
  680. break;
  681. }
  682. }
  683. pInfo->hwndEbUser = GetDlgItem( hwndDlg, CID_DR_EB_User );
  684. ASSERT (pInfo->hwndEbUser);
  685. pInfo->hwndEbPw = GetDlgItem( hwndDlg, CID_DR_EB_Password );
  686. ASSERT (pInfo->hwndEbPw);
  687. pInfo->hwndEbDomain = GetDlgItem( hwndDlg, CID_DR_EB_Domain );
  688. ASSERT (pInfo->hwndEbDomain);
  689. }
  690. while (FALSE);
  691. if (dwRetCode != NO_ERROR)
  692. {
  693. return FALSE;
  694. }
  695. else
  696. {
  697. return TRUE;
  698. }
  699. }
  700. //
  701. // ElContextHelp
  702. //
  703. // Description:
  704. //
  705. // Function supporting help Ids
  706. // Calls WinHelp to popup context sensitive help. padwMap is an array of
  707. // control-ID help-ID pairs terminated with a 0,0 pair. unMsg is WM_HELP or
  708. // WM_CONTEXTMENU indicating the message received requesting help. wParam and
  709. // lParam are the parameters of the message received requesting help.
  710. //
  711. // Arguments:
  712. // hwndDlg -
  713. // pArgs -
  714. //
  715. // Return values:
  716. //
  717. VOID
  718. ElContextHelp(
  719. IN const DWORD* padwMap,
  720. IN HWND hWndDlg,
  721. IN UINT unMsg,
  722. IN WPARAM wParam,
  723. IN LPARAM lParam
  724. )
  725. {
  726. HWND hWnd;
  727. UINT unType;
  728. WCHAR *pwszHelpFile = NULL;
  729. HELPINFO *pHelpInfo;
  730. do
  731. {
  732. if (unMsg == WM_HELP)
  733. {
  734. pHelpInfo = (HELPINFO*) lParam;
  735. if (pHelpInfo->iContextType != HELPINFO_WINDOW)
  736. {
  737. break;
  738. }
  739. hWnd = pHelpInfo->hItemHandle;
  740. unType = HELP_WM_HELP;
  741. }
  742. else
  743. {
  744. // Standard Win95 method that produces a one-item "What's This?"
  745. // menu that user must click to get help.
  746. hWnd = (HWND) wParam;
  747. unType = HELP_CONTEXTMENU;
  748. };
  749. // pwszHelpFile = WszFromId(g_hInstance, IDS_HELPFILE);
  750. if (pwszHelpFile == NULL)
  751. {
  752. break;
  753. }
  754. WinHelp(hWnd, pwszHelpFile, unType, (ULONG_PTR)padwMap);
  755. }
  756. while (FALSE);
  757. if (pwszHelpFile != NULL)
  758. {
  759. LocalFree(pwszHelpFile);
  760. }
  761. }
  762. //
  763. // ElUserDlgCommand
  764. //
  765. // Description:
  766. //
  767. // Function called on WM_COMMAND
  768. // domainname etc.
  769. //
  770. // Arguments:
  771. // pInfo - dialog context
  772. // wNotification - notification code of the command
  773. // wId - control/menu identifier of the command
  774. // hwndCtrl - control window handle the command.
  775. //
  776. // Return values:
  777. // TRUE - success
  778. // FALSE - error
  779. //
  780. BOOL
  781. ElUserDlgCommand (
  782. IN USERDLGINFO *pInfo,
  783. IN WORD wNotification,
  784. IN WORD wId,
  785. IN HWND hwndCtrl
  786. )
  787. {
  788. switch (wId)
  789. {
  790. case IDOK:
  791. case CID_DR_PB_DialConnect:
  792. {
  793. ElUserDlgSave (pInfo);
  794. EndDialog (pInfo->hwndDlg, TRUE);
  795. return TRUE;
  796. }
  797. case IDCANCEL:
  798. case CID_DR_PB_Cancel:
  799. {
  800. EndDialog (pInfo->hwndDlg, TRUE);
  801. return TRUE;
  802. }
  803. default:
  804. {
  805. break;
  806. }
  807. }
  808. return FALSE;
  809. }
  810. //
  811. // ElUserDlgSave
  812. //
  813. // Description:
  814. //
  815. // Function handling saving of credentials
  816. //
  817. // Arguments:
  818. // pInfo -
  819. //
  820. // Return values:
  821. //
  822. VOID
  823. ElUserDlgSave (
  824. IN USERDLGINFO *pInfo
  825. )
  826. {
  827. EAPOLMD5UI *pEapolMD5UI = NULL;
  828. int iError;
  829. WCHAR wszUserName[UNLEN + 1];
  830. WCHAR wszDomain[DNLEN + 1];
  831. WCHAR wszIdentity[UNLEN + DNLEN + 1];
  832. WCHAR wszPassword[PWLEN + 1];
  833. DWORD dwRetCode = NO_ERROR;
  834. pEapolMD5UI = (EAPOLMD5UI *)pInfo->pArgs->pEapolMD5UI;
  835. do
  836. {
  837. // Username
  838. if ((iError =
  839. GetWindowText (
  840. pInfo->hwndEbUser,
  841. &(wszUserName[0]),
  842. UNLEN + 1 )) == 0)
  843. {
  844. dwRetCode = GetLastError ();
  845. TRACE1 (USER, "ElUserDlgSave: GetWindowText - Username failed with error %ld",
  846. dwRetCode);
  847. }
  848. wszUserName[iError] = L'\0';
  849. TRACE1 (USER, "ElUserDlgSave: Get Username %ws", wszUserName);
  850. // Password
  851. if ((iError =
  852. GetWindowText (
  853. pInfo->hwndEbPw,
  854. &(wszPassword[0]),
  855. PWLEN + 1 )) == 0)
  856. {
  857. dwRetCode = GetLastError ();
  858. TRACE1 (USER, "ElUserDlgSave: GetWindowText - Password failed with error %ld",
  859. dwRetCode);
  860. }
  861. wszPassword[iError] = L'\0';
  862. if (pEapolMD5UI->pwszPassword != NULL)
  863. {
  864. FREE (pEapolMD5UI->pwszPassword);
  865. pEapolMD5UI->pwszPassword = NULL;
  866. }
  867. pEapolMD5UI->pwszPassword = MALLOC ((wcslen(wszPassword) + 1)*sizeof(WCHAR));
  868. if (pEapolMD5UI->pwszPassword == NULL)
  869. {
  870. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  871. TRACE0 (USER, "ElUserDlgSave: MALLOC failed for pEapolMD5UI->pwszPassword");
  872. break;
  873. }
  874. wcscpy (pEapolMD5UI->pwszPassword, wszPassword);
  875. ZeroMemory (wszPassword, wcslen(wszPassword)*sizeof(WCHAR));
  876. // Domain
  877. if ((iError =
  878. GetWindowText (
  879. pInfo->hwndEbDomain,
  880. &(wszDomain[0]),
  881. DNLEN + 1 )) == 0)
  882. {
  883. dwRetCode = GetLastError ();
  884. TRACE1 (USER, "ElUserDlgSave: GetWindowText - Domain failed with error %ld",
  885. dwRetCode);
  886. }
  887. wszDomain[iError] = L'\0';
  888. TRACE1 (USER, "ElUserDlgSave: Got Domain %ws", wszDomain);
  889. if (pEapolMD5UI->pszIdentity != NULL)
  890. {
  891. FREE (pEapolMD5UI->pszIdentity);
  892. pEapolMD5UI->pszIdentity = NULL;
  893. }
  894. if (wcslen(wszDomain)+wcslen(wszUserName) > (UNLEN+DNLEN-1))
  895. {
  896. dwRetCode = ERROR_INVALID_DATA;
  897. break;
  898. }
  899. if ((wszDomain != NULL) &&
  900. (wszDomain[0] != (CHAR)NULL))
  901. {
  902. wcscpy (wszIdentity, wszDomain);
  903. wcscat (wszIdentity, L"\\" );
  904. wcscat (wszIdentity, wszUserName);
  905. }
  906. else
  907. {
  908. wcscpy (wszIdentity, wszUserName);
  909. }
  910. if (wszIdentity[0] != (CHAR)NULL)
  911. {
  912. pEapolMD5UI->pszIdentity = MALLOC (wcslen(wszIdentity)*sizeof(CHAR) + sizeof(CHAR));
  913. if (pEapolMD5UI->pszIdentity == NULL)
  914. {
  915. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  916. TRACE0 (USER, "ElUserDlgSave: MALLOC failed for pEapolMD5UI->pszIdentity");
  917. break;
  918. }
  919. if (0 == WideCharToMultiByte (
  920. CP_ACP,
  921. 0,
  922. wszIdentity,
  923. -1,
  924. pEapolMD5UI->pszIdentity,
  925. wcslen(wszIdentity)*sizeof(CHAR)+sizeof(CHAR),
  926. NULL,
  927. NULL ))
  928. {
  929. dwRetCode = GetLastError();
  930. TRACE2 (USER, "ElUserDlgSave: WideCharToMultiByte (%ws) failed: %ld",
  931. wszIdentity, dwRetCode);
  932. break;
  933. }
  934. }
  935. TRACE1 (USER, "ElUserDlgSave: Got identity %s", pEapolMD5UI->pszIdentity);
  936. // Encrypt password, using user's ACL via Crypt API
  937. // The service will be able to decrypt it, since it has handle to
  938. // user's token
  939. if ((dwRetCode = ElSecureEncodePw (
  940. &(pEapolMD5UI->pwszPassword),
  941. &(pEapolMD5UI->PasswordBlob))) != NO_ERROR)
  942. {
  943. TRACE1 (USER, "ElUserDlgSave: ElSecureEncodePw failed with error %ld",
  944. dwRetCode);
  945. break;
  946. }
  947. }
  948. while (FALSE);
  949. if (dwRetCode != NO_ERROR)
  950. {
  951. if (pEapolMD5UI->pszIdentity != NULL)
  952. {
  953. FREE (pEapolMD5UI->pszIdentity);
  954. pEapolMD5UI->pszIdentity = NULL;
  955. }
  956. if (pEapolMD5UI->PasswordBlob.pbData != NULL)
  957. {
  958. FREE (pEapolMD5UI->PasswordBlob.pbData);
  959. pEapolMD5UI->PasswordBlob.pbData = NULL;
  960. pEapolMD5UI->PasswordBlob.cbData = 0;
  961. }
  962. }
  963. if (pEapolMD5UI->pwszPassword != NULL)
  964. {
  965. FREE (pEapolMD5UI->pwszPassword);
  966. pEapolMD5UI->pwszPassword = NULL;
  967. }
  968. return;
  969. }
  970. //
  971. // ElUserDlgTerm
  972. //
  973. // Description:
  974. //
  975. // Function handling dialog termination
  976. //
  977. // Arguments:
  978. // hwndDlg -
  979. // pInfo -
  980. //
  981. // Return values:
  982. //
  983. VOID
  984. ElUserDlgTerm (
  985. IN HWND hwndDlg,
  986. IN USERDLGINFO *pInfo
  987. )
  988. {
  989. EndDialog (hwndDlg, TRUE);
  990. FREE (pInfo);
  991. }
  992. //
  993. // ElInvokeInteractiveUIDlgWorker
  994. //
  995. // Description:
  996. //
  997. // Function called to pop-up UI dialog to user via EAP-dll
  998. //
  999. // Arguments:
  1000. //
  1001. DWORD
  1002. ElInvokeInteractiveUIDlgWorker (
  1003. IN WCHAR *pwszConnectionName,
  1004. IN VOID *pvContext
  1005. )
  1006. {
  1007. DTLLIST *pListEaps = NULL;
  1008. DTLNODE *pEapcfgNode = NULL;
  1009. EAPCFG *pEapcfg = NULL;
  1010. HANDLE hLib = NULL;
  1011. RASEAPFREE pFreeFunc = NULL;
  1012. RASEAPINVOKEINTERACTIVEUI pEapInvokeUI = NULL;
  1013. BYTE *pUIDataOut = NULL;
  1014. DWORD dwSizeOfUIDataOut = 0;
  1015. HWND hwndOwner = NULL;
  1016. EAPOL_EAP_UI_CONTEXT *pEAPUIContext = NULL;
  1017. DWORD dwEapTypeToBeUsed = 0;
  1018. EAPOLUI_RESP EapolUIResp;
  1019. DWORD dwRetCode = NO_ERROR;
  1020. do
  1021. {
  1022. TRACE0 (USER, "ElInvokeInteractiveUIDlgWorker entered");
  1023. if (pvContext == NULL)
  1024. {
  1025. dwRetCode = ERROR_INVALID_PARAMETER;
  1026. return dwRetCode;
  1027. }
  1028. pEAPUIContext = (EAPOL_EAP_UI_CONTEXT *)pvContext;
  1029. pListEaps = ReadEapcfgList (0);
  1030. if (pListEaps == NULL)
  1031. {
  1032. dwRetCode = ERROR_CAN_NOT_COMPLETE;
  1033. break;
  1034. }
  1035. pEapcfgNode = EapcfgNodeFromKey (
  1036. pListEaps,
  1037. pEAPUIContext->dwEapTypeId
  1038. );
  1039. if (pEapcfgNode == NULL)
  1040. {
  1041. dwRetCode = ERROR_CAN_NOT_COMPLETE;
  1042. break;
  1043. }
  1044. pEapcfg = (EAPCFG*) DtlGetData (pEapcfgNode);
  1045. hLib = LoadLibrary (pEapcfg->pszIdentityDll);
  1046. if (hLib == NULL)
  1047. {
  1048. dwRetCode = GetLastError ();
  1049. break;
  1050. }
  1051. dwEapTypeToBeUsed = pEAPUIContext->dwEapTypeId;
  1052. pEapInvokeUI = (RASEAPINVOKEINTERACTIVEUI) GetProcAddress
  1053. (hLib, "RasEapInvokeInteractiveUI");
  1054. pFreeFunc = (RASEAPFREE) GetProcAddress (hLib, "RasEapFreeMemory");
  1055. if ((pFreeFunc == NULL) || (pEapInvokeUI == NULL))
  1056. {
  1057. TRACE0 (USER, "ElInvokeInteractiveUIDlgWorker: pEapInvokeUI or pFreeFunc does not exist in the EAP implementation");
  1058. dwRetCode = ERROR_CAN_NOT_COMPLETE;
  1059. break;
  1060. }
  1061. // Get handle to desktop window
  1062. hwndOwner = GetDesktopWindow ();
  1063. if ((dwRetCode = (*(pEapInvokeUI))(
  1064. dwEapTypeToBeUsed,
  1065. hwndOwner, // hwndOwner
  1066. pEAPUIContext->bEapUIData,
  1067. pEAPUIContext->dwSizeOfEapUIData,
  1068. &pUIDataOut,
  1069. &dwSizeOfUIDataOut
  1070. )) != NO_ERROR)
  1071. {
  1072. TRACE1 (USER, "ElInvokeInteractiveUIDlgWorker: Error in calling InvokeInteractiveUI = %ld",
  1073. dwRetCode);
  1074. // break;
  1075. }
  1076. // Create UI Response for Service
  1077. ZeroMemory ((VOID *)&EapolUIResp, sizeof (EapolUIResp));
  1078. EapolUIResp.rdData0.dwDataLen = dwSizeOfUIDataOut;
  1079. EapolUIResp.rdData0.pData = pUIDataOut;
  1080. pEAPUIContext->dwRetCode = dwRetCode;
  1081. if ((dwRetCode = WZCEapolUIResponse (
  1082. NULL,
  1083. *pEAPUIContext,
  1084. EapolUIResp
  1085. )) != NO_ERROR)
  1086. {
  1087. TRACE1 (USER, "ElInvokeInteractiveUIDlgWorker: WZCEapolUIResponse failed with error %ld",
  1088. dwRetCode);
  1089. break;
  1090. }
  1091. TRACE0 (USER, "ElInvokeInteractiveUIDlgWorker: Calling ElEapWork");
  1092. } while (FALSE);
  1093. if (pFreeFunc != NULL)
  1094. {
  1095. if (pUIDataOut != NULL)
  1096. {
  1097. if (( dwRetCode = (*(pFreeFunc)) ((BYTE *)pUIDataOut)) != NO_ERROR)
  1098. {
  1099. TRACE1 (USER, "ElInvokeInteractiveUIDlgWorker: Error in pFreeFunc = %ld",
  1100. dwRetCode);
  1101. }
  1102. }
  1103. }
  1104. if (pListEaps != NULL)
  1105. {
  1106. DtlDestroyList(pListEaps, NULL);
  1107. }
  1108. if (hLib != NULL)
  1109. {
  1110. FreeLibrary (hLib);
  1111. }
  1112. TRACE1 (USER, "ElInvokeInteractiveUIDlgWorker completed with error %ld",
  1113. dwRetCode);
  1114. return dwRetCode;
  1115. }
  1116. //
  1117. // ElDialogCleanup
  1118. //
  1119. // Description:
  1120. //
  1121. // Function called close any old dialogs for the user
  1122. //
  1123. // Arguments:
  1124. //
  1125. DWORD
  1126. ElDialogCleanup (
  1127. IN WCHAR *pwszConnectionName,
  1128. IN VOID *pvContext
  1129. )
  1130. {
  1131. HWND hwnd = NULL;
  1132. UINT Msg;
  1133. WPARAM wparam;
  1134. LPARAM lparam;
  1135. DWORD dwRetCode = NO_ERROR;
  1136. do
  1137. {
  1138. // Find earlier instances of 802.1X windows on this interface
  1139. // Send message to quit
  1140. // SendMessage (hwnd, Msg, wparam, lparam);
  1141. }
  1142. while (FALSE);
  1143. return dwRetCode;
  1144. }