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.

722 lines
17 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: negpols-r.c
  7. //
  8. // Contents: Negotiation Policy management for registry.
  9. //
  10. //
  11. // History: KrishnaG.
  12. // AbhisheV.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "precomp.h"
  16. extern LPWSTR NegPolDNAttributes[];
  17. DWORD
  18. RegEnumNegPolData(
  19. HKEY hRegistryKey,
  20. LPWSTR pszIpsecRootContainer,
  21. PIPSEC_NEGPOL_DATA ** pppIpsecNegPolData,
  22. PDWORD pdwNumNegPolObjects
  23. )
  24. {
  25. DWORD dwError = 0;
  26. PIPSEC_NEGPOL_OBJECT * ppIpsecNegPolObjects = NULL;
  27. PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
  28. PIPSEC_NEGPOL_DATA * ppIpsecNegPolData = NULL;
  29. DWORD dwNumNegPolObjects = 0;
  30. DWORD i = 0;
  31. DWORD j = 0;
  32. dwError = RegEnumNegPolObjects(
  33. hRegistryKey,
  34. pszIpsecRootContainer,
  35. &ppIpsecNegPolObjects,
  36. &dwNumNegPolObjects
  37. );
  38. BAIL_ON_WIN32_ERROR(dwError);
  39. if (dwNumNegPolObjects) {
  40. ppIpsecNegPolData = (PIPSEC_NEGPOL_DATA *) AllocPolMem(
  41. dwNumNegPolObjects*sizeof(PIPSEC_NEGPOL_DATA));
  42. if (!ppIpsecNegPolData) {
  43. dwError = ERROR_OUTOFMEMORY;
  44. BAIL_ON_WIN32_ERROR(dwError);
  45. }
  46. }
  47. for (i = 0; i < dwNumNegPolObjects; i++) {
  48. dwError = RegUnmarshallNegPolData(
  49. *(ppIpsecNegPolObjects + i),
  50. &pIpsecNegPolData
  51. );
  52. if (!dwError) {
  53. *(ppIpsecNegPolData + j) = pIpsecNegPolData;
  54. j++;
  55. }
  56. }
  57. if (j == 0) {
  58. if (ppIpsecNegPolData) {
  59. FreePolMem(ppIpsecNegPolData);
  60. ppIpsecNegPolData = NULL;
  61. }
  62. }
  63. *pppIpsecNegPolData = ppIpsecNegPolData;
  64. *pdwNumNegPolObjects = j;
  65. dwError = ERROR_SUCCESS;
  66. cleanup:
  67. if (ppIpsecNegPolObjects) {
  68. FreeIpsecNegPolObjects(
  69. ppIpsecNegPolObjects,
  70. dwNumNegPolObjects
  71. );
  72. }
  73. return(dwError);
  74. error:
  75. if (ppIpsecNegPolData) {
  76. FreeMulIpsecNegPolData(
  77. ppIpsecNegPolData,
  78. i
  79. );
  80. }
  81. *pppIpsecNegPolData = NULL;
  82. *pdwNumNegPolObjects = 0;
  83. goto cleanup;
  84. }
  85. DWORD
  86. RegEnumNegPolObjects(
  87. HKEY hRegistryKey,
  88. LPWSTR pszIpsecRootContainer,
  89. PIPSEC_NEGPOL_OBJECT ** pppIpsecNegPolObjects,
  90. PDWORD pdwNumNegPolObjects
  91. )
  92. {
  93. DWORD dwError = 0;
  94. DWORD i = 0;
  95. DWORD dwCount = 0;
  96. PIPSEC_NEGPOL_OBJECT pIpsecNegPolObject = NULL;
  97. PIPSEC_NEGPOL_OBJECT * ppIpsecNegPolObjects = NULL;
  98. DWORD dwNumNegPolObjectsReturned = 0;
  99. DWORD dwIndex = 0;
  100. WCHAR szNegPolName[MAX_PATH];
  101. DWORD dwSize = 0;
  102. DWORD dwReserved = 0;
  103. *pppIpsecNegPolObjects = NULL;
  104. *pdwNumNegPolObjects = 0;
  105. while (1) {
  106. dwSize = MAX_PATH;
  107. dwReserved = 0;
  108. szNegPolName[0] = L'\0';
  109. dwError = RegEnumKeyExW(
  110. hRegistryKey,
  111. dwIndex,
  112. szNegPolName,
  113. &dwSize,
  114. NULL,
  115. NULL,
  116. 0,
  117. 0
  118. );
  119. if (dwError == ERROR_NO_MORE_ITEMS) {
  120. break;
  121. }
  122. BAIL_ON_WIN32_ERROR(dwError);
  123. if (!wcsstr(szNegPolName, L"ipsecNegotiationPolicy")) {
  124. dwIndex++;
  125. continue;
  126. }
  127. pIpsecNegPolObject = NULL;
  128. dwError =UnMarshallRegistryNegPolObject(
  129. hRegistryKey,
  130. pszIpsecRootContainer,
  131. szNegPolName,
  132. REG_RELATIVE_NAME,
  133. &pIpsecNegPolObject
  134. );
  135. if (dwError == ERROR_SUCCESS) {
  136. dwError = ReallocatePolMem(
  137. (LPVOID *) &ppIpsecNegPolObjects,
  138. sizeof(PIPSEC_NEGPOL_OBJECT)*(dwNumNegPolObjectsReturned),
  139. sizeof(PIPSEC_NEGPOL_OBJECT)*(dwNumNegPolObjectsReturned + 1)
  140. );
  141. BAIL_ON_WIN32_ERROR(dwError);
  142. *(ppIpsecNegPolObjects + dwNumNegPolObjectsReturned) = pIpsecNegPolObject;
  143. dwNumNegPolObjectsReturned++;
  144. }
  145. dwIndex++;
  146. }
  147. *pppIpsecNegPolObjects = ppIpsecNegPolObjects;
  148. *pdwNumNegPolObjects = dwNumNegPolObjectsReturned;
  149. dwError = ERROR_SUCCESS;
  150. return(dwError);
  151. error:
  152. if (ppIpsecNegPolObjects) {
  153. FreeIpsecNegPolObjects(
  154. ppIpsecNegPolObjects,
  155. dwNumNegPolObjectsReturned
  156. );
  157. }
  158. if (pIpsecNegPolObject) {
  159. FreeIpsecNegPolObject(
  160. pIpsecNegPolObject
  161. );
  162. }
  163. *pppIpsecNegPolObjects = NULL;
  164. *pdwNumNegPolObjects = 0;
  165. return(dwError);
  166. }
  167. DWORD
  168. RegSetNegPolData(
  169. HKEY hRegistryKey,
  170. LPWSTR pszIpsecRootContainer,
  171. LPWSTR pszLocationName,
  172. PIPSEC_NEGPOL_DATA pIpsecNegPolData
  173. )
  174. {
  175. DWORD dwError = 0;
  176. PIPSEC_NEGPOL_OBJECT pIpsecNegPolObject = NULL;
  177. dwError = RegMarshallNegPolObject(
  178. pIpsecNegPolData,
  179. &pIpsecNegPolObject
  180. );
  181. BAIL_ON_WIN32_ERROR(dwError);
  182. dwError = RegSetNegPolObject(
  183. hRegistryKey,
  184. pszIpsecRootContainer,
  185. pIpsecNegPolObject
  186. );
  187. BAIL_ON_WIN32_ERROR(dwError);
  188. dwError = RegBackPropIncChangesForNegPolToNFA(
  189. hRegistryKey,
  190. pszIpsecRootContainer,
  191. pszLocationName,
  192. pIpsecNegPolObject
  193. );
  194. BAIL_ON_WIN32_ERROR(dwError);
  195. error:
  196. if (pIpsecNegPolObject) {
  197. FreeIpsecNegPolObject(pIpsecNegPolObject);
  198. }
  199. return(dwError);
  200. }
  201. DWORD
  202. RegSetNegPolObject(
  203. HKEY hRegistryKey,
  204. LPWSTR pszIpsecRootContainer,
  205. PIPSEC_NEGPOL_OBJECT pIpsecNegPolObject
  206. )
  207. {
  208. DWORD dwError = 0;
  209. dwError = PersistNegPolObject(
  210. hRegistryKey,
  211. pIpsecNegPolObject
  212. );
  213. BAIL_ON_WIN32_ERROR(dwError);
  214. error:
  215. return(dwError);
  216. }
  217. DWORD
  218. RegCreateNegPolData(
  219. HKEY hRegistryKey,
  220. LPWSTR pszIpsecRootContainer,
  221. PIPSEC_NEGPOL_DATA pIpsecNegPolData
  222. )
  223. {
  224. DWORD dwError = 0;
  225. PIPSEC_NEGPOL_OBJECT pIpsecNegPolObject = NULL;
  226. dwError = RegMarshallNegPolObject(
  227. pIpsecNegPolData,
  228. &pIpsecNegPolObject
  229. );
  230. BAIL_ON_WIN32_ERROR(dwError);
  231. dwError = RegCreateNegPolObject(
  232. hRegistryKey,
  233. pszIpsecRootContainer,
  234. pIpsecNegPolObject
  235. );
  236. BAIL_ON_WIN32_ERROR(dwError);
  237. error:
  238. if (pIpsecNegPolObject) {
  239. FreeIpsecNegPolObject(
  240. pIpsecNegPolObject
  241. );
  242. }
  243. return(dwError);
  244. }
  245. DWORD
  246. RegCreateNegPolObject(
  247. HKEY hRegistryKey,
  248. LPWSTR pszIpsecRootContainer,
  249. PIPSEC_NEGPOL_OBJECT pIpsecNegPolObject
  250. )
  251. {
  252. DWORD dwError = 0;
  253. dwError = PersistNegPolObject(
  254. hRegistryKey,
  255. pIpsecNegPolObject
  256. );
  257. BAIL_ON_WIN32_ERROR(dwError);
  258. error:
  259. return(dwError);
  260. }
  261. DWORD
  262. RegDeleteNegPolData(
  263. HKEY hRegistryKey,
  264. LPWSTR pszIpsecRootContainer,
  265. GUID NegPolIdentifier
  266. )
  267. {
  268. DWORD dwError = ERROR_SUCCESS;
  269. WCHAR szGuid[MAX_PATH];
  270. WCHAR szDistinguishedName[MAX_PATH];
  271. LPWSTR pszStringUuid = NULL;
  272. szGuid[0] = L'\0';
  273. szDistinguishedName[0] = L'\0';
  274. dwError = UuidToString(
  275. &NegPolIdentifier,
  276. &pszStringUuid
  277. );
  278. BAIL_ON_WIN32_ERROR(dwError);
  279. wcscpy(szGuid, L"{");
  280. wcscat(szGuid, pszStringUuid);
  281. wcscat(szGuid, L"}");
  282. wcscpy(szDistinguishedName,L"ipsecNegotiationPolicy");
  283. wcscat(szDistinguishedName, szGuid);
  284. dwError = RegDeleteKeyW(
  285. hRegistryKey,
  286. szDistinguishedName
  287. );
  288. BAIL_ON_WIN32_ERROR(dwError);
  289. error:
  290. if (pszStringUuid) {
  291. RpcStringFree(&pszStringUuid);
  292. }
  293. return(dwError);
  294. }
  295. DWORD
  296. RegUnmarshallNegPolData(
  297. PIPSEC_NEGPOL_OBJECT pIpsecNegPolObject,
  298. PIPSEC_NEGPOL_DATA * ppIpsecNegPolData
  299. )
  300. {
  301. DWORD dwError = 0;
  302. dwError = UnmarshallNegPolObject(
  303. pIpsecNegPolObject,
  304. ppIpsecNegPolData
  305. );
  306. return(dwError);
  307. }
  308. DWORD
  309. RegMarshallNegPolObject(
  310. PIPSEC_NEGPOL_DATA pIpsecNegPolData,
  311. PIPSEC_NEGPOL_OBJECT * ppIpsecNegPolObject
  312. )
  313. {
  314. DWORD dwError = 0;
  315. PIPSEC_NEGPOL_OBJECT pIpsecNegPolObject = NULL;
  316. WCHAR szGuid[MAX_PATH];
  317. WCHAR szDistinguishedName[MAX_PATH];
  318. LPBYTE pBuffer = NULL;
  319. DWORD dwBufferLen = 0;
  320. LPWSTR pszStringUuid = NULL;
  321. LPWSTR pszNegPolActionUuid = NULL;
  322. LPWSTR pszNegPolTypeUuid = NULL;
  323. time_t PresentTime;
  324. WCHAR szGuidAction[MAX_PATH];
  325. WCHAR szGuidType[MAX_PATH];
  326. szGuidAction[0] = L'\0';
  327. szGuidType[0] = L'\0';
  328. szGuid[0] = L'\0';
  329. szDistinguishedName[0] = L'\0';
  330. pIpsecNegPolObject = (PIPSEC_NEGPOL_OBJECT)AllocPolMem(
  331. sizeof(IPSEC_NEGPOL_OBJECT)
  332. );
  333. if (!pIpsecNegPolObject) {
  334. dwError = ERROR_OUTOFMEMORY;
  335. BAIL_ON_WIN32_ERROR(dwError);
  336. }
  337. dwError = UuidToString(
  338. &pIpsecNegPolData->NegPolIdentifier,
  339. &pszStringUuid
  340. );
  341. BAIL_ON_WIN32_ERROR(dwError);
  342. wcscpy(szGuid, L"{");
  343. wcscat(szGuid, pszStringUuid);
  344. wcscat(szGuid, L"}");
  345. //
  346. // Fill in the distinguishedName
  347. //
  348. wcscpy(szDistinguishedName,L"ipsecNegotiationPolicy");
  349. wcscat(szDistinguishedName, szGuid);
  350. pIpsecNegPolObject->pszDistinguishedName = AllocPolStr(
  351. szDistinguishedName
  352. );
  353. if (!pIpsecNegPolObject->pszDistinguishedName) {
  354. dwError = ERROR_OUTOFMEMORY;
  355. BAIL_ON_WIN32_ERROR(dwError);
  356. }
  357. //
  358. // Fill in the ipsecName
  359. //
  360. if (pIpsecNegPolData->pszIpsecName &&
  361. *pIpsecNegPolData->pszIpsecName) {
  362. pIpsecNegPolObject->pszIpsecName = AllocPolStr(
  363. pIpsecNegPolData->pszIpsecName
  364. );
  365. if (!pIpsecNegPolObject->pszIpsecName) {
  366. dwError = ERROR_OUTOFMEMORY;
  367. BAIL_ON_WIN32_ERROR(dwError);
  368. }
  369. }
  370. if (pIpsecNegPolData->pszDescription &&
  371. *pIpsecNegPolData->pszDescription) {
  372. pIpsecNegPolObject->pszDescription = AllocPolStr(
  373. pIpsecNegPolData->pszDescription
  374. );
  375. if (!pIpsecNegPolObject->pszDescription) {
  376. dwError = ERROR_OUTOFMEMORY;
  377. BAIL_ON_WIN32_ERROR(dwError);
  378. }
  379. }
  380. //
  381. // Fill in the ipsecID
  382. //
  383. pIpsecNegPolObject->pszIpsecID = AllocPolStr(
  384. szGuid
  385. );
  386. if (!pIpsecNegPolObject->pszIpsecID) {
  387. dwError = ERROR_OUTOFMEMORY;
  388. BAIL_ON_WIN32_ERROR(dwError);
  389. }
  390. dwError = UuidToString(
  391. &pIpsecNegPolData->NegPolAction,
  392. &pszNegPolActionUuid
  393. );
  394. BAIL_ON_WIN32_ERROR(dwError);
  395. wcscpy(szGuidAction, L"{");
  396. wcscat(szGuidAction, pszNegPolActionUuid);
  397. wcscat(szGuidAction, L"}");
  398. pIpsecNegPolObject->pszIpsecNegPolAction = AllocPolStr(
  399. szGuidAction
  400. );
  401. if (!pIpsecNegPolObject->pszIpsecNegPolAction) {
  402. dwError = ERROR_OUTOFMEMORY;
  403. BAIL_ON_WIN32_ERROR(dwError);
  404. }
  405. dwError = UuidToString(
  406. &pIpsecNegPolData->NegPolType,
  407. &pszNegPolTypeUuid
  408. );
  409. BAIL_ON_WIN32_ERROR(dwError);
  410. wcscpy(szGuidType, L"{");
  411. wcscat(szGuidType, pszNegPolTypeUuid);
  412. wcscat(szGuidType, L"}");
  413. pIpsecNegPolObject->pszIpsecNegPolType = AllocPolStr(
  414. szGuidType
  415. );
  416. if (!pIpsecNegPolObject->pszIpsecNegPolType) {
  417. dwError = ERROR_OUTOFMEMORY;
  418. BAIL_ON_WIN32_ERROR(dwError);
  419. }
  420. //
  421. // Fill in the ipsecDataType
  422. //
  423. pIpsecNegPolObject->dwIpsecDataType = 0x100;
  424. //
  425. // Marshall the pIpsecDataBuffer and the Length
  426. //
  427. dwError = MarshallNegPolBuffer(
  428. pIpsecNegPolData,
  429. &pBuffer,
  430. &dwBufferLen
  431. );
  432. BAIL_ON_WIN32_ERROR(dwError);
  433. pIpsecNegPolObject->pIpsecData = pBuffer;
  434. pIpsecNegPolObject->dwIpsecDataLen = dwBufferLen;
  435. time(&PresentTime);
  436. pIpsecNegPolObject->dwWhenChanged = (DWORD) PresentTime;
  437. *ppIpsecNegPolObject = pIpsecNegPolObject;
  438. cleanup:
  439. if (pszStringUuid) {
  440. RpcStringFree(
  441. &pszStringUuid
  442. );
  443. }
  444. if (pszNegPolActionUuid) {
  445. RpcStringFree(
  446. &pszNegPolActionUuid
  447. );
  448. }
  449. if (pszNegPolTypeUuid) {
  450. RpcStringFree(
  451. &pszNegPolTypeUuid
  452. );
  453. }
  454. return(dwError);
  455. error:
  456. if (pIpsecNegPolObject) {
  457. FreeIpsecNegPolObject(
  458. pIpsecNegPolObject
  459. );
  460. }
  461. *ppIpsecNegPolObject = NULL;
  462. goto cleanup;
  463. }
  464. DWORD
  465. MarshallNegPolBuffer(
  466. PIPSEC_NEGPOL_DATA pIpsecNegPolData,
  467. LPBYTE * ppBuffer,
  468. DWORD * pdwBufferLen
  469. )
  470. {
  471. LPBYTE pCurrentPos = NULL;
  472. LPBYTE pBuffer = NULL;
  473. DWORD dwSize = 0;
  474. DWORD dwError = 0;
  475. DWORD dwNumSecurityOffers = 0;
  476. IPSEC_SECURITY_METHOD * pIpsecOffer = NULL;
  477. DWORD i = 0;
  478. DWORD dwEffectiveSize = 0;
  479. // {80DC20B9-2EC8-11d1-A89E-00A0248D3021}
  480. static const GUID GUID_IPSEC_NEGPOLICY_BLOB =
  481. { 0x80dc20b9, 0x2ec8, 0x11d1, { 0xa8, 0x9e, 0x0, 0xa0, 0x24, 0x8d, 0x30, 0x21 } };
  482. dwNumSecurityOffers = pIpsecNegPolData->dwSecurityMethodCount;
  483. pIpsecOffer = pIpsecNegPolData->pIpsecSecurityMethods;
  484. dwSize += sizeof(GUID);
  485. dwSize += sizeof(DWORD);
  486. dwSize += sizeof(DWORD);
  487. for (i = 0; i < dwNumSecurityOffers; i++) {
  488. dwSize += sizeof(IPSEC_SECURITY_METHOD);
  489. }
  490. dwSize++;
  491. pBuffer = (LPBYTE)AllocPolMem(dwSize);
  492. if (!pBuffer) {
  493. dwError = ERROR_OUTOFMEMORY;
  494. BAIL_ON_WIN32_ERROR(dwError);
  495. }
  496. pCurrentPos = pBuffer;
  497. memcpy(pCurrentPos, &GUID_IPSEC_NEGPOLICY_BLOB, sizeof(GUID));
  498. pCurrentPos += sizeof(GUID);
  499. dwEffectiveSize = dwSize - sizeof(GUID) - sizeof(DWORD) - 1;
  500. memcpy(pCurrentPos, &dwEffectiveSize, sizeof(DWORD));
  501. pCurrentPos += sizeof(DWORD);
  502. memcpy(pCurrentPos, &dwNumSecurityOffers, sizeof(DWORD));
  503. pCurrentPos += sizeof(DWORD);
  504. for (i = 0; i < dwNumSecurityOffers; i++) {
  505. memcpy(pCurrentPos, pIpsecOffer + i, sizeof(IPSEC_SECURITY_METHOD));
  506. pCurrentPos += sizeof(IPSEC_SECURITY_METHOD);
  507. }
  508. *ppBuffer = pBuffer;
  509. *pdwBufferLen = dwSize;
  510. return(dwError);
  511. error:
  512. if (pBuffer) {
  513. FreePolMem(pBuffer);
  514. }
  515. *ppBuffer = NULL;
  516. *pdwBufferLen = 0;
  517. return(dwError);
  518. }
  519. DWORD
  520. RegGetNegPolData(
  521. HKEY hRegistryKey,
  522. LPWSTR pszIpsecRootContainer,
  523. GUID NegPolGUID,
  524. PIPSEC_NEGPOL_DATA * ppIpsecNegPolData
  525. )
  526. {
  527. DWORD dwError = 0;
  528. PIPSEC_NEGPOL_OBJECT pIpsecNegPolObject = NULL;
  529. PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
  530. WCHAR szIpsecNegPolName[MAX_PATH];
  531. LPWSTR pszNegPolName = NULL;
  532. szIpsecNegPolName[0] = L'\0';
  533. wcscpy(szIpsecNegPolName, L"ipsecNegotiationPolicy");
  534. dwError = UuidToString(&NegPolGUID, &pszNegPolName);
  535. BAIL_ON_WIN32_ERROR(dwError);
  536. wcscat(szIpsecNegPolName, L"{");
  537. wcscat(szIpsecNegPolName, pszNegPolName);
  538. wcscat(szIpsecNegPolName, L"}");
  539. dwError =UnMarshallRegistryNegPolObject(
  540. hRegistryKey,
  541. pszIpsecRootContainer,
  542. szIpsecNegPolName,
  543. REG_RELATIVE_NAME,
  544. &pIpsecNegPolObject
  545. );
  546. BAIL_ON_WIN32_ERROR(dwError);
  547. dwError = RegUnmarshallNegPolData(
  548. pIpsecNegPolObject,
  549. &pIpsecNegPolData
  550. );
  551. BAIL_ON_WIN32_ERROR(dwError);
  552. error:
  553. if (pIpsecNegPolObject) {
  554. FreeIpsecNegPolObject(
  555. pIpsecNegPolObject
  556. );
  557. }
  558. if (pszNegPolName) {
  559. RpcStringFree(&pszNegPolName);
  560. }
  561. *ppIpsecNegPolData = pIpsecNegPolData;
  562. return(dwError);
  563. }