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.

1740 lines
42 KiB

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