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.

1271 lines
24 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. mm-policy.c
  5. Abstract:
  6. Author:
  7. Environment: User Mode
  8. Revision History:
  9. --*/
  10. #include "precomp.h"
  11. DWORD
  12. AddMMPolicy(
  13. LPWSTR pServerName,
  14. DWORD dwFlags,
  15. PIPSEC_MM_POLICY pMMPolicy
  16. )
  17. /*++
  18. Routine Description:
  19. This function adds a main mode policy to the SPD.
  20. Arguments:
  21. pServerName - Server on which the main mode policy is to be added.
  22. pMMPolicy - Main mode policy to be added.
  23. Return Value:
  24. ERROR_SUCCESS - Success.
  25. Win32 Error - Failure.
  26. --*/
  27. {
  28. DWORD dwError = 0;
  29. PINIMMPOLICY pIniMMPolicy = NULL;
  30. BOOL bPersist = FALSE;
  31. bPersist = (BOOL) (dwFlags & PERSIST_SPD_OBJECT);
  32. //
  33. // Validate the main mode policy.
  34. //
  35. dwError = ValidateMMPolicy(
  36. pMMPolicy
  37. );
  38. BAIL_ON_WIN32_ERROR(dwError);
  39. ENTER_SPD_SECTION();
  40. dwError = ValidateSecurity(
  41. SPD_OBJECT_SERVER,
  42. SERVER_ACCESS_ADMINISTER,
  43. NULL,
  44. NULL
  45. );
  46. BAIL_ON_LOCK_ERROR(dwError);
  47. pIniMMPolicy = FindMMPolicy(
  48. gpIniMMPolicy,
  49. pMMPolicy->pszPolicyName
  50. );
  51. if (pIniMMPolicy) {
  52. dwError = ERROR_IPSEC_MM_POLICY_EXISTS;
  53. BAIL_ON_LOCK_ERROR(dwError);
  54. }
  55. pIniMMPolicy = FindMMPolicyByGuid(
  56. gpIniMMPolicy,
  57. pMMPolicy->gPolicyID
  58. );
  59. if (pIniMMPolicy) {
  60. dwError = ERROR_IPSEC_MM_POLICY_EXISTS;
  61. BAIL_ON_LOCK_ERROR(dwError);
  62. }
  63. if (bPersist && !gbLoadingPersistence) {
  64. dwError = PersistMMPolicy(
  65. pMMPolicy
  66. );
  67. BAIL_ON_LOCK_ERROR(dwError);
  68. }
  69. dwError = CreateIniMMPolicy(
  70. pMMPolicy,
  71. &pIniMMPolicy
  72. );
  73. BAIL_ON_LOCK_ERROR(dwError);
  74. pIniMMPolicy->bIsPersisted = bPersist;
  75. pIniMMPolicy->pNext = gpIniMMPolicy;
  76. gpIniMMPolicy = pIniMMPolicy;
  77. if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
  78. gpIniDefaultMMPolicy = pIniMMPolicy;
  79. }
  80. LEAVE_SPD_SECTION();
  81. return (dwError);
  82. lock:
  83. LEAVE_SPD_SECTION();
  84. error:
  85. if (pMMPolicy && bPersist && !gbLoadingPersistence) {
  86. (VOID) SPDPurgeMMPolicy(
  87. pMMPolicy->gPolicyID
  88. );
  89. }
  90. return (dwError);
  91. }
  92. DWORD
  93. ValidateMMPolicy(
  94. PIPSEC_MM_POLICY pMMPolicy
  95. )
  96. {
  97. DWORD dwError = 0;
  98. if (!pMMPolicy) {
  99. dwError = ERROR_INVALID_PARAMETER;
  100. BAIL_ON_WIN32_ERROR(dwError);
  101. }
  102. if (!(pMMPolicy->pszPolicyName) || !(*(pMMPolicy->pszPolicyName))) {
  103. dwError = ERROR_INVALID_PARAMETER;
  104. BAIL_ON_WIN32_ERROR(dwError);
  105. }
  106. dwError = ValidateMMOffers(
  107. pMMPolicy->dwOfferCount,
  108. pMMPolicy->pOffers
  109. );
  110. BAIL_ON_WIN32_ERROR(dwError);
  111. error:
  112. return (dwError);
  113. }
  114. DWORD
  115. ValidateMMOffers(
  116. DWORD dwOfferCount,
  117. PIPSEC_MM_OFFER pOffers
  118. )
  119. {
  120. DWORD dwError = 0;
  121. DWORD i = 0;
  122. PIPSEC_MM_OFFER pTemp = NULL;
  123. if (!dwOfferCount || !pOffers) {
  124. dwError = ERROR_INVALID_PARAMETER;
  125. BAIL_ON_WIN32_ERROR(dwError);
  126. }
  127. //
  128. // Need to catch the exception when the number of offers
  129. // specified is more than the actual number of offers.
  130. //
  131. pTemp = pOffers;
  132. for (i = 0; i < dwOfferCount; i++) {
  133. if ((pTemp->dwDHGroup != DH_GROUP_1) &&
  134. (pTemp->dwDHGroup != DH_GROUP_2)) {
  135. dwError = ERROR_INVALID_PARAMETER;
  136. BAIL_ON_WIN32_ERROR(dwError);
  137. }
  138. if (pTemp->EncryptionAlgorithm.uAlgoIdentifier >= IPSEC_DOI_ESP_MAX) {
  139. dwError = ERROR_INVALID_PARAMETER;
  140. BAIL_ON_WIN32_ERROR(dwError);
  141. }
  142. if (pTemp->HashingAlgorithm.uAlgoIdentifier >= IPSEC_DOI_AH_MAX) {
  143. dwError = ERROR_INVALID_PARAMETER;
  144. BAIL_ON_WIN32_ERROR(dwError);
  145. }
  146. pTemp++;
  147. }
  148. error:
  149. return (dwError);
  150. }
  151. DWORD
  152. CreateIniMMPolicy(
  153. PIPSEC_MM_POLICY pMMPolicy,
  154. PINIMMPOLICY * ppIniMMPolicy
  155. )
  156. {
  157. DWORD dwError = 0;
  158. PINIMMPOLICY pIniMMPolicy = NULL;
  159. dwError = AllocateSPDMemory(
  160. sizeof(INIMMPOLICY),
  161. &pIniMMPolicy
  162. );
  163. BAIL_ON_WIN32_ERROR(dwError);
  164. memcpy(
  165. &(pIniMMPolicy->gPolicyID),
  166. &(pMMPolicy->gPolicyID),
  167. sizeof(GUID)
  168. );
  169. dwError = AllocateSPDString(
  170. pMMPolicy->pszPolicyName,
  171. &(pIniMMPolicy->pszPolicyName)
  172. );
  173. BAIL_ON_WIN32_ERROR(dwError);
  174. pIniMMPolicy->cRef = 0;
  175. pIniMMPolicy->bIsPersisted = FALSE;
  176. pIniMMPolicy->dwFlags = pMMPolicy->dwFlags;
  177. pIniMMPolicy->uSoftSAExpirationTime = pMMPolicy->uSoftSAExpirationTime;
  178. pIniMMPolicy->pNext = NULL;
  179. dwError = CreateIniMMOffers(
  180. pMMPolicy->dwOfferCount,
  181. pMMPolicy->pOffers,
  182. &(pIniMMPolicy->dwOfferCount),
  183. &(pIniMMPolicy->pOffers)
  184. );
  185. BAIL_ON_WIN32_ERROR(dwError);
  186. *ppIniMMPolicy = pIniMMPolicy;
  187. return (dwError);
  188. error:
  189. if (pIniMMPolicy) {
  190. FreeIniMMPolicy(
  191. pIniMMPolicy
  192. );
  193. }
  194. *ppIniMMPolicy = NULL;
  195. return (dwError);
  196. }
  197. DWORD
  198. CreateIniMMOffers(
  199. DWORD dwInOfferCount,
  200. PIPSEC_MM_OFFER pInOffers,
  201. PDWORD pdwOfferCount,
  202. PIPSEC_MM_OFFER * ppOffers
  203. )
  204. {
  205. DWORD dwError = 0;
  206. PIPSEC_MM_OFFER pOffers = NULL;
  207. PIPSEC_MM_OFFER pTemp = NULL;
  208. PIPSEC_MM_OFFER pInTempOffer = NULL;
  209. DWORD i = 0;
  210. //
  211. // Offer count and the offers themselves have already been validated.
  212. //
  213. dwError = AllocateSPDMemory(
  214. sizeof(IPSEC_MM_OFFER) * dwInOfferCount,
  215. &(pOffers)
  216. );
  217. BAIL_ON_WIN32_ERROR(dwError);
  218. pTemp = pOffers;
  219. pInTempOffer = pInOffers;
  220. for (i = 0; i < dwInOfferCount; i++) {
  221. memcpy(
  222. &(pTemp->Lifetime),
  223. &(pInTempOffer->Lifetime),
  224. sizeof(KEY_LIFETIME)
  225. );
  226. if (!(pTemp->Lifetime.uKeyExpirationTime)) {
  227. pTemp->Lifetime.uKeyExpirationTime = DEFAULT_MM_KEY_EXPIRATION_TIME;
  228. }
  229. pTemp->dwFlags = pInTempOffer->dwFlags;
  230. pTemp->dwQuickModeLimit = pInTempOffer->dwQuickModeLimit;
  231. pTemp->dwDHGroup = pInTempOffer->dwDHGroup;
  232. memcpy(
  233. &(pTemp->EncryptionAlgorithm),
  234. &(pInTempOffer->EncryptionAlgorithm),
  235. sizeof(IPSEC_MM_ALGO)
  236. );
  237. memcpy(
  238. &(pTemp->HashingAlgorithm),
  239. &(pInTempOffer->HashingAlgorithm),
  240. sizeof(IPSEC_MM_ALGO)
  241. );
  242. pInTempOffer++;
  243. pTemp++;
  244. }
  245. *pdwOfferCount = dwInOfferCount;
  246. *ppOffers = pOffers;
  247. return (dwError);
  248. error:
  249. if (pOffers) {
  250. FreeIniMMOffers(
  251. i,
  252. pOffers
  253. );
  254. }
  255. *pdwOfferCount = 0;
  256. *ppOffers = NULL;
  257. return (dwError);
  258. }
  259. VOID
  260. FreeIniMMPolicy(
  261. PINIMMPOLICY pIniMMPolicy
  262. )
  263. {
  264. if (pIniMMPolicy) {
  265. if (pIniMMPolicy->pszPolicyName) {
  266. FreeSPDString(pIniMMPolicy->pszPolicyName);
  267. }
  268. FreeIniMMOffers(
  269. pIniMMPolicy->dwOfferCount,
  270. pIniMMPolicy->pOffers
  271. );
  272. FreeSPDMemory(pIniMMPolicy);
  273. }
  274. }
  275. VOID
  276. FreeIniMMOffers(
  277. DWORD dwOfferCount,
  278. PIPSEC_MM_OFFER pOffers
  279. )
  280. {
  281. if (pOffers) {
  282. FreeSPDMemory(pOffers);
  283. }
  284. }
  285. PINIMMPOLICY
  286. FindMMPolicy(
  287. PINIMMPOLICY pIniMMPolicyList,
  288. LPWSTR pszPolicyName
  289. )
  290. {
  291. DWORD dwError = 0;
  292. PINIMMPOLICY pTemp = NULL;
  293. pTemp = pIniMMPolicyList;
  294. while (pTemp) {
  295. if (!_wcsicmp(pTemp->pszPolicyName, pszPolicyName)) {
  296. return (pTemp);
  297. }
  298. pTemp = pTemp->pNext;
  299. }
  300. return (NULL);
  301. }
  302. DWORD
  303. DeleteMMPolicy(
  304. LPWSTR pServerName,
  305. LPWSTR pszPolicyName
  306. )
  307. /*++
  308. Routine Description:
  309. This function deletes a main mode policy from the SPD.
  310. Arguments:
  311. pServerName - Server on which the main mode policy is to be deleted.
  312. pszPolicyName - Main mode policy to be deleted.
  313. Return Value:
  314. ERROR_SUCCESS - Success.
  315. Win32 Error - Failure.
  316. --*/
  317. {
  318. DWORD dwError = 0;
  319. PINIMMPOLICY pIniMMPolicy = NULL;
  320. GUID gPolicyID;
  321. if (!pszPolicyName || !*pszPolicyName) {
  322. return (ERROR_INVALID_PARAMETER);
  323. }
  324. ENTER_SPD_SECTION();
  325. dwError = ValidateSecurity(
  326. SPD_OBJECT_SERVER,
  327. SERVER_ACCESS_ADMINISTER,
  328. NULL,
  329. NULL
  330. );
  331. BAIL_ON_LOCK_ERROR(dwError);
  332. pIniMMPolicy = FindMMPolicy(
  333. gpIniMMPolicy,
  334. pszPolicyName
  335. );
  336. if (!pIniMMPolicy) {
  337. dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND;
  338. BAIL_ON_LOCK_ERROR(dwError);
  339. }
  340. if (pIniMMPolicy->cRef) {
  341. dwError = ERROR_IPSEC_MM_POLICY_IN_USE;
  342. memcpy(&gPolicyID, &pIniMMPolicy->gPolicyID, sizeof(GUID));
  343. BAIL_ON_LOCK_ERROR(dwError);
  344. }
  345. memcpy(&gPolicyID, &pIniMMPolicy->gPolicyID, sizeof(GUID));
  346. if (pIniMMPolicy->bIsPersisted) {
  347. dwError = SPDPurgeMMPolicy(
  348. gPolicyID
  349. );
  350. BAIL_ON_LOCK_ERROR(dwError);
  351. }
  352. dwError = DeleteIniMMPolicy(
  353. pIniMMPolicy
  354. );
  355. BAIL_ON_LOCK_ERROR(dwError);
  356. LEAVE_SPD_SECTION();
  357. if (gbIKENotify) {
  358. (VOID) IKENotifyPolicyChange(
  359. &(gPolicyID),
  360. POLICY_GUID_MM
  361. );
  362. }
  363. return (dwError);
  364. lock:
  365. LEAVE_SPD_SECTION();
  366. if ((dwError == ERROR_IPSEC_MM_POLICY_IN_USE) && gbIKENotify) {
  367. (VOID) IKENotifyPolicyChange(
  368. &(gPolicyID),
  369. POLICY_GUID_MM
  370. );
  371. }
  372. return (dwError);
  373. }
  374. DWORD
  375. EnumMMPolicies(
  376. LPWSTR pServerName,
  377. PIPSEC_MM_POLICY * ppMMPolicies,
  378. DWORD dwPreferredNumEntries,
  379. LPDWORD pdwNumPolicies,
  380. LPDWORD pdwResumeHandle
  381. )
  382. /*++
  383. Routine Description:
  384. This function enumerates main mode policies from the SPD.
  385. Arguments:
  386. pServerName - Server on which the main mode policies are to
  387. be enumerated.
  388. ppMMPolicies - Enumerated main mode policies returned to the
  389. caller.
  390. dwPreferredNumEntries - Preferred number of enumeration entries.
  391. pdwNumPolicies - Number of main mode policies actually enumerated.
  392. pdwResumeHandle - Handle to the location in the main mode policy
  393. list from which to resume enumeration.
  394. Return Value:
  395. ERROR_SUCCESS - Success.
  396. Win32 Error - Failure.
  397. --*/
  398. {
  399. DWORD dwError = 0;
  400. DWORD dwResumeHandle = 0;
  401. DWORD dwNumToEnum = 0;
  402. PINIMMPOLICY pIniMMPolicy = NULL;
  403. DWORD i = 0;
  404. PINIMMPOLICY pTemp = NULL;
  405. DWORD dwNumPolicies = 0;
  406. PIPSEC_MM_POLICY pMMPolicies = NULL;
  407. PIPSEC_MM_POLICY pMMPolicy = NULL;
  408. dwResumeHandle = *pdwResumeHandle;
  409. if (!dwPreferredNumEntries || (dwPreferredNumEntries > MAX_MMPOLICY_ENUM_COUNT)) {
  410. dwNumToEnum = MAX_MMPOLICY_ENUM_COUNT;
  411. }
  412. else {
  413. dwNumToEnum = dwPreferredNumEntries;
  414. }
  415. ENTER_SPD_SECTION();
  416. dwError = ValidateSecurity(
  417. SPD_OBJECT_SERVER,
  418. SERVER_ACCESS_ADMINISTER,
  419. NULL,
  420. NULL
  421. );
  422. BAIL_ON_LOCK_ERROR(dwError);
  423. pIniMMPolicy = gpIniMMPolicy;
  424. for (i = 0; (i < dwResumeHandle) && (pIniMMPolicy != NULL); i++) {
  425. pIniMMPolicy = pIniMMPolicy->pNext;
  426. }
  427. if (!pIniMMPolicy) {
  428. dwError = ERROR_NO_DATA;
  429. BAIL_ON_LOCK_ERROR(dwError);
  430. }
  431. pTemp = pIniMMPolicy;
  432. while (pTemp && (dwNumPolicies < dwNumToEnum)) {
  433. dwNumPolicies++;
  434. pTemp = pTemp->pNext;
  435. }
  436. dwError = SPDApiBufferAllocate(
  437. sizeof(IPSEC_MM_POLICY)*dwNumPolicies,
  438. &pMMPolicies
  439. );
  440. BAIL_ON_LOCK_ERROR(dwError);
  441. pTemp = pIniMMPolicy;
  442. pMMPolicy = pMMPolicies;
  443. for (i = 0; i < dwNumPolicies; i++) {
  444. dwError = CopyMMPolicy(
  445. pTemp,
  446. pMMPolicy
  447. );
  448. BAIL_ON_LOCK_ERROR(dwError);
  449. pTemp = pTemp->pNext;
  450. pMMPolicy++;
  451. }
  452. *ppMMPolicies = pMMPolicies;
  453. *pdwResumeHandle = dwResumeHandle + dwNumPolicies;
  454. *pdwNumPolicies = dwNumPolicies;
  455. LEAVE_SPD_SECTION();
  456. return (dwError);
  457. lock:
  458. LEAVE_SPD_SECTION();
  459. if (pMMPolicies) {
  460. FreeMMPolicies(
  461. i,
  462. pMMPolicies
  463. );
  464. }
  465. *ppMMPolicies = NULL;
  466. *pdwResumeHandle = dwResumeHandle;
  467. *pdwNumPolicies = 0;
  468. return (dwError);
  469. }
  470. DWORD
  471. SetMMPolicy(
  472. LPWSTR pServerName,
  473. LPWSTR pszPolicyName,
  474. PIPSEC_MM_POLICY pMMPolicy
  475. )
  476. /*++
  477. Routine Description:
  478. This function updates a main mode policy in the SPD.
  479. Arguments:
  480. pServerName - Server on which the main mode policy is to be
  481. updated.
  482. pszPolicyName - Name of the main mode policy to be updated.
  483. pMMPolicy - New main mode policy which will replace the
  484. existing policy.
  485. Return Value:
  486. ERROR_SUCCESS - Success.
  487. Win32 Error - Failure.
  488. --*/
  489. {
  490. DWORD dwError = 0;
  491. PINIMMPOLICY pIniMMPolicy = NULL;
  492. if (!pszPolicyName || !*pszPolicyName) {
  493. return (ERROR_INVALID_PARAMETER);
  494. }
  495. //
  496. // Validate main mode policy.
  497. //
  498. dwError = ValidateMMPolicy(
  499. pMMPolicy
  500. );
  501. BAIL_ON_WIN32_ERROR(dwError);
  502. ENTER_SPD_SECTION();
  503. dwError = ValidateSecurity(
  504. SPD_OBJECT_SERVER,
  505. SERVER_ACCESS_ADMINISTER,
  506. NULL,
  507. NULL
  508. );
  509. BAIL_ON_LOCK_ERROR(dwError);
  510. pIniMMPolicy = FindMMPolicy(
  511. gpIniMMPolicy,
  512. pszPolicyName
  513. );
  514. if (!pIniMMPolicy) {
  515. dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND;
  516. BAIL_ON_LOCK_ERROR(dwError);
  517. }
  518. if (memcmp(
  519. &(pIniMMPolicy->gPolicyID),
  520. &(pMMPolicy->gPolicyID),
  521. sizeof(GUID))) {
  522. dwError = ERROR_INVALID_PARAMETER;
  523. BAIL_ON_LOCK_ERROR(dwError);
  524. }
  525. dwError = SetIniMMPolicy(
  526. pIniMMPolicy,
  527. pMMPolicy
  528. );
  529. BAIL_ON_LOCK_ERROR(dwError);
  530. if (pIniMMPolicy->bIsPersisted) {
  531. dwError = PersistMMPolicy(
  532. pMMPolicy
  533. );
  534. BAIL_ON_LOCK_ERROR(dwError);
  535. }
  536. LEAVE_SPD_SECTION();
  537. (VOID) IKENotifyPolicyChange(
  538. &(pMMPolicy->gPolicyID),
  539. POLICY_GUID_MM
  540. );
  541. return (dwError);
  542. lock:
  543. LEAVE_SPD_SECTION();
  544. error:
  545. return (dwError);
  546. }
  547. DWORD
  548. GetMMPolicy(
  549. LPWSTR pServerName,
  550. LPWSTR pszPolicyName,
  551. PIPSEC_MM_POLICY * ppMMPolicy
  552. )
  553. /*++
  554. Routine Description:
  555. This function gets a main mode policy from the SPD.
  556. Arguments:
  557. pServerName - Server from which to get the main mode policy.
  558. pszPolicyName - Name of the main mode policy to get.
  559. ppMMPolicy - Main mode policy found returned to the caller.
  560. Return Value:
  561. ERROR_SUCCESS - Success.
  562. Win32 Error - Failure.
  563. --*/
  564. {
  565. DWORD dwError = 0;
  566. PINIMMPOLICY pIniMMPolicy = NULL;
  567. PIPSEC_MM_POLICY pMMPolicy = NULL;
  568. if (!pszPolicyName || !*pszPolicyName) {
  569. dwError = ERROR_INVALID_PARAMETER;
  570. BAIL_ON_WIN32_ERROR(dwError);
  571. }
  572. ENTER_SPD_SECTION();
  573. dwError = ValidateSecurity(
  574. SPD_OBJECT_SERVER,
  575. SERVER_ACCESS_ADMINISTER,
  576. NULL,
  577. NULL
  578. );
  579. BAIL_ON_LOCK_ERROR(dwError);
  580. pIniMMPolicy = FindMMPolicy(
  581. gpIniMMPolicy,
  582. pszPolicyName
  583. );
  584. if (!pIniMMPolicy) {
  585. dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND;
  586. BAIL_ON_LOCK_ERROR(dwError);
  587. }
  588. dwError = GetIniMMPolicy(
  589. pIniMMPolicy,
  590. &pMMPolicy
  591. );
  592. BAIL_ON_LOCK_ERROR(dwError);
  593. *ppMMPolicy = pMMPolicy;
  594. LEAVE_SPD_SECTION();
  595. return (dwError);
  596. lock:
  597. LEAVE_SPD_SECTION();
  598. error:
  599. *ppMMPolicy = NULL;
  600. return (dwError);
  601. }
  602. DWORD
  603. SetIniMMPolicy(
  604. PINIMMPOLICY pIniMMPolicy,
  605. PIPSEC_MM_POLICY pMMPolicy
  606. )
  607. {
  608. DWORD dwError = 0;
  609. DWORD dwOfferCount = 0;
  610. PIPSEC_MM_OFFER pOffers = NULL;
  611. dwError = CreateIniMMOffers(
  612. pMMPolicy->dwOfferCount,
  613. pMMPolicy->pOffers,
  614. &dwOfferCount,
  615. &pOffers
  616. );
  617. BAIL_ON_WIN32_ERROR(dwError);
  618. FreeIniMMOffers(
  619. pIniMMPolicy->dwOfferCount,
  620. pIniMMPolicy->pOffers
  621. );
  622. if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
  623. gpIniDefaultMMPolicy = NULL;
  624. }
  625. pIniMMPolicy->dwFlags = pMMPolicy->dwFlags;
  626. pIniMMPolicy->uSoftSAExpirationTime = pMMPolicy->uSoftSAExpirationTime;
  627. pIniMMPolicy->dwOfferCount = dwOfferCount;
  628. pIniMMPolicy->pOffers = pOffers;
  629. if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
  630. gpIniDefaultMMPolicy = pIniMMPolicy;
  631. }
  632. error:
  633. return (dwError);
  634. }
  635. DWORD
  636. GetIniMMPolicy(
  637. PINIMMPOLICY pIniMMPolicy,
  638. PIPSEC_MM_POLICY * ppMMPolicy
  639. )
  640. {
  641. DWORD dwError = 0;
  642. PIPSEC_MM_POLICY pMMPolicy = NULL;
  643. dwError = SPDApiBufferAllocate(
  644. sizeof(IPSEC_MM_POLICY),
  645. &pMMPolicy
  646. );
  647. BAIL_ON_WIN32_ERROR(dwError);
  648. dwError = CopyMMPolicy(
  649. pIniMMPolicy,
  650. pMMPolicy
  651. );
  652. BAIL_ON_WIN32_ERROR(dwError);
  653. *ppMMPolicy = pMMPolicy;
  654. return (dwError);
  655. error:
  656. if (pMMPolicy) {
  657. SPDApiBufferFree(pMMPolicy);
  658. }
  659. *ppMMPolicy = NULL;
  660. return (dwError);
  661. }
  662. DWORD
  663. CopyMMPolicy(
  664. PINIMMPOLICY pIniMMPolicy,
  665. PIPSEC_MM_POLICY pMMPolicy
  666. )
  667. {
  668. DWORD dwError = 0;
  669. memcpy(
  670. &(pMMPolicy->gPolicyID),
  671. &(pIniMMPolicy->gPolicyID),
  672. sizeof(GUID)
  673. );
  674. dwError = SPDApiBufferAllocate(
  675. wcslen(pIniMMPolicy->pszPolicyName)*sizeof(WCHAR)
  676. + sizeof(WCHAR),
  677. &(pMMPolicy->pszPolicyName)
  678. );
  679. BAIL_ON_WIN32_ERROR(dwError);
  680. wcscpy(pMMPolicy->pszPolicyName, pIniMMPolicy->pszPolicyName);
  681. pMMPolicy->dwFlags = pIniMMPolicy->dwFlags;
  682. pMMPolicy->uSoftSAExpirationTime = pIniMMPolicy->uSoftSAExpirationTime;
  683. dwError = CreateMMOffers(
  684. pIniMMPolicy->dwOfferCount,
  685. pIniMMPolicy->pOffers,
  686. &(pMMPolicy->dwOfferCount),
  687. &(pMMPolicy->pOffers)
  688. );
  689. BAIL_ON_WIN32_ERROR(dwError);
  690. return (dwError);
  691. error:
  692. if (pMMPolicy->pszPolicyName) {
  693. SPDApiBufferFree(pMMPolicy->pszPolicyName);
  694. }
  695. return (dwError);
  696. }
  697. DWORD
  698. CreateMMOffers(
  699. DWORD dwInOfferCount,
  700. PIPSEC_MM_OFFER pInOffers,
  701. PDWORD pdwOfferCount,
  702. PIPSEC_MM_OFFER * ppOffers
  703. )
  704. {
  705. DWORD dwError = 0;
  706. PIPSEC_MM_OFFER pOffers = NULL;
  707. PIPSEC_MM_OFFER pTemp = NULL;
  708. PIPSEC_MM_OFFER pInTempOffer = NULL;
  709. DWORD i = 0;
  710. //
  711. // Offer count and the offers themselves have already been validated.
  712. //
  713. dwError = SPDApiBufferAllocate(
  714. sizeof(IPSEC_MM_OFFER) * dwInOfferCount,
  715. &(pOffers)
  716. );
  717. BAIL_ON_WIN32_ERROR(dwError);
  718. pTemp = pOffers;
  719. pInTempOffer = pInOffers;
  720. for (i = 0; i < dwInOfferCount; i++) {
  721. memcpy(
  722. &(pTemp->Lifetime),
  723. &(pInTempOffer->Lifetime),
  724. sizeof(KEY_LIFETIME)
  725. );
  726. pTemp->dwFlags = pInTempOffer->dwFlags;
  727. pTemp->dwQuickModeLimit = pInTempOffer->dwQuickModeLimit;
  728. pTemp->dwDHGroup = pInTempOffer->dwDHGroup;
  729. memcpy(
  730. &(pTemp->EncryptionAlgorithm),
  731. &(pInTempOffer->EncryptionAlgorithm),
  732. sizeof(IPSEC_MM_ALGO)
  733. );
  734. memcpy(
  735. &(pTemp->HashingAlgorithm),
  736. &(pInTempOffer->HashingAlgorithm),
  737. sizeof(IPSEC_MM_ALGO)
  738. );
  739. pInTempOffer++;
  740. pTemp++;
  741. }
  742. *pdwOfferCount = dwInOfferCount;
  743. *ppOffers = pOffers;
  744. return (dwError);
  745. error:
  746. if (pOffers) {
  747. FreeMMOffers(
  748. i,
  749. pOffers
  750. );
  751. }
  752. *pdwOfferCount = 0;
  753. *ppOffers = NULL;
  754. return (dwError);
  755. }
  756. DWORD
  757. DeleteIniMMPolicy(
  758. PINIMMPOLICY pIniMMPolicy
  759. )
  760. {
  761. DWORD dwError = 0;
  762. PINIMMPOLICY * ppTemp = NULL;
  763. ppTemp = &gpIniMMPolicy;
  764. while (*ppTemp) {
  765. if (*ppTemp == pIniMMPolicy) {
  766. break;
  767. }
  768. ppTemp = &((*ppTemp)->pNext);
  769. }
  770. if (*ppTemp) {
  771. *ppTemp = pIniMMPolicy->pNext;
  772. }
  773. if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
  774. gpIniDefaultMMPolicy = NULL;
  775. }
  776. FreeIniMMPolicy(pIniMMPolicy);
  777. return (dwError);
  778. }
  779. VOID
  780. FreeMMOffers(
  781. DWORD dwOfferCount,
  782. PIPSEC_MM_OFFER pOffers
  783. )
  784. {
  785. if (pOffers) {
  786. SPDApiBufferFree(pOffers);
  787. }
  788. }
  789. VOID
  790. FreeIniMMPolicyList(
  791. PINIMMPOLICY pIniMMPolicyList
  792. )
  793. {
  794. PINIMMPOLICY pTemp = NULL;
  795. PINIMMPOLICY pIniMMPolicy = NULL;
  796. pTemp = pIniMMPolicyList;
  797. while (pTemp) {
  798. pIniMMPolicy = pTemp;
  799. pTemp = pTemp->pNext;
  800. FreeIniMMPolicy(pIniMMPolicy);
  801. }
  802. }
  803. PINIMMPOLICY
  804. FindMMPolicyByGuid(
  805. PINIMMPOLICY pIniMMPolicyList,
  806. GUID gPolicyID
  807. )
  808. {
  809. DWORD dwError = 0;
  810. PINIMMPOLICY pTemp = NULL;
  811. pTemp = pIniMMPolicyList;
  812. while (pTemp) {
  813. if (!memcmp(&(pTemp->gPolicyID), &gPolicyID, sizeof(GUID))) {
  814. return (pTemp);
  815. }
  816. pTemp = pTemp->pNext;
  817. }
  818. return (NULL);
  819. }
  820. VOID
  821. FreeMMPolicies(
  822. DWORD dwNumMMPolicies,
  823. PIPSEC_MM_POLICY pMMPolicies
  824. )
  825. {
  826. DWORD i = 0;
  827. if (pMMPolicies) {
  828. for (i = 0; i < dwNumMMPolicies; i++) {
  829. if (pMMPolicies[i].pszPolicyName) {
  830. SPDApiBufferFree(pMMPolicies[i].pszPolicyName);
  831. }
  832. FreeMMOffers(
  833. pMMPolicies[i].dwOfferCount,
  834. pMMPolicies[i].pOffers
  835. );
  836. }
  837. SPDApiBufferFree(pMMPolicies);
  838. }
  839. }
  840. DWORD
  841. GetMMPolicyByID(
  842. LPWSTR pServerName,
  843. GUID gMMPolicyID,
  844. PIPSEC_MM_POLICY * ppMMPolicy
  845. )
  846. /*++
  847. Routine Description:
  848. This function gets a main mode policy from the SPD.
  849. Arguments:
  850. pServerName - Server from which to get the main mode policy.
  851. gMMPolicyID - Guid of the main mode policy to get.
  852. ppMMPolicy - Main mode policy found returned to the caller.
  853. Return Value:
  854. ERROR_SUCCESS - Success.
  855. Win32 Error - Failure.
  856. --*/
  857. {
  858. DWORD dwError = 0;
  859. PINIMMPOLICY pIniMMPolicy = NULL;
  860. PIPSEC_MM_POLICY pMMPolicy = NULL;
  861. ENTER_SPD_SECTION();
  862. dwError = ValidateSecurity(
  863. SPD_OBJECT_SERVER,
  864. SERVER_ACCESS_ADMINISTER,
  865. NULL,
  866. NULL
  867. );
  868. BAIL_ON_LOCK_ERROR(dwError);
  869. pIniMMPolicy = FindMMPolicyByGuid(
  870. gpIniMMPolicy,
  871. gMMPolicyID
  872. );
  873. if (!pIniMMPolicy) {
  874. dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND;
  875. BAIL_ON_LOCK_ERROR(dwError);
  876. }
  877. dwError = GetIniMMPolicy(
  878. pIniMMPolicy,
  879. &pMMPolicy
  880. );
  881. BAIL_ON_LOCK_ERROR(dwError);
  882. *ppMMPolicy = pMMPolicy;
  883. LEAVE_SPD_SECTION();
  884. return (dwError);
  885. lock:
  886. LEAVE_SPD_SECTION();
  887. *ppMMPolicy = NULL;
  888. return (dwError);
  889. }
  890. DWORD
  891. LocateMMPolicy(
  892. PMM_FILTER pMMFilter,
  893. PINIMMPOLICY * ppIniMMPolicy
  894. )
  895. {
  896. DWORD dwError = 0;
  897. PINIMMPOLICY pIniMMPolicy = NULL;
  898. if ((pMMFilter->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
  899. if (!gpIniDefaultMMPolicy) {
  900. dwError = ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND;
  901. BAIL_ON_WIN32_ERROR(dwError);
  902. }
  903. pIniMMPolicy = gpIniDefaultMMPolicy;
  904. }
  905. else {
  906. pIniMMPolicy = FindMMPolicyByGuid(
  907. gpIniMMPolicy,
  908. pMMFilter->gPolicyID
  909. );
  910. if (!pIniMMPolicy) {
  911. dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND;
  912. BAIL_ON_WIN32_ERROR(dwError);
  913. }
  914. }
  915. *ppIniMMPolicy = pIniMMPolicy;
  916. return (dwError);
  917. error:
  918. *ppIniMMPolicy = NULL;
  919. return (dwError);
  920. }