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.

1115 lines
32 KiB

  1. /*++
  2. Copyright (c) 2001, Microsoft Corporation
  3. Module Name:
  4. elpolicy.c
  5. Abstract:
  6. The module deals with functions related to managing group policy
  7. settings
  8. Revision History:
  9. sachins, November 14 2001, Created
  10. --*/
  11. #include "pcheapol.h"
  12. #pragma hdrstop
  13. VOID
  14. ElPrintPolicyList (
  15. EAPOL_POLICY_LIST *pEAPOLPolicyList
  16. )
  17. {
  18. EAPOL_POLICY_DATA *Tmp = NULL;
  19. DWORD i = 0;
  20. if (pEAPOLPolicyList == NULL)
  21. {
  22. EapolTrace ("ElPrintPolicyList: pEAPOLPolicyList is NULL");
  23. return;
  24. }
  25. for (i=0; i<pEAPOLPolicyList->dwNumberOfItems;i++)
  26. {
  27. Tmp = &pEAPOLPolicyList->EAPOLPolicy[i];
  28. EapolTrace ("Policy [%ld]:\n \
  29. SSID [%s]\n \
  30. Enable-802.1x [%ld]\n \
  31. dw8021xMode [%ld]\n \
  32. dwEapType [%ld]\n \
  33. dwEAPDataLen [%ld]\n \
  34. dwMachineAuthentication [%ld]\n \
  35. dwMachineAuthenticationType [%ld]\n \
  36. dwGuestAuthentication [%ld]\n \
  37. dwIEEE8021xMaxStart [%ld]\n \
  38. dwIEEE8021xStartPeriod [%ld]\n \
  39. dwIEEE8021xAuthPeriod [%ld]\n \
  40. dwIEEE8021xHeldPeriod [%ld]\n \
  41. ",
  42. i,
  43. (PCHAR)Tmp->pbWirelessSSID,
  44. Tmp->dwEnable8021x,
  45. Tmp->dw8021xMode,
  46. Tmp->dwEAPType,
  47. Tmp->dwEAPDataLen,
  48. Tmp->dwMachineAuthentication,
  49. Tmp->dwMachineAuthenticationType,
  50. Tmp->dwGuestAuthentication,
  51. Tmp->dwIEEE8021xMaxStart,
  52. Tmp->dwIEEE8021xStartPeriod,
  53. Tmp->dwIEEE8021xAuthPeriod,
  54. Tmp->dwIEEE8021xHeldPeriod
  55. );
  56. EapolTrace ("====================");
  57. }
  58. return;
  59. }
  60. DWORD
  61. ElCopyPolicyList (
  62. IN PEAPOL_POLICY_LIST pInList,
  63. OUT PEAPOL_POLICY_LIST *ppOutList
  64. )
  65. {
  66. PEAPOL_POLICY_LIST pOutList = NULL;
  67. PEAPOL_POLICY_DATA pDataIn = NULL, pDataOut = NULL;
  68. DWORD i = 0;
  69. DWORD dwRetCode = NO_ERROR;
  70. do
  71. {
  72. pOutList = MALLOC(sizeof(EAPOL_POLICY_LIST)+
  73. pInList->dwNumberOfItems*sizeof(EAPOL_POLICY_DATA));
  74. if (pOutList == NULL)
  75. {
  76. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  77. break;
  78. }
  79. pOutList->dwNumberOfItems = pInList->dwNumberOfItems;
  80. for (i=0; i<pInList->dwNumberOfItems; i++)
  81. {
  82. pDataIn = &(pInList->EAPOLPolicy[i]);
  83. pDataOut = &(pOutList->EAPOLPolicy[i]);
  84. memcpy (pDataOut, pDataIn, sizeof(EAPOL_POLICY_DATA));
  85. pDataOut->pbEAPData = NULL;
  86. pDataOut->dwEAPDataLen = 0;
  87. if (pDataIn->dwEAPDataLen)
  88. {
  89. if ((pDataOut->pbEAPData = MALLOC (pDataIn->dwEAPDataLen)) == NULL)
  90. {
  91. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  92. break;
  93. }
  94. memcpy (pDataOut->pbEAPData, pDataIn->pbEAPData, pDataIn->dwEAPDataLen);
  95. }
  96. pDataOut->dwEAPDataLen = pDataIn->dwEAPDataLen;
  97. }
  98. if (dwRetCode != NO_ERROR)
  99. {
  100. break;
  101. }
  102. }
  103. while (FALSE);
  104. if (dwRetCode != NO_ERROR)
  105. {
  106. if (pOutList != NULL)
  107. {
  108. ElFreePolicyList (pOutList);
  109. pOutList = NULL;
  110. }
  111. }
  112. *ppOutList = pOutList;
  113. return dwRetCode;
  114. }
  115. VOID
  116. ElFreePolicyList (
  117. IN PEAPOL_POLICY_LIST pEAPOLList
  118. )
  119. {
  120. DWORD dwIndex = 0;
  121. PEAPOL_POLICY_DATA pEAPOLData = NULL;
  122. if (pEAPOLList)
  123. {
  124. for (dwIndex = 0; dwIndex < pEAPOLList->dwNumberOfItems; dwIndex++)
  125. {
  126. pEAPOLData = &(pEAPOLList->EAPOLPolicy[dwIndex]);
  127. if (pEAPOLData->pbEAPData)
  128. {
  129. FREE (pEAPOLData->pbEAPData);
  130. }
  131. }
  132. FREE (pEAPOLList);
  133. }
  134. return;
  135. }
  136. BOOLEAN
  137. ElIsEqualEAPOLPolicyData (
  138. IN PEAPOL_POLICY_DATA pData1,
  139. IN PEAPOL_POLICY_DATA pData2
  140. )
  141. {
  142. BOOLEAN fEqual = FALSE;
  143. DWORD dwStaticStructLen = 0;
  144. DWORD dwRetCode = NO_ERROR;
  145. do
  146. {
  147. dwStaticStructLen = FIELD_OFFSET (EAPOL_POLICY_DATA, dwEAPDataLen);
  148. if (memcmp ((PVOID)pData1, (PVOID)pData2, dwStaticStructLen) == 0)
  149. {
  150. if (pData1->dwEAPDataLen == pData2->dwEAPDataLen)
  151. {
  152. if (memcmp (pData1->pbEAPData, pData2->pbEAPData, pData1->dwEAPDataLen) == 0)
  153. {
  154. fEqual = TRUE;
  155. }
  156. }
  157. }
  158. }
  159. while (FALSE);
  160. return fEqual;
  161. }
  162. //
  163. // ElPolicyChange
  164. //
  165. // Description:
  166. //
  167. // Arguments:
  168. // pPCB - Current interface context
  169. //
  170. // Return values:
  171. // NO_ERROR - success
  172. // Other - error
  173. //
  174. DWORD
  175. ElPolicyChange (
  176. IN EAPOL_POLICY_LIST *pEAPOLPolicyList
  177. )
  178. {
  179. BYTE *pbData = NULL;
  180. DWORD dwEventStatus = 0;
  181. BOOLEAN fDecrWorkerThreadCount = FALSE;
  182. DWORD dwSizeOfList = 0;
  183. EAPOL_POLICY_LIST *pLocalPolicyList = NULL;
  184. DWORD dwRetCode = NO_ERROR;
  185. do
  186. {
  187. TRACE0 (ANY, "ElPolicyChange: Entered");
  188. if (g_hEventTerminateEAPOL == NULL)
  189. {
  190. dwRetCode = ERROR_INVALID_STATE;
  191. break;
  192. }
  193. if (( dwEventStatus = WaitForSingleObject (
  194. g_hEventTerminateEAPOL,
  195. 0)) == WAIT_FAILED)
  196. {
  197. dwRetCode = GetLastError ();
  198. break;
  199. }
  200. if (dwEventStatus == WAIT_OBJECT_0)
  201. {
  202. dwRetCode = ERROR_INVALID_STATE;
  203. break;
  204. }
  205. DbLogPCBEvent (DBLOG_CATEG_INFO, NULL, EAPOL_POLICY_CHANGE_NOTIFICATION);
  206. TRACE0 (ANY, "ElPolicyChange: Ready to accept policy");
  207. InterlockedIncrement (&g_lWorkerThreads);
  208. fDecrWorkerThreadCount = TRUE;
  209. if ((dwRetCode = ElCopyPolicyList (pEAPOLPolicyList, &pLocalPolicyList)) != NO_ERROR)
  210. {
  211. TRACE1 (DEVICE, "ElPolicyChange: ElCopyPolicyList failed with error (%ld)",
  212. dwRetCode);
  213. break;
  214. }
  215. if (!QueueUserWorkItem (
  216. (LPTHREAD_START_ROUTINE)ElPolicyChangeWorker,
  217. (PVOID)pLocalPolicyList,
  218. WT_EXECUTELONGFUNCTION))
  219. {
  220. dwRetCode = GetLastError();
  221. TRACE1 (DEVICE, "ElPolicyChange: ElPolicyChangeWorker failed with error %ld",
  222. dwRetCode);
  223. break;
  224. }
  225. else
  226. {
  227. fDecrWorkerThreadCount = FALSE;
  228. }
  229. }
  230. while (FALSE);
  231. if (dwRetCode != NO_ERROR)
  232. {
  233. TRACE1 (DEVICE, "ElPolicyChange: Completed with error (%ld)",
  234. dwRetCode);
  235. if (pLocalPolicyList != NULL)
  236. {
  237. ElFreePolicyList (pLocalPolicyList);
  238. }
  239. }
  240. if (fDecrWorkerThreadCount)
  241. {
  242. InterlockedDecrement (&g_lWorkerThreads);
  243. }
  244. return dwRetCode;
  245. }
  246. //
  247. // ElPolicyChangeWorker
  248. //
  249. // Description:
  250. //
  251. // Arguments:
  252. // pPCB - Current interface context
  253. //
  254. // Return values:
  255. // NO_ERROR - success
  256. // Other - error
  257. //
  258. DWORD
  259. WINAPI
  260. ElPolicyChangeWorker (
  261. IN PVOID pvContext
  262. )
  263. {
  264. BOOLEAN fLocked = FALSE;
  265. BOOLEAN fIdentical = FALSE;
  266. EAPOL_POLICY_LIST *pNewPolicyList = pvContext;
  267. EAPOL_POLICY_LIST *pReauthPolicyList = NULL;
  268. EAPOL_POLICY_LIST *pRestartPolicyList = NULL;
  269. DWORD dwRetCode = NO_ERROR;
  270. do
  271. {
  272. TRACE0 (ANY, "ElPolicyChangeWorker entered");
  273. ACQUIRE_WRITE_LOCK (&g_PolicyLock);
  274. fLocked = TRUE;
  275. EapolTrace ("Old Policy = ");
  276. ElPrintPolicyList (g_pEAPOLPolicyList);
  277. EapolTrace ("New Policy = ");
  278. ElPrintPolicyList (pNewPolicyList);
  279. TRACE0 (ANY, "Entering ElVerifyPolicySettingsChange");
  280. if ((dwRetCode = ElVerifyPolicySettingsChange (
  281. pNewPolicyList,
  282. &fIdentical
  283. )) != NO_ERROR)
  284. {
  285. TRACE1 (ANY, "ElPolicyChangeWorker: ElVerifyPolicySettingsChange failed with error (%ld)",
  286. dwRetCode);
  287. break;
  288. }
  289. if (fIdentical)
  290. {
  291. TRACE0 (ANY, "ElPolicyChangeWorker: No change in policy settings");
  292. break;
  293. }
  294. TRACE0 (ANY, "Entering ElProcessAddedPolicySettings");
  295. if ((dwRetCode = ElProcessAddedPolicySettings (
  296. pNewPolicyList,
  297. &pReauthPolicyList,
  298. &pRestartPolicyList
  299. )) != NO_ERROR)
  300. {
  301. TRACE1 (ANY, "ElProcessAddedPolicySettings failed with error %ld", dwRetCode);
  302. break;
  303. }
  304. TRACE0 (ANY, "Entering ElProcessChangedPolicySettings");
  305. if ((dwRetCode = ElProcessChangedPolicySettings (
  306. pNewPolicyList,
  307. &pReauthPolicyList,
  308. &pRestartPolicyList
  309. )) != NO_ERROR)
  310. {
  311. TRACE1 (ANY, "ElProcessChangedPolicySettings failed with error %ld", dwRetCode);
  312. break;
  313. }
  314. TRACE0 (ANY, "Entering ElProcessDeletedPolicySettings");
  315. if ((dwRetCode = ElProcessDeletedPolicySettings (
  316. pNewPolicyList,
  317. &pReauthPolicyList,
  318. &pRestartPolicyList
  319. )) != NO_ERROR)
  320. {
  321. TRACE1 (ANY, "ElProcessDeletedPolicySettings failed with error %ld", dwRetCode);
  322. break;
  323. }
  324. EapolTrace ("Policy setting requiring restart = ");
  325. ElPrintPolicyList (pRestartPolicyList);
  326. EapolTrace ("Policy setting requiring reauth = ");
  327. ElPrintPolicyList (pReauthPolicyList);
  328. TRACE0 (ANY, "Entering ElUpdateGlobalPolicySettings");
  329. if ((dwRetCode = ElUpdateGlobalPolicySettings (
  330. pNewPolicyList
  331. )) != NO_ERROR)
  332. {
  333. TRACE1 (ANY, "ElUpdateGlobalPolicySettings failed with error %ld", dwRetCode);
  334. break;
  335. }
  336. DbLogPCBEvent (DBLOG_CATEG_INFO, NULL, EAPOL_POLICY_UPDATED);
  337. EapolTrace ("Updated policy = ");
  338. ElPrintPolicyList (g_pEAPOLPolicyList);
  339. RELEASE_WRITE_LOCK (&g_PolicyLock);
  340. fLocked = FALSE;
  341. TRACE0 (ANY, "Entering ElProcessPolicySettings");
  342. if ((dwRetCode = ElProcessPolicySettings (
  343. pReauthPolicyList,
  344. pRestartPolicyList
  345. )) != NO_ERROR)
  346. {
  347. TRACE1 (ANY, "ElProcessPolicySettings failed with error %ld", dwRetCode);
  348. break;
  349. }
  350. }
  351. while (FALSE);
  352. if (fLocked)
  353. {
  354. RELEASE_WRITE_LOCK (&g_PolicyLock)
  355. }
  356. if (pReauthPolicyList != NULL)
  357. {
  358. ElFreePolicyList (pReauthPolicyList);
  359. }
  360. if (pRestartPolicyList != NULL)
  361. {
  362. ElFreePolicyList (pRestartPolicyList);
  363. }
  364. if (pNewPolicyList != NULL)
  365. {
  366. ElFreePolicyList (pNewPolicyList);
  367. }
  368. InterlockedDecrement (&g_lWorkerThreads);
  369. return dwRetCode;
  370. }
  371. DWORD
  372. ElVerifyPolicySettingsChange (
  373. IN EAPOL_POLICY_LIST *pNewPolicyList,
  374. IN OUT BOOLEAN *pfIdentical
  375. )
  376. {
  377. DWORD i = 0;
  378. DWORD dwRetCode = NO_ERROR;
  379. do
  380. {
  381. *pfIdentical = FALSE;
  382. if (g_pEAPOLPolicyList == NULL)
  383. {
  384. break;
  385. }
  386. if (pNewPolicyList->dwNumberOfItems == g_pEAPOLPolicyList->dwNumberOfItems)
  387. {
  388. for (i= 0; i<g_pEAPOLPolicyList->dwNumberOfItems; i++)
  389. {
  390. *pfIdentical = TRUE;
  391. if (!ElIsEqualEAPOLPolicyData (&g_pEAPOLPolicyList->EAPOLPolicy[i], &pNewPolicyList->EAPOLPolicy[i]))
  392. {
  393. *pfIdentical = FALSE;
  394. break;
  395. }
  396. }
  397. }
  398. }
  399. while (FALSE);
  400. return dwRetCode;
  401. }
  402. DWORD
  403. ElProcessAddedPolicySettings (
  404. IN EAPOL_POLICY_LIST *pNewPolicyList,
  405. IN OUT PEAPOL_POLICY_LIST *ppReauthPolicyList,
  406. IN OUT PEAPOL_POLICY_LIST *ppRestartPolicyList
  407. )
  408. {
  409. DWORD i = 0, j = 0, k = 0;
  410. BOOLEAN fFoundInOld = FALSE;
  411. DWORD dwRetCode = NO_ERROR;
  412. do
  413. {
  414. for (i=0; i<pNewPolicyList->dwNumberOfItems; i++)
  415. {
  416. fFoundInOld = FALSE;
  417. if (g_pEAPOLPolicyList != NULL)
  418. for (j=0; j<g_pEAPOLPolicyList->dwNumberOfItems; j++)
  419. {
  420. if (pNewPolicyList->EAPOLPolicy[i].dwWirelessSSIDLen ==
  421. g_pEAPOLPolicyList->EAPOLPolicy[j].dwWirelessSSIDLen)
  422. {
  423. if (memcmp ((PVOID)pNewPolicyList->EAPOLPolicy[i].pbWirelessSSID,
  424. (PVOID)&g_pEAPOLPolicyList->EAPOLPolicy[j].pbWirelessSSID,
  425. pNewPolicyList->EAPOLPolicy[i].dwWirelessSSIDLen)
  426. == 0)
  427. {
  428. fFoundInOld = TRUE;
  429. }
  430. }
  431. }
  432. if (!fFoundInOld)
  433. {
  434. for (k=i+1; k<pNewPolicyList->dwNumberOfItems; k++)
  435. {
  436. if ((dwRetCode = ElAddToPolicyList (
  437. ppRestartPolicyList,
  438. &pNewPolicyList->EAPOLPolicy[k]
  439. )) != NO_ERROR)
  440. {
  441. break;
  442. }
  443. }
  444. if (dwRetCode != NO_ERROR)
  445. {
  446. break;
  447. }
  448. if ((dwRetCode = ElAddToPolicyList (
  449. ppReauthPolicyList,
  450. &pNewPolicyList->EAPOLPolicy[i]
  451. )) != NO_ERROR)
  452. {
  453. break;
  454. }
  455. break;
  456. }
  457. }
  458. }
  459. while (FALSE);
  460. return dwRetCode;
  461. }
  462. DWORD
  463. ElProcessChangedPolicySettings (
  464. IN EAPOL_POLICY_LIST *pNewPolicyList,
  465. IN OUT PEAPOL_POLICY_LIST *ppReauthPolicyList,
  466. IN OUT PEAPOL_POLICY_LIST *ppRestartPolicyList
  467. )
  468. {
  469. DWORD i = 0, j = 0, k = 0;
  470. BOOLEAN fChangedInNew = FALSE;
  471. DWORD dwRetCode = NO_ERROR;
  472. do
  473. {
  474. if (g_pEAPOLPolicyList == NULL)
  475. {
  476. TRACE0 (ANY, "ElProcessChangedPolicySettings: Global Policy List = NULL");
  477. break;
  478. }
  479. for (i=0; i<g_pEAPOLPolicyList->dwNumberOfItems; i++)
  480. {
  481. fChangedInNew = FALSE;
  482. for (j=0; j<pNewPolicyList->dwNumberOfItems; j++)
  483. {
  484. if (g_pEAPOLPolicyList->EAPOLPolicy[i].dwWirelessSSIDLen ==
  485. pNewPolicyList->EAPOLPolicy[j].dwWirelessSSIDLen)
  486. {
  487. if (memcmp ((PVOID)g_pEAPOLPolicyList->EAPOLPolicy[i].pbWirelessSSID,
  488. (PVOID)pNewPolicyList->EAPOLPolicy[j].pbWirelessSSID,
  489. g_pEAPOLPolicyList->EAPOLPolicy[i].dwWirelessSSIDLen)
  490. == 0)
  491. {
  492. if (!ElIsEqualEAPOLPolicyData (&g_pEAPOLPolicyList->EAPOLPolicy[i], &pNewPolicyList->EAPOLPolicy[j]))
  493. {
  494. fChangedInNew = TRUE;
  495. }
  496. }
  497. }
  498. }
  499. if (fChangedInNew)
  500. {
  501. for (k=i+1; k<g_pEAPOLPolicyList->dwNumberOfItems; k++)
  502. {
  503. if ((dwRetCode = ElAddToPolicyList (
  504. ppRestartPolicyList,
  505. &g_pEAPOLPolicyList->EAPOLPolicy[k]
  506. )) != NO_ERROR)
  507. {
  508. break;
  509. }
  510. }
  511. if (dwRetCode != NO_ERROR)
  512. {
  513. break;
  514. }
  515. if ((dwRetCode = ElAddToPolicyList (
  516. ppReauthPolicyList,
  517. &g_pEAPOLPolicyList->EAPOLPolicy[i]
  518. )) != NO_ERROR)
  519. {
  520. break;
  521. }
  522. break;
  523. }
  524. }
  525. }
  526. while (FALSE);
  527. return dwRetCode;
  528. }
  529. DWORD
  530. ElProcessDeletedPolicySettings (
  531. IN EAPOL_POLICY_LIST *pNewPolicyList,
  532. IN OUT PEAPOL_POLICY_LIST *ppReauthPolicyList,
  533. IN OUT PEAPOL_POLICY_LIST *ppRestartPolicyList
  534. )
  535. {
  536. DWORD i = 0, j = 0, k = 0;
  537. BOOLEAN fFoundInNew = FALSE;
  538. DWORD dwRetCode = NO_ERROR;
  539. do
  540. {
  541. if (g_pEAPOLPolicyList == NULL)
  542. {
  543. TRACE0 (ANY, "ElProcessDeletedPolicySettings: Global Policy List = NULL");
  544. break;
  545. }
  546. for (i=0; i<g_pEAPOLPolicyList->dwNumberOfItems; i++)
  547. {
  548. fFoundInNew = FALSE;
  549. for (j=0; j<pNewPolicyList->dwNumberOfItems; j++)
  550. {
  551. if (g_pEAPOLPolicyList->EAPOLPolicy[i].dwWirelessSSIDLen ==
  552. pNewPolicyList->EAPOLPolicy[j].dwWirelessSSIDLen)
  553. {
  554. if (memcmp ((PVOID)g_pEAPOLPolicyList->EAPOLPolicy[i].pbWirelessSSID,
  555. (PVOID)pNewPolicyList->EAPOLPolicy[j].pbWirelessSSID,
  556. g_pEAPOLPolicyList->EAPOLPolicy[i].dwWirelessSSIDLen)
  557. == 0)
  558. {
  559. fFoundInNew = TRUE;
  560. }
  561. }
  562. }
  563. if (!fFoundInNew)
  564. {
  565. for (k=i; k<g_pEAPOLPolicyList->dwNumberOfItems; k++)
  566. {
  567. if ((dwRetCode = ElAddToPolicyList (
  568. ppRestartPolicyList,
  569. &g_pEAPOLPolicyList->EAPOLPolicy[k]
  570. )) != NO_ERROR)
  571. {
  572. break;
  573. }
  574. }
  575. break;
  576. }
  577. }
  578. }
  579. while (FALSE);
  580. return dwRetCode;
  581. }
  582. DWORD
  583. ElAddToPolicyList (
  584. IN OUT PEAPOL_POLICY_LIST *ppList,
  585. IN EAPOL_POLICY_DATA *pData
  586. )
  587. {
  588. DWORD i = 0;
  589. BOOLEAN fFoundInList = FALSE;
  590. DWORD dwNumberOfItems = 0;
  591. PEAPOL_POLICY_LIST pInList = NULL;
  592. PEAPOL_POLICY_LIST pOutList = NULL;
  593. PEAPOL_POLICY_DATA pDataIn = NULL, pDataOut = NULL;
  594. DWORD dwRetCode = NO_ERROR;
  595. do
  596. {
  597. if (*ppList)
  598. {
  599. dwNumberOfItems = (*ppList)->dwNumberOfItems;
  600. }
  601. else
  602. {
  603. dwNumberOfItems = 0;
  604. }
  605. for (i=0; i<dwNumberOfItems; i++)
  606. {
  607. if ((*ppList)->EAPOLPolicy[i].dwWirelessSSIDLen ==
  608. pData->dwWirelessSSIDLen)
  609. {
  610. if (memcmp ((*ppList)->EAPOLPolicy[i].pbWirelessSSID,
  611. pData->pbWirelessSSID,
  612. pData->dwWirelessSSIDLen) == 0)
  613. {
  614. fFoundInList = TRUE;
  615. break;
  616. }
  617. }
  618. }
  619. if (!fFoundInList)
  620. {
  621. pInList = *ppList;
  622. pOutList = MALLOC(sizeof(EAPOL_POLICY_LIST)+
  623. (dwNumberOfItems+1)*sizeof(EAPOL_POLICY_DATA));
  624. if (pOutList == NULL)
  625. {
  626. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  627. break;
  628. }
  629. pOutList->dwNumberOfItems = dwNumberOfItems+1;
  630. // Copy the original list
  631. for (i=0; i<dwNumberOfItems; i++)
  632. {
  633. pDataIn = &(pInList->EAPOLPolicy[i]);
  634. pDataOut = &(pOutList->EAPOLPolicy[i]);
  635. memcpy (pDataOut, pDataIn, sizeof(EAPOL_POLICY_DATA));
  636. pDataOut->pbEAPData = NULL;
  637. pDataOut->dwEAPDataLen = 0;
  638. if (pDataIn->dwEAPDataLen)
  639. {
  640. if ((pDataOut->pbEAPData = MALLOC (pDataIn->dwEAPDataLen)) == NULL)
  641. {
  642. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  643. break;
  644. }
  645. memcpy (pDataOut->pbEAPData, pDataIn->pbEAPData, pDataIn->dwEAPDataLen);
  646. }
  647. pDataOut->dwEAPDataLen = pDataIn->dwEAPDataLen;
  648. }
  649. if (dwRetCode != NO_ERROR)
  650. {
  651. break;
  652. }
  653. // Copy the new item
  654. pDataIn = pData;
  655. pDataOut = &pOutList->EAPOLPolicy[dwNumberOfItems];
  656. memcpy (pDataOut, pDataIn, sizeof(EAPOL_POLICY_DATA));
  657. pDataOut->pbEAPData = NULL;
  658. pDataOut->dwEAPDataLen = 0;
  659. if (pDataIn->dwEAPDataLen)
  660. {
  661. if ((pDataOut->pbEAPData = MALLOC (pDataIn->dwEAPDataLen)) == NULL)
  662. {
  663. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  664. break;
  665. }
  666. memcpy (pDataOut->pbEAPData, pDataIn->pbEAPData, pDataIn->dwEAPDataLen);
  667. }
  668. pDataOut->dwEAPDataLen = pDataIn->dwEAPDataLen;
  669. if (*ppList)
  670. {
  671. ElFreePolicyList (*ppList);
  672. }
  673. *ppList = pOutList;
  674. }
  675. }
  676. while (FALSE);
  677. if (dwRetCode != NO_ERROR)
  678. {
  679. if (pOutList != NULL)
  680. {
  681. ElFreePolicyList (pOutList);
  682. }
  683. }
  684. return dwRetCode;
  685. }
  686. //
  687. // ElProcessPolicySettings
  688. //
  689. // Description:
  690. //
  691. // Arguments:
  692. //
  693. // Return values:
  694. // NO_ERROR - success
  695. // Other - error
  696. //
  697. DWORD
  698. ElProcessPolicySettings (
  699. IN EAPOL_POLICY_LIST *pReauthList,
  700. IN EAPOL_POLICY_LIST *pRestartList
  701. )
  702. {
  703. DWORD dwIndex = 0;
  704. EAPOL_PCB *pPCB = NULL;
  705. BOOLEAN fFoundInReauth = FALSE;
  706. BOOLEAN fFoundInRestart = FALSE;
  707. EAPOL_POLICY_DATA *pEAPOLPolicyData = NULL;
  708. EAPOL_ZC_INTF ZCData = {0};
  709. DWORD dwRetCode = NO_ERROR;
  710. do
  711. {
  712. if (!(g_dwModulesStarted & ALL_MODULES_STARTED))
  713. {
  714. dwRetCode = ERROR_INVALID_STATE;
  715. break;
  716. }
  717. ACQUIRE_WRITE_LOCK (&(g_PCBLock));
  718. for (dwIndex = 0; dwIndex<PORT_TABLE_BUCKETS; dwIndex++)
  719. {
  720. for (pPCB = g_PCBTable.pPCBBuckets[dwIndex].pPorts;
  721. pPCB != NULL;
  722. pPCB = pPCB->pNext)
  723. {
  724. ACQUIRE_WRITE_LOCK (&(pPCB->rwLock));
  725. fFoundInRestart = fFoundInReauth = FALSE;
  726. if ((dwRetCode = ElFindPolicyData (
  727. pPCB->pSSID?pPCB->pSSID->SsidLength:0,
  728. pPCB->pSSID?pPCB->pSSID->Ssid:NULL,
  729. pRestartList,
  730. &pEAPOLPolicyData
  731. )) == NO_ERROR)
  732. {
  733. fFoundInRestart = TRUE;
  734. }
  735. if ((dwRetCode = ElFindPolicyData (
  736. pPCB->pSSID?pPCB->pSSID->SsidLength:0,
  737. pPCB->pSSID?pPCB->pSSID->Ssid:NULL,
  738. pReauthList,
  739. &pEAPOLPolicyData
  740. )) == NO_ERROR)
  741. {
  742. fFoundInReauth = TRUE;
  743. }
  744. if (fFoundInRestart)
  745. {
  746. #ifdef ZEROCONFIG_LINKED
  747. // Indicate hard-reset to WZC
  748. ZeroMemory ((PVOID)&ZCData, sizeof(EAPOL_ZC_INTF));
  749. ZCData.dwAuthFailCount = 0;
  750. ZCData.PreviousAuthenticationType = 0;
  751. if ((dwRetCode = ElZeroConfigNotify (
  752. 0,
  753. WZCCMD_HARD_RESET,
  754. pPCB->pwszDeviceGUID,
  755. &ZCData
  756. )) != NO_ERROR)
  757. {
  758. TRACE1 (ANY, "ElProcessPolicySettings: ElZeroConfigNotify failed with error %ld",
  759. dwRetCode);
  760. dwRetCode = NO_ERROR;
  761. }
  762. #endif // ZEROCONFIG_LINKED
  763. }
  764. if (fFoundInRestart || fFoundInReauth)
  765. {
  766. if ((dwRetCode = ElReAuthenticateInterface (
  767. pPCB->pwszDeviceGUID
  768. )) != NO_ERROR)
  769. {
  770. TRACE2 (ANY, "ElProcessPolicySettings: ElReAuthenticateInterface failed for (%ws) with error (%ld)",
  771. pPCB->pwszDeviceGUID, dwRetCode);
  772. dwRetCode = NO_ERROR;
  773. }
  774. }
  775. RELEASE_WRITE_LOCK (&(pPCB->rwLock));
  776. }
  777. dwRetCode = NO_ERROR;
  778. }
  779. RELEASE_WRITE_LOCK (&(g_PCBLock));
  780. }
  781. while (FALSE);
  782. return dwRetCode;
  783. }
  784. DWORD
  785. ElUpdateGlobalPolicySettings (
  786. IN EAPOL_POLICY_LIST *pNewPolicyList
  787. )
  788. {
  789. DWORD dwSizeOfList = 0;
  790. EAPOL_POLICY_LIST *pTmpPolicyList = NULL;
  791. DWORD dwRetCode = NO_ERROR;
  792. do
  793. {
  794. if (pNewPolicyList == NULL)
  795. {
  796. TRACE0 (ANY, "ElUpdateGlobalPolicySettings: New Policy List = NULL");
  797. break;
  798. }
  799. if ((dwRetCode = ElCopyPolicyList (pNewPolicyList, &pTmpPolicyList)) != NO_ERROR)
  800. {
  801. TRACE1 (ANY, "ElUpdateGlobalPolicySettings: ElCopyPolicyList failed with error (%ld)",
  802. dwRetCode);
  803. break;
  804. }
  805. ElFreePolicyList (g_pEAPOLPolicyList);
  806. g_pEAPOLPolicyList = pTmpPolicyList;
  807. }
  808. while (FALSE);
  809. return dwRetCode;
  810. }
  811. //
  812. // ElGetPolicyInterfaceParams
  813. //
  814. // Description:
  815. //
  816. // Arguments:
  817. //
  818. // Return values:
  819. // NO_ERROR - success
  820. // Other - error
  821. //
  822. DWORD
  823. ElGetPolicyInterfaceParams (
  824. IN DWORD dwSizeOfSSID,
  825. IN BYTE *pbSSID,
  826. IN OUT EAPOL_POLICY_PARAMS *pEAPOLPolicyParams
  827. )
  828. {
  829. EAPOL_POLICY_DATA *pEAPOLData = NULL;
  830. DWORD dwEapFlags = 0;
  831. BOOLEAN fLocked = FALSE;
  832. DWORD dwRetCode = NO_ERROR;
  833. do
  834. {
  835. ACQUIRE_WRITE_LOCK (&g_PolicyLock);
  836. fLocked = TRUE;
  837. if ((dwRetCode = ElFindPolicyData (
  838. dwSizeOfSSID,
  839. pbSSID,
  840. g_pEAPOLPolicyList,
  841. &pEAPOLData
  842. )) != NO_ERROR)
  843. {
  844. if (dwRetCode != ERROR_FILE_NOT_FOUND)
  845. {
  846. TRACE1 (ANY, "ElGetPolicyInterfaceParams: ElFindPolicyData failed with error %ld",
  847. dwRetCode);
  848. }
  849. dwRetCode = ERROR_FILE_NOT_FOUND;
  850. break;
  851. }
  852. pEAPOLPolicyParams->IntfParams.dwEapType = pEAPOLData->dwEAPType;
  853. pEAPOLPolicyParams->IntfParams.dwSizeOfSSID = dwSizeOfSSID;
  854. memcpy (pEAPOLPolicyParams->IntfParams.bSSID, pbSSID, dwSizeOfSSID);
  855. dwEapFlags |= (pEAPOLData->dwEnable8021x?EAPOL_ENABLED:0);
  856. dwEapFlags |= (pEAPOLData->dwMachineAuthentication?EAPOL_MACHINE_AUTH_ENABLED:0);
  857. dwEapFlags |= (pEAPOLData->dwGuestAuthentication?EAPOL_GUEST_AUTH_ENABLED:0);
  858. pEAPOLPolicyParams->IntfParams.dwEapFlags = dwEapFlags;
  859. pEAPOLPolicyParams->IntfParams.dwVersion = EAPOL_CURRENT_VERSION;;
  860. pEAPOLPolicyParams->dwEAPOLAuthMode = pEAPOLData->dwMachineAuthenticationType;
  861. pEAPOLPolicyParams->dwSupplicantMode = pEAPOLData->dw8021xMode;
  862. pEAPOLPolicyParams->dwmaxStart = pEAPOLData->dwIEEE8021xMaxStart;
  863. pEAPOLPolicyParams->dwstartPeriod = pEAPOLData->dwIEEE8021xStartPeriod;
  864. pEAPOLPolicyParams->dwauthPeriod = pEAPOLData->dwIEEE8021xAuthPeriod;
  865. pEAPOLPolicyParams->dwheldPeriod = pEAPOLData->dwIEEE8021xHeldPeriod;
  866. RELEASE_WRITE_LOCK (&g_PolicyLock);
  867. fLocked = FALSE;
  868. }
  869. while (FALSE);
  870. if (fLocked)
  871. {
  872. RELEASE_WRITE_LOCK (&g_PolicyLock);
  873. }
  874. return dwRetCode;
  875. }
  876. //
  877. // ElGetPolicyCustomAuthData
  878. //
  879. // Description:
  880. //
  881. // Arguments:
  882. //
  883. // Return values:
  884. // NO_ERROR - success
  885. // ERROR_FILE_NOT_FOUND - No relevant Policy Data was found
  886. // Other - error
  887. //
  888. DWORD
  889. ElGetPolicyCustomAuthData (
  890. IN DWORD dwEapTypeId,
  891. IN DWORD dwSizeOfSSID,
  892. IN BYTE *pbSSID,
  893. IN PBYTE *ppbConnInfoIn,
  894. IN DWORD *pdwInfoSizeIn,
  895. OUT PBYTE *ppbConnInfoOut,
  896. OUT DWORD *pdwInfoSizeOut
  897. )
  898. {
  899. DWORD dwIndex = 0;
  900. HANDLE hLib = NULL;
  901. EAPOL_POLICY_DATA *pEAPOLData = NULL;
  902. RASEAPCREATECONNPROP pCreateConnPropFunc = NULL;
  903. EAPTLS_CONNPROP_ATTRIBUTE ConnProp[4] = {0};
  904. PVOID pAuthDataIn = NULL;
  905. DWORD dwSizeDataIn = 0;
  906. PVOID pAuthDataOut = NULL;
  907. DWORD dwSizeDataOut = 0;
  908. BOOLEAN fLocked = FALSE;
  909. DWORD dwRetCode = NO_ERROR;
  910. do
  911. {
  912. ACQUIRE_WRITE_LOCK (&g_PolicyLock);
  913. fLocked = TRUE;
  914. if ((dwRetCode = ElFindPolicyData (
  915. dwSizeOfSSID,
  916. pbSSID,
  917. g_pEAPOLPolicyList,
  918. &pEAPOLData
  919. )) != NO_ERROR)
  920. {
  921. if (dwRetCode != ERROR_FILE_NOT_FOUND)
  922. {
  923. TRACE1 (ANY, "ElGetPolicyCustomAuthData: ElFindPolicyData failed with error %ld",
  924. dwRetCode);
  925. }
  926. dwRetCode = ERROR_FILE_NOT_FOUND;
  927. break;
  928. }
  929. if (pEAPOLData)
  930. {
  931. if (pEAPOLData->dwEAPDataLen != 0)
  932. {
  933. if ((pAuthDataOut = MALLOC (pEAPOLData->dwEAPDataLen)) == NULL)
  934. {
  935. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  936. break;
  937. }
  938. memcpy (pAuthDataOut, pEAPOLData->pbEAPData,
  939. pEAPOLData->dwEAPDataLen);
  940. dwSizeDataOut = pEAPOLData->dwEAPDataLen;
  941. }
  942. }
  943. *ppbConnInfoOut = pAuthDataOut;
  944. *pdwInfoSizeOut = dwSizeDataOut;
  945. }
  946. while (FALSE);
  947. if (fLocked)
  948. {
  949. RELEASE_WRITE_LOCK (&g_PolicyLock);
  950. }
  951. return dwRetCode;
  952. }
  953. //
  954. // ElFindPolicyData
  955. //
  956. // Description:
  957. //
  958. // Arguments:
  959. //
  960. // Return values:
  961. // NO_ERROR - success
  962. // Other - error
  963. //
  964. DWORD
  965. ElFindPolicyData (
  966. IN DWORD dwSizeOfSSID,
  967. IN BYTE *pbSSID,
  968. IN EAPOL_POLICY_LIST *pPolicyList,
  969. OUT PEAPOL_POLICY_DATA *ppEAPOLPolicyData
  970. )
  971. {
  972. DWORD dwIndex = 0;
  973. DWORD dwRetCode = NO_ERROR;
  974. do
  975. {
  976. *ppEAPOLPolicyData = NULL;
  977. if (pPolicyList == NULL)
  978. {
  979. dwRetCode = ERROR_FILE_NOT_FOUND;
  980. break;
  981. }
  982. for (dwIndex=0; dwIndex<pPolicyList->dwNumberOfItems; dwIndex++)
  983. {
  984. if (pPolicyList->EAPOLPolicy[dwIndex].dwWirelessSSIDLen ==
  985. dwSizeOfSSID)
  986. {
  987. if (memcmp (pbSSID,
  988. pPolicyList->EAPOLPolicy[dwIndex].pbWirelessSSID,
  989. dwSizeOfSSID) == 0)
  990. {
  991. *ppEAPOLPolicyData = &(pPolicyList->EAPOLPolicy[dwIndex]);
  992. break;
  993. }
  994. }
  995. }
  996. if (*ppEAPOLPolicyData == NULL)
  997. {
  998. dwRetCode = ERROR_FILE_NOT_FOUND;
  999. }
  1000. }
  1001. while (FALSE);
  1002. return dwRetCode;
  1003. }