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.

1708 lines
40 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. mmspecific.c
  5. Abstract:
  6. This module contains all of the code to drive the
  7. mm specific filter list management of IPSecSPD Service.
  8. Author:
  9. abhisheV 08-December-1999
  10. Environment
  11. User Level: Win32
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. DWORD
  16. ApplyMMTransform(
  17. PINIMMFILTER pFilter,
  18. MATCHING_ADDR * pMatchingAddresses,
  19. DWORD dwAddrCnt,
  20. PSPECIAL_ADDR pSpecialAddrsList,
  21. PINIMMSFILTER * ppSpecificFilters
  22. )
  23. /*++
  24. Routine Description:
  25. This function expands a generic mm filter into its
  26. corresponding specific filters.
  27. Arguments:
  28. pFilter - Generic filter to expand.
  29. pMatchingAddresses - List of local ip addresses whose interface
  30. type matches that of the filter.
  31. dwAddrCnt - Number of local ip addresses in the list.
  32. ppSpecificFilters - List of specific filters expanded for the
  33. given generic filter.
  34. Return Value:
  35. ERROR_SUCCESS - Success.
  36. Win32 Error - Failure.
  37. --*/
  38. {
  39. DWORD dwError = 0;
  40. PINIMMSFILTER pSpecificFilters = NULL;
  41. PINIMMSFILTER pOutboundSpecificFilters = NULL;
  42. PINIMMSFILTER pInboundSpecificFilters = NULL;
  43. PADDR_V4 pOutSrcAddrList = NULL;
  44. DWORD dwOutSrcAddrCnt = 0;
  45. PADDR_V4 pInSrcAddrList = NULL;
  46. DWORD dwInSrcAddrCnt = 0;
  47. PADDR_V4 pOutDesAddrList = NULL;
  48. DWORD dwOutDesAddrCnt = 0;
  49. PADDR_V4 pInDesAddrList = NULL;
  50. DWORD dwInDesAddrCnt = 0;
  51. //
  52. // Form the outbound and inbound source and destination
  53. // address lists.
  54. //
  55. dwError = FormMMOutboundInboundAddresses(
  56. pFilter,
  57. pMatchingAddresses,
  58. dwAddrCnt,
  59. pSpecialAddrsList,
  60. &pOutSrcAddrList,
  61. &dwOutSrcAddrCnt,
  62. &pInSrcAddrList,
  63. &dwInSrcAddrCnt,
  64. &pOutDesAddrList,
  65. &dwOutDesAddrCnt,
  66. &pInDesAddrList,
  67. &dwInDesAddrCnt
  68. );
  69. BAIL_ON_WIN32_ERROR(dwError);
  70. //
  71. // Form outbound specific filters.
  72. //
  73. dwError = FormSpecificMMFilters(
  74. pFilter,
  75. pOutSrcAddrList,
  76. dwOutSrcAddrCnt,
  77. pOutDesAddrList,
  78. dwOutDesAddrCnt,
  79. FILTER_DIRECTION_OUTBOUND,
  80. &pOutboundSpecificFilters
  81. );
  82. BAIL_ON_WIN32_ERROR(dwError);
  83. //
  84. // Form inbound specific filters.
  85. //
  86. dwError = FormSpecificMMFilters(
  87. pFilter,
  88. pInSrcAddrList,
  89. dwInSrcAddrCnt,
  90. pInDesAddrList,
  91. dwInDesAddrCnt,
  92. FILTER_DIRECTION_INBOUND,
  93. &pInboundSpecificFilters
  94. );
  95. BAIL_ON_WIN32_ERROR(dwError);
  96. pSpecificFilters = pOutboundSpecificFilters;
  97. AddToSpecificMMList(
  98. &pSpecificFilters,
  99. pInboundSpecificFilters
  100. );
  101. *ppSpecificFilters = pSpecificFilters;
  102. cleanup:
  103. if (pOutSrcAddrList) {
  104. FreeSPDMemory(pOutSrcAddrList);
  105. }
  106. if (pInSrcAddrList) {
  107. FreeSPDMemory(pInSrcAddrList);
  108. }
  109. if (pOutDesAddrList) {
  110. FreeSPDMemory(pOutDesAddrList);
  111. }
  112. if (pInDesAddrList) {
  113. FreeSPDMemory(pInDesAddrList);
  114. }
  115. return (dwError);
  116. error:
  117. if (pOutboundSpecificFilters) {
  118. FreeIniMMSFilterList(pOutboundSpecificFilters);
  119. }
  120. if (pInboundSpecificFilters) {
  121. FreeIniMMSFilterList(pInboundSpecificFilters);
  122. }
  123. *ppSpecificFilters = NULL;
  124. goto cleanup;
  125. }
  126. DWORD
  127. FormMMOutboundInboundAddresses(
  128. PINIMMFILTER pFilter,
  129. MATCHING_ADDR * pMatchingAddresses,
  130. DWORD dwAddrCnt,
  131. PSPECIAL_ADDR pSpecialAddrsList,
  132. PADDR_V4 * ppOutSrcAddrList,
  133. PDWORD pdwOutSrcAddrCnt,
  134. PADDR_V4 * ppInSrcAddrList,
  135. PDWORD pdwInSrcAddrCnt,
  136. PADDR_V4 * ppOutDesAddrList,
  137. PDWORD pdwOutDesAddrCnt,
  138. PADDR_V4 * ppInDesAddrList,
  139. PDWORD pdwInDesAddrCnt
  140. )
  141. /*++
  142. Routine Description:
  143. This function forms the outbound and inbound source and
  144. destination address sets for a generic filter.
  145. Arguments:
  146. pFilter - Generic filter under consideration.
  147. pMatchingAddresses - List of local ip addresses whose interface
  148. type matches that of the filter.
  149. dwAddrCnt - Number of local ip addresses in the list.
  150. ppOutSrcAddrList - List of outbound source addresses.
  151. pdwOutSrcAddrCnt - Number of addresses in the outbound
  152. source address list.
  153. ppInSrcAddrList - List of inbound source addresses.
  154. pdwInSrcAddrCnt - Number of addresses in the inbound
  155. source address list.
  156. ppOutDesAddrList - List of outbound destination addresses.
  157. pdwOutDesAddrCnt - Number of addresses in the outbound
  158. destination address list.
  159. ppInDesAddrList - List of inbound destination addresses.
  160. pdwInDesAddrCnt - Number of addresses in the inbound
  161. destination address list.
  162. Return Value:
  163. ERROR_SUCCESS - Success.
  164. Win32 Error - Failure.
  165. --*/
  166. {
  167. DWORD dwError = 0;
  168. PADDR_V4 pSrcAddrList = NULL;
  169. DWORD dwSrcAddrCnt = 0;
  170. PADDR_V4 pDesAddrList = NULL;
  171. DWORD dwDesAddrCnt = 0;
  172. PADDR_V4 pOutSrcAddrList = NULL;
  173. DWORD dwOutSrcAddrCnt = 0;
  174. PADDR_V4 pInSrcAddrList = NULL;
  175. DWORD dwInSrcAddrCnt = 0;
  176. PADDR_V4 pOutDesAddrList = NULL;
  177. DWORD dwOutDesAddrCnt = 0;
  178. PADDR_V4 pInDesAddrList = NULL;
  179. DWORD dwInDesAddrCnt = 0;
  180. //
  181. // Replace wild card information to generate the new source
  182. // address list.
  183. //
  184. dwError = FormAddressList(
  185. pFilter->SrcAddr,
  186. pMatchingAddresses,
  187. dwAddrCnt,
  188. pSpecialAddrsList,
  189. pFilter->InterfaceType,
  190. &pSrcAddrList,
  191. &dwSrcAddrCnt
  192. );
  193. BAIL_ON_WIN32_ERROR(dwError);
  194. //
  195. // Replace wild card information to generate the new destination
  196. // address list.
  197. //
  198. dwError = FormAddressList(
  199. pFilter->DesAddr,
  200. pMatchingAddresses,
  201. dwAddrCnt,
  202. pSpecialAddrsList,
  203. pFilter->InterfaceType,
  204. &pDesAddrList,
  205. &dwDesAddrCnt
  206. );
  207. BAIL_ON_WIN32_ERROR(dwError);
  208. //
  209. // Separate the source address list into outbound and inbound
  210. // source address sets based on the local machine's ip addresses.
  211. //
  212. dwError = SeparateAddrList(
  213. pFilter->SrcAddr.AddrType,
  214. pSrcAddrList,
  215. dwSrcAddrCnt,
  216. pMatchingAddresses,
  217. dwAddrCnt,
  218. &pOutSrcAddrList,
  219. &dwOutSrcAddrCnt,
  220. &pInSrcAddrList,
  221. &dwInSrcAddrCnt
  222. );
  223. BAIL_ON_WIN32_ERROR(dwError);
  224. //
  225. // Separate the destination address list into outbound and inbound
  226. // destination address sets based on the local machine's ip
  227. // addresses.
  228. //
  229. dwError = SeparateAddrList(
  230. pFilter->DesAddr.AddrType,
  231. pDesAddrList,
  232. dwDesAddrCnt,
  233. pMatchingAddresses,
  234. dwAddrCnt,
  235. &pInDesAddrList,
  236. &dwInDesAddrCnt,
  237. &pOutDesAddrList,
  238. &dwOutDesAddrCnt
  239. );
  240. BAIL_ON_WIN32_ERROR(dwError);
  241. *ppOutSrcAddrList = pOutSrcAddrList;
  242. *pdwOutSrcAddrCnt = dwOutSrcAddrCnt;
  243. *ppInSrcAddrList = pInSrcAddrList;
  244. *pdwInSrcAddrCnt = dwInSrcAddrCnt;
  245. *ppOutDesAddrList = pOutDesAddrList;
  246. *pdwOutDesAddrCnt = dwOutDesAddrCnt;
  247. *ppInDesAddrList = pInDesAddrList;
  248. *pdwInDesAddrCnt = dwInDesAddrCnt;
  249. cleanup:
  250. if (pSrcAddrList) {
  251. FreeSPDMemory(pSrcAddrList);
  252. }
  253. if (pDesAddrList) {
  254. FreeSPDMemory(pDesAddrList);
  255. }
  256. return (dwError);
  257. error:
  258. if (pOutSrcAddrList) {
  259. FreeSPDMemory(pOutSrcAddrList);
  260. }
  261. if (pInSrcAddrList) {
  262. FreeSPDMemory(pInSrcAddrList);
  263. }
  264. if (pOutDesAddrList) {
  265. FreeSPDMemory(pOutDesAddrList);
  266. }
  267. if (pInDesAddrList) {
  268. FreeSPDMemory(pInDesAddrList);
  269. }
  270. *ppOutSrcAddrList = NULL;
  271. *pdwOutSrcAddrCnt = 0;
  272. *ppInSrcAddrList = NULL;
  273. *pdwInSrcAddrCnt = 0;
  274. *ppOutDesAddrList = NULL;
  275. *pdwOutDesAddrCnt = 0;
  276. *ppInDesAddrList = NULL;
  277. *pdwInDesAddrCnt = 0;
  278. goto cleanup;
  279. }
  280. DWORD
  281. FormSpecificMMFilters(
  282. PINIMMFILTER pFilter,
  283. PADDR_V4 pSrcAddrList,
  284. DWORD dwSrcAddrCnt,
  285. PADDR_V4 pDesAddrList,
  286. DWORD dwDesAddrCnt,
  287. DWORD dwDirection,
  288. PINIMMSFILTER * ppSpecificFilters
  289. )
  290. /*++
  291. Routine Description:
  292. This function forms the specific main mode filters
  293. for the given generic filter and the source and
  294. destination address sets.
  295. Arguments:
  296. pFilter - Generic filter for which specific filters
  297. are to be created.
  298. pSrcAddrList - List of source addresses.
  299. dwSrcAddrCnt - Number of addresses in the source
  300. address list.
  301. pDesAddrList - List of destination addresses.
  302. dwDesAddrCnt - Number of addresses in the destination
  303. address list.
  304. ppSpecificFilters - Specific filters created for the given
  305. generic filter and the given addresses.
  306. Return Value:
  307. ERROR_SUCCESS - Success.
  308. Win32 Error - Failure.
  309. --*/
  310. {
  311. DWORD dwError = 0;
  312. PINIMMSFILTER pSpecificFilters = NULL;
  313. DWORD i = 0, j = 0;
  314. PINIMMSFILTER pSpecificFilter = NULL;
  315. for (i = 0; i < dwSrcAddrCnt; i++) {
  316. for (j = 0; j < dwDesAddrCnt; j++) {
  317. dwError = CreateSpecificMMFilter(
  318. pFilter,
  319. pSrcAddrList[i],
  320. pDesAddrList[j],
  321. &pSpecificFilter
  322. );
  323. BAIL_ON_WIN32_ERROR(dwError);
  324. //
  325. // Set the direction of the filter.
  326. //
  327. pSpecificFilter->dwDirection = dwDirection;
  328. AssignMMFilterWeight(pSpecificFilter);
  329. AddToSpecificMMList(
  330. &pSpecificFilters,
  331. pSpecificFilter
  332. );
  333. }
  334. }
  335. *ppSpecificFilters = pSpecificFilters;
  336. return (dwError);
  337. error:
  338. if (pSpecificFilters) {
  339. FreeIniMMSFilterList(pSpecificFilters);
  340. }
  341. *ppSpecificFilters = NULL;
  342. return (dwError);
  343. }
  344. DWORD
  345. CreateSpecificMMFilter(
  346. PINIMMFILTER pGenericFilter,
  347. ADDR_V4 SrcAddr,
  348. ADDR_V4 DesAddr,
  349. PINIMMSFILTER * ppSpecificFilter
  350. )
  351. {
  352. DWORD dwError = 0;
  353. PINIMMSFILTER pSpecificFilter = NULL;
  354. dwError = AllocateSPDMemory(
  355. sizeof(INIMMSFILTER),
  356. &pSpecificFilter
  357. );
  358. BAIL_ON_WIN32_ERROR(dwError);
  359. pSpecificFilter->cRef = 0;
  360. pSpecificFilter->IpVersion = pGenericFilter->IpVersion;
  361. CopyGuid(pGenericFilter->gFilterID, &(pSpecificFilter->gParentID));
  362. dwError = AllocateSPDString(
  363. pGenericFilter->pszFilterName,
  364. &(pSpecificFilter->pszFilterName)
  365. );
  366. BAIL_ON_WIN32_ERROR(dwError);
  367. pSpecificFilter->InterfaceType = pGenericFilter->InterfaceType;
  368. pSpecificFilter->dwFlags = pGenericFilter->dwFlags;
  369. CopyAddresses(SrcAddr, &(pSpecificFilter->SrcAddr));
  370. CopyAddresses(DesAddr, &(pSpecificFilter->DesAddr));
  371. //
  372. // Direction must be set in the calling routine.
  373. //
  374. pSpecificFilter->dwDirection = 0;
  375. //
  376. // Weight must be set in the calling routine.
  377. //
  378. pSpecificFilter->dwWeight = 0;
  379. CopyGuid(pGenericFilter->gMMAuthID, &(pSpecificFilter->gMMAuthID));
  380. CopyGuid(pGenericFilter->gPolicyID, &(pSpecificFilter->gPolicyID));
  381. pSpecificFilter->pIniMMAuthMethods = NULL;
  382. pSpecificFilter->pIniMMPolicy = NULL;
  383. pSpecificFilter->pNext = NULL;
  384. *ppSpecificFilter = pSpecificFilter;
  385. return (dwError);
  386. error:
  387. if (pSpecificFilter) {
  388. FreeIniMMSFilter(pSpecificFilter);
  389. }
  390. *ppSpecificFilter = NULL;
  391. return (dwError);
  392. }
  393. VOID
  394. AssignMMFilterWeight(
  395. PINIMMSFILTER pSpecificFilter
  396. )
  397. /*++
  398. Routine Description:
  399. Computes and assigns the weight to a specific mm filter.
  400. The mm filter weight consists of the following:
  401. 31 16 12 8 0
  402. +-----------+--------+-----------+--------+
  403. |AddrMaskWgt| Reserved |
  404. +-----------+--------+-----------+--------+
  405. Arguments:
  406. pSpecificFilter - Specific mm filter to which the weight
  407. is to be assigned.
  408. Return Value:
  409. None.
  410. --*/
  411. {
  412. DWORD dwWeight = 0;
  413. ULONG SrcMask = 0;
  414. ULONG DesMask = 0;
  415. DWORD dwSrcMaskWeight = 0;
  416. DWORD dwDesMaskWeight = 0;
  417. DWORD dwMaskWeight = 0;
  418. DWORD i = 0;
  419. //
  420. // Weight Rule:
  421. // A field with a more specific value gets a higher weight than
  422. // the same field with a lesser specific value.
  423. //
  424. //
  425. // IP addresses get the weight values based on their mask values.
  426. // In the address case, the weight is computed as a sum of the
  427. // bit positions starting from the position that contains the
  428. // first least significant non-zero bit to the most significant
  429. // bit position of the mask.
  430. // All unique ip addresses have a mask of 0xFFFFFFFF and thus get
  431. // the same weight, which is 1 + 2 + .... + 32.
  432. // A subnet address has a mask with atleast the least significant
  433. // bit zero and thus gets weight in the range (2 + .. + 32) to 0.
  434. //
  435. DesMask = ntohl(pSpecificFilter->DesAddr.uSubNetMask);
  436. for (i = 0; i < sizeof(ULONG) * 8; i++) {
  437. //
  438. // If the bit position contains a non-zero bit, add the bit
  439. // position to the sum.
  440. //
  441. if ((DesMask & 0x1) == 0x1) {
  442. dwMaskWeight += (i+1);
  443. dwDesMaskWeight += (i+1);
  444. }
  445. //
  446. // Move to the next bit position.
  447. //
  448. DesMask = DesMask >> 1;
  449. }
  450. SrcMask = ntohl(pSpecificFilter->SrcAddr.uSubNetMask);
  451. for (i = 0; i < sizeof(ULONG) * 8; i++) {
  452. //
  453. // If the bit position contains a non-zero bit, add the bit
  454. // position to the sum.
  455. //
  456. if ((SrcMask & 0x1) == 0x1) {
  457. dwMaskWeight += (i+1);
  458. dwSrcMaskWeight += (i+1);
  459. }
  460. //
  461. // Move to the next bit position.
  462. //
  463. SrcMask = SrcMask >> 1;
  464. }
  465. if (dwDesMaskWeight >= dwSrcMaskWeight) {
  466. dwWeight |= WEIGHT_ADDRESS_TIE_BREAKER;
  467. }
  468. //
  469. // Move the mask weight to the set of bits in the overall weight
  470. // that it occupies.
  471. //
  472. dwMaskWeight = dwMaskWeight << 16;
  473. dwWeight += dwMaskWeight;
  474. pSpecificFilter->dwWeight = dwWeight;
  475. }
  476. VOID
  477. AddToSpecificMMList(
  478. PINIMMSFILTER * ppSpecificMMFilterList,
  479. PINIMMSFILTER pSpecificMMFilters
  480. )
  481. {
  482. PINIMMSFILTER pListOne = NULL;
  483. PINIMMSFILTER pListTwo = NULL;
  484. PINIMMSFILTER pListMerge = NULL;
  485. PINIMMSFILTER pLast = NULL;
  486. if (!(*ppSpecificMMFilterList) && !pSpecificMMFilters) {
  487. return;
  488. }
  489. if (!(*ppSpecificMMFilterList)) {
  490. *ppSpecificMMFilterList = pSpecificMMFilters;
  491. return;
  492. }
  493. if (!pSpecificMMFilters) {
  494. return;
  495. }
  496. pListOne = *ppSpecificMMFilterList;
  497. pListTwo = pSpecificMMFilters;
  498. while (pListOne && pListTwo) {
  499. if ((pListOne->dwWeight) > (pListTwo->dwWeight)) {
  500. if (!pListMerge) {
  501. pListMerge = pListOne;
  502. pLast = pListOne;
  503. pListOne = pListOne->pNext;
  504. }
  505. else {
  506. pLast->pNext = pListOne;
  507. pListOne = pListOne->pNext;
  508. pLast = pLast->pNext;
  509. }
  510. }
  511. else {
  512. if (!pListMerge) {
  513. pListMerge = pListTwo;
  514. pLast = pListTwo;
  515. pListTwo = pListTwo->pNext;
  516. }
  517. else {
  518. pLast->pNext = pListTwo;
  519. pListTwo = pListTwo->pNext;
  520. pLast = pLast->pNext;
  521. }
  522. }
  523. }
  524. if (pListMerge) {
  525. if (pListOne) {
  526. pLast->pNext = pListOne;
  527. }
  528. else {
  529. pLast->pNext = pListTwo;
  530. }
  531. }
  532. *ppSpecificMMFilterList = pListMerge;
  533. return;
  534. }
  535. VOID
  536. FreeIniMMSFilterList(
  537. PINIMMSFILTER pIniMMSFilterList
  538. )
  539. {
  540. PINIMMSFILTER pFilter = NULL;
  541. PINIMMSFILTER pTempFilter = NULL;
  542. pFilter = pIniMMSFilterList;
  543. while (pFilter) {
  544. pTempFilter = pFilter;
  545. pFilter = pFilter->pNext;
  546. FreeIniMMSFilter(pTempFilter);
  547. }
  548. }
  549. VOID
  550. FreeIniMMSFilter(
  551. PINIMMSFILTER pIniMMSFilter
  552. )
  553. {
  554. if (pIniMMSFilter) {
  555. if (pIniMMSFilter->pszFilterName) {
  556. FreeSPDString(pIniMMSFilter->pszFilterName);
  557. }
  558. //
  559. // Must not ever free pIniMMSFilter->pIniMMPolicy.
  560. //
  561. FreeSPDMemory(pIniMMSFilter);
  562. }
  563. }
  564. VOID
  565. LinkMMSpecificFiltersToPolicy(
  566. PINIMMPOLICY pIniMMPolicy,
  567. PINIMMSFILTER pIniMMSFilters
  568. )
  569. {
  570. PINIMMSFILTER pTemp = NULL;
  571. pTemp = pIniMMSFilters;
  572. while (pTemp) {
  573. pTemp->pIniMMPolicy = pIniMMPolicy;
  574. pTemp = pTemp->pNext;
  575. }
  576. return;
  577. }
  578. VOID
  579. LinkMMSpecificFiltersToAuth(
  580. PINIMMAUTHMETHODS pIniMMAuthMethods,
  581. PINIMMSFILTER pIniMMSFilters
  582. )
  583. {
  584. PINIMMSFILTER pTemp = NULL;
  585. pTemp = pIniMMSFilters;
  586. while (pTemp) {
  587. pTemp->pIniMMAuthMethods = pIniMMAuthMethods;
  588. pTemp = pTemp->pNext;
  589. }
  590. return;
  591. }
  592. VOID
  593. RemoveIniMMSFilter(
  594. PINIMMSFILTER pIniMMSFilter
  595. )
  596. {
  597. PINIMMSFILTER * ppTemp = NULL;
  598. ppTemp = &gpIniMMSFilter;
  599. while (*ppTemp) {
  600. if (*ppTemp == pIniMMSFilter) {
  601. break;
  602. }
  603. ppTemp = &((*ppTemp)->pNext);
  604. }
  605. if (*ppTemp) {
  606. *ppTemp = pIniMMSFilter->pNext;
  607. }
  608. return;
  609. }
  610. DWORD
  611. EnumSpecificMMFilters(
  612. PINIMMSFILTER pIniMMSFilterList,
  613. DWORD dwResumeHandle,
  614. DWORD dwPreferredNumEntries,
  615. PMM_FILTER * ppMMFilters,
  616. PDWORD pdwNumMMFilters
  617. )
  618. /*++
  619. Routine Description:
  620. This function creates enumerated specific filters.
  621. Arguments:
  622. pIniMMSFilterList - List of specific filters to enumerate.
  623. dwResumeHandle - Location in the specific filter list from which
  624. to resume enumeration.
  625. dwPreferredNumEntries - Preferred number of enumeration entries.
  626. ppMMFilters - Enumerated filters returned to the caller.
  627. pdwNumMMFilters - Number of filters actually enumerated.
  628. Return Value:
  629. ERROR_SUCCESS - Success.
  630. Win32 Error - Failure.
  631. --*/
  632. {
  633. DWORD dwError = 0;
  634. DWORD dwNumToEnum = 0;
  635. PINIMMSFILTER pIniMMSFilter = NULL;
  636. DWORD i = 0;
  637. PINIMMSFILTER pTemp = NULL;
  638. DWORD dwNumMMFilters = 0;
  639. PMM_FILTER pMMFilters = 0;
  640. PMM_FILTER pMMFilter = 0;
  641. if (!dwPreferredNumEntries ||
  642. (dwPreferredNumEntries > MAX_MMFILTER_ENUM_COUNT)) {
  643. dwNumToEnum = MAX_MMFILTER_ENUM_COUNT;
  644. }
  645. else {
  646. dwNumToEnum = dwPreferredNumEntries;
  647. }
  648. pIniMMSFilter = pIniMMSFilterList;
  649. for (i = 0; (i < dwResumeHandle) && (pIniMMSFilter != NULL); i++) {
  650. pIniMMSFilter = pIniMMSFilter->pNext;
  651. }
  652. if (!pIniMMSFilter) {
  653. dwError = ERROR_NO_DATA;
  654. BAIL_ON_WIN32_ERROR(dwError);
  655. }
  656. pTemp = pIniMMSFilter;
  657. while (pTemp && (dwNumMMFilters < dwNumToEnum)) {
  658. dwNumMMFilters++;
  659. pTemp = pTemp->pNext;
  660. }
  661. dwError = SPDApiBufferAllocate(
  662. sizeof(MM_FILTER)*dwNumMMFilters,
  663. &pMMFilters
  664. );
  665. BAIL_ON_WIN32_ERROR(dwError);
  666. pTemp = pIniMMSFilter;
  667. pMMFilter = pMMFilters;
  668. for (i = 0; i < dwNumMMFilters; i++) {
  669. dwError = CopyMMSFilter(
  670. pTemp,
  671. pMMFilter
  672. );
  673. BAIL_ON_WIN32_ERROR(dwError);
  674. pTemp = pTemp->pNext;
  675. pMMFilter++;
  676. }
  677. *ppMMFilters = pMMFilters;
  678. *pdwNumMMFilters = dwNumMMFilters;
  679. return (dwError);
  680. error:
  681. if (pMMFilters) {
  682. FreeMMFilters(
  683. i,
  684. pMMFilters
  685. );
  686. }
  687. *ppMMFilters = NULL;
  688. *pdwNumMMFilters = 0;
  689. return (dwError);
  690. }
  691. DWORD
  692. CopyMMSFilter(
  693. PINIMMSFILTER pIniMMSFilter,
  694. PMM_FILTER pMMFilter
  695. )
  696. /*++
  697. Routine Description:
  698. This function copies an internal filter into an external filter
  699. container.
  700. Arguments:
  701. pIniMMSFilter - Internal filter to copy.
  702. pMMFilter - External filter container in which to copy.
  703. Return Value:
  704. ERROR_SUCCESS - Success.
  705. Win32 Error - Failure.
  706. --*/
  707. {
  708. DWORD dwError = 0;
  709. pMMFilter->IpVersion = pIniMMSFilter->IpVersion;
  710. CopyGuid(pIniMMSFilter->gParentID, &(pMMFilter->gFilterID));
  711. dwError = CopyName(
  712. pIniMMSFilter->pszFilterName,
  713. &(pMMFilter->pszFilterName)
  714. );
  715. BAIL_ON_WIN32_ERROR(dwError);
  716. pMMFilter->InterfaceType = pIniMMSFilter->InterfaceType;
  717. pMMFilter->bCreateMirror = FALSE;
  718. pMMFilter->dwFlags = pIniMMSFilter->dwFlags;
  719. dwError = CopyIntToExtAddresses(pIniMMSFilter->SrcAddr, &(pMMFilter->SrcAddr));
  720. BAIL_ON_WIN32_ERROR(dwError);
  721. dwError = CopyIntToExtAddresses(pIniMMSFilter->DesAddr, &(pMMFilter->DesAddr));
  722. BAIL_ON_WIN32_ERROR(dwError);
  723. pMMFilter->dwDirection = pIniMMSFilter->dwDirection;
  724. pMMFilter->dwWeight = pIniMMSFilter->dwWeight;
  725. CopyGuid(pIniMMSFilter->gMMAuthID, &(pMMFilter->gMMAuthID));
  726. CopyGuid(pIniMMSFilter->gPolicyID, &(pMMFilter->gPolicyID));
  727. return (dwError);
  728. error:
  729. if (pMMFilter->pszFilterName) {
  730. SPDApiBufferFree(pMMFilter->pszFilterName);
  731. pMMFilter->pszFilterName = NULL;
  732. }
  733. if (pMMFilter->SrcAddr.pgInterfaceID) {
  734. SPDApiBufferFree(pMMFilter->SrcAddr.pgInterfaceID);
  735. pMMFilter->SrcAddr.pgInterfaceID = NULL;
  736. }
  737. if (pMMFilter->DesAddr.pgInterfaceID) {
  738. SPDApiBufferFree(pMMFilter->DesAddr.pgInterfaceID);
  739. pMMFilter->DesAddr.pgInterfaceID = NULL;
  740. }
  741. return (dwError);
  742. }
  743. DWORD
  744. EnumSelectSpecificMMFilters(
  745. PINIMMFILTER pIniMMFilter,
  746. DWORD dwResumeHandle,
  747. DWORD dwPreferredNumEntries,
  748. PMM_FILTER * ppMMFilters,
  749. PDWORD pdwNumMMFilters
  750. )
  751. /*++
  752. Routine Description:
  753. This function creates enumerated specific filters for
  754. the given generic filter.
  755. Arguments:
  756. pIniMMFilter - Generic filter for which specific filters
  757. are to be enumerated.
  758. dwResumeHandle - Location in the specific filter list for the
  759. given generic filter from which to resume
  760. enumeration.
  761. dwPreferredNumEntries - Preferred number of enumeration entries.
  762. ppMMFilters - Enumerated filters returned to the caller.
  763. pdwNumMMFilters - Number of filters actually enumerated.
  764. Return Value:
  765. ERROR_SUCCESS - Success.
  766. Win32 Error - Failure.
  767. --*/
  768. {
  769. DWORD dwError = 0;
  770. DWORD dwNumToEnum = 0;
  771. DWORD dwNumMMSFilters = 0;
  772. PINIMMSFILTER * ppIniMMSFilters = NULL;
  773. DWORD i = 0;
  774. DWORD dwNumMMFilters = 0;
  775. PMM_FILTER pMMFilters = 0;
  776. PMM_FILTER pMMFilter = 0;
  777. if (!dwPreferredNumEntries ||
  778. (dwPreferredNumEntries > MAX_MMFILTER_ENUM_COUNT)) {
  779. dwNumToEnum = MAX_MMFILTER_ENUM_COUNT;
  780. }
  781. else {
  782. dwNumToEnum = dwPreferredNumEntries;
  783. }
  784. dwNumMMSFilters = pIniMMFilter->dwNumMMSFilters;
  785. ppIniMMSFilters = pIniMMFilter->ppIniMMSFilters;
  786. if (!dwNumMMSFilters || (dwNumMMSFilters <= dwResumeHandle)) {
  787. dwError = ERROR_NO_DATA;
  788. BAIL_ON_WIN32_ERROR(dwError);
  789. }
  790. dwNumMMFilters = min((dwNumMMSFilters-dwResumeHandle),
  791. dwNumToEnum);
  792. dwError = SPDApiBufferAllocate(
  793. sizeof(MM_FILTER)*dwNumMMFilters,
  794. &pMMFilters
  795. );
  796. BAIL_ON_WIN32_ERROR(dwError);
  797. pMMFilter = pMMFilters;
  798. for (i = 0; i < dwNumMMFilters; i++) {
  799. dwError = CopyMMSFilter(
  800. *(ppIniMMSFilters + (dwResumeHandle + i)),
  801. pMMFilter
  802. );
  803. BAIL_ON_WIN32_ERROR(dwError);
  804. pMMFilter++;
  805. }
  806. *ppMMFilters = pMMFilters;
  807. *pdwNumMMFilters = dwNumMMFilters;
  808. return (dwError);
  809. error:
  810. if (pMMFilters) {
  811. FreeMMFilters(
  812. i,
  813. pMMFilters
  814. );
  815. }
  816. *ppMMFilters = NULL;
  817. *pdwNumMMFilters = 0;
  818. return (dwError);
  819. }
  820. DWORD
  821. IntMatchMMFilter(
  822. LPWSTR pServerName,
  823. DWORD dwVersion,
  824. PMM_FILTER pMMFilter,
  825. DWORD dwFlags,
  826. DWORD dwPreferredNumEntries,
  827. PMM_FILTER * ppMatchedMMFilters,
  828. PIPSEC_MM_POLICY * ppMatchedMMPolicies,
  829. PINT_MM_AUTH_METHODS * ppMatchedMMAuthMethods,
  830. LPDWORD pdwNumMatches,
  831. LPDWORD pdwResumeHandle,
  832. LPVOID pvReserved
  833. )
  834. /*++
  835. Routine Description:
  836. This function finds the matching mm filters for the given mm
  837. filter template. The matched filters can not be more specific
  838. than the given filter template.
  839. Arguments:
  840. pServerName - Server on which a filter template is to be matched.
  841. pMMFilter - Filter template to match.
  842. dwFlags - Flags.
  843. ppMatchedMMFilters - Matched main mode filters returned to the
  844. caller.
  845. ppMatchedMMPolicies - Main mode policies corresponding to the
  846. matched main mode filters returned to the
  847. caller.
  848. ppMatchedMMAuthMethods - Main mode auth methods corresponding to the
  849. matched main mode filters returned to the
  850. caller.
  851. dwPreferredNumEntries - Preferred number of matched entries.
  852. pdwNumMatches - Number of filters actually matched.
  853. pdwResumeHandle - Handle to the location in the matched filter
  854. list from which to resume enumeration.
  855. Return Value:
  856. ERROR_SUCCESS - Success.
  857. Win32 Error - Failure.
  858. --*/
  859. {
  860. DWORD dwError = 0;
  861. DWORD dwResumeHandle = 0;
  862. DWORD dwNumToMatch = 0;
  863. PINIMMSFILTER pIniMMSFilter = NULL;
  864. DWORD i = 0;
  865. BOOL bMatches = FALSE;
  866. PINIMMSFILTER pTemp = NULL;
  867. DWORD dwNumMatches = 0;
  868. PINIMMSFILTER pLastMatchedFilter = NULL;
  869. PMM_FILTER pMatchedMMFilters = NULL;
  870. PIPSEC_MM_POLICY pMatchedMMPolicies = NULL;
  871. PINT_MM_AUTH_METHODS pMatchedMMAuthMethods = NULL;
  872. DWORD dwNumFilters = 0;
  873. DWORD dwNumPolicies = 0;
  874. DWORD dwNumAuthMethods = 0;
  875. PMM_FILTER pMatchedMMFilter = NULL;
  876. PIPSEC_MM_POLICY pMatchedMMPolicy = NULL;
  877. PINT_MM_AUTH_METHODS pTempMMAuthMethods = NULL;
  878. dwError = ValidateMMFilterTemplate(
  879. pMMFilter
  880. );
  881. BAIL_ON_WIN32_ERROR(dwError);
  882. dwResumeHandle = *pdwResumeHandle;
  883. if (!dwPreferredNumEntries) {
  884. dwNumToMatch = 1;
  885. }
  886. else if (dwPreferredNumEntries > MAX_MMFILTER_ENUM_COUNT) {
  887. dwNumToMatch = MAX_MMFILTER_ENUM_COUNT;
  888. }
  889. else {
  890. dwNumToMatch = dwPreferredNumEntries;
  891. }
  892. ENTER_SPD_SECTION();
  893. dwError = ValidateMMSecurity(
  894. SPD_OBJECT_SERVER,
  895. SERVER_ACCESS_ADMINISTER,
  896. NULL,
  897. NULL
  898. );
  899. BAIL_ON_LOCK_ERROR(dwError);
  900. pIniMMSFilter = gpIniMMSFilter;
  901. while ((i < dwResumeHandle) && (pIniMMSFilter != NULL)) {
  902. bMatches = MatchIniMMSFilter(
  903. pIniMMSFilter,
  904. pMMFilter
  905. );
  906. if (bMatches) {
  907. i++;
  908. }
  909. pIniMMSFilter = pIniMMSFilter->pNext;
  910. }
  911. if (!pIniMMSFilter) {
  912. if (!(dwFlags & RETURN_DEFAULTS_ON_NO_MATCH)) {
  913. dwError = ERROR_NO_DATA;
  914. BAIL_ON_LOCK_ERROR(dwError);
  915. }
  916. else {
  917. dwError = CopyMMMatchDefaults(
  918. &pMatchedMMFilters,
  919. &pMatchedMMAuthMethods,
  920. &pMatchedMMPolicies,
  921. &dwNumMatches
  922. );
  923. BAIL_ON_LOCK_ERROR(dwError);
  924. BAIL_ON_LOCK_SUCCESS(dwError);
  925. }
  926. }
  927. pTemp = pIniMMSFilter;
  928. while (pTemp && (dwNumMatches < dwNumToMatch)) {
  929. bMatches = MatchIniMMSFilter(
  930. pTemp,
  931. pMMFilter
  932. );
  933. if (bMatches) {
  934. pLastMatchedFilter = pTemp;
  935. dwNumMatches++;
  936. }
  937. pTemp = pTemp->pNext;
  938. }
  939. if (!dwNumMatches) {
  940. if (!(dwFlags & RETURN_DEFAULTS_ON_NO_MATCH)) {
  941. dwError = ERROR_NO_DATA;
  942. BAIL_ON_LOCK_ERROR(dwError);
  943. }
  944. else {
  945. dwError = CopyMMMatchDefaults(
  946. &pMatchedMMFilters,
  947. &pMatchedMMAuthMethods,
  948. &pMatchedMMPolicies,
  949. &dwNumMatches
  950. );
  951. BAIL_ON_LOCK_ERROR(dwError);
  952. BAIL_ON_LOCK_SUCCESS(dwError);
  953. }
  954. }
  955. dwError = SPDApiBufferAllocate(
  956. sizeof(MM_FILTER)*dwNumMatches,
  957. &pMatchedMMFilters
  958. );
  959. BAIL_ON_LOCK_ERROR(dwError);
  960. dwError = SPDApiBufferAllocate(
  961. sizeof(IPSEC_MM_POLICY)*dwNumMatches,
  962. &pMatchedMMPolicies
  963. );
  964. BAIL_ON_LOCK_ERROR(dwError);
  965. dwError = SPDApiBufferAllocate(
  966. sizeof(INT_MM_AUTH_METHODS)*dwNumMatches,
  967. &pMatchedMMAuthMethods
  968. );
  969. BAIL_ON_LOCK_ERROR(dwError);
  970. if (dwNumMatches == 1) {
  971. dwError = CopyMMSFilter(
  972. pLastMatchedFilter,
  973. pMatchedMMFilters
  974. );
  975. BAIL_ON_LOCK_ERROR(dwError);
  976. dwNumFilters++;
  977. if (pLastMatchedFilter->pIniMMPolicy) {
  978. dwError = CopyMMPolicy(
  979. pLastMatchedFilter->pIniMMPolicy,
  980. pMatchedMMPolicies
  981. );
  982. BAIL_ON_LOCK_ERROR(dwError);
  983. }
  984. else {
  985. memset(pMatchedMMPolicies, 0, sizeof(IPSEC_MM_POLICY));
  986. }
  987. dwNumPolicies++;
  988. if (pLastMatchedFilter->pIniMMAuthMethods) {
  989. dwError = CopyMMAuthMethods(
  990. pLastMatchedFilter->pIniMMAuthMethods,
  991. pMatchedMMAuthMethods
  992. );
  993. BAIL_ON_LOCK_ERROR(dwError);
  994. }
  995. else {
  996. memset(pMatchedMMAuthMethods, 0, sizeof(INT_MM_AUTH_METHODS));
  997. }
  998. dwNumAuthMethods++;
  999. }
  1000. else {
  1001. pTemp = pIniMMSFilter;
  1002. pMatchedMMFilter = pMatchedMMFilters;
  1003. pMatchedMMPolicy = pMatchedMMPolicies;
  1004. pTempMMAuthMethods = pMatchedMMAuthMethods;
  1005. i = 0;
  1006. while (i < dwNumMatches) {
  1007. bMatches = MatchIniMMSFilter(
  1008. pTemp,
  1009. pMMFilter
  1010. );
  1011. if (bMatches) {
  1012. dwError = CopyMMSFilter(
  1013. pTemp,
  1014. pMatchedMMFilter
  1015. );
  1016. BAIL_ON_LOCK_ERROR(dwError);
  1017. pMatchedMMFilter++;
  1018. dwNumFilters++;
  1019. if (pTemp->pIniMMPolicy) {
  1020. dwError = CopyMMPolicy(
  1021. pTemp->pIniMMPolicy,
  1022. pMatchedMMPolicy
  1023. );
  1024. BAIL_ON_LOCK_ERROR(dwError);
  1025. }
  1026. else {
  1027. memset(pMatchedMMPolicy, 0, sizeof(IPSEC_MM_POLICY));
  1028. }
  1029. pMatchedMMPolicy++;
  1030. dwNumPolicies++;
  1031. if (pTemp->pIniMMAuthMethods) {
  1032. dwError = CopyMMAuthMethods(
  1033. pTemp->pIniMMAuthMethods,
  1034. pTempMMAuthMethods
  1035. );
  1036. BAIL_ON_LOCK_ERROR(dwError);
  1037. }
  1038. else {
  1039. memset(pTempMMAuthMethods, 0, sizeof(INT_MM_AUTH_METHODS));
  1040. }
  1041. pTempMMAuthMethods++;
  1042. dwNumAuthMethods++;
  1043. i++;
  1044. }
  1045. pTemp = pTemp->pNext;
  1046. }
  1047. }
  1048. lock_success:
  1049. LEAVE_SPD_SECTION();
  1050. *ppMatchedMMFilters = pMatchedMMFilters;
  1051. *ppMatchedMMPolicies = pMatchedMMPolicies;
  1052. *ppMatchedMMAuthMethods = pMatchedMMAuthMethods;
  1053. *pdwNumMatches = dwNumMatches;
  1054. *pdwResumeHandle = dwResumeHandle + dwNumMatches;
  1055. return (dwError);
  1056. lock:
  1057. LEAVE_SPD_SECTION();
  1058. error:
  1059. if (pMatchedMMFilters) {
  1060. FreeMMFilters(
  1061. dwNumFilters,
  1062. pMatchedMMFilters
  1063. );
  1064. }
  1065. if (pMatchedMMPolicies) {
  1066. FreeMMPolicies(
  1067. dwNumPolicies,
  1068. pMatchedMMPolicies
  1069. );
  1070. }
  1071. if (pMatchedMMAuthMethods) {
  1072. FreeMMAuthMethods(
  1073. dwNumAuthMethods,
  1074. pMatchedMMAuthMethods
  1075. );
  1076. }
  1077. *ppMatchedMMFilters = NULL;
  1078. *ppMatchedMMPolicies = NULL;
  1079. *ppMatchedMMAuthMethods = NULL;
  1080. *pdwNumMatches = 0;
  1081. *pdwResumeHandle = dwResumeHandle;
  1082. return (dwError);
  1083. }
  1084. DWORD
  1085. ValidateMMFilterTemplate(
  1086. PMM_FILTER pMMFilter
  1087. )
  1088. {
  1089. DWORD dwError = 0;
  1090. BOOL bConflicts = FALSE;
  1091. if (!pMMFilter) {
  1092. dwError = ERROR_INVALID_PARAMETER;
  1093. BAIL_ON_WIN32_ERROR(dwError);
  1094. }
  1095. dwError = VerifyAddresses(&(pMMFilter->SrcAddr), TRUE, FALSE);
  1096. BAIL_ON_WIN32_ERROR(dwError);
  1097. dwError = VerifyAddresses(&(pMMFilter->DesAddr), TRUE, TRUE);
  1098. BAIL_ON_WIN32_ERROR(dwError);
  1099. bConflicts = AddressesConflict(
  1100. pMMFilter->SrcAddr,
  1101. pMMFilter->DesAddr
  1102. );
  1103. if (bConflicts) {
  1104. dwError = ERROR_INVALID_PARAMETER;
  1105. BAIL_ON_WIN32_ERROR(dwError);
  1106. }
  1107. if (pMMFilter->dwDirection) {
  1108. if ((pMMFilter->dwDirection != FILTER_DIRECTION_INBOUND) &&
  1109. (pMMFilter->dwDirection != FILTER_DIRECTION_OUTBOUND)) {
  1110. dwError = ERROR_INVALID_PARAMETER;
  1111. BAIL_ON_WIN32_ERROR(dwError);
  1112. }
  1113. }
  1114. error:
  1115. return (dwError);
  1116. }
  1117. BOOL
  1118. MatchIniMMSFilter(
  1119. PINIMMSFILTER pIniMMSFilter,
  1120. PMM_FILTER pMMFilter
  1121. )
  1122. {
  1123. BOOL bMatches = FALSE;
  1124. if (pMMFilter->dwDirection) {
  1125. if (pMMFilter->dwDirection != pIniMMSFilter->dwDirection) {
  1126. return (FALSE);
  1127. }
  1128. }
  1129. bMatches = MatchAddresses(
  1130. pIniMMSFilter->SrcAddr,
  1131. pMMFilter->SrcAddr
  1132. );
  1133. if (!bMatches) {
  1134. return (FALSE);
  1135. }
  1136. bMatches = MatchAddresses(
  1137. pIniMMSFilter->DesAddr,
  1138. pMMFilter->DesAddr
  1139. );
  1140. if (!bMatches) {
  1141. return (FALSE);
  1142. }
  1143. return (TRUE);
  1144. }
  1145. DWORD
  1146. CopyMMMatchDefaults(
  1147. PMM_FILTER * ppMMFilters,
  1148. PINT_MM_AUTH_METHODS * ppMMAuthMethods,
  1149. PIPSEC_MM_POLICY * ppMMPolicies,
  1150. PDWORD pdwNumMatches
  1151. )
  1152. {
  1153. DWORD dwError = 0;
  1154. PMM_FILTER pMMFilters = NULL;
  1155. PINT_MM_AUTH_METHODS pMMAuthMethods = NULL;
  1156. PIPSEC_MM_POLICY pMMPolicies = NULL;
  1157. DWORD dwNumFilters = 0;
  1158. DWORD dwNumAuthMethods = 0;
  1159. DWORD dwNumPolicies = 0;
  1160. if (!gpIniDefaultMMPolicy) {
  1161. dwError = ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND;
  1162. BAIL_ON_WIN32_ERROR(dwError);
  1163. }
  1164. if (!gpIniDefaultMMAuthMethods) {
  1165. dwError = ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND;
  1166. BAIL_ON_WIN32_ERROR(dwError);
  1167. }
  1168. dwError = SPDApiBufferAllocate(
  1169. sizeof(MM_FILTER),
  1170. &pMMFilters
  1171. );
  1172. BAIL_ON_WIN32_ERROR(dwError);
  1173. dwError = SPDApiBufferAllocate(
  1174. sizeof(IPSEC_MM_POLICY),
  1175. &pMMPolicies
  1176. );
  1177. BAIL_ON_WIN32_ERROR(dwError);
  1178. dwError = SPDApiBufferAllocate(
  1179. sizeof(INT_MM_AUTH_METHODS),
  1180. &pMMAuthMethods
  1181. );
  1182. BAIL_ON_WIN32_ERROR(dwError);
  1183. dwError = CopyDefaultMMFilter(
  1184. pMMFilters,
  1185. gpIniDefaultMMAuthMethods,
  1186. gpIniDefaultMMPolicy
  1187. );
  1188. BAIL_ON_WIN32_ERROR(dwError);
  1189. dwNumFilters++;
  1190. dwError = CopyMMPolicy(
  1191. gpIniDefaultMMPolicy,
  1192. pMMPolicies
  1193. );
  1194. BAIL_ON_WIN32_ERROR(dwError);
  1195. pMMPolicies->dwFlags |= IPSEC_MM_POLICY_ON_NO_MATCH;
  1196. dwNumPolicies++;
  1197. dwError = CopyMMAuthMethods(
  1198. gpIniDefaultMMAuthMethods,
  1199. pMMAuthMethods
  1200. );
  1201. BAIL_ON_WIN32_ERROR(dwError);
  1202. pMMAuthMethods->dwFlags |= IPSEC_MM_AUTH_ON_NO_MATCH;
  1203. dwNumAuthMethods++;
  1204. *ppMMFilters = pMMFilters;
  1205. *ppMMPolicies = pMMPolicies;
  1206. *ppMMAuthMethods = pMMAuthMethods;
  1207. *pdwNumMatches = 1;
  1208. return (dwError);
  1209. error:
  1210. if (pMMFilters) {
  1211. FreeMMFilters(
  1212. dwNumFilters,
  1213. pMMFilters
  1214. );
  1215. }
  1216. if (pMMPolicies) {
  1217. FreeMMPolicies(
  1218. dwNumPolicies,
  1219. pMMPolicies
  1220. );
  1221. }
  1222. if (pMMAuthMethods) {
  1223. FreeMMAuthMethods(
  1224. dwNumAuthMethods,
  1225. pMMAuthMethods
  1226. );
  1227. }
  1228. *ppMMFilters = NULL;
  1229. *ppMMPolicies = NULL;
  1230. *ppMMAuthMethods = NULL;
  1231. *pdwNumMatches = 0;
  1232. return (dwError);
  1233. }
  1234. DWORD
  1235. CopyDefaultMMFilter(
  1236. PMM_FILTER pMMFilter,
  1237. PINIMMAUTHMETHODS pIniMMAuthMethods,
  1238. PINIMMPOLICY pIniMMPolicy
  1239. )
  1240. {
  1241. DWORD dwError = 0;
  1242. RPC_STATUS RpcStatus = RPC_S_OK;
  1243. pMMFilter->IpVersion = IPSEC_PROTOCOL_V4;
  1244. RpcStatus = UuidCreate(&(pMMFilter->gFilterID));
  1245. if (!(RpcStatus == RPC_S_OK || RpcStatus == RPC_S_UUID_LOCAL_ONLY)) {
  1246. dwError = RPC_S_CALL_FAILED;
  1247. BAIL_ON_WIN32_ERROR(dwError);
  1248. }
  1249. dwError = CopyName(
  1250. L"0",
  1251. &(pMMFilter->pszFilterName)
  1252. );
  1253. BAIL_ON_WIN32_ERROR(dwError);
  1254. pMMFilter->InterfaceType = INTERFACE_TYPE_ALL;
  1255. pMMFilter->bCreateMirror = TRUE;
  1256. pMMFilter->dwFlags = 0;
  1257. pMMFilter->dwFlags |= IPSEC_MM_POLICY_DEFAULT_POLICY;
  1258. pMMFilter->dwFlags |= IPSEC_MM_AUTH_DEFAULT_AUTH;
  1259. pMMFilter->SrcAddr.AddrType = IP_ADDR_SUBNET;
  1260. pMMFilter->SrcAddr.uIpAddr = SUBNET_ADDRESS_ANY;
  1261. pMMFilter->SrcAddr.uSubNetMask = SUBNET_MASK_ANY;
  1262. pMMFilter->SrcAddr.pgInterfaceID = NULL;
  1263. pMMFilter->DesAddr.AddrType = IP_ADDR_SUBNET;
  1264. pMMFilter->DesAddr.uIpAddr = SUBNET_ADDRESS_ANY;
  1265. pMMFilter->DesAddr.uSubNetMask = SUBNET_MASK_ANY;
  1266. pMMFilter->DesAddr.pgInterfaceID = NULL;
  1267. pMMFilter->dwDirection = 0;
  1268. pMMFilter->dwWeight = 0;
  1269. CopyGuid(pIniMMAuthMethods->gMMAuthID, &(pMMFilter->gMMAuthID));
  1270. CopyGuid(pIniMMPolicy->gPolicyID, &(pMMFilter->gPolicyID));
  1271. error:
  1272. return (dwError);
  1273. }