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.

2308 lines
58 KiB

  1. #include "precomp.h"
  2. #ifdef TRACE_ON
  3. #include "paupdate.tmh"
  4. #endif
  5. DWORD
  6. PADeleteObseleteISAKMPData(
  7. PIPSEC_ISAKMP_DATA * ppOldIpsecISAKMPData,
  8. DWORD dwNumOldPolicies,
  9. PIPSEC_NFA_DATA * ppOldIpsecNFAData,
  10. DWORD dwNumOldNFACount,
  11. PIPSEC_ISAKMP_DATA * ppNewIpsecISAKMPData,
  12. DWORD dwNumNewPolicies
  13. )
  14. {
  15. DWORD dwError = 0;
  16. DWORD i = 0;
  17. PIPSEC_ISAKMP_DATA pOldIpsecISAKMPData = NULL;
  18. PIPSEC_ISAKMP_DATA pFoundISAKMPData = NULL;
  19. TRACE(TRC_INFORMATION, (L"Pastore update deleting obselete ISAKMP policy information"));
  20. for (i = 0; i < dwNumOldPolicies; i++) {
  21. pOldIpsecISAKMPData = *(ppOldIpsecISAKMPData + i);
  22. pFoundISAKMPData = FindISAKMPData(
  23. pOldIpsecISAKMPData,
  24. ppNewIpsecISAKMPData,
  25. dwNumNewPolicies
  26. );
  27. if (!pFoundISAKMPData) {
  28. dwError = PADeleteMMFilters(
  29. pOldIpsecISAKMPData,
  30. ppOldIpsecNFAData,
  31. dwNumOldNFACount
  32. );
  33. dwError = PADeleteMMPolicy(
  34. pOldIpsecISAKMPData->ISAKMPIdentifier
  35. );
  36. }
  37. }
  38. return (dwError);
  39. }
  40. PIPSEC_ISAKMP_DATA
  41. FindISAKMPData(
  42. PIPSEC_ISAKMP_DATA pIpsecISAKMPData,
  43. PIPSEC_ISAKMP_DATA * ppIpsecISAKMPData,
  44. DWORD dwNumPolicies
  45. )
  46. {
  47. DWORD i = 0;
  48. PIPSEC_ISAKMP_DATA pTemp = NULL;
  49. for (i = 0; i < dwNumPolicies; i++) {
  50. pTemp = *(ppIpsecISAKMPData + i);
  51. if (!memcmp(
  52. &(pIpsecISAKMPData->ISAKMPIdentifier),
  53. &(pTemp->ISAKMPIdentifier),
  54. sizeof(GUID))) {
  55. return (pTemp);
  56. }
  57. }
  58. return (NULL);
  59. }
  60. DWORD
  61. PADeleteObseleteNFAData(
  62. PIPSEC_ISAKMP_DATA pNewIpsecISAKMPData,
  63. PIPSEC_NFA_DATA * ppOldIpsecNFAData,
  64. DWORD dwNumOldNFACount,
  65. PIPSEC_NFA_DATA * ppNewIpsecNFAData,
  66. DWORD dwNumNewNFACount
  67. )
  68. {
  69. DWORD dwError = 0;
  70. DWORD i = 0;
  71. PIPSEC_NFA_DATA pOldIpsecNFAData = NULL;
  72. PIPSEC_NFA_DATA pFoundNFAData = NULL;
  73. TRACE(TRC_INFORMATION, (L"Pastore update deleting obselete MM and QM NFA-derived filters and policies"));
  74. for (i = 0; i < dwNumOldNFACount; i++) {
  75. pOldIpsecNFAData = *(ppOldIpsecNFAData + i);
  76. pFoundNFAData = FindNFAData(
  77. pOldIpsecNFAData,
  78. ppNewIpsecNFAData,
  79. dwNumNewNFACount
  80. );
  81. if (!pFoundNFAData) {
  82. dwError = PADeleteMMFilterSpecs(
  83. pNewIpsecISAKMPData,
  84. pOldIpsecNFAData
  85. );
  86. dwError = PADeleteMMAuthMethod(
  87. pOldIpsecNFAData->NFAIdentifier
  88. );
  89. dwError = PADeleteQMInfoForNFA(
  90. pOldIpsecNFAData
  91. );
  92. }
  93. }
  94. return (dwError);
  95. }
  96. PIPSEC_NFA_DATA
  97. FindNFAData(
  98. PIPSEC_NFA_DATA pIpsecNFAData,
  99. PIPSEC_NFA_DATA * ppIpsecNFAData,
  100. DWORD dwNumNFACount
  101. )
  102. {
  103. DWORD i = 0;
  104. PIPSEC_NFA_DATA pTemp = NULL;
  105. for (i = 0; i < dwNumNFACount; i++) {
  106. pTemp = *(ppIpsecNFAData + i);
  107. if (!memcmp(
  108. &(pIpsecNFAData->NFAIdentifier),
  109. &(pTemp->NFAIdentifier),
  110. sizeof(GUID))) {
  111. return (pTemp);
  112. }
  113. }
  114. return (NULL);
  115. }
  116. DWORD
  117. PAUpdateISAKMPData(
  118. PIPSEC_ISAKMP_DATA * ppNewIpsecISAKMPData,
  119. DWORD dwNumNewPolicies,
  120. PIPSEC_NFA_DATA * ppOldIpsecNFAData,
  121. DWORD dwNumOldNFACount,
  122. PIPSEC_ISAKMP_DATA * ppOldIpsecISAKMPData,
  123. DWORD dwNumOldPolicies,
  124. IN DWORD dwSource
  125. )
  126. {
  127. DWORD dwError = 0;
  128. DWORD i = 0;
  129. PIPSEC_ISAKMP_DATA pNewIpsecISAKMPData = NULL;
  130. PIPSEC_ISAKMP_DATA pFoundISAKMPData = NULL;
  131. TRACE(
  132. TRC_INFORMATION,
  133. (L"Pastore updating MM filters based on new ISAKMP data")
  134. );
  135. for (i = 0; i < dwNumNewPolicies; i++) {
  136. pNewIpsecISAKMPData = *(ppNewIpsecISAKMPData + i);
  137. pFoundISAKMPData = FindISAKMPData(
  138. pNewIpsecISAKMPData,
  139. ppOldIpsecISAKMPData,
  140. dwNumOldPolicies
  141. );
  142. if (!pFoundISAKMPData) {
  143. dwError = PAAddMMPolicies(
  144. &pNewIpsecISAKMPData,
  145. 1,
  146. dwSource
  147. );
  148. dwError = PAAddMMFilters(
  149. pNewIpsecISAKMPData,
  150. ppOldIpsecNFAData,
  151. dwNumOldNFACount,
  152. dwSource
  153. );
  154. }
  155. else {
  156. dwError = PAProcessISAKMPUpdate(
  157. pFoundISAKMPData,
  158. ppOldIpsecNFAData,
  159. dwNumOldNFACount,
  160. pNewIpsecISAKMPData,
  161. dwSource
  162. );
  163. }
  164. }
  165. return (dwError);
  166. }
  167. DWORD
  168. PAUpdateNFAData(
  169. PIPSEC_ISAKMP_DATA pNewIpsecISAKMPData,
  170. PIPSEC_NFA_DATA * ppNewIpsecNFAData,
  171. DWORD dwNumNewNFACount,
  172. PIPSEC_NFA_DATA * ppOldIpsecNFAData,
  173. DWORD dwNumOldNFACount,
  174. DWORD dwSource
  175. )
  176. {
  177. DWORD dwError = 0;
  178. DWORD i = 0;
  179. PIPSEC_NFA_DATA pNewIpsecNFAData = NULL;
  180. PIPSEC_NFA_DATA pFoundNFAData = NULL;
  181. for (i = 0; i < dwNumNewNFACount; i++) {
  182. pNewIpsecNFAData = *(ppNewIpsecNFAData + i);
  183. TRACE(
  184. TRC_INFORMATION,
  185. (L"Pastore updating QM and MM filters and polcies based on NFA %!guid! data.",
  186. &pNewIpsecNFAData->NFAIdentifier)
  187. );
  188. pFoundNFAData = FindNFAData(
  189. pNewIpsecNFAData,
  190. ppOldIpsecNFAData,
  191. dwNumOldNFACount
  192. );
  193. if (!pFoundNFAData) {
  194. dwError = PAAddMMAuthMethods(
  195. &pNewIpsecNFAData,
  196. 1,
  197. dwSource
  198. );
  199. dwError = PAAddMMFilterSpecs(
  200. pNewIpsecISAKMPData,
  201. pNewIpsecNFAData,
  202. dwSource
  203. );
  204. dwError = PAAddQMInfoForNFA(
  205. pNewIpsecNFAData,
  206. dwSource
  207. );
  208. }
  209. else {
  210. dwError = PAProcessNFAUpdate(
  211. pNewIpsecISAKMPData,
  212. pFoundNFAData,
  213. pNewIpsecNFAData,
  214. dwSource
  215. );
  216. }
  217. }
  218. return (dwError);
  219. }
  220. DWORD
  221. PAProcessISAKMPUpdate(
  222. PIPSEC_ISAKMP_DATA pOldIpsecISAKMPData,
  223. PIPSEC_NFA_DATA * ppOldIpsecNFAData,
  224. DWORD dwNumOldNFACount,
  225. PIPSEC_ISAKMP_DATA pNewIpsecISAKMPData,
  226. IN DWORD dwSource
  227. )
  228. {
  229. DWORD dwError = 0;
  230. PMMPOLICYSTATE pMMPolicyState = NULL;
  231. BOOL bEqual = FALSE;
  232. PIPSEC_MM_POLICY pSPDMMPolicy = NULL;
  233. LPWSTR pServerName = NULL;
  234. DWORD dwVersion = 0;
  235. pMMPolicyState = FindMMPolicyState(
  236. pOldIpsecISAKMPData->ISAKMPIdentifier
  237. );
  238. if (!pMMPolicyState) {
  239. dwError = PAAddMMPolicies(
  240. &pNewIpsecISAKMPData,
  241. 1,
  242. dwSource
  243. );
  244. dwError = PAAddMMFilters(
  245. pNewIpsecISAKMPData,
  246. ppOldIpsecNFAData,
  247. dwNumOldNFACount,
  248. dwSource
  249. );
  250. return (dwError);
  251. }
  252. if (!(pMMPolicyState->bInSPD)) {
  253. PADeleteMMPolicyState(pMMPolicyState);
  254. dwError = PAAddMMPolicies(
  255. &pNewIpsecISAKMPData,
  256. 1,
  257. dwSource
  258. );
  259. dwError = PAAddMMFilters(
  260. pNewIpsecISAKMPData,
  261. ppOldIpsecNFAData,
  262. dwNumOldNFACount,
  263. dwSource
  264. );
  265. return (dwError);
  266. }
  267. bEqual = EqualISAKMPData(
  268. pOldIpsecISAKMPData,
  269. pNewIpsecISAKMPData
  270. );
  271. if (bEqual) {
  272. dwError = ERROR_SUCCESS;
  273. return (dwError);
  274. }
  275. dwError = PACreateMMPolicy(
  276. pNewIpsecISAKMPData,
  277. pMMPolicyState,
  278. &pSPDMMPolicy
  279. );
  280. BAIL_ON_WIN32_ERROR(dwError);
  281. dwError = SetMMPolicy(
  282. pServerName,
  283. dwVersion,
  284. pMMPolicyState->pszPolicyName,
  285. pSPDMMPolicy,
  286. NULL
  287. );
  288. if (dwError != WARNING_IPSEC_MM_POLICY_PRUNED) {
  289. BAIL_ON_WIN32_ERROR(dwError);
  290. } else {
  291. dwError = ERROR_SUCCESS;
  292. }
  293. error:
  294. #ifdef TRACE_ON
  295. if (dwError) {
  296. TRACE(TRC_ERROR, (L"Pastore update failed during processing of ISAKMP policy update: %!winerr!", dwError));
  297. }
  298. #endif
  299. if (pSPDMMPolicy) {
  300. PAFreeMMPolicy(pSPDMMPolicy);
  301. }
  302. return (dwError);
  303. }
  304. BOOL
  305. EqualISAKMPData(
  306. PIPSEC_ISAKMP_DATA pOldIpsecISAKMPData,
  307. PIPSEC_ISAKMP_DATA pNewIpsecISAKMPData
  308. )
  309. {
  310. BOOL bEqual = FALSE;
  311. DWORD dwOldCnt = 0;
  312. PCRYPTO_BUNDLE pOldSecurityMethods = NULL;
  313. DWORD dwNewCnt = 0;
  314. PCRYPTO_BUNDLE pNewSecurityMethods = NULL;
  315. DWORD i = 0;
  316. PCRYPTO_BUNDLE pNewTemp = NULL;
  317. PCRYPTO_BUNDLE pOldTemp = NULL;
  318. //
  319. // At this point, pszPolicyName and ISAKMPIdentifier are same and
  320. // dwWhenChanged is different.
  321. //
  322. dwOldCnt = pOldIpsecISAKMPData->dwNumISAKMPSecurityMethods;
  323. pOldSecurityMethods = pOldIpsecISAKMPData->pSecurityMethods;
  324. dwNewCnt = pNewIpsecISAKMPData->dwNumISAKMPSecurityMethods;
  325. pNewSecurityMethods = pNewIpsecISAKMPData->pSecurityMethods;
  326. //
  327. // At this point, dwOldCnt >= 1 and pOldSecurityMethods != NULL.
  328. //
  329. if (!dwNewCnt || !pNewSecurityMethods) {
  330. return (FALSE);
  331. }
  332. if (dwOldCnt != dwNewCnt) {
  333. return (FALSE);
  334. }
  335. if (pOldIpsecISAKMPData->ISAKMPPolicy.dwFlags != pNewIpsecISAKMPData->ISAKMPPolicy.dwFlags) {
  336. return (FALSE);
  337. }
  338. pNewTemp = pNewSecurityMethods;
  339. pOldTemp = pOldSecurityMethods;
  340. for (i = 0; i < dwNewCnt; i++) {
  341. bEqual = FALSE;
  342. bEqual = EqualCryptoBundle(
  343. pOldTemp,
  344. pNewTemp
  345. );
  346. if (!bEqual) {
  347. break;
  348. }
  349. pOldTemp++;
  350. pNewTemp++;
  351. }
  352. return (bEqual);
  353. }
  354. BOOL
  355. EqualCryptoBundle(
  356. PCRYPTO_BUNDLE pOldBundle,
  357. PCRYPTO_BUNDLE pNewBundle
  358. )
  359. {
  360. if (memcmp(
  361. &(pOldBundle->Lifetime),
  362. &(pNewBundle->Lifetime),
  363. sizeof(OAKLEY_LIFETIME))) {
  364. return (FALSE);
  365. }
  366. if (pOldBundle->QuickModeLimit != pNewBundle->QuickModeLimit) {
  367. return (FALSE);
  368. }
  369. if (pOldBundle->OakleyGroup != pNewBundle->OakleyGroup) {
  370. return (FALSE);
  371. }
  372. if (memcmp(
  373. &(pOldBundle->EncryptionAlgorithm),
  374. &(pNewBundle->EncryptionAlgorithm),
  375. sizeof(OAKLEY_ALGORITHM))) {
  376. return (FALSE);
  377. }
  378. if (memcmp(
  379. &(pOldBundle->HashAlgorithm),
  380. &(pNewBundle->HashAlgorithm),
  381. sizeof(OAKLEY_ALGORITHM))) {
  382. return (FALSE);
  383. }
  384. return (TRUE);
  385. }
  386. DWORD
  387. PAProcessNFAUpdate(
  388. PIPSEC_ISAKMP_DATA pNewIpsecISAKMPData,
  389. PIPSEC_NFA_DATA pOldIpsecNFAData,
  390. PIPSEC_NFA_DATA pNewIpsecNFAData,
  391. DWORD dwSource
  392. )
  393. {
  394. DWORD dwError = 0;
  395. BOOL bAddedMMFilters = FALSE;
  396. dwError = PAUpdateAuthMethod(
  397. pNewIpsecISAKMPData,
  398. pOldIpsecNFAData,
  399. pNewIpsecNFAData,
  400. &bAddedMMFilters,
  401. dwSource
  402. );
  403. if (!bAddedMMFilters) {
  404. dwError = PAUpdateMMFilters(
  405. pNewIpsecISAKMPData,
  406. pOldIpsecNFAData,
  407. pNewIpsecNFAData,
  408. dwSource
  409. );
  410. }
  411. dwError = PAProcessQMNFAUpdate(
  412. pOldIpsecNFAData,
  413. pNewIpsecNFAData,
  414. dwSource
  415. );
  416. return (dwError);
  417. }
  418. DWORD
  419. PAUpdateAuthMethod(
  420. PIPSEC_ISAKMP_DATA pNewIpsecISAKMPData,
  421. PIPSEC_NFA_DATA pOldIpsecNFAData,
  422. PIPSEC_NFA_DATA pNewIpsecNFAData,
  423. PBOOL pbAddedMMFilters,
  424. DWORD dwSource
  425. )
  426. {
  427. DWORD dwError = 0;
  428. PMMAUTHSTATE pMMAuthState = NULL;
  429. BOOL bEqual = FALSE;
  430. PINT_MM_AUTH_METHODS pSPDMMAuthMethods = NULL;
  431. LPWSTR pServerName = NULL;
  432. DWORD dwVersion = 0;
  433. *pbAddedMMFilters = FALSE;
  434. pMMAuthState = FindMMAuthState(
  435. pOldIpsecNFAData->NFAIdentifier
  436. );
  437. if (!pMMAuthState) {
  438. dwError = PAAddMMAuthMethods(
  439. &pNewIpsecNFAData,
  440. 1,
  441. dwSource
  442. );
  443. dwError = PAAddMMFilterSpecs(
  444. pNewIpsecISAKMPData,
  445. pNewIpsecNFAData,
  446. dwSource
  447. );
  448. *pbAddedMMFilters = TRUE;
  449. return (dwError);
  450. }
  451. if (!(pMMAuthState->bInSPD)) {
  452. PADeleteMMAuthState(pMMAuthState);
  453. dwError = PAAddMMAuthMethods(
  454. &pNewIpsecNFAData,
  455. 1,
  456. dwSource
  457. );
  458. dwError = PAAddMMFilterSpecs(
  459. pNewIpsecISAKMPData,
  460. pNewIpsecNFAData,
  461. dwSource
  462. );
  463. *pbAddedMMFilters = TRUE;
  464. return (dwError);
  465. }
  466. bEqual = EqualAuthMethodData(
  467. pOldIpsecNFAData,
  468. pNewIpsecNFAData
  469. );
  470. if (bEqual) {
  471. dwError = ERROR_SUCCESS;
  472. return (dwError);
  473. }
  474. dwError = PACreateMMAuthMethods(
  475. pNewIpsecNFAData,
  476. &pSPDMMAuthMethods
  477. );
  478. BAIL_ON_WIN32_ERROR(dwError);
  479. dwError = IntSetMMAuthMethods(
  480. pServerName,
  481. dwVersion,
  482. pMMAuthState->gMMAuthID,
  483. pSPDMMAuthMethods,
  484. NULL
  485. );
  486. BAIL_ON_WIN32_ERROR(dwError);
  487. error:
  488. if (pSPDMMAuthMethods) {
  489. PAFreeMMAuthMethods(pSPDMMAuthMethods);
  490. }
  491. return (dwError);
  492. }
  493. BOOL
  494. EqualAuthMethodData(
  495. PIPSEC_NFA_DATA pOldIpsecNFAData,
  496. PIPSEC_NFA_DATA pNewIpsecNFAData
  497. )
  498. {
  499. BOOL bEqual = FALSE;
  500. DWORD dwOldCnt = 0;
  501. PIPSEC_AUTH_METHOD * ppOldAuthMethods = NULL;
  502. DWORD dwNewCnt = 0;
  503. PIPSEC_AUTH_METHOD * ppNewAuthMethods = NULL;
  504. DWORD i = 0;
  505. PIPSEC_AUTH_METHOD pNewAuthMethod = NULL;
  506. PIPSEC_AUTH_METHOD pOldAuthMethod = NULL;
  507. //
  508. // At this point, NFAIdentifier is same and
  509. // dwWhenChanged is different.
  510. //
  511. dwOldCnt = pOldIpsecNFAData->dwAuthMethodCount;
  512. ppOldAuthMethods = pOldIpsecNFAData->ppAuthMethods;
  513. dwNewCnt = pNewIpsecNFAData->dwAuthMethodCount;
  514. ppNewAuthMethods = pNewIpsecNFAData->ppAuthMethods;
  515. //
  516. // At this point, dwOldCnt >= 1 and ppOldAuthMethods != NULL.
  517. //
  518. if (!dwNewCnt || !ppNewAuthMethods) {
  519. return (FALSE);
  520. }
  521. if (dwOldCnt != dwNewCnt) {
  522. return (FALSE);
  523. }
  524. for (i = 0; i < dwNewCnt; i++) {
  525. pNewAuthMethod = *(ppNewAuthMethods + i);
  526. pOldAuthMethod = *(ppOldAuthMethods + i);
  527. bEqual = FALSE;
  528. bEqual = EqualAuthBundle(
  529. pOldAuthMethod,
  530. pNewAuthMethod
  531. );
  532. if (!bEqual) {
  533. break;
  534. }
  535. }
  536. return (bEqual);
  537. }
  538. BOOL
  539. EqualAuthBundle(
  540. PIPSEC_AUTH_METHOD pOldAuthMethod,
  541. PIPSEC_AUTH_METHOD pNewAuthMethod
  542. )
  543. {
  544. BOOL bEqual = FALSE;
  545. DWORD dwOldAuthLen = 0;
  546. DWORD dwNewAuthLen = 0;
  547. if (pOldAuthMethod->dwAuthType != pNewAuthMethod->dwAuthType) {
  548. return (FALSE);
  549. }
  550. switch (pNewAuthMethod->dwAuthType) {
  551. case OAK_SSPI:
  552. bEqual = TRUE;
  553. break;
  554. default:
  555. //
  556. // Since auth version 2 also has auth version 1 fields filled in it, so
  557. // there is no need to explicitly compare exclusive auth version 2 fields.
  558. //
  559. dwOldAuthLen = pOldAuthMethod->dwAuthLen;
  560. dwNewAuthLen = pNewAuthMethod->dwAuthLen;
  561. if (pOldAuthMethod->dwAuthFlags != pNewAuthMethod->dwAuthFlags) {
  562. bEqual = FALSE;
  563. break;
  564. }
  565. if (!dwNewAuthLen || !(pNewAuthMethod->pszAuthMethod)) {
  566. bEqual = FALSE;
  567. break;
  568. }
  569. if (dwOldAuthLen != dwNewAuthLen) {
  570. bEqual = FALSE;
  571. break;
  572. }
  573. if (!memcmp(
  574. (LPBYTE) pNewAuthMethod->pszAuthMethod,
  575. (LPBYTE) pOldAuthMethod->pszAuthMethod,
  576. (dwNewAuthLen*sizeof(WCHAR)))) {
  577. bEqual = TRUE;
  578. break;
  579. }
  580. break;
  581. }
  582. return (bEqual);
  583. }
  584. DWORD
  585. PAProcessQMNFAUpdate(
  586. PIPSEC_NFA_DATA pOldIpsecNFAData,
  587. PIPSEC_NFA_DATA pNewIpsecNFAData,
  588. DWORD dwSource
  589. )
  590. {
  591. DWORD dwError = 0;
  592. PIPSEC_NEGPOL_DATA pOldIpsecNegPolData = NULL;
  593. PIPSEC_NEGPOL_DATA pNewIpsecNegPolData = NULL;
  594. BOOL bAddedQMFilters = FALSE;
  595. pOldIpsecNegPolData = pOldIpsecNFAData->pIpsecNegPolData;
  596. pNewIpsecNegPolData = pNewIpsecNFAData->pIpsecNegPolData;
  597. if (memcmp(
  598. &(pOldIpsecNegPolData->NegPolIdentifier),
  599. &(pNewIpsecNegPolData->NegPolIdentifier),
  600. sizeof(GUID))) {
  601. dwError = PADeleteQMInfoForNFA(pOldIpsecNFAData);
  602. dwError = PAAddQMInfoForNFA(pNewIpsecNFAData, dwSource);
  603. }
  604. else {
  605. dwError = PAProcessNegPolUpdate(
  606. pOldIpsecNFAData,
  607. pNewIpsecNFAData,
  608. &bAddedQMFilters,
  609. dwSource
  610. );
  611. if (!bAddedQMFilters) {
  612. dwError = PAUpdateQMFilters(
  613. pOldIpsecNFAData,
  614. pNewIpsecNFAData,
  615. dwSource
  616. );
  617. }
  618. }
  619. return (dwError);
  620. }
  621. DWORD
  622. PADeleteQMInfoForNFA(
  623. PIPSEC_NFA_DATA pOldIpsecNFAData
  624. )
  625. {
  626. DWORD dwError = 0;
  627. PIPSEC_NEGPOL_DATA pOldIpsecNegPolData = NULL;
  628. dwError = PADeleteQMFilterSpecs(
  629. pOldIpsecNFAData
  630. );
  631. pOldIpsecNegPolData = pOldIpsecNFAData->pIpsecNegPolData;
  632. dwError = PADeleteQMPolicy(
  633. pOldIpsecNegPolData->NegPolIdentifier
  634. );
  635. return (dwError);
  636. }
  637. DWORD
  638. PAAddQMInfoForNFA(
  639. PIPSEC_NFA_DATA pNewIpsecNFAData,
  640. DWORD dwSource
  641. )
  642. {
  643. DWORD dwError = 0;
  644. dwError = PAAddQMPolicies(
  645. &pNewIpsecNFAData,
  646. 1,
  647. dwSource
  648. );
  649. dwError = PAAddQMFilterSpecs(
  650. pNewIpsecNFAData,
  651. dwSource
  652. );
  653. return (dwError);
  654. }
  655. DWORD
  656. PAProcessNegPolUpdate(
  657. PIPSEC_NFA_DATA pOldIpsecNFAData,
  658. PIPSEC_NFA_DATA pNewIpsecNFAData,
  659. PBOOL pbAddedQMFilters,
  660. DWORD dwSource
  661. )
  662. {
  663. DWORD dwError = 0;
  664. PIPSEC_NEGPOL_DATA pOldIpsecNegPolData = NULL;
  665. PIPSEC_NEGPOL_DATA pNewIpsecNegPolData = NULL;
  666. PQMPOLICYSTATE pQMPolicyState = NULL;
  667. BOOL bEqual = FALSE;
  668. PIPSEC_QM_POLICY pSPDQMPolicy = NULL;
  669. LPWSTR pServerName = NULL;
  670. DWORD dwVersion = 0;
  671. *pbAddedQMFilters = FALSE;
  672. pOldIpsecNegPolData = pOldIpsecNFAData->pIpsecNegPolData;
  673. pNewIpsecNegPolData = pNewIpsecNFAData->pIpsecNegPolData;
  674. pQMPolicyState = FindQMPolicyState(
  675. pOldIpsecNegPolData->NegPolIdentifier
  676. );
  677. if (!pQMPolicyState) {
  678. dwError = PAAddQMInfoForNFA(pNewIpsecNFAData, dwSource);
  679. *pbAddedQMFilters = TRUE;
  680. return (dwError);
  681. }
  682. if (IsClearOnly(pQMPolicyState->gNegPolAction)) {
  683. if (IsClearOnly(pNewIpsecNegPolData->NegPolAction)) {
  684. dwError = ERROR_SUCCESS;
  685. return (dwError);
  686. }
  687. else {
  688. dwError = PADeleteQMInfoForNFA(pOldIpsecNFAData);
  689. dwError = PAAddQMInfoForNFA(pNewIpsecNFAData, dwSource);
  690. *pbAddedQMFilters = TRUE;
  691. return (dwError);
  692. }
  693. }
  694. if (IsBlocking(pQMPolicyState->gNegPolAction)) {
  695. if (IsBlocking(pNewIpsecNegPolData->NegPolAction)) {
  696. dwError = ERROR_SUCCESS;
  697. return (dwError);
  698. }
  699. else {
  700. dwError = PADeleteQMInfoForNFA(pOldIpsecNFAData);
  701. dwError = PAAddQMInfoForNFA(pNewIpsecNFAData, dwSource);
  702. *pbAddedQMFilters = TRUE;
  703. return (dwError);
  704. }
  705. }
  706. if (IsClearOnly(pNewIpsecNegPolData->NegPolAction)) {
  707. if (IsClearOnly(pQMPolicyState->gNegPolAction)) {
  708. dwError = ERROR_SUCCESS;
  709. return (dwError);
  710. }
  711. else {
  712. dwError = PADeleteQMInfoForNFA(pOldIpsecNFAData);
  713. dwError = PAAddQMInfoForNFA(pNewIpsecNFAData, dwSource);
  714. *pbAddedQMFilters = TRUE;
  715. return (dwError);
  716. }
  717. }
  718. if (IsBlocking(pNewIpsecNegPolData->NegPolAction)) {
  719. if (IsBlocking(pQMPolicyState->gNegPolAction)) {
  720. dwError = ERROR_SUCCESS;
  721. return (dwError);
  722. }
  723. else {
  724. dwError = PADeleteQMInfoForNFA(pOldIpsecNFAData);
  725. dwError = PAAddQMInfoForNFA(pNewIpsecNFAData, dwSource);
  726. *pbAddedQMFilters = TRUE;
  727. return (dwError);
  728. }
  729. }
  730. if (!(pQMPolicyState->bInSPD)) {
  731. PADeleteQMPolicy(pQMPolicyState->gPolicyID);
  732. dwError = PAAddQMInfoForNFA(pNewIpsecNFAData, dwSource);
  733. *pbAddedQMFilters = TRUE;
  734. return (dwError);
  735. }
  736. bEqual = EqualNegPolData(
  737. pOldIpsecNegPolData,
  738. pNewIpsecNegPolData
  739. );
  740. if (bEqual) {
  741. dwError = ERROR_SUCCESS;
  742. return (dwError);
  743. }
  744. memcpy(
  745. &(pQMPolicyState->gNegPolType),
  746. &(pNewIpsecNegPolData->NegPolType),
  747. sizeof(GUID)
  748. );
  749. memcpy(
  750. &(pQMPolicyState->gNegPolAction),
  751. &(pNewIpsecNegPolData->NegPolAction),
  752. sizeof(GUID)
  753. );
  754. dwError = PACreateQMPolicy(
  755. pNewIpsecNFAData,
  756. pQMPolicyState,
  757. &pSPDQMPolicy
  758. );
  759. BAIL_ON_WIN32_ERROR(dwError);
  760. dwError = SetQMPolicy(
  761. pServerName,
  762. dwVersion,
  763. pQMPolicyState->pszPolicyName,
  764. pSPDQMPolicy,
  765. NULL
  766. );
  767. if (dwError != WARNING_IPSEC_QM_POLICY_PRUNED) {
  768. BAIL_ON_WIN32_ERROR(dwError);
  769. } else {
  770. dwError = ERROR_SUCCESS;
  771. }
  772. error:
  773. if (pSPDQMPolicy) {
  774. PAFreeQMPolicy(pSPDQMPolicy);
  775. }
  776. return (dwError);
  777. }
  778. BOOL
  779. EqualNegPolData(
  780. PIPSEC_NEGPOL_DATA pOldIpsecNegPolData,
  781. PIPSEC_NEGPOL_DATA pNewIpsecNegPolData
  782. )
  783. {
  784. BOOL bEqual = FALSE;
  785. DWORD dwOldCnt = 0;
  786. PIPSEC_SECURITY_METHOD pOldSecurityMethods = NULL;
  787. DWORD dwNewCnt = 0;
  788. PIPSEC_SECURITY_METHOD pNewSecurityMethods = NULL;
  789. DWORD i = 0;
  790. PIPSEC_SECURITY_METHOD pNewTemp = NULL;
  791. PIPSEC_SECURITY_METHOD pOldTemp = NULL;
  792. //
  793. // At this point, pszPolicyName and NegPolIdentifier are same and
  794. // dwWhenChanged is different.
  795. //
  796. if (memcmp(
  797. &(pOldIpsecNegPolData->NegPolAction),
  798. &(pNewIpsecNegPolData->NegPolAction),
  799. sizeof(GUID))) {
  800. return (FALSE);
  801. }
  802. if (memcmp(
  803. &(pOldIpsecNegPolData->NegPolType),
  804. &(pNewIpsecNegPolData->NegPolType),
  805. sizeof(GUID))) {
  806. return (FALSE);
  807. }
  808. dwOldCnt = pOldIpsecNegPolData->dwSecurityMethodCount;
  809. pOldSecurityMethods = pOldIpsecNegPolData->pIpsecSecurityMethods;
  810. dwNewCnt = pNewIpsecNegPolData->dwSecurityMethodCount;
  811. pNewSecurityMethods = pNewIpsecNegPolData->pIpsecSecurityMethods;
  812. //
  813. // At this point, dwOldCnt >= 1 and pOldSecurityMethods != NULL.
  814. //
  815. if (!dwNewCnt || !pNewSecurityMethods) {
  816. return (FALSE);
  817. }
  818. if (dwOldCnt != dwNewCnt) {
  819. return (FALSE);
  820. }
  821. pNewTemp = pNewSecurityMethods;
  822. pOldTemp = pOldSecurityMethods;
  823. for (i = 0; i < dwNewCnt; i++) {
  824. bEqual = FALSE;
  825. bEqual = EqualSecurityMethod(
  826. pOldTemp,
  827. pNewTemp
  828. );
  829. if (!bEqual) {
  830. break;
  831. }
  832. pOldTemp++;
  833. pNewTemp++;
  834. }
  835. return (bEqual);
  836. }
  837. BOOL
  838. EqualSecurityMethod(
  839. PIPSEC_SECURITY_METHOD pOldBundle,
  840. PIPSEC_SECURITY_METHOD pNewBundle
  841. )
  842. {
  843. DWORD i = 0;
  844. if (memcmp(
  845. &(pOldBundle->Lifetime),
  846. &(pNewBundle->Lifetime),
  847. sizeof(LIFETIME))) {
  848. return (FALSE);
  849. }
  850. if (pOldBundle->Flags != pNewBundle->Flags) {
  851. return (FALSE);
  852. }
  853. if (pOldBundle->PfsQMRequired != pNewBundle->PfsQMRequired) {
  854. return (FALSE);
  855. }
  856. if (pOldBundle->Count != pNewBundle->Count) {
  857. return (FALSE);
  858. }
  859. if (pNewBundle->Count == 0) {
  860. return (TRUE);
  861. }
  862. for (i = 0; i < (pNewBundle->Count); i++) {
  863. if (memcmp(
  864. &(pOldBundle->Algos[i]),
  865. &(pNewBundle->Algos[i]),
  866. sizeof(IPSEC_ALGO_INFO))) {
  867. return (FALSE);
  868. }
  869. }
  870. return (TRUE);
  871. }
  872. DWORD
  873. PAUpdateMMFilters(
  874. PIPSEC_ISAKMP_DATA pNewIpsecISAKMPData,
  875. PIPSEC_NFA_DATA pOldIpsecNFAData,
  876. PIPSEC_NFA_DATA pNewIpsecNFAData,
  877. DWORD dwSource
  878. )
  879. {
  880. DWORD dwError = 0;
  881. BOOL bEqual = FALSE;
  882. PIPSEC_NEGPOL_DATA pOldIpsecNegPolData = NULL;
  883. PIPSEC_NEGPOL_DATA pNewIpsecNegPolData = NULL;
  884. pOldIpsecNegPolData = pOldIpsecNFAData->pIpsecNegPolData;
  885. pNewIpsecNegPolData = pNewIpsecNFAData->pIpsecNegPolData;
  886. bEqual = EqualFilterKeysInNegPols(
  887. pOldIpsecNegPolData,
  888. pNewIpsecNegPolData
  889. );
  890. if (!bEqual) {
  891. dwError = PADeleteMMFilterSpecs(
  892. pNewIpsecISAKMPData,
  893. pOldIpsecNFAData
  894. );
  895. dwError = PAAddMMFilterSpecs(
  896. pNewIpsecISAKMPData,
  897. pNewIpsecNFAData,
  898. dwSource
  899. );
  900. return (dwError);
  901. }
  902. bEqual = EqualFilterKeysInNFAs(
  903. pOldIpsecNFAData,
  904. pNewIpsecNFAData
  905. );
  906. if (!bEqual) {
  907. dwError = PADeleteMMFilterSpecs(
  908. pNewIpsecISAKMPData,
  909. pOldIpsecNFAData
  910. );
  911. dwError = PAAddMMFilterSpecs(
  912. pNewIpsecISAKMPData,
  913. pNewIpsecNFAData,
  914. dwSource
  915. );
  916. return (dwError);
  917. }
  918. if (!memcmp(
  919. &(pNewIpsecNegPolData->NegPolType),
  920. &(GUID_NEGOTIATION_TYPE_DEFAULT),
  921. sizeof(GUID))) {
  922. dwError = ERROR_SUCCESS;
  923. return (dwError);
  924. }
  925. if (IsClearOnly(pNewIpsecNegPolData->NegPolAction) ||
  926. IsBlocking(pNewIpsecNegPolData->NegPolAction)) {
  927. dwError = ERROR_SUCCESS;
  928. return (dwError);
  929. }
  930. dwError = PAProcessMMFilterDataForNFAs(
  931. pNewIpsecISAKMPData,
  932. pOldIpsecNFAData,
  933. pNewIpsecNFAData,
  934. dwSource
  935. );
  936. return (dwError);
  937. }
  938. BOOL
  939. EqualFilterKeysInNegPols(
  940. PIPSEC_NEGPOL_DATA pOldIpsecNegPolData,
  941. PIPSEC_NEGPOL_DATA pNewIpsecNegPolData
  942. )
  943. {
  944. BOOL bOldAllowsSoft = FALSE;
  945. BOOL bNewAllowsSoft = FALSE;
  946. if (memcmp(
  947. &(pOldIpsecNegPolData->NegPolType),
  948. &(pNewIpsecNegPolData->NegPolType),
  949. sizeof(GUID))) {
  950. return (FALSE);
  951. }
  952. if (memcmp(
  953. &(pOldIpsecNegPolData->NegPolAction),
  954. &(pNewIpsecNegPolData->NegPolAction),
  955. sizeof(GUID))) {
  956. return (FALSE);
  957. }
  958. bOldAllowsSoft = AllowsSoft(
  959. pOldIpsecNegPolData->dwSecurityMethodCount,
  960. pOldIpsecNegPolData->pIpsecSecurityMethods
  961. );
  962. bNewAllowsSoft = AllowsSoft(
  963. pNewIpsecNegPolData->dwSecurityMethodCount,
  964. pNewIpsecNegPolData->pIpsecSecurityMethods
  965. );
  966. if (bOldAllowsSoft != bNewAllowsSoft) {
  967. return (FALSE);
  968. }
  969. return (TRUE);
  970. }
  971. BOOL
  972. EqualFilterKeysInNFAs(
  973. PIPSEC_NFA_DATA pOldIpsecNFAData,
  974. PIPSEC_NFA_DATA pNewIpsecNFAData
  975. )
  976. {
  977. if (pOldIpsecNFAData->dwInterfaceType !=
  978. pNewIpsecNFAData->dwInterfaceType) {
  979. return (FALSE);
  980. }
  981. if (pOldIpsecNFAData->dwTunnelFlags !=
  982. pNewIpsecNFAData->dwTunnelFlags) {
  983. return (FALSE);
  984. }
  985. if (pOldIpsecNFAData->dwTunnelIpAddr !=
  986. pNewIpsecNFAData->dwTunnelIpAddr) {
  987. return (FALSE);
  988. }
  989. return (TRUE);
  990. }
  991. DWORD
  992. PAProcessMMFilterDataForNFAs(
  993. PIPSEC_ISAKMP_DATA pNewIpsecISAKMPData,
  994. PIPSEC_NFA_DATA pOldIpsecNFAData,
  995. PIPSEC_NFA_DATA pNewIpsecNFAData,
  996. DWORD dwSource
  997. )
  998. {
  999. DWORD dwError = 0;
  1000. PIPSEC_FILTER_DATA pOldIpsecFilterData = NULL;
  1001. PIPSEC_FILTER_DATA pNewIpsecFilterData = NULL;
  1002. DWORD dwNumOldFilterSpecs = 0;
  1003. PIPSEC_FILTER_SPEC * ppOldFilterSpecs = NULL;
  1004. DWORD dwNumNewFilterSpecs = 0;
  1005. PIPSEC_FILTER_SPEC * ppNewFilterSpecs = NULL;
  1006. pOldIpsecFilterData = pOldIpsecNFAData->pIpsecFilterData;
  1007. pNewIpsecFilterData = pNewIpsecNFAData->pIpsecFilterData;
  1008. if (!pOldIpsecFilterData) {
  1009. if (!pNewIpsecFilterData) {
  1010. dwError = ERROR_SUCCESS;
  1011. return (dwError);
  1012. }
  1013. else {
  1014. dwError = PAAddMMFilterSpecs(
  1015. pNewIpsecISAKMPData,
  1016. pNewIpsecNFAData,
  1017. dwSource
  1018. );
  1019. return (dwError);
  1020. }
  1021. }
  1022. if (!pNewIpsecFilterData) {
  1023. dwError = PADeleteMMFilterSpecs(
  1024. pNewIpsecISAKMPData,
  1025. pOldIpsecNFAData
  1026. );
  1027. return (dwError);
  1028. }
  1029. if (memcmp(
  1030. &(pOldIpsecFilterData->FilterIdentifier),
  1031. &(pNewIpsecFilterData->FilterIdentifier),
  1032. sizeof(GUID))) {
  1033. dwError = PADeleteMMFilterSpecs(
  1034. pNewIpsecISAKMPData,
  1035. pOldIpsecNFAData
  1036. );
  1037. dwError = PAAddMMFilterSpecs(
  1038. pNewIpsecISAKMPData,
  1039. pNewIpsecNFAData,
  1040. dwSource
  1041. );
  1042. return (dwError);
  1043. }
  1044. dwNumOldFilterSpecs = pOldIpsecFilterData->dwNumFilterSpecs;
  1045. ppOldFilterSpecs = pOldIpsecFilterData->ppFilterSpecs;
  1046. dwNumNewFilterSpecs = pNewIpsecFilterData->dwNumFilterSpecs;
  1047. ppNewFilterSpecs = pNewIpsecFilterData->ppFilterSpecs;
  1048. dwError = PADeleteObseleteMMFilterSpecs(
  1049. pNewIpsecISAKMPData,
  1050. pOldIpsecNFAData,
  1051. dwNumOldFilterSpecs,
  1052. ppOldFilterSpecs,
  1053. pNewIpsecNFAData,
  1054. dwNumNewFilterSpecs,
  1055. ppNewFilterSpecs
  1056. );
  1057. dwError = PAUpdateMMFilterSpecs(
  1058. pNewIpsecISAKMPData,
  1059. pOldIpsecNFAData,
  1060. dwNumOldFilterSpecs,
  1061. ppOldFilterSpecs,
  1062. pNewIpsecNFAData,
  1063. dwNumNewFilterSpecs,
  1064. ppNewFilterSpecs,
  1065. dwSource
  1066. );
  1067. return (dwError);
  1068. }
  1069. DWORD
  1070. PADeleteObseleteMMFilterSpecs(
  1071. PIPSEC_ISAKMP_DATA pNewIpsecISAKMPData,
  1072. PIPSEC_NFA_DATA pOldIpsecNFAData,
  1073. DWORD dwNumOldFilterSpecs,
  1074. PIPSEC_FILTER_SPEC * ppOldFilterSpecs,
  1075. PIPSEC_NFA_DATA pNewIpsecNFAData,
  1076. DWORD dwNumNewFilterSpecs,
  1077. PIPSEC_FILTER_SPEC * ppNewFilterSpecs
  1078. )
  1079. {
  1080. DWORD dwError = 0;
  1081. DWORD i = 0;
  1082. PIPSEC_FILTER_SPEC pOldFilterSpec = NULL;
  1083. PIPSEC_FILTER_SPEC pFoundFilterSpec = NULL;
  1084. for (i = 0; i < dwNumOldFilterSpecs; i++) {
  1085. pOldFilterSpec = *(ppOldFilterSpecs + i);
  1086. pFoundFilterSpec = FindFilterSpec(
  1087. pOldFilterSpec,
  1088. ppNewFilterSpecs,
  1089. dwNumNewFilterSpecs
  1090. );
  1091. if (!pFoundFilterSpec) {
  1092. dwError = PADeleteMMFilter(
  1093. pOldFilterSpec->FilterSpecGUID,
  1094. pOldIpsecNFAData->NFAIdentifier
  1095. );
  1096. }
  1097. }
  1098. return (dwError);
  1099. }
  1100. PIPSEC_FILTER_SPEC
  1101. FindFilterSpec(
  1102. PIPSEC_FILTER_SPEC pFilterSpec,
  1103. PIPSEC_FILTER_SPEC * ppFilterSpecs,
  1104. DWORD dwNumFilterSpecs
  1105. )
  1106. {
  1107. DWORD i = 0;
  1108. PIPSEC_FILTER_SPEC pTemp = NULL;
  1109. for (i = 0; i < dwNumFilterSpecs; i++) {
  1110. pTemp = *(ppFilterSpecs + i);
  1111. if (!memcmp(
  1112. &(pFilterSpec->FilterSpecGUID),
  1113. &(pTemp->FilterSpecGUID),
  1114. sizeof(GUID))) {
  1115. return (pTemp);
  1116. }
  1117. }
  1118. return (NULL);
  1119. }
  1120. DWORD
  1121. PAUpdateMMFilterSpecs(
  1122. PIPSEC_ISAKMP_DATA pNewIpsecISAKMPData,
  1123. PIPSEC_NFA_DATA pOldIpsecNFAData,
  1124. DWORD dwNumOldFilterSpecs,
  1125. PIPSEC_FILTER_SPEC * ppOldFilterSpecs,
  1126. PIPSEC_NFA_DATA pNewIpsecNFAData,
  1127. DWORD dwNumNewFilterSpecs,
  1128. PIPSEC_FILTER_SPEC * ppNewFilterSpecs,
  1129. DWORD dwSource
  1130. )
  1131. {
  1132. DWORD dwError = 0;
  1133. PMMPOLICYSTATE pMMPolicyState = NULL;
  1134. PMMAUTHSTATE pMMAuthState = NULL;
  1135. DWORD i = 0;
  1136. PIPSEC_FILTER_SPEC pNewFilterSpec = NULL;
  1137. PIPSEC_FILTER_SPEC pFoundFilterSpec = NULL;
  1138. BOOL bEqual = FALSE;
  1139. PMMFILTERSTATE pMMFilterState = NULL;
  1140. pMMPolicyState = FindMMPolicyState(
  1141. pNewIpsecISAKMPData->ISAKMPIdentifier
  1142. );
  1143. if (!pMMPolicyState || !(pMMPolicyState->bInSPD)) {
  1144. TRACE(
  1145. TRC_ERROR,
  1146. (L"Pastore update failed to find SPD MM policy state associated with ISAKMP policy %!guid!.",
  1147. &pNewIpsecISAKMPData->ISAKMPIdentifier)
  1148. );
  1149. dwError = ERROR_INVALID_PARAMETER;
  1150. return (dwError);
  1151. }
  1152. pMMAuthState = FindMMAuthState(
  1153. pNewIpsecNFAData->NFAIdentifier
  1154. );
  1155. if (!pMMAuthState || !(pMMAuthState->bInSPD)) {
  1156. TRACE(
  1157. TRC_ERROR,
  1158. (L"Pastore update failed to find SPD MM auth method state associated with NFA %!guid!.",
  1159. &pNewIpsecNFAData->NFAIdentifier)
  1160. );
  1161. dwError = ERROR_INVALID_PARAMETER;
  1162. return (dwError);
  1163. }
  1164. for (i = 0; i < dwNumNewFilterSpecs; i++) {
  1165. pNewFilterSpec = *(ppNewFilterSpecs + i);
  1166. pFoundFilterSpec = FindFilterSpec(
  1167. pNewFilterSpec,
  1168. ppOldFilterSpecs,
  1169. dwNumOldFilterSpecs
  1170. );
  1171. if (!pFoundFilterSpec) {
  1172. dwError = PAAddMMFilterSpec(
  1173. pNewIpsecISAKMPData,
  1174. pNewIpsecNFAData,
  1175. pNewFilterSpec,
  1176. dwSource
  1177. );
  1178. }
  1179. else {
  1180. bEqual = FALSE;
  1181. bEqual = EqualFilterSpecs(
  1182. pFoundFilterSpec,
  1183. pNewFilterSpec
  1184. );
  1185. if (!bEqual) {
  1186. // ASSERT: pOldIpsecNFAData->NFAIdentifier == pNewIpsecNFAData->NFAIdentifier
  1187. //
  1188. dwError = PADeleteMMFilter(
  1189. pFoundFilterSpec->FilterSpecGUID,
  1190. pOldIpsecNFAData->NFAIdentifier
  1191. );
  1192. dwError = PAAddMMFilterSpec(
  1193. pNewIpsecISAKMPData,
  1194. pNewIpsecNFAData,
  1195. pNewFilterSpec,
  1196. dwSource
  1197. );
  1198. }
  1199. else {
  1200. // ASSERT: pOldIpsecNFAData->NFAIdentifier == pNewIpsecNFAData->NFAIdentifier
  1201. //
  1202. pMMFilterState = FindMMFilterState(
  1203. pFoundFilterSpec->FilterSpecGUID,
  1204. pNewIpsecNFAData->NFAIdentifier
  1205. );
  1206. if (!pMMFilterState) {
  1207. dwError = PAAddMMFilterSpec(
  1208. pNewIpsecISAKMPData,
  1209. pNewIpsecNFAData,
  1210. pNewFilterSpec,
  1211. dwSource
  1212. );
  1213. }
  1214. else {
  1215. if (!pMMFilterState->hMMFilter) {
  1216. PADeleteMMFilterState(pMMFilterState);
  1217. dwError = PAAddMMFilterSpec(
  1218. pNewIpsecISAKMPData,
  1219. pNewIpsecNFAData,
  1220. pNewFilterSpec,
  1221. dwSource
  1222. );
  1223. }
  1224. }
  1225. }
  1226. }
  1227. }
  1228. return (dwError);
  1229. }
  1230. DWORD
  1231. PAAddMMFilterSpec(
  1232. PIPSEC_ISAKMP_DATA pIpsecISAKMPData,
  1233. PIPSEC_NFA_DATA pIpsecNFAData,
  1234. PIPSEC_FILTER_SPEC pFilterSpec,
  1235. DWORD dwSource
  1236. )
  1237. {
  1238. DWORD dwError = 0;
  1239. PMMFILTERSTATE pMMFilterState = NULL;
  1240. PMM_FILTER pSPDMMFilter = NULL;
  1241. LPWSTR pServerName = NULL;
  1242. DWORD dwVersion = 0;
  1243. dwError = PACreateMMFilterState(
  1244. pIpsecISAKMPData,
  1245. pIpsecNFAData,
  1246. pFilterSpec,
  1247. &pMMFilterState
  1248. );
  1249. if (dwError) {
  1250. return (dwError);
  1251. }
  1252. dwError = PACreateMMFilter(
  1253. pIpsecISAKMPData,
  1254. pIpsecNFAData,
  1255. pFilterSpec,
  1256. &pSPDMMFilter
  1257. );
  1258. if (dwError) {
  1259. pMMFilterState->hMMFilter = NULL;
  1260. pMMFilterState->pNext = gpMMFilterState;
  1261. gpMMFilterState = pMMFilterState;
  1262. return (dwError);
  1263. }
  1264. dwError = AddMMFilterInternal(
  1265. pServerName,
  1266. dwVersion,
  1267. 0,
  1268. dwSource,
  1269. pSPDMMFilter,
  1270. NULL,
  1271. &(pMMFilterState->hMMFilter)
  1272. );
  1273. pMMFilterState->pNext = gpMMFilterState;
  1274. gpMMFilterState = pMMFilterState;
  1275. PAFreeMMFilter(pSPDMMFilter);
  1276. return (dwError);
  1277. }
  1278. BOOL
  1279. EqualFilterSpecs(
  1280. PIPSEC_FILTER_SPEC pOldFilterSpec,
  1281. PIPSEC_FILTER_SPEC pNewFilterSpec
  1282. )
  1283. {
  1284. BOOL bEqual = FALSE;
  1285. //
  1286. // At this point, FilterSpecGUID is same.
  1287. //
  1288. bEqual = AreNamesEqual(
  1289. pOldFilterSpec->pszDescription,
  1290. pNewFilterSpec->pszDescription
  1291. );
  1292. if (!bEqual) {
  1293. return (FALSE);
  1294. }
  1295. if (pOldFilterSpec->dwMirrorFlag !=
  1296. pNewFilterSpec->dwMirrorFlag) {
  1297. return (FALSE);
  1298. }
  1299. if (memcmp(
  1300. &(pOldFilterSpec->Filter),
  1301. &(pNewFilterSpec->Filter),
  1302. sizeof(IPSEC_FILTER))) {
  1303. return (FALSE);
  1304. }
  1305. return (TRUE);
  1306. }
  1307. DWORD
  1308. PAUpdateQMFilters(
  1309. PIPSEC_NFA_DATA pOldIpsecNFAData,
  1310. PIPSEC_NFA_DATA pNewIpsecNFAData,
  1311. DWORD dwSource
  1312. )
  1313. {
  1314. DWORD dwError = 0;
  1315. BOOL bEqual = FALSE;
  1316. PIPSEC_NEGPOL_DATA pOldIpsecNegPolData = NULL;
  1317. PIPSEC_NEGPOL_DATA pNewIpsecNegPolData = NULL;
  1318. BOOL bHardError = FALSE;
  1319. pOldIpsecNegPolData = pOldIpsecNFAData->pIpsecNegPolData;
  1320. pNewIpsecNegPolData = pNewIpsecNFAData->pIpsecNegPolData;
  1321. bEqual = EqualFilterKeysInNegPols(
  1322. pOldIpsecNegPolData,
  1323. pNewIpsecNegPolData
  1324. );
  1325. if (!bEqual) {
  1326. dwError = PADeleteQMFilterSpecs(
  1327. pOldIpsecNFAData
  1328. );
  1329. dwError = PAAddQMFilterSpecs(
  1330. pNewIpsecNFAData,
  1331. dwSource
  1332. );
  1333. return (dwError);
  1334. }
  1335. bEqual = EqualFilterKeysInNFAs(
  1336. pOldIpsecNFAData,
  1337. pNewIpsecNFAData
  1338. );
  1339. if (!bEqual) {
  1340. dwError = PADeleteQMFilterSpecs(
  1341. pOldIpsecNFAData
  1342. );
  1343. dwError = PAAddQMFilterSpecs(
  1344. pNewIpsecNFAData,
  1345. dwSource
  1346. );
  1347. return (dwError);
  1348. }
  1349. if (!memcmp(
  1350. &(pNewIpsecNegPolData->NegPolType),
  1351. &(GUID_NEGOTIATION_TYPE_DEFAULT),
  1352. sizeof(GUID))) {
  1353. dwError = ERROR_SUCCESS;
  1354. return (dwError);
  1355. }
  1356. dwError = PAProcessQMFilterDataForNFAs(
  1357. pOldIpsecNFAData,
  1358. pNewIpsecNFAData,
  1359. dwSource
  1360. );
  1361. // Not returning bHardError from here because for DCR 537526 we decided not to do
  1362. // anything for errors during updates.
  1363. return (dwError);
  1364. }
  1365. DWORD
  1366. PAAddQMFilterSpecs(
  1367. PIPSEC_NFA_DATA pNewIpsecNFAData,
  1368. DWORD dwSource
  1369. )
  1370. {
  1371. DWORD dwError = 0;
  1372. BOOL bHardError = FALSE;
  1373. if (!(pNewIpsecNFAData->dwTunnelFlags)) {
  1374. dwError = PAAddTxFilterSpecs(
  1375. pNewIpsecNFAData,
  1376. dwSource,
  1377. &bHardError
  1378. );
  1379. }
  1380. else {
  1381. dwError = PAAddTnFilterSpecs(
  1382. pNewIpsecNFAData,
  1383. dwSource,
  1384. &bHardError
  1385. );
  1386. }
  1387. // Not returning bHardError from here because for DCR 537526 we decided not to do
  1388. // anything for errors during updates.
  1389. return (dwError);
  1390. }
  1391. DWORD
  1392. PADeleteQMFilterSpecs(
  1393. PIPSEC_NFA_DATA pOldIpsecNFAData
  1394. )
  1395. {
  1396. DWORD dwError = 0;
  1397. if (!(pOldIpsecNFAData->dwTunnelFlags)) {
  1398. dwError = PADeleteTxFilterSpecs(
  1399. pOldIpsecNFAData
  1400. );
  1401. }
  1402. else {
  1403. dwError = PADeleteTnFilterSpecs(
  1404. pOldIpsecNFAData
  1405. );
  1406. }
  1407. return (dwError);
  1408. }
  1409. DWORD
  1410. PAProcessQMFilterDataForNFAs(
  1411. PIPSEC_NFA_DATA pOldIpsecNFAData,
  1412. PIPSEC_NFA_DATA pNewIpsecNFAData,
  1413. DWORD dwSource
  1414. )
  1415. {
  1416. DWORD dwError = 0;
  1417. PIPSEC_FILTER_DATA pOldIpsecFilterData = NULL;
  1418. PIPSEC_FILTER_DATA pNewIpsecFilterData = NULL;
  1419. DWORD dwNumOldFilterSpecs = 0;
  1420. PIPSEC_FILTER_SPEC * ppOldFilterSpecs = NULL;
  1421. DWORD dwNumNewFilterSpecs = 0;
  1422. PIPSEC_FILTER_SPEC * ppNewFilterSpecs = NULL;
  1423. pOldIpsecFilterData = pOldIpsecNFAData->pIpsecFilterData;
  1424. pNewIpsecFilterData = pNewIpsecNFAData->pIpsecFilterData;
  1425. if (!pOldIpsecFilterData) {
  1426. if (!pNewIpsecFilterData) {
  1427. dwError = ERROR_SUCCESS;
  1428. return (dwError);
  1429. }
  1430. else {
  1431. dwError = PAAddQMFilterSpecs(
  1432. pNewIpsecNFAData,
  1433. dwSource
  1434. );
  1435. return (dwError);
  1436. }
  1437. }
  1438. if (!pNewIpsecFilterData) {
  1439. dwError = PADeleteQMFilterSpecs(
  1440. pOldIpsecNFAData
  1441. );
  1442. return (dwError);
  1443. }
  1444. if (memcmp(
  1445. &(pOldIpsecFilterData->FilterIdentifier),
  1446. &(pNewIpsecFilterData->FilterIdentifier),
  1447. sizeof(GUID))) {
  1448. dwError = PADeleteQMFilterSpecs(
  1449. pOldIpsecNFAData
  1450. );
  1451. dwError = PAAddQMFilterSpecs(
  1452. pNewIpsecNFAData,
  1453. dwSource
  1454. );
  1455. return (dwError);
  1456. }
  1457. dwNumOldFilterSpecs = pOldIpsecFilterData->dwNumFilterSpecs;
  1458. ppOldFilterSpecs = pOldIpsecFilterData->ppFilterSpecs;
  1459. dwNumNewFilterSpecs = pNewIpsecFilterData->dwNumFilterSpecs;
  1460. ppNewFilterSpecs = pNewIpsecFilterData->ppFilterSpecs;
  1461. dwError = PADeleteObseleteQMFilterSpecs(
  1462. pOldIpsecNFAData,
  1463. dwNumOldFilterSpecs,
  1464. ppOldFilterSpecs,
  1465. pNewIpsecNFAData,
  1466. dwNumNewFilterSpecs,
  1467. ppNewFilterSpecs
  1468. );
  1469. dwError = PAUpdateQMFilterSpecs(
  1470. pOldIpsecNFAData,
  1471. dwNumOldFilterSpecs,
  1472. ppOldFilterSpecs,
  1473. pNewIpsecNFAData,
  1474. dwNumNewFilterSpecs,
  1475. ppNewFilterSpecs,
  1476. dwSource
  1477. );
  1478. return (dwError);
  1479. }
  1480. DWORD
  1481. PADeleteObseleteQMFilterSpecs(
  1482. PIPSEC_NFA_DATA pOldIpsecNFAData,
  1483. DWORD dwNumOldFilterSpecs,
  1484. PIPSEC_FILTER_SPEC * ppOldFilterSpecs,
  1485. PIPSEC_NFA_DATA pNewIpsecNFAData,
  1486. DWORD dwNumNewFilterSpecs,
  1487. PIPSEC_FILTER_SPEC * ppNewFilterSpecs
  1488. )
  1489. {
  1490. DWORD dwError = 0;
  1491. DWORD i = 0;
  1492. PIPSEC_FILTER_SPEC pOldFilterSpec = NULL;
  1493. PIPSEC_FILTER_SPEC pFoundFilterSpec = NULL;
  1494. for (i = 0; i < dwNumOldFilterSpecs; i++) {
  1495. pOldFilterSpec = *(ppOldFilterSpecs + i);
  1496. pFoundFilterSpec = FindFilterSpec(
  1497. pOldFilterSpec,
  1498. ppNewFilterSpecs,
  1499. dwNumNewFilterSpecs
  1500. );
  1501. if (!pFoundFilterSpec) {
  1502. dwError = PADeleteQMFilter(
  1503. pOldIpsecNFAData,
  1504. pOldFilterSpec->FilterSpecGUID
  1505. );
  1506. }
  1507. }
  1508. return (dwError);
  1509. }
  1510. DWORD
  1511. PAUpdateQMFilterSpecs(
  1512. PIPSEC_NFA_DATA pOldIpsecNFAData,
  1513. DWORD dwNumOldFilterSpecs,
  1514. PIPSEC_FILTER_SPEC * ppOldFilterSpecs,
  1515. PIPSEC_NFA_DATA pNewIpsecNFAData,
  1516. DWORD dwNumNewFilterSpecs,
  1517. PIPSEC_FILTER_SPEC * ppNewFilterSpecs,
  1518. DWORD dwSource
  1519. )
  1520. {
  1521. DWORD dwError = 0;
  1522. PIPSEC_NEGPOL_DATA pNewIpsecNegPolData = NULL;
  1523. PQMPOLICYSTATE pQMPolicyState = NULL;
  1524. DWORD i = 0;
  1525. PIPSEC_FILTER_SPEC pNewFilterSpec = NULL;
  1526. PIPSEC_FILTER_SPEC pFoundFilterSpec = NULL;
  1527. BOOL bEqual = FALSE;
  1528. pNewIpsecNegPolData = pNewIpsecNFAData->pIpsecNegPolData;
  1529. pQMPolicyState = FindQMPolicyState(
  1530. pNewIpsecNegPolData->NegPolIdentifier
  1531. );
  1532. if (!pQMPolicyState) {
  1533. TRACE(
  1534. TRC_ERROR,
  1535. (L"Pastore update failed to find SPD QM policy state associated for neg pol %!guid!.",
  1536. &pNewIpsecNegPolData->NegPolIdentifier)
  1537. );
  1538. dwError = ERROR_INVALID_PARAMETER;
  1539. return (dwError);
  1540. }
  1541. if (!IsClearOnly(pQMPolicyState->gNegPolAction) &&
  1542. !IsBlocking(pQMPolicyState->gNegPolAction) &&
  1543. !(pQMPolicyState->bInSPD)) {
  1544. TRACE(
  1545. TRC_ERROR,
  1546. (L"Pastore update failed to find SPD QM policy plumbed into SPD for neg pol %!guid!.",
  1547. &pNewIpsecNegPolData->NegPolIdentifier)
  1548. );
  1549. dwError = ERROR_INVALID_PARAMETER;
  1550. return (dwError);
  1551. }
  1552. for (i = 0; i < dwNumNewFilterSpecs; i++) {
  1553. pNewFilterSpec = *(ppNewFilterSpecs + i);
  1554. pFoundFilterSpec = FindFilterSpec(
  1555. pNewFilterSpec,
  1556. ppOldFilterSpecs,
  1557. dwNumOldFilterSpecs
  1558. );
  1559. if (!pFoundFilterSpec) {
  1560. dwError = PAAddQMFilterSpec(
  1561. pNewIpsecNFAData,
  1562. pQMPolicyState,
  1563. pNewFilterSpec,
  1564. dwSource
  1565. );
  1566. }
  1567. else {
  1568. bEqual = FALSE;
  1569. bEqual = EqualFilterSpecs(
  1570. pFoundFilterSpec,
  1571. pNewFilterSpec
  1572. );
  1573. if (!bEqual) {
  1574. dwError = PADeleteQMFilter(
  1575. pOldIpsecNFAData,
  1576. pFoundFilterSpec->FilterSpecGUID
  1577. );
  1578. dwError = PAAddQMFilterSpec(
  1579. pNewIpsecNFAData,
  1580. pQMPolicyState,
  1581. pNewFilterSpec,
  1582. dwSource
  1583. );
  1584. }
  1585. else {
  1586. dwError = PAUpdateQMFilterSpec(
  1587. pNewIpsecNFAData,
  1588. pQMPolicyState,
  1589. pNewFilterSpec,
  1590. dwSource
  1591. );
  1592. }
  1593. }
  1594. }
  1595. return (dwError);
  1596. }
  1597. DWORD
  1598. PADeleteQMFilter(
  1599. PIPSEC_NFA_DATA pIpsecNFAData,
  1600. GUID FilterSpecGUID
  1601. )
  1602. {
  1603. DWORD dwError = 0;
  1604. if (!(pIpsecNFAData->dwTunnelFlags)) {
  1605. dwError = PADeleteTxFilter(
  1606. FilterSpecGUID,
  1607. pIpsecNFAData->NFAIdentifier
  1608. );
  1609. }
  1610. else {
  1611. dwError = PADeleteTnFilter(
  1612. FilterSpecGUID,
  1613. pIpsecNFAData->NFAIdentifier
  1614. );
  1615. }
  1616. return (dwError);
  1617. }
  1618. DWORD
  1619. PAAddQMFilterSpec(
  1620. PIPSEC_NFA_DATA pIpsecNFAData,
  1621. PQMPOLICYSTATE pQMPolicyState,
  1622. PIPSEC_FILTER_SPEC pFilterSpec,
  1623. DWORD dwSource
  1624. )
  1625. {
  1626. DWORD dwError = 0;
  1627. if (!(pIpsecNFAData->dwTunnelFlags)) {
  1628. dwError = PAAddTxFilterSpec(
  1629. pIpsecNFAData,
  1630. pQMPolicyState,
  1631. pFilterSpec,
  1632. dwSource
  1633. );
  1634. }
  1635. else {
  1636. dwError = PAAddTnFilterSpec(
  1637. pIpsecNFAData,
  1638. pQMPolicyState,
  1639. pFilterSpec,
  1640. dwSource
  1641. );
  1642. }
  1643. return (dwError);
  1644. }
  1645. DWORD
  1646. PAAddTxFilterSpec(
  1647. PIPSEC_NFA_DATA pIpsecNFAData,
  1648. PQMPOLICYSTATE pQMPolicyState,
  1649. PIPSEC_FILTER_SPEC pFilterSpec,
  1650. DWORD dwSource
  1651. )
  1652. {
  1653. DWORD dwError = 0;
  1654. PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
  1655. PTXFILTERSTATE pTxFilterState = NULL;
  1656. PTRANSPORT_FILTER pSPDTxFilter = NULL;
  1657. LPWSTR pServerName = NULL;
  1658. DWORD dwVersion = 0;
  1659. pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
  1660. dwError = PACreateTxFilterState(
  1661. pIpsecNegPolData,
  1662. pIpsecNFAData,
  1663. pFilterSpec,
  1664. &pTxFilterState
  1665. );
  1666. if (dwError) {
  1667. return (dwError);
  1668. }
  1669. dwError = PACreateTxFilter(
  1670. pIpsecNegPolData,
  1671. pIpsecNFAData,
  1672. pFilterSpec,
  1673. pQMPolicyState,
  1674. &pSPDTxFilter
  1675. );
  1676. if (dwError) {
  1677. pTxFilterState->hTxFilter = NULL;
  1678. pTxFilterState->pNext = gpTxFilterState;
  1679. gpTxFilterState = pTxFilterState;
  1680. return (dwError);
  1681. }
  1682. dwError = AddTransportFilterInternal(
  1683. pServerName,
  1684. dwVersion,
  1685. 0,
  1686. dwSource,
  1687. pSPDTxFilter,
  1688. NULL,
  1689. &(pTxFilterState->hTxFilter)
  1690. );
  1691. pTxFilterState->pNext = gpTxFilterState;
  1692. gpTxFilterState = pTxFilterState;
  1693. PAFreeTxFilter(pSPDTxFilter);
  1694. return (dwError);
  1695. }
  1696. DWORD
  1697. PAAddTnFilterSpec(
  1698. PIPSEC_NFA_DATA pIpsecNFAData,
  1699. PQMPOLICYSTATE pQMPolicyState,
  1700. PIPSEC_FILTER_SPEC pFilterSpec,
  1701. DWORD dwSource
  1702. )
  1703. {
  1704. DWORD dwError = 0;
  1705. PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
  1706. PTNFILTERSTATE pTnFilterState = NULL;
  1707. PTUNNEL_FILTER pSPDTnFilter = NULL;
  1708. LPWSTR pServerName = NULL;
  1709. DWORD dwVersion = 0;
  1710. pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
  1711. dwError = PACreateTnFilterState(
  1712. pIpsecNegPolData,
  1713. pIpsecNFAData,
  1714. pFilterSpec,
  1715. &pTnFilterState
  1716. );
  1717. if (dwError) {
  1718. return (dwError);
  1719. }
  1720. dwError = PACreateTnFilter(
  1721. pIpsecNegPolData,
  1722. pIpsecNFAData,
  1723. pFilterSpec,
  1724. pQMPolicyState,
  1725. &pSPDTnFilter
  1726. );
  1727. if (dwError) {
  1728. pTnFilterState->hTnFilter = NULL;
  1729. pTnFilterState->pNext = gpTnFilterState;
  1730. gpTnFilterState = pTnFilterState;
  1731. return (dwError);
  1732. }
  1733. dwError = AddTunnelFilterInternal(
  1734. pServerName,
  1735. dwVersion,
  1736. 0,
  1737. dwSource,
  1738. pSPDTnFilter,
  1739. NULL,
  1740. &(pTnFilterState->hTnFilter)
  1741. );
  1742. pTnFilterState->pNext = gpTnFilterState;
  1743. gpTnFilterState = pTnFilterState;
  1744. PAFreeTnFilter(pSPDTnFilter);
  1745. return (dwError);
  1746. }
  1747. BOOL
  1748. AllowsSoft(
  1749. DWORD dwSecurityMethodCount,
  1750. PIPSEC_SECURITY_METHOD pIpsecSecurityMethods
  1751. )
  1752. {
  1753. DWORD dwTempOfferCount = 0;
  1754. PIPSEC_SECURITY_METHOD pTempMethod = NULL;
  1755. BOOL bAllowsSoft = FALSE;
  1756. DWORD i = 0;
  1757. if (!dwSecurityMethodCount || !pIpsecSecurityMethods) {
  1758. return (FALSE);
  1759. }
  1760. if (dwSecurityMethodCount > IPSEC_MAX_QM_OFFERS) {
  1761. dwTempOfferCount = IPSEC_MAX_QM_OFFERS;
  1762. }
  1763. else {
  1764. dwTempOfferCount = dwSecurityMethodCount;
  1765. }
  1766. pTempMethod = pIpsecSecurityMethods;
  1767. for (i = 0; i < dwTempOfferCount; i++) {
  1768. if (pTempMethod->Count == 0) {
  1769. bAllowsSoft = TRUE;
  1770. break;
  1771. }
  1772. pTempMethod++;
  1773. }
  1774. return (bAllowsSoft);
  1775. }
  1776. DWORD
  1777. PAUpdateQMFilterSpec(
  1778. PIPSEC_NFA_DATA pIpsecNFAData,
  1779. PQMPOLICYSTATE pQMPolicyState,
  1780. PIPSEC_FILTER_SPEC pFilterSpec,
  1781. DWORD dwSource
  1782. )
  1783. {
  1784. DWORD dwError = 0;
  1785. if (!(pIpsecNFAData->dwTunnelFlags)) {
  1786. dwError = PAUpdateTxFilterSpec(
  1787. pIpsecNFAData,
  1788. pQMPolicyState,
  1789. pFilterSpec,
  1790. dwSource
  1791. );
  1792. }
  1793. else {
  1794. dwError = PAUpdateTnFilterSpec(
  1795. pIpsecNFAData,
  1796. pQMPolicyState,
  1797. pFilterSpec,
  1798. dwSource
  1799. );
  1800. }
  1801. return (dwError);
  1802. }
  1803. DWORD
  1804. PAUpdateTxFilterSpec(
  1805. PIPSEC_NFA_DATA pIpsecNFAData,
  1806. PQMPOLICYSTATE pQMPolicyState,
  1807. PIPSEC_FILTER_SPEC pFilterSpec,
  1808. DWORD dwSource
  1809. )
  1810. {
  1811. DWORD dwError = 0;
  1812. PTXFILTERSTATE pTxFilterState = NULL;
  1813. pTxFilterState = FindTxFilterState(
  1814. pFilterSpec->FilterSpecGUID,
  1815. pIpsecNFAData->NFAIdentifier
  1816. );
  1817. if (!pTxFilterState) {
  1818. dwError = PAAddTxFilterSpec(
  1819. pIpsecNFAData,
  1820. pQMPolicyState,
  1821. pFilterSpec,
  1822. dwSource
  1823. );
  1824. }
  1825. else {
  1826. if (!pTxFilterState->hTxFilter) {
  1827. PADeleteTxFilterState(pTxFilterState);
  1828. dwError = PAAddTxFilterSpec(
  1829. pIpsecNFAData,
  1830. pQMPolicyState,
  1831. pFilterSpec,
  1832. dwSource
  1833. );
  1834. }
  1835. }
  1836. return (dwError);
  1837. }
  1838. DWORD
  1839. PAUpdateTnFilterSpec(
  1840. PIPSEC_NFA_DATA pIpsecNFAData,
  1841. PQMPOLICYSTATE pQMPolicyState,
  1842. PIPSEC_FILTER_SPEC pFilterSpec,
  1843. DWORD dwSource
  1844. )
  1845. {
  1846. DWORD dwError = 0;
  1847. PTNFILTERSTATE pTnFilterState = NULL;
  1848. pTnFilterState = FindTnFilterState(
  1849. pFilterSpec->FilterSpecGUID,
  1850. pIpsecNFAData->NFAIdentifier
  1851. );
  1852. if (!pTnFilterState) {
  1853. dwError = PAAddTnFilterSpec(
  1854. pIpsecNFAData,
  1855. pQMPolicyState,
  1856. pFilterSpec,
  1857. dwSource
  1858. );
  1859. }
  1860. else {
  1861. if (!pTnFilterState->hTnFilter) {
  1862. PADeleteTnFilterState(pTnFilterState);
  1863. dwError = PAAddTnFilterSpec(
  1864. pIpsecNFAData,
  1865. pQMPolicyState,
  1866. pFilterSpec,
  1867. dwSource
  1868. );
  1869. }
  1870. }
  1871. return (dwError);
  1872. }