Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

830 lines
17 KiB

  1. #include "precomp.h"
  2. DWORD
  3. PAAddQMPolicies(
  4. PIPSEC_NFA_DATA * ppIpsecNFAData,
  5. DWORD dwNumNFACount
  6. )
  7. {
  8. DWORD dwError = 0;
  9. DWORD i = 0;
  10. PIPSEC_NFA_DATA pIpsecNFAData = NULL;
  11. PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
  12. PQMPOLICYSTATE pQMPolicyState = NULL;
  13. PIPSEC_QM_POLICY pSPDQMPolicy = NULL;
  14. LPWSTR pServerName = NULL;
  15. DWORD dwPersist = 0;
  16. for (i = 0; i < dwNumNFACount; i++) {
  17. pIpsecNFAData = *(ppIpsecNFAData + i);
  18. pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
  19. pQMPolicyState = FindQMPolicyState(
  20. pIpsecNegPolData->NegPolIdentifier
  21. );
  22. if (pQMPolicyState) {
  23. pQMPolicyState->cRef++;
  24. continue;
  25. }
  26. dwError = PACreateQMPolicyState(
  27. *(ppIpsecNFAData + i),
  28. &pQMPolicyState
  29. );
  30. if (dwError) {
  31. continue;
  32. }
  33. if (IsClearOnly(pQMPolicyState->gNegPolAction) ||
  34. IsBlocking(pQMPolicyState->gNegPolAction)) {
  35. pQMPolicyState->bInSPD = FALSE;
  36. pQMPolicyState->dwErrorCode = 0;
  37. pQMPolicyState->pNext = gpQMPolicyState;
  38. gpQMPolicyState = pQMPolicyState;
  39. continue;
  40. }
  41. dwError = PACreateQMPolicy(
  42. *(ppIpsecNFAData + i),
  43. pQMPolicyState,
  44. &pSPDQMPolicy
  45. );
  46. if (dwError) {
  47. pQMPolicyState->bInSPD = FALSE;
  48. pQMPolicyState->dwErrorCode = dwError;
  49. pQMPolicyState->pNext = gpQMPolicyState;
  50. gpQMPolicyState = pQMPolicyState;
  51. continue;
  52. }
  53. dwError = AddQMPolicy(
  54. pServerName,
  55. dwPersist,
  56. pSPDQMPolicy
  57. );
  58. if (dwError) {
  59. pQMPolicyState->bInSPD = FALSE;
  60. pQMPolicyState->dwErrorCode = dwError;
  61. }
  62. else {
  63. pQMPolicyState->bInSPD = TRUE;
  64. pQMPolicyState->dwErrorCode = ERROR_SUCCESS;
  65. }
  66. pQMPolicyState->pNext = gpQMPolicyState;
  67. gpQMPolicyState = pQMPolicyState;
  68. PAFreeQMPolicy(pSPDQMPolicy);
  69. }
  70. return (dwError);
  71. }
  72. DWORD
  73. PACreateQMPolicyState(
  74. PIPSEC_NFA_DATA pIpsecNFAData,
  75. PQMPOLICYSTATE * ppQMPolicyState
  76. )
  77. {
  78. DWORD dwError = 0;
  79. PQMPOLICYSTATE pQMPolicyState = NULL;
  80. PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
  81. WCHAR pszName[512];
  82. dwError = AllocateSPDMemory(
  83. sizeof(QMPOLICYSTATE),
  84. &pQMPolicyState
  85. );
  86. BAIL_ON_WIN32_ERROR(dwError);
  87. pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
  88. memcpy(
  89. &(pQMPolicyState->gPolicyID),
  90. &(pIpsecNegPolData->NegPolIdentifier),
  91. sizeof(GUID)
  92. );
  93. if (pIpsecNegPolData->pszIpsecName && *(pIpsecNegPolData->pszIpsecName)) {
  94. dwError = AllocateSPDString(
  95. pIpsecNegPolData->pszIpsecName,
  96. &(pQMPolicyState->pszPolicyName)
  97. );
  98. BAIL_ON_WIN32_ERROR(dwError);
  99. }
  100. else {
  101. wsprintf(pszName, L"%d", ++gdwQMPolicyCounter);
  102. dwError = AllocateSPDString(
  103. pszName,
  104. &(pQMPolicyState->pszPolicyName)
  105. );
  106. BAIL_ON_WIN32_ERROR(dwError);
  107. }
  108. memcpy(
  109. &(pQMPolicyState->gNegPolType),
  110. &(pIpsecNegPolData->NegPolType),
  111. sizeof(GUID)
  112. );
  113. memcpy(
  114. &(pQMPolicyState->gNegPolAction),
  115. &(pIpsecNegPolData->NegPolAction),
  116. sizeof(GUID)
  117. );
  118. pQMPolicyState->bAllowsSoft = FALSE;
  119. pQMPolicyState->cRef = 1;
  120. pQMPolicyState->bInSPD = FALSE;
  121. pQMPolicyState->dwErrorCode = 0;
  122. pQMPolicyState->pNext = NULL;
  123. *ppQMPolicyState = pQMPolicyState;
  124. return (dwError);
  125. error:
  126. if (pQMPolicyState) {
  127. PAFreeQMPolicyState(pQMPolicyState);
  128. }
  129. *ppQMPolicyState = NULL;
  130. return (dwError);
  131. }
  132. VOID
  133. PAFreeQMPolicyState(
  134. PQMPOLICYSTATE pQMPolicyState
  135. )
  136. {
  137. if (pQMPolicyState) {
  138. if (pQMPolicyState->pszPolicyName) {
  139. FreeSPDString(pQMPolicyState->pszPolicyName);
  140. }
  141. FreeSPDMemory(pQMPolicyState);
  142. }
  143. }
  144. BOOL
  145. IsClearOnly(
  146. GUID gNegPolAction
  147. )
  148. {
  149. if (!memcmp(
  150. &gNegPolAction,
  151. &(GUID_NEGOTIATION_ACTION_NO_IPSEC),
  152. sizeof(GUID))) {
  153. return (TRUE);
  154. }
  155. else {
  156. return (FALSE);
  157. }
  158. }
  159. BOOL
  160. IsBlocking(
  161. GUID gNegPolAction
  162. )
  163. {
  164. if (!memcmp(
  165. &gNegPolAction,
  166. &(GUID_NEGOTIATION_ACTION_BLOCK),
  167. sizeof(GUID))) {
  168. return (TRUE);
  169. }
  170. else {
  171. return (FALSE);
  172. }
  173. }
  174. BOOL
  175. IsInboundPassThru(
  176. GUID gNegPolAction
  177. )
  178. {
  179. if (!memcmp(
  180. &gNegPolAction,
  181. &(GUID_NEGOTIATION_ACTION_INBOUND_PASSTHRU),
  182. sizeof(GUID))) {
  183. return (TRUE);
  184. }
  185. else {
  186. return (FALSE);
  187. }
  188. }
  189. DWORD
  190. PACreateQMPolicy(
  191. PIPSEC_NFA_DATA pIpsecNFAData,
  192. PQMPOLICYSTATE pQMPolicyState,
  193. PIPSEC_QM_POLICY * ppSPDQMPolicy
  194. )
  195. {
  196. DWORD dwError = 0;
  197. PIPSEC_QM_POLICY pSPDQMPolicy = NULL;
  198. PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
  199. pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
  200. dwError = AllocateSPDMemory(
  201. sizeof(IPSEC_QM_POLICY),
  202. &pSPDQMPolicy
  203. );
  204. BAIL_ON_WIN32_ERROR(dwError);
  205. memcpy(
  206. &(pSPDQMPolicy->gPolicyID),
  207. &(pIpsecNegPolData->NegPolIdentifier),
  208. sizeof(GUID)
  209. );
  210. dwError = AllocateSPDString(
  211. pQMPolicyState->pszPolicyName,
  212. &(pSPDQMPolicy->pszPolicyName)
  213. );
  214. BAIL_ON_WIN32_ERROR(dwError);
  215. dwError = PACreateQMOffers(
  216. pIpsecNegPolData->dwSecurityMethodCount,
  217. pIpsecNegPolData->pIpsecSecurityMethods,
  218. pQMPolicyState,
  219. &(pSPDQMPolicy->dwOfferCount),
  220. &(pSPDQMPolicy->pOffers)
  221. );
  222. BAIL_ON_WIN32_ERROR(dwError);
  223. pSPDQMPolicy->dwFlags = 0;
  224. if (!memcmp(
  225. &(pIpsecNegPolData->NegPolType),
  226. &(GUID_NEGOTIATION_TYPE_DEFAULT),
  227. sizeof(GUID))) {
  228. pSPDQMPolicy->dwFlags |= IPSEC_QM_POLICY_DEFAULT_POLICY;
  229. }
  230. if (pIpsecNFAData->dwTunnelFlags) {
  231. pSPDQMPolicy->dwFlags |= IPSEC_QM_POLICY_TUNNEL_MODE;
  232. }
  233. if (pQMPolicyState->bAllowsSoft) {
  234. pSPDQMPolicy->dwFlags |= IPSEC_QM_POLICY_ALLOW_SOFT;
  235. }
  236. *ppSPDQMPolicy = pSPDQMPolicy;
  237. return (dwError);
  238. error:
  239. if (pSPDQMPolicy) {
  240. PAFreeQMPolicy(
  241. pSPDQMPolicy
  242. );
  243. }
  244. *ppSPDQMPolicy = NULL;
  245. return (dwError);
  246. }
  247. DWORD
  248. PACreateQMOffers(
  249. DWORD dwSecurityMethodCount,
  250. PIPSEC_SECURITY_METHOD pIpsecSecurityMethods,
  251. PQMPOLICYSTATE pQMPolicyState,
  252. PDWORD pdwOfferCount,
  253. PIPSEC_QM_OFFER * ppOffers
  254. )
  255. {
  256. DWORD dwError = 0;
  257. DWORD dwTempOfferCount = 0;
  258. PIPSEC_SECURITY_METHOD pTempMethod = NULL;
  259. BOOL bAllowsSoft = FALSE;
  260. DWORD i = 0;
  261. DWORD dwOfferCount = 0;
  262. PIPSEC_QM_OFFER pOffers = NULL;
  263. PIPSEC_QM_OFFER pTempOffer = NULL;
  264. if (!dwSecurityMethodCount || !pIpsecSecurityMethods) {
  265. dwError = ERROR_INVALID_PARAMETER;
  266. BAIL_ON_WIN32_ERROR(dwError);
  267. }
  268. if (dwSecurityMethodCount > IPSEC_MAX_QM_OFFERS) {
  269. dwTempOfferCount = IPSEC_MAX_QM_OFFERS;
  270. }
  271. else {
  272. dwTempOfferCount = dwSecurityMethodCount;
  273. }
  274. pTempMethod = pIpsecSecurityMethods;
  275. for (i = 0; i < dwTempOfferCount; i++) {
  276. if (pTempMethod->Count == 0) {
  277. bAllowsSoft = TRUE;
  278. }
  279. else {
  280. dwOfferCount++;
  281. }
  282. pTempMethod++;
  283. }
  284. if (!dwOfferCount) {
  285. dwError = ERROR_INVALID_PARAMETER;
  286. BAIL_ON_WIN32_ERROR(dwError);
  287. }
  288. dwError = AllocateSPDMemory(
  289. sizeof(IPSEC_QM_OFFER)*dwOfferCount,
  290. &(pOffers)
  291. );
  292. BAIL_ON_WIN32_ERROR(dwError);
  293. pTempOffer = pOffers;
  294. pTempMethod = pIpsecSecurityMethods;
  295. i = 0;
  296. while (i < dwOfferCount) {
  297. if (pTempMethod->Count) {
  298. PACopyQMOffers(
  299. pTempMethod,
  300. pTempOffer
  301. );
  302. i++;
  303. pTempOffer++;
  304. }
  305. pTempMethod++;
  306. }
  307. pQMPolicyState->bAllowsSoft = bAllowsSoft;
  308. *pdwOfferCount = dwOfferCount;
  309. *ppOffers = pOffers;
  310. return (dwError);
  311. error:
  312. if (pOffers) {
  313. PAFreeQMOffers(
  314. i,
  315. pOffers
  316. );
  317. }
  318. *pdwOfferCount = 0;
  319. *ppOffers = NULL;
  320. return (dwError);
  321. }
  322. VOID
  323. PACopyQMOffers(
  324. PIPSEC_SECURITY_METHOD pMethod,
  325. PIPSEC_QM_OFFER pOffer
  326. )
  327. {
  328. DWORD i = 0;
  329. DWORD j = 0;
  330. DWORD k = 0;
  331. pOffer->Lifetime.uKeyExpirationKBytes = pMethod->Lifetime.KeyExpirationBytes;
  332. pOffer->Lifetime.uKeyExpirationTime = pMethod->Lifetime.KeyExpirationTime;
  333. pOffer->dwFlags = pMethod->Flags;
  334. pOffer->bPFSRequired = pMethod->PfsQMRequired;
  335. if (pMethod->PfsQMRequired) {
  336. pOffer->dwPFSGroup = PFS_GROUP_MM;
  337. }
  338. else {
  339. pOffer->dwPFSGroup = PFS_GROUP_NONE;
  340. }
  341. i = 0;
  342. for (j = 0; (j < pMethod->Count) && (i < QM_MAX_ALGOS) ; j++) {
  343. switch (pMethod->Algos[j].operation) {
  344. case Auth:
  345. switch (pMethod->Algos[j].algoIdentifier) {
  346. case IPSEC_AH_MD5:
  347. pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_AH_MD5;
  348. break;
  349. case IPSEC_AH_SHA:
  350. pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_AH_SHA1;
  351. break;
  352. default:
  353. pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_AH_NONE;
  354. break;
  355. }
  356. pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AH_NONE;
  357. pOffer->Algos[i].Operation = AUTHENTICATION;
  358. pOffer->Algos[i].uAlgoKeyLen = pMethod->Algos[j].algoKeylen;
  359. pOffer->Algos[i].uAlgoRounds = pMethod->Algos[j].algoRounds;
  360. pOffer->Algos[i].MySpi = 0;
  361. pOffer->Algos[i].PeerSpi = 0;
  362. i++;
  363. break;
  364. case Encrypt:
  365. switch (pMethod->Algos[j].algoIdentifier) {
  366. case IPSEC_ESP_DES:
  367. pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_ESP_DES;
  368. break;
  369. case IPSEC_ESP_DES_40:
  370. pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_ESP_DES;
  371. break;
  372. case IPSEC_ESP_3_DES:
  373. pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_ESP_3_DES;
  374. break;
  375. default:
  376. pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_ESP_NONE;
  377. break;
  378. }
  379. switch (pMethod->Algos[j].secondaryAlgoIdentifier) {
  380. case IPSEC_AH_MD5:
  381. pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AH_MD5;
  382. break;
  383. case IPSEC_AH_SHA:
  384. pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AH_SHA1;
  385. break;
  386. default:
  387. pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AH_NONE;
  388. break;
  389. }
  390. pOffer->Algos[i].Operation = ENCRYPTION;
  391. pOffer->Algos[i].uAlgoKeyLen = pMethod->Algos[j].algoKeylen;
  392. pOffer->Algos[i].uAlgoRounds = pMethod->Algos[j].algoRounds;
  393. pOffer->Algos[i].MySpi = 0;
  394. pOffer->Algos[i].PeerSpi = 0;
  395. i++;
  396. break;
  397. case None:
  398. case Compress:
  399. default:
  400. break;
  401. }
  402. }
  403. for (k = i; k < QM_MAX_ALGOS; k++) {
  404. memset(&(pOffer->Algos[k]), 0, sizeof(IPSEC_QM_ALGO));
  405. }
  406. pOffer->dwNumAlgos = i;
  407. }
  408. VOID
  409. PAFreeQMPolicy(
  410. PIPSEC_QM_POLICY pSPDQMPolicy
  411. )
  412. {
  413. if (pSPDQMPolicy) {
  414. if (pSPDQMPolicy->pszPolicyName) {
  415. FreeSPDString(pSPDQMPolicy->pszPolicyName);
  416. }
  417. PAFreeQMOffers(
  418. pSPDQMPolicy->dwOfferCount,
  419. pSPDQMPolicy->pOffers
  420. );
  421. FreeSPDMemory(pSPDQMPolicy);
  422. }
  423. }
  424. VOID
  425. PAFreeQMOffers(
  426. DWORD dwOfferCount,
  427. PIPSEC_QM_OFFER pOffers
  428. )
  429. {
  430. if (pOffers) {
  431. FreeSPDMemory(pOffers);
  432. }
  433. }
  434. DWORD
  435. PADeleteAllQMPolicies(
  436. )
  437. {
  438. DWORD dwError = 0;
  439. PQMPOLICYSTATE pQMPolicyState = NULL;
  440. LPWSTR pServerName = NULL;
  441. PQMPOLICYSTATE pTemp = NULL;
  442. PQMPOLICYSTATE pLeftQMPolicyState = NULL;
  443. pQMPolicyState = gpQMPolicyState;
  444. while (pQMPolicyState) {
  445. if (pQMPolicyState->bInSPD) {
  446. dwError = DeleteQMPolicy(
  447. pServerName,
  448. pQMPolicyState->pszPolicyName
  449. );
  450. if (!dwError) {
  451. pTemp = pQMPolicyState;
  452. pQMPolicyState = pQMPolicyState->pNext;
  453. PAFreeQMPolicyState(pTemp);
  454. }
  455. else {
  456. pQMPolicyState->dwErrorCode = dwError;
  457. pTemp = pQMPolicyState;
  458. pQMPolicyState = pQMPolicyState->pNext;
  459. pTemp->pNext = pLeftQMPolicyState;
  460. pLeftQMPolicyState = pTemp;
  461. }
  462. }
  463. else {
  464. pTemp = pQMPolicyState;
  465. pQMPolicyState = pQMPolicyState->pNext;
  466. PAFreeQMPolicyState(pTemp);
  467. }
  468. }
  469. gpQMPolicyState = pLeftQMPolicyState;
  470. return (dwError);
  471. }
  472. VOID
  473. PAFreeQMPolicyStateList(
  474. PQMPOLICYSTATE pQMPolicyState
  475. )
  476. {
  477. PQMPOLICYSTATE pTemp = NULL;
  478. while (pQMPolicyState) {
  479. pTemp = pQMPolicyState;
  480. pQMPolicyState = pQMPolicyState->pNext;
  481. PAFreeQMPolicyState(pTemp);
  482. }
  483. }
  484. PQMPOLICYSTATE
  485. FindQMPolicyState(
  486. GUID gPolicyID
  487. )
  488. {
  489. PQMPOLICYSTATE pQMPolicyState = NULL;
  490. pQMPolicyState = gpQMPolicyState;
  491. while (pQMPolicyState) {
  492. if (!memcmp(&(pQMPolicyState->gPolicyID), &gPolicyID, sizeof(GUID))) {
  493. return (pQMPolicyState);
  494. }
  495. pQMPolicyState = pQMPolicyState->pNext;
  496. }
  497. return (NULL);
  498. }
  499. DWORD
  500. PADeleteQMPolicies(
  501. PIPSEC_NFA_DATA * ppIpsecNFAData,
  502. DWORD dwNumNFACount
  503. )
  504. {
  505. DWORD dwError = 0;
  506. DWORD i = 0;
  507. PIPSEC_NFA_DATA pIpsecNFAData = NULL;
  508. PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
  509. for (i = 0; i < dwNumNFACount; i++) {
  510. pIpsecNFAData = *(ppIpsecNFAData + i);
  511. pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
  512. dwError = PADeleteQMPolicy(
  513. pIpsecNegPolData->NegPolIdentifier
  514. );
  515. }
  516. return (dwError);
  517. }
  518. DWORD
  519. PADeleteQMPolicy(
  520. GUID gPolicyID
  521. )
  522. {
  523. DWORD dwError = 0;
  524. PQMPOLICYSTATE pQMPolicyState = NULL;
  525. LPWSTR pServerName = NULL;
  526. pQMPolicyState = FindQMPolicyState(
  527. gPolicyID
  528. );
  529. if (!pQMPolicyState) {
  530. dwError = ERROR_SUCCESS;
  531. return (dwError);
  532. }
  533. pQMPolicyState->cRef--;
  534. if (pQMPolicyState->cRef > 0) {
  535. dwError = ERROR_SUCCESS;
  536. return (dwError);
  537. }
  538. if (pQMPolicyState->bInSPD) {
  539. dwError = DeleteQMPolicy(
  540. pServerName,
  541. pQMPolicyState->pszPolicyName
  542. );
  543. if (dwError) {
  544. pQMPolicyState->cRef++;
  545. pQMPolicyState->dwErrorCode = dwError;
  546. }
  547. BAIL_ON_WIN32_ERROR(dwError);
  548. }
  549. PADeleteQMPolicyState(pQMPolicyState);
  550. error:
  551. return (dwError);
  552. }
  553. VOID
  554. PADeleteQMPolicyState(
  555. PQMPOLICYSTATE pQMPolicyState
  556. )
  557. {
  558. PQMPOLICYSTATE * ppTemp = NULL;
  559. ppTemp = &gpQMPolicyState;
  560. while (*ppTemp) {
  561. if (*ppTemp == pQMPolicyState) {
  562. break;
  563. }
  564. ppTemp = &((*ppTemp)->pNext);
  565. }
  566. if (*ppTemp) {
  567. *ppTemp = pQMPolicyState->pNext;
  568. }
  569. PAFreeQMPolicyState(pQMPolicyState);
  570. return;
  571. }
  572. DWORD
  573. PADeleteInUseQMPolicies(
  574. )
  575. {
  576. DWORD dwError = 0;
  577. PQMPOLICYSTATE pQMPolicyState = NULL;
  578. LPWSTR pServerName = NULL;
  579. PQMPOLICYSTATE pTemp = NULL;
  580. PQMPOLICYSTATE pLeftQMPolicyState = NULL;
  581. pQMPolicyState = gpQMPolicyState;
  582. while (pQMPolicyState) {
  583. if (pQMPolicyState->bInSPD &&
  584. (pQMPolicyState->dwErrorCode == ERROR_IPSEC_QM_POLICY_IN_USE)) {
  585. dwError = DeleteQMPolicy(
  586. pServerName,
  587. pQMPolicyState->pszPolicyName
  588. );
  589. if (!dwError) {
  590. pTemp = pQMPolicyState;
  591. pQMPolicyState = pQMPolicyState->pNext;
  592. PAFreeQMPolicyState(pTemp);
  593. }
  594. else {
  595. pTemp = pQMPolicyState;
  596. pQMPolicyState = pQMPolicyState->pNext;
  597. pTemp->pNext = pLeftQMPolicyState;
  598. pLeftQMPolicyState = pTemp;
  599. }
  600. }
  601. else {
  602. pTemp = pQMPolicyState;
  603. pQMPolicyState = pQMPolicyState->pNext;
  604. pTemp->pNext = pLeftQMPolicyState;
  605. pLeftQMPolicyState = pTemp;
  606. }
  607. }
  608. gpQMPolicyState = pLeftQMPolicyState;
  609. return (dwError);
  610. }