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.

1896 lines
45 KiB

  1. /*
  2. Copyright (c) 1997, Microsoft Corporation, all rights reserved
  3. Description:
  4. Sample Extensible Authentication Protocol. Here is a graphic of the EAP
  5. sample protocol:
  6. Authenticator Authenticatee
  7. ------------- -------------
  8. "Send Password"
  9. ---------------------->
  10. EAP Request
  11. <password>
  12. <----------------------
  13. EAP Response
  14. ----------------------->
  15. Success/Failure
  16. History:
  17. */
  18. #include <windows.h>
  19. #include <winuser.h>
  20. #include <lmcons.h>
  21. #include <string.h>
  22. #include <stdlib.h>
  23. #include <raseapif.h>
  24. #include <raserror.h>
  25. #include <rtutils.h>
  26. #include <stdio.h>
  27. #define SDEBUGGLOBALS
  28. #define RASEAPGLOBALS
  29. #include "eap.h"
  30. #include "resource.h"
  31. /*---------------------------------------------------------------------------
  32. External entry points
  33. ---------------------------------------------------------------------------*/
  34. /*
  35. Notes:
  36. RasEapGetInfo entry point called by the EAP-PPP engine by name.
  37. */
  38. DWORD APIENTRY
  39. RasEapGetInfo(
  40. IN DWORD dwEapTypeId,
  41. OUT PPP_EAP_INFO* pInfo
  42. )
  43. {
  44. EapTrace("RasEapGetInfo");
  45. if (dwEapTypeId != PPP_EAP_PROTOCOL_ID)
  46. {
  47. //
  48. // We only support PPP_EAP_PROTOCOL_ID eap type
  49. //
  50. EapTrace("Type ID %d is not supported", dwEapTypeId);
  51. return(ERROR_NOT_SUPPORTED);
  52. }
  53. ZeroMemory(pInfo, sizeof(PPP_EAP_INFO));
  54. //
  55. // Fill in the required information
  56. //
  57. pInfo->dwEapTypeId = PPP_EAP_PROTOCOL_ID;
  58. pInfo->RasEapBegin = EapBegin;
  59. pInfo->RasEapEnd = EapEnd;
  60. pInfo->RasEapMakeMessage = EapMakeMessage;
  61. return(NO_ERROR);
  62. }
  63. /*
  64. Notes:
  65. EapBegin entry point called by the EAP PPP engine thru the passed address.
  66. */
  67. DWORD APIENTRY
  68. EapBegin(
  69. OUT VOID** ppWorkBuf,
  70. IN VOID* pInfo
  71. )
  72. {
  73. PPP_EAP_INPUT* pInput = (PPP_EAP_INPUT*)pInfo;
  74. EAPCB* pwb;
  75. EapTrace("EapBegin(%ws)", pInput->pwszIdentity);
  76. //
  77. // Allocate work buffer.
  78. //
  79. if ((pwb = (EAPCB*)LocalAlloc(LPTR, sizeof(EAPCB))) == NULL)
  80. {
  81. EapTrace("Not enough memory");
  82. return(ERROR_NOT_ENOUGH_MEMORY);
  83. }
  84. //
  85. // Save information passed in, will be used later
  86. //
  87. pwb->fFlags = pInput->fFlags;
  88. pwb->fAuthenticator = pInput->fAuthenticator;
  89. pwb->EapState = MYSTATE_Initial;
  90. pwb->dwInitialPacketId = pInput->bInitialId;
  91. if (pInput->pDataFromInteractiveUI != NULL)
  92. {
  93. pwb->dwSizeOfDataFromInteractiveUI =
  94. pInput->dwSizeOfDataFromInteractiveUI;
  95. pwb->pDataFromInteractiveUI =
  96. LocalAlloc(LPTR, pwb->dwSizeOfDataFromInteractiveUI);
  97. if (NULL != pwb->pDataFromInteractiveUI)
  98. {
  99. CopyMemory(pwb->pDataFromInteractiveUI,
  100. pInput->pDataFromInteractiveUI,
  101. pwb->dwSizeOfDataFromInteractiveUI);
  102. }
  103. }
  104. //
  105. // Save the identity. On the authenticatee side, this is obtained by user
  106. // input; on the authenticator side this was obtained by the Identity
  107. // request message.
  108. //
  109. WideCharToMultiByte(
  110. CP_ACP,
  111. 0,
  112. pInput->pwszIdentity,
  113. -1,
  114. pwb->aszIdentity,
  115. UNLEN + 1,
  116. NULL,
  117. NULL );
  118. //
  119. // If we are an authenticatee, then use the password passed in
  120. //
  121. if (!pwb->fAuthenticator)
  122. {
  123. if ( (NULL != pInput->pUserData)
  124. && (sizeof(EAP_NAME_DIALOG) == pInput->dwSizeOfUserData))
  125. {
  126. WideCharToMultiByte(
  127. CP_ACP,
  128. 0,
  129. ((EAP_NAME_DIALOG*)(pInput->pUserData))->awszPassword,
  130. -1,
  131. pwb->aszPassword,
  132. PWLEN + 1,
  133. NULL,
  134. NULL );
  135. }
  136. }
  137. //
  138. // Register work buffer with engine.
  139. //
  140. *ppWorkBuf = pwb;
  141. return(NO_ERROR);
  142. }
  143. /*
  144. Notes:
  145. EapEnd entry point called by the PPP engine thru the passed address.
  146. See EAP interface documentation.
  147. */
  148. DWORD APIENTRY
  149. EapEnd(
  150. IN VOID* pWorkBuf
  151. )
  152. {
  153. EAPCB* pwb = (EAPCB *)pWorkBuf;
  154. if (pwb == NULL)
  155. {
  156. return(NO_ERROR);
  157. }
  158. //
  159. // Release all resources used by this authentication session.
  160. //
  161. EapTrace("EapEnd(%s)", pwb->aszIdentity);
  162. LocalFree(pwb->pUIContext);
  163. LocalFree(pwb->pDataFromInteractiveUI);
  164. if (pwb->pUserAttributes != NULL)
  165. {
  166. //
  167. // Free up Attributes
  168. //
  169. LocalFree(pwb->pUserAttributes[0].Value);
  170. LocalFree(pwb->pUserAttributes[1].Value);
  171. LocalFree(pwb->pUserAttributes);
  172. }
  173. if (pwb->pMPPEKeyAttributes != NULL)
  174. {
  175. //
  176. // Free up the MPPE Key Attributes
  177. //
  178. LocalFree(pwb->pMPPEKeyAttributes[0].Value);
  179. LocalFree(pwb->pMPPEKeyAttributes);
  180. }
  181. ZeroMemory(pwb, sizeof(EAPCB));
  182. LocalFree(pwb);
  183. return(NO_ERROR);
  184. }
  185. /*
  186. Notes:
  187. RasEapMakeMessage entry point called by the PPP engine thru the passed
  188. address.
  189. */
  190. DWORD APIENTRY
  191. EapMakeMessage(
  192. IN VOID* pWorkBuf,
  193. IN PPP_EAP_PACKET* pReceiveBuf,
  194. OUT PPP_EAP_PACKET* pSendBuf,
  195. IN DWORD cbSendBuf,
  196. OUT PPP_EAP_OUTPUT* pResult,
  197. IN PPP_EAP_INPUT* pInput
  198. )
  199. {
  200. EAPCB* pwb = (EAPCB*)pWorkBuf;
  201. EapTrace("EapMakeMessage(%s)", pwb->aszIdentity);
  202. //
  203. // Call the appropriate routine to process the event.
  204. //
  205. if (pwb->fAuthenticator)
  206. {
  207. return(AuthenticatorMakeMessage(pwb,
  208. pReceiveBuf,
  209. pSendBuf,
  210. cbSendBuf,
  211. pInput,
  212. pResult));
  213. }
  214. else
  215. {
  216. return(AuthenticateeMakeMessage(pwb,
  217. pReceiveBuf,
  218. pSendBuf,
  219. cbSendBuf,
  220. pInput,
  221. pResult));
  222. }
  223. }
  224. /*
  225. Notes:
  226. RasEapGetIdentity entry point called by the EAP-PPP engine by name.
  227. */
  228. DWORD APIENTRY
  229. RasEapGetIdentity(
  230. IN DWORD dwEapTypeId,
  231. IN HWND hwndParent,
  232. IN DWORD dwFlags,
  233. IN const WCHAR* pwszPhonebook,
  234. IN const WCHAR* pwszEntry,
  235. IN BYTE* pConnectionDataIn,
  236. IN DWORD dwSizeOfConnectionDataIn,
  237. IN BYTE* pUserDataIn,
  238. IN DWORD dwSizeOfUserDataIn,
  239. OUT BYTE** ppUserDataOut,
  240. OUT DWORD* pdwSizeOfUserDataOut,
  241. OUT WCHAR** ppwszIdentity
  242. )
  243. {
  244. DWORD dwErr = NO_ERROR;
  245. if ( dwFlags & RAS_EAP_FLAG_NON_INTERACTIVE )
  246. {
  247. dwErr = ERROR_INTERACTIVE_MODE;
  248. goto LDone;
  249. }
  250. if ( dwFlags & RAS_EAP_FLAG_MACHINE_AUTH )
  251. {
  252. dwErr = ERROR_NOT_SUPPORTED;
  253. goto LDone;
  254. }
  255. if (dwFlags & RAS_EAP_FLAG_ROUTER)
  256. {
  257. //
  258. // A routing interface must have its credentials set beforehand
  259. //
  260. if ( (NULL == pUserDataIn)
  261. || (sizeof(EAP_NAME_DIALOG) != dwSizeOfUserDataIn))
  262. {
  263. //
  264. // Bad saved credentials
  265. //
  266. EapTrace("Credentials for this interface have not been set");
  267. dwErr = E_FAIL;
  268. goto LDone;
  269. }
  270. }
  271. else
  272. {
  273. //
  274. // Ignore old values. Prompt for username and password.
  275. //
  276. pUserDataIn = NULL;
  277. }
  278. dwErr = GetIdentity(
  279. hwndParent,
  280. pUserDataIn,
  281. dwSizeOfUserDataIn,
  282. ppUserDataOut,
  283. pdwSizeOfUserDataOut,
  284. ppwszIdentity);
  285. LDone:
  286. return(dwErr);
  287. }
  288. /*
  289. Notes:
  290. RasEapInvokeConfigUI entry point called by the EAP-PPP engine by name.
  291. */
  292. DWORD APIENTRY
  293. RasEapInvokeConfigUI(
  294. IN DWORD dwEapTypeId,
  295. IN HWND hwndParent,
  296. IN DWORD dwFlags,
  297. IN BYTE* pConnectionDataIn,
  298. IN DWORD dwSizeOfConnectionDataIn,
  299. OUT BYTE** ppConnectionDataOut,
  300. OUT DWORD* pdwSizeOfConnectionDataOut
  301. )
  302. {
  303. DWORD dwDisplayedNumber;
  304. WCHAR awszMessage[100];
  305. DWORD dwErr = NO_ERROR;
  306. *ppConnectionDataOut = NULL;
  307. *pdwSizeOfConnectionDataOut = 0;
  308. if ( (NULL == pConnectionDataIn)
  309. || (0 == dwSizeOfConnectionDataIn))
  310. {
  311. //
  312. // We are configuring for the first time
  313. //
  314. dwDisplayedNumber = 1;
  315. }
  316. else
  317. {
  318. //
  319. // How many times has this been configured?
  320. //
  321. dwDisplayedNumber = *(DWORD*)pConnectionDataIn;
  322. }
  323. swprintf(awszMessage, L"%5d times", dwDisplayedNumber);
  324. MessageBox(hwndParent, awszMessage,
  325. L"You have configured this interface...", MB_OK | MB_ICONINFORMATION);
  326. //
  327. // Allocate memory for the OUT parameter
  328. //
  329. *ppConnectionDataOut = (BYTE*)LocalAlloc(LPTR, sizeof(DWORD));
  330. if (NULL == *ppConnectionDataOut)
  331. {
  332. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  333. goto LDone;
  334. }
  335. //
  336. // This has been configured one more time
  337. //
  338. dwDisplayedNumber += 1;
  339. //
  340. // Set the OUT parameters
  341. //
  342. CopyMemory(*ppConnectionDataOut, (BYTE*)&dwDisplayedNumber,
  343. sizeof(DWORD));
  344. *pdwSizeOfConnectionDataOut = sizeof(DWORD);
  345. LDone:
  346. return(dwErr);
  347. }
  348. /*
  349. Notes:
  350. RasEapInvokeInteractiveUI entry point called by the EAP-PPP engine by name.
  351. */
  352. DWORD APIENTRY
  353. RasEapInvokeInteractiveUI(
  354. IN DWORD dwEapTypeId,
  355. IN HWND hWndParent,
  356. IN PBYTE pUIContextData,
  357. IN DWORD dwSizeofUIContextData,
  358. OUT PBYTE * ppDataFromInteractiveUI,
  359. OUT DWORD * lpdwSizeOfDataFromInteractiveUI
  360. )
  361. {
  362. EapTrace("RasEapInvokeInteractiveUI");
  363. if (MessageBox(hWndParent,
  364. (WCHAR*)pUIContextData,
  365. L"EAP sample",
  366. MB_OKCANCEL) == IDOK)
  367. {
  368. *lpdwSizeOfDataFromInteractiveUI = (wcslen(L"OK") + 1) * sizeof(WCHAR);
  369. if ((*ppDataFromInteractiveUI =
  370. LocalAlloc(LPTR, *lpdwSizeOfDataFromInteractiveUI)) == NULL)
  371. {
  372. return(ERROR_NOT_ENOUGH_MEMORY);
  373. }
  374. wcsncpy((WCHAR*)*ppDataFromInteractiveUI, L"OK", (*lpdwSizeOfDataFromInteractiveUI) - 1);
  375. }
  376. else
  377. {
  378. *ppDataFromInteractiveUI = NULL;
  379. *lpdwSizeOfDataFromInteractiveUI = 0;
  380. }
  381. return(NO_ERROR);
  382. }
  383. /*
  384. Notes:
  385. RasEapFreeMemory entry point called by the EAP-PPP engine by name.
  386. */
  387. DWORD APIENTRY
  388. RasEapFreeMemory(
  389. IN BYTE* pMemory
  390. )
  391. {
  392. EapTrace("RasEapFreeMemory");
  393. LocalFree(pMemory);
  394. return(NO_ERROR);
  395. }
  396. /*---------------------------------------------------------------------------
  397. Internal routines
  398. ---------------------------------------------------------------------------*/
  399. /*
  400. Notes:
  401. Print debug information.
  402. */
  403. VOID
  404. EapTrace(
  405. IN CHAR* Format,
  406. ...
  407. )
  408. {
  409. va_list arglist;
  410. va_start(arglist, Format);
  411. TraceVprintfExA(g_dwEapTraceId,
  412. 0x00010000 | TRACE_USE_MASK | TRACE_USE_MSEC,
  413. Format,
  414. arglist);
  415. va_end(arglist);
  416. }
  417. /*
  418. Notes:
  419. Will convert a 32 bit integer from host format to wire format.
  420. */
  421. VOID
  422. HostToWireFormat32(
  423. IN DWORD dwHostFormat,
  424. IN OUT PBYTE pWireFormat
  425. )
  426. {
  427. *((PBYTE)(pWireFormat)+0) = (BYTE) ((DWORD)(dwHostFormat) >> 24);
  428. *((PBYTE)(pWireFormat)+1) = (BYTE) ((DWORD)(dwHostFormat) >> 16);
  429. *((PBYTE)(pWireFormat)+2) = (BYTE) ((DWORD)(dwHostFormat) >> 8);
  430. *((PBYTE)(pWireFormat)+3) = (BYTE) (dwHostFormat);
  431. }
  432. /*
  433. Notes:
  434. Will convert a 16 bit integer from host format to wire format.
  435. */
  436. VOID
  437. HostToWireFormat16(
  438. IN WORD wHostFormat,
  439. IN OUT PBYTE pWireFormat
  440. )
  441. {
  442. *((PBYTE)(pWireFormat)+0) = (BYTE) ((DWORD)(wHostFormat) >> 8);
  443. *((PBYTE)(pWireFormat)+1) = (BYTE) (wHostFormat);
  444. }
  445. /*
  446. Notes:
  447. Will convert a 16 bit integer from wire format to host format.
  448. */
  449. WORD
  450. WireToHostFormat16(
  451. IN PBYTE pWireFormat
  452. )
  453. {
  454. WORD wHostFormat = ((*((PBYTE)(pWireFormat)+0) << 8) +
  455. (*((PBYTE)(pWireFormat)+1)));
  456. return(wHostFormat);
  457. }
  458. /*
  459. Notes:
  460. Authenticatee side event handler.
  461. */
  462. DWORD
  463. AuthenticateeMakeMessage(
  464. IN EAPCB* pwb,
  465. IN PPP_EAP_PACKET* pReceiveBuf,
  466. OUT PPP_EAP_PACKET* pSendBuf,
  467. IN DWORD cbSendBuf,
  468. IN PPP_EAP_INPUT* pInput,
  469. OUT PPP_EAP_OUTPUT* pResult
  470. )
  471. {
  472. DWORD dwRetCode = NO_ERROR;
  473. BYTE* pDataFromInteractiveUI;
  474. DWORD dwSizeOfDataFromInteractiveUI;
  475. EapTrace("AuthenticateeMakeMessage");
  476. switch(pwb->EapState)
  477. {
  478. case MYSTATE_Initial:
  479. if (pwb->fFlags & RAS_EAP_FLAG_ROUTER)
  480. {
  481. pwb->EapState = MYSTATE_WaitForRequest;
  482. break;
  483. }
  484. pwb->bRecvPacketId = pReceiveBuf->Id;
  485. if (NULL == pwb->pDataFromInteractiveUI)
  486. {
  487. WCHAR * pUIContextData = L"You are being authenticated by a Sample EAP";
  488. //
  489. // Bring up interactive UI to notify user that he/she is being
  490. // authenticated via the sample EAP
  491. //
  492. pResult->fInvokeInteractiveUI = TRUE;
  493. pResult->dwSizeOfUIContextData =
  494. (wcslen(pUIContextData)+1) *
  495. sizeof(WCHAR);
  496. pResult->pUIContextData = LocalAlloc(
  497. LPTR,
  498. pResult->dwSizeOfUIContextData);
  499. if (pResult->pUIContextData == NULL)
  500. {
  501. EapTrace("OUt of memory");
  502. return(ERROR_NOT_ENOUGH_MEMORY);
  503. }
  504. wcsncpy((WCHAR*)pResult->pUIContextData,
  505. pUIContextData,
  506. wcslen(pUIContextData)
  507. );
  508. pwb->pUIContext = pResult->pUIContextData;
  509. pwb->EapState = MYSTATE_WaitForUserOK;
  510. break;
  511. }
  512. //
  513. // Else, fall through
  514. //
  515. case MYSTATE_WaitForUserOK:
  516. //
  517. // Wait for response from user
  518. //
  519. if ( pInput->fDataReceivedFromInteractiveUI
  520. || (NULL != pwb->pDataFromInteractiveUI))
  521. {
  522. if (pInput->fDataReceivedFromInteractiveUI)
  523. {
  524. pDataFromInteractiveUI =
  525. pInput->pDataFromInteractiveUI;
  526. dwSizeOfDataFromInteractiveUI =
  527. pInput->dwSizeOfDataFromInteractiveUI;
  528. }
  529. else
  530. {
  531. pDataFromInteractiveUI =
  532. pwb->pDataFromInteractiveUI;
  533. dwSizeOfDataFromInteractiveUI =
  534. pwb->dwSizeOfDataFromInteractiveUI;
  535. }
  536. LocalFree(pwb->pUIContext);
  537. pwb->pUIContext = NULL;
  538. //
  539. // If user doesn't like this, then we hangup the line
  540. //
  541. if (dwSizeOfDataFromInteractiveUI !=
  542. (wcslen(L"OK")+1) * sizeof(WCHAR))
  543. {
  544. EapTrace("User chose to cancel");
  545. dwRetCode = ERROR_ACCESS_DENIED;
  546. break;
  547. }
  548. if (wcscmp((WCHAR*)pDataFromInteractiveUI, L"OK") != 0)
  549. {
  550. EapTrace("User chose to cancel");
  551. dwRetCode = ERROR_ACCESS_DENIED;
  552. break;
  553. }
  554. pwb->EapState = MYSTATE_WaitForRequest;
  555. }
  556. else
  557. {
  558. //
  559. // Ignore all other events.
  560. //
  561. pResult->Action = EAPACTION_NoAction;
  562. }
  563. if ( !(pwb->fFlags & RAS_EAP_FLAG_8021X_AUTH ) )
  564. {
  565. //
  566. // if this is a VPN client, we can rely on
  567. // retransmission. But with wireless client
  568. // we cannot do that.
  569. //
  570. break;
  571. }
  572. //fall thru
  573. case MYSTATE_WaitForRequest:
  574. if ( (pwb->fFlags & RAS_EAP_FLAG_8021X_AUTH ) )
  575. {
  576. //
  577. // Build the response packet
  578. //
  579. MakeResponseMessage1(pwb, pSendBuf, cbSendBuf);
  580. //
  581. // Response packets should not be sent with any timeout
  582. //
  583. pResult->Action = EAPACTION_Send;
  584. //
  585. // We are done so we change to MYSTATE_Done
  586. //
  587. pwb->EapState = MYSTATE_Done;
  588. break;
  589. }
  590. else if (pReceiveBuf != NULL )
  591. {
  592. //
  593. // If we received a request packet from the server then we
  594. // process it.
  595. //
  596. if (pReceiveBuf->Code == EAPCODE_Request)
  597. {
  598. //
  599. // Build the response packet
  600. //
  601. MakeResponseMessage(pwb, pReceiveBuf, pSendBuf, cbSendBuf);
  602. //
  603. // Response packets should not be sent with any timeout
  604. //
  605. pResult->Action = EAPACTION_Send;
  606. //
  607. // We are done so we change to MYSTATE_Done
  608. //
  609. pwb->EapState = MYSTATE_Done;
  610. break;
  611. }
  612. else
  613. {
  614. //
  615. // We shouldn't get any other packet in this state so
  616. // we simply drop this invalid packet
  617. //
  618. pResult->Action = EAPACTION_NoAction;
  619. dwRetCode = ERROR_PPP_INVALID_PACKET;
  620. break;
  621. }
  622. }
  623. break;
  624. case MYSTATE_Done:
  625. {
  626. if (pReceiveBuf == NULL)
  627. {
  628. //
  629. // If we did not receive a packet then we check to see if
  630. // the fSuccessPacketReceived flag is set
  631. //
  632. if ((pInput != NULL) && (pInput->fSuccessPacketReceived))
  633. {
  634. //
  635. // We are done
  636. //
  637. //
  638. // Create the MPPE Key Attribute and give it to the EAP-PPP
  639. // engine.
  640. //
  641. dwRetCode = MakeMPPEKeyAttributes(pwb);
  642. if (NO_ERROR == dwRetCode)
  643. {
  644. pResult->pUserAttributes = pwb->pMPPEKeyAttributes;
  645. }
  646. pResult->Action = EAPACTION_Done;
  647. pwb->EapState = MYSTATE_Done;
  648. }
  649. else
  650. {
  651. //
  652. // Otherwise we ignore this event
  653. //
  654. pResult->Action = EAPACTION_NoAction;
  655. }
  656. break;
  657. }
  658. if ((pReceiveBuf->Code == EAPCODE_Success) ||
  659. (pReceiveBuf->Code == EAPCODE_Failure))
  660. {
  661. if (pReceiveBuf->Code == EAPCODE_Success)
  662. {
  663. //
  664. // If we received success or failure, we are done, but first
  665. // make sure the ID's match
  666. //
  667. //
  668. // Create the MPPE Key Attribute and give it to the EAP-PPP
  669. // engine.
  670. //
  671. dwRetCode = MakeMPPEKeyAttributes(pwb);
  672. if (NO_ERROR == dwRetCode)
  673. {
  674. pResult->pUserAttributes = pwb->pMPPEKeyAttributes;
  675. }
  676. pResult->Action = EAPACTION_Done;
  677. pwb->EapState = MYSTATE_Done;
  678. }
  679. else
  680. {
  681. //
  682. // Otherwise drop the packet
  683. //
  684. pResult->Action = EAPACTION_NoAction;
  685. dwRetCode = ERROR_PPP_INVALID_PACKET;
  686. }
  687. break;
  688. }
  689. else if (pReceiveBuf->Code == EAPCODE_Request)
  690. {
  691. //
  692. // We must always respond to requests
  693. //
  694. MakeResponseMessage(pwb, pReceiveBuf, pSendBuf, cbSendBuf);
  695. //
  696. // Response packets should not be sent with any timeout
  697. //
  698. pResult->Action = EAPACTION_Send;
  699. }
  700. else
  701. {
  702. //
  703. // Otherwise we received an illegal packet, wrong code set
  704. // So simply drop the packet.
  705. //
  706. pResult->Action = EAPACTION_NoAction;
  707. dwRetCode = ERROR_PPP_INVALID_PACKET;
  708. }
  709. }
  710. }
  711. return(dwRetCode);
  712. }
  713. VOID
  714. MakeResponseMessage1(
  715. IN EAPCB* pwb,
  716. OUT PPP_EAP_PACKET * pSendBuf,
  717. IN DWORD cbSendBuf
  718. )
  719. {
  720. BYTE* pcbPassword;
  721. CHAR* pchPassword;
  722. EapTrace("MakeResponseMessage1");
  723. (void)cbSendBuf;
  724. //
  725. // Fill in the password.
  726. //
  727. pcbPassword = pSendBuf->Data + 1;
  728. *pcbPassword = (BYTE)strlen(pwb->aszPassword);
  729. pchPassword = pcbPassword + 1;
  730. strcpy(pchPassword, pwb->aszPassword);
  731. //
  732. // Set the response code
  733. //
  734. pSendBuf->Code = (BYTE)EAPCODE_Response;
  735. //
  736. // The Reponse packet Id MUST match the Request packet Id.
  737. //
  738. pSendBuf->Id = pwb->bRecvPacketId;
  739. //
  740. // The Success/Failure packet that we get must match the ID of the last
  741. // response sent
  742. //
  743. pwb->dwIdExpected = pSendBuf->Id;
  744. //
  745. // Set the EAP type ID
  746. //
  747. pSendBuf->Data[0] = (BYTE)PPP_EAP_PROTOCOL_ID;
  748. //
  749. // Set the length of the packet
  750. //
  751. HostToWireFormat16((WORD)(PPP_EAP_PACKET_HDR_LEN+1+*pcbPassword+1),
  752. pSendBuf->Length);
  753. }
  754. /*
  755. Notes:
  756. Builds a response packet. 'pwb' is the address of the work
  757. buffer associated with the port.
  758. */
  759. VOID
  760. MakeResponseMessage(
  761. IN EAPCB* pwb,
  762. IN PPP_EAP_PACKET * pReceiveBuf,
  763. OUT PPP_EAP_PACKET * pSendBuf,
  764. IN DWORD cbSendBuf
  765. )
  766. {
  767. BYTE* pcbPassword;
  768. CHAR* pchPassword;
  769. EapTrace("MakeResponseMessage");
  770. (void)cbSendBuf;
  771. //
  772. // Fill in the password.
  773. //
  774. pcbPassword = pSendBuf->Data + 1;
  775. *pcbPassword = (BYTE)strlen(pwb->aszPassword);
  776. pchPassword = pcbPassword + 1;
  777. strcpy(pchPassword, pwb->aszPassword);
  778. //
  779. // Set the response code
  780. //
  781. pSendBuf->Code = (BYTE)EAPCODE_Response;
  782. //
  783. // The Reponse packet Id MUST match the Request packet Id.
  784. //
  785. pSendBuf->Id = pReceiveBuf->Id;
  786. //
  787. // The Success/Failure packet that we get must match the ID of the last
  788. // response sent
  789. //
  790. pwb->dwIdExpected = pSendBuf->Id;
  791. //
  792. // Set the EAP type ID
  793. //
  794. pSendBuf->Data[0] = (BYTE)PPP_EAP_PROTOCOL_ID;
  795. //
  796. // Set the length of the packet
  797. //
  798. HostToWireFormat16((WORD)(PPP_EAP_PACKET_HDR_LEN+1+*pcbPassword+1),
  799. pSendBuf->Length);
  800. }
  801. /*
  802. Notes:
  803. Builds a result packet (Success or Failure) in caller's 'pSendBuf'
  804. buffer. 'cbSendBuf' is the length of caller's buffer.
  805. 'dwError' indicates whether an Success or Failure should be generated,
  806. 'bId' is the Id of the Success of Failure packet.
  807. */
  808. VOID
  809. MakeResultMessage(
  810. IN EAPCB * pwb,
  811. IN DWORD dwError,
  812. OUT PPP_EAP_PACKET* pSendBuf,
  813. IN DWORD cbSendBuf
  814. )
  815. {
  816. EapTrace("MakeResultMessage");
  817. (void)cbSendBuf;
  818. //
  819. // If there was no error then we send a Success packet, otherwise we send
  820. // a failure message
  821. //
  822. if (dwError == NO_ERROR)
  823. {
  824. pSendBuf->Code = EAPCODE_Success;
  825. }
  826. else
  827. {
  828. pSendBuf->Code = EAPCODE_Failure;
  829. }
  830. //
  831. // The Id of a success or failure message MUST match the Id of the last
  832. // response received from the client according to the EAP spec.
  833. //
  834. pSendBuf->Id = (BYTE)pwb->dwInitialPacketId;
  835. //
  836. // Set the length
  837. //
  838. HostToWireFormat16((WORD)PPP_EAP_PACKET_HDR_LEN, (PBYTE)pSendBuf->Length);
  839. }
  840. /*
  841. Notes:
  842. Will build a request packet.
  843. */
  844. VOID
  845. MakeRequestMessage(
  846. IN EAPCB* pwb,
  847. OUT PPP_EAP_PACKET * pSendBuf,
  848. IN DWORD cbSendBuf
  849. )
  850. {
  851. BYTE *pcbPeerMessage;
  852. CHAR *pchPeerMessage;
  853. EapTrace("MakeRequestMessage");
  854. pcbPeerMessage = pSendBuf->Data + 1;
  855. *pcbPeerMessage = (BYTE)strlen("send password");
  856. pchPeerMessage = pcbPeerMessage + 1;
  857. strncpy(pchPeerMessage, "send password", strlen ("send password"));
  858. //
  859. // Set the Request Code
  860. //
  861. pSendBuf->Code = EAPCODE_Request;
  862. //
  863. // Set the request packet identifier. Start with the Id that was give to us
  864. //
  865. pSendBuf->Id = (BYTE)pwb->dwInitialPacketId;
  866. //
  867. // Set the length
  868. //
  869. HostToWireFormat16((WORD)(PPP_EAP_PACKET_HDR_LEN+1+*pcbPeerMessage+1),
  870. pSendBuf->Length);
  871. //
  872. // Set the EAP Type Id
  873. //
  874. pSendBuf->Data[0] = PPP_EAP_PROTOCOL_ID;
  875. }
  876. /*
  877. Notes:
  878. Authenticator side event handler.
  879. */
  880. DWORD
  881. AuthenticatorMakeMessage(
  882. IN EAPCB* pwb,
  883. IN PPP_EAP_PACKET* pReceiveBuf,
  884. OUT PPP_EAP_PACKET* pSendBuf,
  885. IN DWORD cbSendBuf,
  886. IN PPP_EAP_INPUT* pInput,
  887. OUT PPP_EAP_OUTPUT* pResult
  888. )
  889. {
  890. DWORD dwRetCode = NO_ERROR;
  891. EapTrace("AuthenticatorMakeMessage");
  892. switch(pwb->EapState)
  893. {
  894. case MYSTATE_ReqSent:
  895. if (pReceiveBuf != NULL)
  896. {
  897. //
  898. // If we received a packet
  899. //
  900. if (pReceiveBuf->Code == EAPCODE_Response)
  901. {
  902. //
  903. // If we received a response to our identity request,
  904. // then process it. There is no need to check the Id
  905. // here since the PPP engine will only pass on packets
  906. // whose Id matches those set with the
  907. // EAPACTION_SendWithTimeout action.
  908. //
  909. dwRetCode = GetPasswordFromResponse(pReceiveBuf,
  910. pwb->aszPassword);
  911. if (dwRetCode != NO_ERROR)
  912. {
  913. if (dwRetCode != ERROR_PPP_INVALID_PACKET)
  914. {
  915. //
  916. // Fatal error, we fail the connection.
  917. //
  918. return(dwRetCode);
  919. }
  920. }
  921. else
  922. {
  923. //
  924. // Request authentication provider to authenticate
  925. // this user.
  926. //
  927. dwRetCode = MakeAuthenticationAttributes(
  928. pwb->aszIdentity,
  929. pwb->aszPassword,
  930. pwb);
  931. if (dwRetCode != NO_ERROR)
  932. {
  933. return(dwRetCode);
  934. }
  935. else
  936. {
  937. //
  938. // Authentication request completed successfully.
  939. // This is an asynchronous call so we change state
  940. // and wait for the provider to complete the
  941. // authentication.
  942. //
  943. pResult->pUserAttributes = pwb->pUserAttributes;
  944. pResult->Action = EAPACTION_Authenticate;
  945. //
  946. // Save Id so that we can send the correct one
  947. // in the success/failure packet
  948. //
  949. pwb->dwIdExpected = pReceiveBuf->Id;
  950. pwb->EapState =
  951. MYSTATE_WaitForAuthenticationToComplete;
  952. }
  953. }
  954. break;
  955. }
  956. else
  957. {
  958. //
  959. // Otherwise silently drop the packet.
  960. // We should only get requests
  961. //
  962. pResult->Action = EAPACTION_NoAction;
  963. break;
  964. }
  965. }
  966. break;
  967. case MYSTATE_Initial:
  968. //
  969. // Create Request packet
  970. //
  971. MakeRequestMessage(pwb, pSendBuf, cbSendBuf);
  972. //
  973. // Request messages must be sent with a timeout
  974. //
  975. pResult->Action = EAPACTION_SendWithTimeoutInteractive;
  976. //
  977. // Since we have sent a request we change to the ReqSent state
  978. // where we will wait for a response.
  979. //
  980. pwb->EapState = MYSTATE_ReqSent;
  981. break;
  982. case MYSTATE_WaitForAuthenticationToComplete:
  983. {
  984. if (pInput != NULL)
  985. {
  986. //
  987. // Did the authentication provider complete the authentication?
  988. //
  989. if (pInput->fAuthenticationComplete)
  990. {
  991. //
  992. // If the user failed to authenticate, save the failure
  993. // code.
  994. //
  995. if (pInput->dwAuthResultCode != NO_ERROR)
  996. {
  997. pwb->dwResult = pInput->dwAuthResultCode;
  998. }
  999. pResult->Action = EAPACTION_SendAndDone;
  1000. pwb->EapState = MYSTATE_Done;
  1001. //
  1002. // fall thru to the MYSTATE_Done state where we will
  1003. // send a Success or Failure packet
  1004. //
  1005. }
  1006. }
  1007. if ((pInput == NULL) || (!pInput->fAuthenticationComplete))
  1008. {
  1009. //
  1010. // Ignore everything if authentication is not complete
  1011. //
  1012. pResult->Action = EAPACTION_NoAction;
  1013. break;
  1014. }
  1015. //
  1016. // ...fall thru to the MYSTATE_Done state where we will
  1017. // send a Success or Failure packet
  1018. //
  1019. }
  1020. case MYSTATE_Done:
  1021. {
  1022. //
  1023. // Make Success or Failure packet.
  1024. //
  1025. MakeResultMessage(pwb, pwb->dwResult, pSendBuf, cbSendBuf);
  1026. if (NO_ERROR == pwb->dwResult)
  1027. {
  1028. //
  1029. // If we made a Success packet, create the MPPE Key Attribute
  1030. // and give it to the EAP-PPP engine.
  1031. //
  1032. dwRetCode = MakeMPPEKeyAttributes(pwb);
  1033. if (NO_ERROR == dwRetCode)
  1034. {
  1035. pResult->pUserAttributes = pwb->pMPPEKeyAttributes;
  1036. }
  1037. }
  1038. pResult->Action = EAPACTION_SendAndDone;
  1039. pResult->dwAuthResultCode = pwb->dwResult;
  1040. break;
  1041. }
  1042. default:
  1043. break;
  1044. }
  1045. return(dwRetCode);
  1046. }
  1047. /*
  1048. Notes:
  1049. Fill caller's pszPassword' buffer with the password, in the request
  1050. packet.
  1051. Returns NO_ERROR if successful., or ERROR_PPP_INVALID_PACKET if the
  1052. packet is misformatted in any way.
  1053. */
  1054. DWORD
  1055. GetPasswordFromResponse(
  1056. IN PPP_EAP_PACKET* pReceiveBuf,
  1057. OUT CHAR* pszPassword
  1058. )
  1059. {
  1060. BYTE* pcbPassword;
  1061. CHAR* pchPassword;
  1062. WORD cbPacket;
  1063. EapTrace("GetPasswordFromResponse");
  1064. cbPacket = WireToHostFormat16(pReceiveBuf->Length);
  1065. //
  1066. // Extract the password
  1067. //
  1068. if (cbPacket < (PPP_EAP_PACKET_HDR_LEN + 1 + 1))
  1069. {
  1070. EapTrace("Number of bytes in the EAP packet is only %d", cbPacket);
  1071. return(ERROR_PPP_INVALID_PACKET);
  1072. }
  1073. pcbPassword = pReceiveBuf->Data + 1;
  1074. pchPassword = pcbPassword + 1;
  1075. if (cbPacket < PPP_EAP_PACKET_HDR_LEN + 1 + 1 + *pcbPassword)
  1076. {
  1077. EapTrace("Number of characters in password is %d", *pcbPassword);
  1078. EapTrace("Number of bytes in the EAP packet is only %d", cbPacket);
  1079. return ERROR_PPP_INVALID_PACKET;
  1080. }
  1081. if ( *pcbPassword > PWLEN )
  1082. {
  1083. EapTrace ("Password length received in the packet is > PWLEN" );
  1084. return ERROR_PPP_INVALID_PACKET;
  1085. }
  1086. CopyMemory(pszPassword, pchPassword, *pcbPassword);
  1087. //
  1088. // NULL terminate the password
  1089. //
  1090. pszPassword[ *pcbPassword ] = '\0';
  1091. return(NO_ERROR);
  1092. }
  1093. /*
  1094. Notes:
  1095. Will build user attributes and send them to the authentication provider
  1096. for authentication.
  1097. */
  1098. DWORD
  1099. MakeAuthenticationAttributes(
  1100. IN CHAR * szUserName,
  1101. IN CHAR * szPassword,
  1102. IN EAPCB * pwb
  1103. )
  1104. {
  1105. EapTrace("MakeAuthenticationAttributes");
  1106. if (pwb->pUserAttributes != NULL)
  1107. {
  1108. LocalFree(pwb->pUserAttributes[0].Value);
  1109. LocalFree(pwb->pUserAttributes[1].Value);
  1110. LocalFree(pwb->pUserAttributes);
  1111. pwb->pUserAttributes = NULL;
  1112. }
  1113. pwb->pUserAttributes = (RAS_AUTH_ATTRIBUTE *)
  1114. LocalAlloc(LPTR, sizeof (RAS_AUTH_ATTRIBUTE) * 3);
  1115. if (pwb->pUserAttributes == NULL)
  1116. {
  1117. return(GetLastError());
  1118. }
  1119. //
  1120. // for user name
  1121. //
  1122. pwb->pUserAttributes[0].raaType = raatUserName;
  1123. pwb->pUserAttributes[0].dwLength = strlen(szUserName);
  1124. pwb->pUserAttributes[0].Value = LocalAlloc(LPTR, (strlen(szUserName)+1));
  1125. if (pwb->pUserAttributes[0].Value == NULL)
  1126. {
  1127. LocalFree(pwb->pUserAttributes);
  1128. pwb->pUserAttributes = NULL;
  1129. return(GetLastError());
  1130. }
  1131. CopyMemory(pwb->pUserAttributes[0].Value,szUserName, strlen(szUserName));
  1132. //
  1133. // for password
  1134. //
  1135. pwb->pUserAttributes[1].raaType = raatUserPassword;
  1136. pwb->pUserAttributes[1].dwLength = strlen(szPassword);
  1137. pwb->pUserAttributes[1].Value = LocalAlloc(LPTR, (strlen(szPassword)+1));
  1138. if (pwb->pUserAttributes[1].Value == NULL)
  1139. {
  1140. LocalFree(pwb->pUserAttributes[0].Value);
  1141. LocalFree(pwb->pUserAttributes);
  1142. pwb->pUserAttributes = NULL;
  1143. return(GetLastError());
  1144. }
  1145. CopyMemory(pwb->pUserAttributes[1].Value,szPassword, strlen(szPassword));
  1146. //
  1147. // For Termination
  1148. //
  1149. pwb->pUserAttributes[2].raaType = raatMinimum;
  1150. pwb->pUserAttributes[2].dwLength = 0;
  1151. pwb->pUserAttributes[2].Value = NULL;
  1152. return(NO_ERROR);
  1153. }
  1154. /*
  1155. Notes:
  1156. */
  1157. DWORD
  1158. MakeMPPEKeyAttributes(
  1159. IN EAPCB * pwb
  1160. )
  1161. {
  1162. DWORD dwErr = NO_ERROR;
  1163. DWORD dwIndex;
  1164. DWORD dwSendPattern;
  1165. DWORD dwRecvPattern;
  1166. BYTE* pByte;
  1167. EapTrace("MakeMPPEKeyAttributes");
  1168. if (NULL != pwb->pMPPEKeyAttributes)
  1169. {
  1170. //
  1171. // Free up the MPPE Key Attributes if they exist
  1172. //
  1173. LocalFree(pwb->pMPPEKeyAttributes[0].Value);
  1174. LocalFree(pwb->pMPPEKeyAttributes[1].Value);
  1175. LocalFree(pwb->pMPPEKeyAttributes);
  1176. pwb->pMPPEKeyAttributes = NULL;
  1177. }
  1178. //
  1179. // We need 3 RAS_AUTH_ATTRIBUTE structs: for MS-MPPE-Send-Key,
  1180. // MS-MPPE-Recv-Key, and termination
  1181. //
  1182. pwb->pMPPEKeyAttributes = (RAS_AUTH_ATTRIBUTE *) LocalAlloc(
  1183. LPTR, sizeof(RAS_AUTH_ATTRIBUTE) * 3);
  1184. if (NULL == pwb->pMPPEKeyAttributes)
  1185. {
  1186. dwErr = GetLastError();
  1187. goto LDone;
  1188. }
  1189. if (pwb->fAuthenticator)
  1190. {
  1191. dwSendPattern = 0xAB;
  1192. dwRecvPattern = 0xCD;
  1193. }
  1194. else
  1195. {
  1196. dwSendPattern = 0xCD;
  1197. dwRecvPattern = 0xAB;
  1198. }
  1199. //
  1200. // Bytes needed:
  1201. // 4: Vendor-Id
  1202. // 1: Vendor-Type
  1203. // 1: Vendor-Length
  1204. // 2: Salt
  1205. // 1: Key-Length
  1206. // 32: Key
  1207. // 15: Padding
  1208. // -----------------
  1209. // 56: Total
  1210. //
  1211. //
  1212. // Copy MS-MPPE-Send-Key
  1213. //
  1214. pwb->pMPPEKeyAttributes[0].Value = LocalAlloc(LPTR, 56);
  1215. if (pwb->pMPPEKeyAttributes[0].Value == NULL)
  1216. {
  1217. dwErr = GetLastError();
  1218. goto LDone;
  1219. }
  1220. pByte = pwb->pMPPEKeyAttributes[0].Value;
  1221. HostToWireFormat32(311, pByte); // Vendor-Id
  1222. pByte[4] = 16; // Vendor-Type (MS-MPPE-Send-Key)
  1223. pByte[5] = 56 - 4; // Vendor-Length (all except Vendor-Id)
  1224. // pByte[6-7] is the zero-filled salt field
  1225. pByte[8] = 32; // Key-Length
  1226. {
  1227. //
  1228. // This is just an example. Copy a real key here.
  1229. //
  1230. CopyMemory(pByte + 9, pwb->aszPassword, 32);
  1231. for (dwIndex = 0; dwIndex < 32; dwIndex++)
  1232. {
  1233. pByte[9 + dwIndex] ^= dwSendPattern;
  1234. }
  1235. }
  1236. // pByte[41-55] is the Padding (zero octets)
  1237. pwb->pMPPEKeyAttributes[0].dwLength = 56;
  1238. pwb->pMPPEKeyAttributes[0].raaType = raatVendorSpecific;
  1239. //
  1240. // Copy MS-MPPE-Recv-Key
  1241. //
  1242. pwb->pMPPEKeyAttributes[1].Value = LocalAlloc(LPTR, 56);
  1243. if (pwb->pMPPEKeyAttributes[1].Value == NULL)
  1244. {
  1245. dwErr = GetLastError();
  1246. goto LDone;
  1247. }
  1248. pByte = pwb->pMPPEKeyAttributes[1].Value;
  1249. HostToWireFormat32(311, pByte); // Vendor-Id
  1250. pByte[4] = 17; // Vendor-Type (MS-MPPE-Recv-Key)
  1251. pByte[5] = 56 - 4; // Vendor-Length (all except Vendor-Id)
  1252. // pByte[6-7] is the zero-filled salt field
  1253. pByte[8] = 32; // Key-Length
  1254. {
  1255. //
  1256. // This is just an example. Copy a real key here.
  1257. //
  1258. CopyMemory(pByte + 9, pwb->aszPassword, 32);
  1259. for (dwIndex = 0; dwIndex < 32; dwIndex++)
  1260. {
  1261. pByte[9 + dwIndex] ^= dwRecvPattern;
  1262. }
  1263. }
  1264. // pByte[41-55] is the Padding (zero octets)
  1265. pwb->pMPPEKeyAttributes[1].dwLength = 56;
  1266. pwb->pMPPEKeyAttributes[1].raaType = raatVendorSpecific;
  1267. //
  1268. // For Termination
  1269. //
  1270. pwb->pMPPEKeyAttributes[2].raaType = raatMinimum;
  1271. pwb->pMPPEKeyAttributes[2].dwLength = 0;
  1272. pwb->pMPPEKeyAttributes[2].Value = NULL;
  1273. LDone:
  1274. if (NO_ERROR != dwErr)
  1275. {
  1276. //
  1277. // If something failed, free the allocated memory
  1278. //
  1279. if (pwb->pMPPEKeyAttributes != NULL)
  1280. {
  1281. LocalFree(pwb->pMPPEKeyAttributes[0].Value);
  1282. LocalFree(pwb->pMPPEKeyAttributes[1].Value);
  1283. LocalFree(pwb->pMPPEKeyAttributes);
  1284. pwb->pMPPEKeyAttributes = NULL;
  1285. }
  1286. }
  1287. return(dwErr);
  1288. }
  1289. /*
  1290. Notes:
  1291. */
  1292. DWORD
  1293. GetIdentity(
  1294. IN HWND hwndParent,
  1295. IN BYTE* pUserDataIn,
  1296. IN DWORD dwSizeOfUserDataIn,
  1297. OUT BYTE** ppUserDataOut,
  1298. OUT DWORD* pdwSizeOfUserDataOut,
  1299. OUT WCHAR** ppwszIdentity
  1300. )
  1301. {
  1302. EAP_NAME_DIALOG* pEapNameDialog = NULL;
  1303. WCHAR* pwszIdentity = NULL;
  1304. DWORD dwErr = NO_ERROR;
  1305. //
  1306. // Allocate memory for OUT parameters
  1307. //
  1308. pEapNameDialog = LocalAlloc(LPTR, sizeof(EAP_NAME_DIALOG));
  1309. if (NULL == pEapNameDialog)
  1310. {
  1311. EapTrace("Out of memory");
  1312. dwErr = GetLastError();
  1313. goto LDone;
  1314. }
  1315. pwszIdentity = LocalAlloc(LPTR, (UNLEN + 1) * sizeof(WCHAR));
  1316. if (NULL == pwszIdentity)
  1317. {
  1318. EapTrace("Out of memory");
  1319. dwErr = GetLastError();
  1320. goto LDone;
  1321. }
  1322. if (NULL != pUserDataIn)
  1323. {
  1324. //
  1325. // Use the saved credentials if they exist
  1326. //
  1327. CopyMemory(pEapNameDialog, pUserDataIn, sizeof(EAP_NAME_DIALOG));
  1328. }
  1329. else
  1330. {
  1331. //
  1332. // Else prompt for username and password
  1333. //
  1334. GetUsernameAndPassword(hwndParent, pEapNameDialog);
  1335. }
  1336. wcscpy(pwszIdentity, pEapNameDialog->awszIdentity);
  1337. //
  1338. // Set the OUT paramters
  1339. //
  1340. *ppUserDataOut = (BYTE*)pEapNameDialog;
  1341. *pdwSizeOfUserDataOut = sizeof(EAP_NAME_DIALOG);
  1342. *ppwszIdentity = pwszIdentity;
  1343. //
  1344. // We mustn't LocalFree OUT parameters
  1345. //
  1346. pEapNameDialog = NULL;
  1347. pwszIdentity = NULL;
  1348. LDone:
  1349. LocalFree(pEapNameDialog);
  1350. LocalFree(pwszIdentity);
  1351. return(dwErr);
  1352. }
  1353. /*---------------------------------------------------------------------------
  1354. Dialog routines
  1355. ---------------------------------------------------------------------------*/
  1356. /*
  1357. Notes:
  1358. Displays the IDD_DIALOG dialog, and fills up pEapNameDialog with the
  1359. username and password.
  1360. */
  1361. VOID
  1362. GetUsernameAndPassword(
  1363. IN HWND hwndParent,
  1364. IN EAP_NAME_DIALOG* pEapNameDialog
  1365. )
  1366. {
  1367. DialogBoxParam(
  1368. g_hInstance,
  1369. MAKEINTRESOURCE(IDD_DIALOG),
  1370. hwndParent,
  1371. UsernameDialogProc,
  1372. (LPARAM)pEapNameDialog);
  1373. }
  1374. /*
  1375. Notes:
  1376. Callback function used with the DialogBoxParam function. It processes
  1377. messages sent to the dialog box. See the DialogProc documentation in MSDN.
  1378. */
  1379. INT_PTR CALLBACK
  1380. UsernameDialogProc(
  1381. IN HWND hWnd,
  1382. IN UINT unMsg,
  1383. IN WPARAM wParam,
  1384. IN LPARAM lParam
  1385. )
  1386. {
  1387. EAP_NAME_DIALOG* pEapNameDialog;
  1388. switch (unMsg)
  1389. {
  1390. case WM_INITDIALOG:
  1391. return(InitUsernameDialog(hWnd, lParam));
  1392. case WM_COMMAND:
  1393. pEapNameDialog = (EAP_NAME_DIALOG*)GetWindowLongPtr(hWnd, DWLP_USER);
  1394. return(UsernameCommand(pEapNameDialog, LOWORD(wParam), hWnd));
  1395. }
  1396. return(FALSE);
  1397. }
  1398. /*
  1399. Returns:
  1400. FALSE (prevent Windows from setting the default keyboard focus).
  1401. Notes:
  1402. Response to the WM_INITDIALOG message.
  1403. */
  1404. BOOL
  1405. InitUsernameDialog(
  1406. IN HWND hWnd,
  1407. IN LPARAM lParam
  1408. )
  1409. {
  1410. HWND hWndEdit;
  1411. SetWindowLongPtr(hWnd, DWLP_USER, lParam);
  1412. return(FALSE);
  1413. }
  1414. /*
  1415. Returns:
  1416. TRUE: We prrocessed this message.
  1417. FALSE: We did not prrocess this message.
  1418. Notes:
  1419. Response to the WM_COMMAND message.
  1420. */
  1421. BOOL
  1422. UsernameCommand(
  1423. IN EAP_NAME_DIALOG* pEapNameDialog,
  1424. IN WORD wId,
  1425. IN HWND hWndDlg
  1426. )
  1427. {
  1428. HWND hWnd;
  1429. switch(wId)
  1430. {
  1431. case IDOK:
  1432. //
  1433. // Save whatever the user typed in as the user name
  1434. //
  1435. hWnd = GetDlgItem(hWndDlg, IDC_EDIT_NAME);
  1436. GetWindowText(hWnd, pEapNameDialog->awszIdentity, UNLEN + 1);
  1437. //
  1438. // Save whatever the user typed in as the password
  1439. //
  1440. hWnd = GetDlgItem(hWndDlg, IDC_EDIT_PASSWD);
  1441. GetWindowText(hWnd, pEapNameDialog->awszPassword, PWLEN + 1);
  1442. // Fall through
  1443. case IDCANCEL:
  1444. EndDialog(hWndDlg, wId);
  1445. return(TRUE);
  1446. default:
  1447. return(FALSE);
  1448. }
  1449. }