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.

666 lines
15 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: isakmp-r.c
  7. //
  8. // Contents: ISAKMP management for registry.
  9. //
  10. //
  11. // History: KrishnaG.
  12. // AbhisheV.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "precomp.h"
  16. extern LPWSTR ISAKMPDNAttributes[];
  17. DWORD
  18. RegEnumISAKMPData(
  19. HKEY hRegistryKey,
  20. LPWSTR pszIpsecRootContainer,
  21. PIPSEC_ISAKMP_DATA ** pppIpsecISAKMPData,
  22. PDWORD pdwNumISAKMPObjects
  23. )
  24. {
  25. DWORD dwError = 0;
  26. PIPSEC_ISAKMP_OBJECT * ppIpsecISAKMPObjects = NULL;
  27. PIPSEC_ISAKMP_DATA pIpsecISAKMPData = NULL;
  28. PIPSEC_ISAKMP_DATA * ppIpsecISAKMPData = NULL;
  29. DWORD dwNumISAKMPObjects = 0;
  30. DWORD i = 0;
  31. DWORD j = 0;
  32. dwError = RegEnumISAKMPObjects(
  33. hRegistryKey,
  34. pszIpsecRootContainer,
  35. &ppIpsecISAKMPObjects,
  36. &dwNumISAKMPObjects
  37. );
  38. BAIL_ON_WIN32_ERROR(dwError);
  39. if (dwNumISAKMPObjects) {
  40. ppIpsecISAKMPData = (PIPSEC_ISAKMP_DATA *) AllocPolMem(
  41. dwNumISAKMPObjects*sizeof(PIPSEC_ISAKMP_DATA));
  42. if (!ppIpsecISAKMPData) {
  43. dwError = ERROR_OUTOFMEMORY;
  44. BAIL_ON_WIN32_ERROR(dwError);
  45. }
  46. }
  47. for (i = 0; i < dwNumISAKMPObjects; i++) {
  48. dwError = RegUnmarshallISAKMPData(
  49. *(ppIpsecISAKMPObjects + i),
  50. &pIpsecISAKMPData
  51. );
  52. if (!dwError) {
  53. *(ppIpsecISAKMPData + j) = pIpsecISAKMPData;
  54. j++;
  55. }
  56. }
  57. if (j == 0) {
  58. if (ppIpsecISAKMPData) {
  59. FreePolMem(ppIpsecISAKMPData);
  60. ppIpsecISAKMPData = NULL;
  61. }
  62. }
  63. *pppIpsecISAKMPData = ppIpsecISAKMPData;
  64. *pdwNumISAKMPObjects = j;
  65. dwError = ERROR_SUCCESS;
  66. cleanup:
  67. if (ppIpsecISAKMPObjects) {
  68. FreeIpsecISAKMPObjects(
  69. ppIpsecISAKMPObjects,
  70. dwNumISAKMPObjects
  71. );
  72. }
  73. return(dwError);
  74. error:
  75. if (ppIpsecISAKMPData) {
  76. FreeMulIpsecISAKMPData(
  77. ppIpsecISAKMPData,
  78. i
  79. );
  80. }
  81. *pppIpsecISAKMPData = NULL;
  82. *pdwNumISAKMPObjects = 0;
  83. goto cleanup;
  84. }
  85. DWORD
  86. RegEnumISAKMPObjects(
  87. HKEY hRegistryKey,
  88. LPWSTR pszIpsecRootContainer,
  89. PIPSEC_ISAKMP_OBJECT ** pppIpsecISAKMPObjects,
  90. PDWORD pdwNumISAKMPObjects
  91. )
  92. {
  93. DWORD dwError = 0;
  94. DWORD i = 0;
  95. DWORD dwCount = 0;
  96. PIPSEC_ISAKMP_OBJECT pIpsecISAKMPObject = NULL;
  97. PIPSEC_ISAKMP_OBJECT * ppIpsecISAKMPObjects = NULL;
  98. DWORD dwNumISAKMPObjectsReturned = 0;
  99. DWORD dwIndex = 0;
  100. WCHAR szISAKMPName[MAX_PATH];
  101. DWORD dwSize = 0;
  102. DWORD dwReserved = 0;
  103. *pppIpsecISAKMPObjects = NULL;
  104. *pdwNumISAKMPObjects = 0;
  105. while (1) {
  106. dwSize = MAX_PATH;
  107. dwReserved = 0;
  108. szISAKMPName[0] = L'\0';
  109. dwError = RegEnumKeyExW(
  110. hRegistryKey,
  111. dwIndex,
  112. szISAKMPName,
  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(szISAKMPName, L"ipsecISAKMPPolicy")) {
  124. dwIndex++;
  125. continue;
  126. }
  127. pIpsecISAKMPObject = NULL;
  128. dwError =UnMarshallRegistryISAKMPObject(
  129. hRegistryKey,
  130. pszIpsecRootContainer,
  131. szISAKMPName,
  132. REG_RELATIVE_NAME,
  133. &pIpsecISAKMPObject
  134. );
  135. if (dwError == ERROR_SUCCESS) {
  136. dwError = ReallocatePolMem(
  137. (LPVOID *) &ppIpsecISAKMPObjects,
  138. sizeof(PIPSEC_ISAKMP_OBJECT)*(dwNumISAKMPObjectsReturned),
  139. sizeof(PIPSEC_ISAKMP_OBJECT)*(dwNumISAKMPObjectsReturned + 1)
  140. );
  141. BAIL_ON_WIN32_ERROR(dwError);
  142. *(ppIpsecISAKMPObjects + dwNumISAKMPObjectsReturned) = pIpsecISAKMPObject;
  143. dwNumISAKMPObjectsReturned++;
  144. }
  145. dwIndex++;
  146. }
  147. *pppIpsecISAKMPObjects = ppIpsecISAKMPObjects;
  148. *pdwNumISAKMPObjects = dwNumISAKMPObjectsReturned;
  149. dwError = ERROR_SUCCESS;
  150. return(dwError);
  151. error:
  152. if (ppIpsecISAKMPObjects) {
  153. FreeIpsecISAKMPObjects(
  154. ppIpsecISAKMPObjects,
  155. dwNumISAKMPObjectsReturned
  156. );
  157. }
  158. if (pIpsecISAKMPObject) {
  159. FreeIpsecISAKMPObject(
  160. pIpsecISAKMPObject
  161. );
  162. }
  163. *pppIpsecISAKMPObjects = NULL;
  164. *pdwNumISAKMPObjects = 0;
  165. return(dwError);
  166. }
  167. DWORD
  168. RegSetISAKMPData(
  169. HKEY hRegistryKey,
  170. LPWSTR pszIpsecRootContainer,
  171. LPWSTR pszLocationName,
  172. PIPSEC_ISAKMP_DATA pIpsecISAKMPData
  173. )
  174. {
  175. DWORD dwError = 0;
  176. PIPSEC_ISAKMP_OBJECT pIpsecISAKMPObject = NULL;
  177. dwError = RegMarshallISAKMPObject(
  178. pIpsecISAKMPData,
  179. &pIpsecISAKMPObject
  180. );
  181. BAIL_ON_WIN32_ERROR(dwError);
  182. dwError = RegSetISAKMPObject(
  183. hRegistryKey,
  184. pszIpsecRootContainer,
  185. pIpsecISAKMPObject
  186. );
  187. BAIL_ON_WIN32_ERROR(dwError);
  188. dwError = RegBackPropIncChangesForISAKMPToPolicy(
  189. hRegistryKey,
  190. pszIpsecRootContainer,
  191. pszLocationName,
  192. pIpsecISAKMPObject
  193. );
  194. BAIL_ON_WIN32_ERROR(dwError);
  195. error:
  196. if (pIpsecISAKMPObject) {
  197. FreeIpsecISAKMPObject(pIpsecISAKMPObject);
  198. }
  199. return(dwError);
  200. }
  201. DWORD
  202. RegSetISAKMPObject(
  203. HKEY hRegistryKey,
  204. LPWSTR pszIpsecRootContainer,
  205. PIPSEC_ISAKMP_OBJECT pIpsecISAKMPObject
  206. )
  207. {
  208. DWORD dwError = 0;
  209. dwError = PersistISAKMPObject(
  210. hRegistryKey,
  211. pIpsecISAKMPObject
  212. );
  213. BAIL_ON_WIN32_ERROR(dwError);
  214. error:
  215. return(dwError);
  216. }
  217. DWORD
  218. RegCreateISAKMPData(
  219. HKEY hRegistryKey,
  220. LPWSTR pszIpsecRootContainer,
  221. PIPSEC_ISAKMP_DATA pIpsecISAKMPData
  222. )
  223. {
  224. DWORD dwError = 0;
  225. PIPSEC_ISAKMP_OBJECT pIpsecISAKMPObject = NULL;
  226. dwError = RegMarshallISAKMPObject(
  227. pIpsecISAKMPData,
  228. &pIpsecISAKMPObject
  229. );
  230. BAIL_ON_WIN32_ERROR(dwError);
  231. dwError = RegCreateISAKMPObject(
  232. hRegistryKey,
  233. pszIpsecRootContainer,
  234. pIpsecISAKMPObject
  235. );
  236. BAIL_ON_WIN32_ERROR(dwError);
  237. error:
  238. if (pIpsecISAKMPObject) {
  239. FreeIpsecISAKMPObject(
  240. pIpsecISAKMPObject
  241. );
  242. }
  243. return(dwError);
  244. }
  245. DWORD
  246. RegCreateISAKMPObject(
  247. HKEY hRegistryKey,
  248. LPWSTR pszIpsecRootContainer,
  249. PIPSEC_ISAKMP_OBJECT pIpsecISAKMPObject
  250. )
  251. {
  252. DWORD dwError = 0;
  253. dwError = PersistISAKMPObject(
  254. hRegistryKey,
  255. pIpsecISAKMPObject
  256. );
  257. BAIL_ON_WIN32_ERROR(dwError);
  258. error:
  259. return(dwError);
  260. }
  261. DWORD
  262. RegDeleteISAKMPData(
  263. HKEY hRegistryKey,
  264. LPWSTR pszIpsecRootContainer,
  265. GUID ISAKMPIdentifier
  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. &ISAKMPIdentifier,
  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"ipsecISAKMPPolicy");
  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. RegUnmarshallISAKMPData(
  297. PIPSEC_ISAKMP_OBJECT pIpsecISAKMPObject,
  298. PIPSEC_ISAKMP_DATA * ppIpsecISAKMPData
  299. )
  300. {
  301. DWORD dwError = 0;
  302. dwError = UnmarshallISAKMPObject(
  303. pIpsecISAKMPObject,
  304. ppIpsecISAKMPData
  305. );
  306. return(dwError);
  307. }
  308. DWORD
  309. RegMarshallISAKMPObject(
  310. PIPSEC_ISAKMP_DATA pIpsecISAKMPData,
  311. PIPSEC_ISAKMP_OBJECT * ppIpsecISAKMPObject
  312. )
  313. {
  314. DWORD dwError = 0;
  315. PIPSEC_ISAKMP_OBJECT pIpsecISAKMPObject = NULL;
  316. WCHAR szGuid[MAX_PATH];
  317. WCHAR szDistinguishedName[MAX_PATH];
  318. LPBYTE pBuffer = NULL;
  319. DWORD dwBufferLen = 0;
  320. LPWSTR pszStringUuid = NULL;
  321. time_t PresentTime;
  322. szGuid[0] = L'\0';
  323. szDistinguishedName[0] = L'\0';
  324. pIpsecISAKMPObject = (PIPSEC_ISAKMP_OBJECT)AllocPolMem(
  325. sizeof(IPSEC_ISAKMP_OBJECT)
  326. );
  327. if (!pIpsecISAKMPObject) {
  328. dwError = ERROR_OUTOFMEMORY;
  329. BAIL_ON_WIN32_ERROR(dwError);
  330. }
  331. dwError = UuidToString(
  332. &pIpsecISAKMPData->ISAKMPIdentifier,
  333. &pszStringUuid
  334. );
  335. BAIL_ON_WIN32_ERROR(dwError);
  336. wcscpy(szGuid, L"{");
  337. wcscat(szGuid, pszStringUuid);
  338. wcscat(szGuid, L"}");
  339. //
  340. // Fill in the distinguishedName
  341. //
  342. wcscpy(szDistinguishedName,L"ipsecISAKMPPolicy");
  343. wcscat(szDistinguishedName, szGuid);
  344. pIpsecISAKMPObject->pszDistinguishedName = AllocPolStr(
  345. szDistinguishedName
  346. );
  347. if (!pIpsecISAKMPObject->pszDistinguishedName) {
  348. dwError = ERROR_OUTOFMEMORY;
  349. BAIL_ON_WIN32_ERROR(dwError);
  350. }
  351. //
  352. // Fill in the ipsecName.
  353. // ISAKMPData doesn't have a name.
  354. //
  355. pIpsecISAKMPObject->pszIpsecName = NULL;
  356. /*
  357. if (pIpsecISAKMPData->pszIpsecName &&
  358. *pIpsecISAKMPData->pszIpsecName) {
  359. pIpsecISAKMPObject->pszIpsecName = AllocPolStr(
  360. pIpsecISAKMPData->pszIpsecName
  361. );
  362. if (!pIpsecISAKMPObject->pszIpsecName) {
  363. dwError = ERROR_OUTOFMEMORY;
  364. BAIL_ON_WIN32_ERROR(dwError);
  365. }
  366. }
  367. */
  368. //
  369. // Fill in the ipsecID
  370. //
  371. pIpsecISAKMPObject->pszIpsecID = AllocPolStr(
  372. szGuid
  373. );
  374. if (!pIpsecISAKMPObject->pszIpsecID) {
  375. dwError = ERROR_OUTOFMEMORY;
  376. BAIL_ON_WIN32_ERROR(dwError);
  377. }
  378. //
  379. // Fill in the ipsecDataType
  380. //
  381. pIpsecISAKMPObject->dwIpsecDataType = 0x100;
  382. //
  383. // Marshall the pIpsecDataBuffer and the Length
  384. //
  385. dwError = MarshallISAKMPBuffer(
  386. pIpsecISAKMPData,
  387. &pBuffer,
  388. &dwBufferLen
  389. );
  390. BAIL_ON_WIN32_ERROR(dwError);
  391. pIpsecISAKMPObject->pIpsecData = pBuffer;
  392. pIpsecISAKMPObject->dwIpsecDataLen = dwBufferLen;
  393. time(&PresentTime);
  394. pIpsecISAKMPObject->dwWhenChanged = (DWORD) PresentTime;
  395. *ppIpsecISAKMPObject = pIpsecISAKMPObject;
  396. cleanup:
  397. if (pszStringUuid) {
  398. RpcStringFree(
  399. &pszStringUuid
  400. );
  401. }
  402. return(dwError);
  403. error:
  404. if (pIpsecISAKMPObject) {
  405. FreeIpsecISAKMPObject(
  406. pIpsecISAKMPObject
  407. );
  408. }
  409. *ppIpsecISAKMPObject = NULL;
  410. goto cleanup;
  411. }
  412. DWORD
  413. MarshallISAKMPBuffer(
  414. PIPSEC_ISAKMP_DATA pIpsecISAKMPData,
  415. LPBYTE * ppBuffer,
  416. DWORD * pdwBufferLen
  417. )
  418. {
  419. LPBYTE pCurrentPos = NULL;
  420. LPBYTE pBuffer = NULL;
  421. DWORD dwSize = 0;
  422. DWORD dwError = 0;
  423. DWORD i = 0;
  424. DWORD dwNumISAKMPSecurityMethods = 0;
  425. PCRYPTO_BUNDLE pSecurityMethods = NULL;
  426. PCRYPTO_BUNDLE pSecurityMethod = NULL;
  427. ISAKMP_POLICY * pISAKMPPolicy = NULL;
  428. DWORD dwEffectiveSize = 0;
  429. // {80DC20B8-2EC8-11d1-A89E-00A0248D3021}
  430. static const GUID GUID_IPSEC_ISAKMP_POLICY_BLOB =
  431. { 0x80dc20b8, 0x2ec8, 0x11d1, { 0xa8, 0x9e, 0x0, 0xa0, 0x24, 0x8d, 0x30, 0x21 } };
  432. dwNumISAKMPSecurityMethods =pIpsecISAKMPData->dwNumISAKMPSecurityMethods;
  433. pISAKMPPolicy = &(pIpsecISAKMPData->ISAKMPPolicy);
  434. pSecurityMethods = pIpsecISAKMPData->pSecurityMethods;
  435. dwSize += sizeof(GUID);
  436. dwSize += sizeof(DWORD);
  437. dwSize += sizeof(ISAKMP_POLICY);
  438. dwSize += sizeof(DWORD);
  439. dwSize += sizeof(CRYPTO_BUNDLE)*dwNumISAKMPSecurityMethods;
  440. dwSize++;
  441. pBuffer = (LPBYTE)AllocPolMem(dwSize);
  442. if (!pBuffer) {
  443. dwError = ERROR_OUTOFMEMORY;
  444. BAIL_ON_WIN32_ERROR(dwError);
  445. }
  446. pCurrentPos = pBuffer;
  447. memcpy(pCurrentPos, &GUID_IPSEC_ISAKMP_POLICY_BLOB, sizeof(GUID));
  448. pCurrentPos += sizeof(GUID);
  449. dwEffectiveSize = dwSize - sizeof(GUID) - sizeof(DWORD) - 1;
  450. memcpy(pCurrentPos, &dwEffectiveSize, sizeof(DWORD));
  451. pCurrentPos += sizeof(DWORD);
  452. memcpy(pCurrentPos, pISAKMPPolicy, sizeof(ISAKMP_POLICY));
  453. pCurrentPos += sizeof(ISAKMP_POLICY);
  454. memcpy(pCurrentPos, &dwNumISAKMPSecurityMethods, sizeof(DWORD));
  455. pCurrentPos += sizeof(DWORD);
  456. for (i = 0; i < dwNumISAKMPSecurityMethods; i++) {
  457. pSecurityMethod = pSecurityMethods + i;
  458. memcpy(pCurrentPos, pSecurityMethod, sizeof(CRYPTO_BUNDLE));
  459. pCurrentPos += sizeof(CRYPTO_BUNDLE);
  460. }
  461. *ppBuffer = pBuffer;
  462. *pdwBufferLen = dwSize;
  463. return(dwError);
  464. error:
  465. if (pBuffer) {
  466. FreePolMem(pBuffer);
  467. }
  468. *ppBuffer = NULL;
  469. *pdwBufferLen = 0;
  470. return(dwError);
  471. }
  472. DWORD
  473. RegGetISAKMPData(
  474. HKEY hRegistryKey,
  475. LPWSTR pszIpsecRootContainer,
  476. GUID ISAKMPGUID,
  477. PIPSEC_ISAKMP_DATA * ppIpsecISAKMPData
  478. )
  479. {
  480. DWORD dwError = 0;
  481. PIPSEC_ISAKMP_OBJECT pIpsecISAKMPObject = NULL;
  482. PIPSEC_ISAKMP_DATA pIpsecISAKMPData = NULL;
  483. WCHAR szIpsecISAKMPName[MAX_PATH];
  484. LPWSTR pszISAKMPName = NULL;
  485. szIpsecISAKMPName[0] = L'\0';
  486. wcscpy(szIpsecISAKMPName, L"ipsecISAKMPPolicy");
  487. dwError = UuidToString(&ISAKMPGUID, &pszISAKMPName);
  488. BAIL_ON_WIN32_ERROR(dwError);
  489. wcscat(szIpsecISAKMPName, L"{");
  490. wcscat(szIpsecISAKMPName, pszISAKMPName);
  491. wcscat(szIpsecISAKMPName, L"}");
  492. dwError =UnMarshallRegistryISAKMPObject(
  493. hRegistryKey,
  494. pszIpsecRootContainer,
  495. szIpsecISAKMPName,
  496. REG_RELATIVE_NAME,
  497. &pIpsecISAKMPObject
  498. );
  499. BAIL_ON_WIN32_ERROR(dwError);
  500. dwError = RegUnmarshallISAKMPData(
  501. pIpsecISAKMPObject,
  502. &pIpsecISAKMPData
  503. );
  504. BAIL_ON_WIN32_ERROR(dwError);
  505. error:
  506. if (pIpsecISAKMPObject) {
  507. FreeIpsecISAKMPObject(
  508. pIpsecISAKMPObject
  509. );
  510. }
  511. if (pszISAKMPName) {
  512. RpcStringFree(&pszISAKMPName);
  513. }
  514. *ppIpsecISAKMPData = pIpsecISAKMPData;
  515. return(dwError);
  516. }