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.

655 lines
14 KiB

  1. #include "precomp.h"
  2. DWORD
  3. PAAddMMAuthMethods(
  4. PIPSEC_NFA_DATA * ppIpsecNFAData,
  5. DWORD dwNumNFACount
  6. )
  7. {
  8. DWORD dwError = 0;
  9. DWORD i = 0;
  10. PMMAUTHSTATE pMMAuthState = NULL;
  11. PMM_AUTH_METHODS pSPDMMAuthMethods = NULL;
  12. LPWSTR pServerName = NULL;
  13. DWORD dwPersist = 0;
  14. for (i = 0; i < dwNumNFACount; i++) {
  15. dwError = PACreateMMAuthState(
  16. *(ppIpsecNFAData + i),
  17. &pMMAuthState
  18. );
  19. if (dwError) {
  20. continue;
  21. }
  22. dwError = PACreateMMAuthMethods(
  23. *(ppIpsecNFAData + i),
  24. &pSPDMMAuthMethods
  25. );
  26. if (dwError) {
  27. pMMAuthState->bInSPD = FALSE;
  28. pMMAuthState->dwErrorCode = dwError;
  29. pMMAuthState->pNext = gpMMAuthState;
  30. gpMMAuthState = pMMAuthState;
  31. continue;
  32. }
  33. dwError = AddMMAuthMethods(
  34. pServerName,
  35. dwPersist,
  36. pSPDMMAuthMethods
  37. );
  38. if (dwError) {
  39. pMMAuthState->bInSPD = FALSE;
  40. pMMAuthState->dwErrorCode = dwError;
  41. }
  42. else {
  43. pMMAuthState->bInSPD = TRUE;
  44. pMMAuthState->dwErrorCode = ERROR_SUCCESS;
  45. }
  46. pMMAuthState->pNext = gpMMAuthState;
  47. gpMMAuthState = pMMAuthState;
  48. PAFreeMMAuthMethods(pSPDMMAuthMethods);
  49. }
  50. return (dwError);
  51. }
  52. DWORD
  53. PACreateMMAuthState(
  54. PIPSEC_NFA_DATA pIpsecNFAData,
  55. PMMAUTHSTATE * ppMMAuthState
  56. )
  57. {
  58. DWORD dwError = 0;
  59. PMMAUTHSTATE pMMAuthState = NULL;
  60. dwError = AllocateSPDMemory(
  61. sizeof(MMAUTHSTATE),
  62. &pMMAuthState
  63. );
  64. BAIL_ON_WIN32_ERROR(dwError);
  65. memcpy(
  66. &(pMMAuthState->gMMAuthID),
  67. &(pIpsecNFAData->NFAIdentifier),
  68. sizeof(GUID)
  69. );
  70. pMMAuthState->bInSPD = FALSE;
  71. pMMAuthState->dwErrorCode = 0;
  72. pMMAuthState->pNext = NULL;
  73. *ppMMAuthState = pMMAuthState;
  74. return (dwError);
  75. error:
  76. *ppMMAuthState = NULL;
  77. return (dwError);
  78. }
  79. DWORD
  80. PACreateMMAuthMethods(
  81. PIPSEC_NFA_DATA pIpsecNFAData,
  82. PMM_AUTH_METHODS * ppSPDMMAuthMethods
  83. )
  84. {
  85. DWORD dwError = 0;
  86. DWORD dwAuthMethodCount = 0;
  87. PIPSEC_AUTH_METHOD * ppAuthMethods = NULL;
  88. PMM_AUTH_METHODS pSPDMMAuthMethods = NULL;
  89. PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
  90. dwAuthMethodCount = pIpsecNFAData->dwAuthMethodCount;
  91. ppAuthMethods = pIpsecNFAData->ppAuthMethods;
  92. if (!dwAuthMethodCount || !ppAuthMethods) {
  93. dwError = ERROR_INVALID_PARAMETER;
  94. BAIL_ON_WIN32_ERROR(dwError);
  95. }
  96. dwError = AllocateSPDMemory(
  97. sizeof(MM_AUTH_METHODS),
  98. &pSPDMMAuthMethods
  99. );
  100. BAIL_ON_WIN32_ERROR(dwError);
  101. memcpy(
  102. &(pSPDMMAuthMethods->gMMAuthID),
  103. &(pIpsecNFAData->NFAIdentifier),
  104. sizeof(GUID)
  105. );
  106. pSPDMMAuthMethods->dwFlags = 0;
  107. pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
  108. if (!memcmp(
  109. &(pIpsecNegPolData->NegPolType),
  110. &(GUID_NEGOTIATION_TYPE_DEFAULT),
  111. sizeof(GUID))) {
  112. pSPDMMAuthMethods->dwFlags |= IPSEC_MM_AUTH_DEFAULT_AUTH;
  113. }
  114. dwError = PACreateMMAuthInfos(
  115. dwAuthMethodCount,
  116. ppAuthMethods,
  117. &(pSPDMMAuthMethods->dwNumAuthInfos),
  118. &(pSPDMMAuthMethods->pAuthenticationInfo)
  119. );
  120. BAIL_ON_WIN32_ERROR(dwError);
  121. *ppSPDMMAuthMethods = pSPDMMAuthMethods;
  122. return (dwError);
  123. error:
  124. if (pSPDMMAuthMethods) {
  125. PAFreeMMAuthMethods(pSPDMMAuthMethods);
  126. }
  127. *ppSPDMMAuthMethods = NULL;
  128. return (dwError);
  129. }
  130. DWORD
  131. PACreateMMAuthInfos(
  132. DWORD dwAuthMethodCount,
  133. PIPSEC_AUTH_METHOD * ppAuthMethods,
  134. PDWORD pdwNumAuthInfos,
  135. PIPSEC_MM_AUTH_INFO * ppAuthenticationInfo
  136. )
  137. {
  138. DWORD dwError = 0;
  139. PIPSEC_MM_AUTH_INFO pAuthenticationInfo = NULL;
  140. PIPSEC_MM_AUTH_INFO pTemp = NULL;
  141. PIPSEC_AUTH_METHOD pAuthMethod = NULL;
  142. DWORD i = 0;
  143. //
  144. // dwAuthMethodCount is not zero at this point.
  145. // ppAuthMethods is not null at this point.
  146. //
  147. dwError = AllocateSPDMemory(
  148. sizeof(IPSEC_MM_AUTH_INFO)*dwAuthMethodCount,
  149. &(pAuthenticationInfo)
  150. );
  151. BAIL_ON_WIN32_ERROR(dwError);
  152. pTemp = pAuthenticationInfo;
  153. for (i = 0; i < dwAuthMethodCount; i++) {
  154. pAuthMethod = *(ppAuthMethods + i);
  155. pTemp->AuthMethod = (MM_AUTH_ENUM) pAuthMethod->dwAuthType;
  156. switch(pTemp->AuthMethod) {
  157. case IKE_SSPI:
  158. pTemp->dwAuthInfoSize = 0;
  159. pTemp->pAuthInfo = NULL;
  160. break;
  161. case IKE_RSA_SIGNATURE:
  162. if (pAuthMethod->dwAltAuthLen && pAuthMethod->pAltAuthMethod) {
  163. dwError = AllocateSPDMemory(
  164. pAuthMethod->dwAltAuthLen,
  165. &(pTemp->pAuthInfo)
  166. );
  167. BAIL_ON_WIN32_ERROR(dwError);
  168. pTemp->dwAuthInfoSize = pAuthMethod->dwAltAuthLen;
  169. //
  170. // Need to catch the exception when the size of auth info
  171. // specified is more than the actual size.
  172. //
  173. //
  174. memcpy(
  175. pTemp->pAuthInfo,
  176. pAuthMethod->pAltAuthMethod,
  177. pAuthMethod->dwAltAuthLen
  178. );
  179. }
  180. else {
  181. if (!(pAuthMethod->dwAuthLen) || !(pAuthMethod->pszAuthMethod)) {
  182. dwError = ERROR_INVALID_PARAMETER;
  183. BAIL_ON_WIN32_ERROR(dwError);
  184. }
  185. dwError = EncodeName(
  186. pAuthMethod->pszAuthMethod,
  187. &pTemp->pAuthInfo,
  188. &pTemp->dwAuthInfoSize
  189. );
  190. BAIL_ON_WIN32_ERROR(dwError);
  191. }
  192. break;
  193. default:
  194. if (!(pAuthMethod->dwAuthLen) || !(pAuthMethod->pszAuthMethod)) {
  195. dwError = ERROR_INVALID_PARAMETER;
  196. BAIL_ON_WIN32_ERROR(dwError);
  197. }
  198. dwError = AllocateSPDMemory(
  199. (pAuthMethod->dwAuthLen)*sizeof(WCHAR),
  200. &(pTemp->pAuthInfo)
  201. );
  202. BAIL_ON_WIN32_ERROR(dwError);
  203. pTemp->dwAuthInfoSize = (pAuthMethod->dwAuthLen)*sizeof(WCHAR);
  204. //
  205. // Need to catch the exception when the size of auth info
  206. // specified is more than the actual size.
  207. //
  208. //
  209. memcpy(
  210. pTemp->pAuthInfo,
  211. (LPBYTE) pAuthMethod->pszAuthMethod,
  212. (pAuthMethod->dwAuthLen)*sizeof(WCHAR)
  213. );
  214. break;
  215. }
  216. pTemp++;
  217. }
  218. *pdwNumAuthInfos = dwAuthMethodCount;
  219. *ppAuthenticationInfo = pAuthenticationInfo;
  220. return (dwError);
  221. error:
  222. if (pAuthenticationInfo) {
  223. PAFreeMMAuthInfos(
  224. i,
  225. pAuthenticationInfo
  226. );
  227. }
  228. *pdwNumAuthInfos = 0;
  229. *ppAuthenticationInfo = NULL;
  230. return (dwError);
  231. }
  232. VOID
  233. PAFreeMMAuthMethods(
  234. PMM_AUTH_METHODS pSPDMMAuthMethods
  235. )
  236. {
  237. if (pSPDMMAuthMethods) {
  238. PAFreeMMAuthInfos(
  239. pSPDMMAuthMethods->dwNumAuthInfos,
  240. pSPDMMAuthMethods->pAuthenticationInfo
  241. );
  242. FreeSPDMemory(pSPDMMAuthMethods);
  243. }
  244. }
  245. VOID
  246. PAFreeMMAuthInfos(
  247. DWORD dwNumAuthInfos,
  248. PIPSEC_MM_AUTH_INFO pAuthenticationInfo
  249. )
  250. {
  251. DWORD i = 0;
  252. PIPSEC_MM_AUTH_INFO pTemp = NULL;
  253. if (pAuthenticationInfo) {
  254. pTemp = pAuthenticationInfo;
  255. for (i = 0; i < dwNumAuthInfos; i++) {
  256. if (pTemp->pAuthInfo) {
  257. FreeSPDMemory(pTemp->pAuthInfo);
  258. }
  259. pTemp++;
  260. }
  261. FreeSPDMemory(pAuthenticationInfo);
  262. }
  263. }
  264. DWORD
  265. PADeleteAllMMAuthMethods(
  266. )
  267. {
  268. DWORD dwError = 0;
  269. PMMAUTHSTATE pMMAuthState = NULL;
  270. LPWSTR pServerName = NULL;
  271. PMMAUTHSTATE pTemp = NULL;
  272. PMMAUTHSTATE pLeftMMAuthState = NULL;
  273. pMMAuthState = gpMMAuthState;
  274. while (pMMAuthState) {
  275. if (pMMAuthState->bInSPD) {
  276. dwError = DeleteMMAuthMethods(
  277. pServerName,
  278. pMMAuthState->gMMAuthID
  279. );
  280. if (!dwError) {
  281. pTemp = pMMAuthState;
  282. pMMAuthState = pMMAuthState->pNext;
  283. FreeSPDMemory(pTemp);
  284. }
  285. else {
  286. pMMAuthState->dwErrorCode = dwError;
  287. pTemp = pMMAuthState;
  288. pMMAuthState = pMMAuthState->pNext;
  289. pTemp->pNext = pLeftMMAuthState;
  290. pLeftMMAuthState = pTemp;
  291. }
  292. }
  293. else {
  294. pTemp = pMMAuthState;
  295. pMMAuthState = pMMAuthState->pNext;
  296. FreeSPDMemory(pTemp);
  297. }
  298. }
  299. gpMMAuthState = pLeftMMAuthState;
  300. return (dwError);
  301. }
  302. VOID
  303. PAFreeMMAuthStateList(
  304. PMMAUTHSTATE pMMAuthState
  305. )
  306. {
  307. PMMAUTHSTATE pTemp = NULL;
  308. while (pMMAuthState) {
  309. pTemp = pMMAuthState;
  310. pMMAuthState = pMMAuthState->pNext;
  311. FreeSPDMemory(pTemp);
  312. }
  313. }
  314. PMMAUTHSTATE
  315. FindMMAuthState(
  316. GUID gMMAuthID
  317. )
  318. {
  319. PMMAUTHSTATE pMMAuthState = NULL;
  320. pMMAuthState = gpMMAuthState;
  321. while (pMMAuthState) {
  322. if (!memcmp(&(pMMAuthState->gMMAuthID), &gMMAuthID, sizeof(GUID))) {
  323. return (pMMAuthState);
  324. }
  325. pMMAuthState = pMMAuthState->pNext;
  326. }
  327. return (NULL);
  328. }
  329. DWORD
  330. PADeleteMMAuthMethods(
  331. PIPSEC_NFA_DATA * ppIpsecNFAData,
  332. DWORD dwNumNFACount
  333. )
  334. {
  335. DWORD dwError = 0;
  336. DWORD i = 0;
  337. PIPSEC_NFA_DATA pIpsecNFAData = NULL;
  338. for (i = 0; i < dwNumNFACount; i++) {
  339. pIpsecNFAData = *(ppIpsecNFAData + i);
  340. dwError = PADeleteMMAuthMethod(
  341. pIpsecNFAData->NFAIdentifier
  342. );
  343. }
  344. return (dwError);
  345. }
  346. DWORD
  347. PADeleteMMAuthMethod(
  348. GUID gMMAuthID
  349. )
  350. {
  351. DWORD dwError = 0;
  352. PMMAUTHSTATE pMMAuthState = NULL;
  353. LPWSTR pServerName = NULL;
  354. pMMAuthState = FindMMAuthState(
  355. gMMAuthID
  356. );
  357. if (!pMMAuthState) {
  358. dwError = ERROR_SUCCESS;
  359. return (dwError);
  360. }
  361. if (pMMAuthState->bInSPD) {
  362. dwError = DeleteMMAuthMethods(
  363. pServerName,
  364. pMMAuthState->gMMAuthID
  365. );
  366. if (dwError) {
  367. pMMAuthState->dwErrorCode = dwError;
  368. }
  369. BAIL_ON_WIN32_ERROR(dwError);
  370. }
  371. PADeleteMMAuthState(pMMAuthState);
  372. error:
  373. return (dwError);
  374. }
  375. VOID
  376. PADeleteMMAuthState(
  377. PMMAUTHSTATE pMMAuthState
  378. )
  379. {
  380. PMMAUTHSTATE * ppTemp = NULL;
  381. ppTemp = &gpMMAuthState;
  382. while (*ppTemp) {
  383. if (*ppTemp == pMMAuthState) {
  384. break;
  385. }
  386. ppTemp = &((*ppTemp)->pNext);
  387. }
  388. if (*ppTemp) {
  389. *ppTemp = pMMAuthState->pNext;
  390. }
  391. FreeSPDMemory(pMMAuthState);
  392. return;
  393. }
  394. DWORD
  395. PADeleteInUseMMAuthMethods(
  396. )
  397. {
  398. DWORD dwError = 0;
  399. PMMAUTHSTATE pMMAuthState = NULL;
  400. LPWSTR pServerName = NULL;
  401. PMMAUTHSTATE pTemp = NULL;
  402. PMMAUTHSTATE pLeftMMAuthState = NULL;
  403. pMMAuthState = gpMMAuthState;
  404. while (pMMAuthState) {
  405. if (pMMAuthState->bInSPD &&
  406. (pMMAuthState->dwErrorCode == ERROR_IPSEC_MM_AUTH_IN_USE)) {
  407. dwError = DeleteMMAuthMethods(
  408. pServerName,
  409. pMMAuthState->gMMAuthID
  410. );
  411. if (!dwError) {
  412. pTemp = pMMAuthState;
  413. pMMAuthState = pMMAuthState->pNext;
  414. FreeSPDMemory(pTemp);
  415. }
  416. else {
  417. pTemp = pMMAuthState;
  418. pMMAuthState = pMMAuthState->pNext;
  419. pTemp->pNext = pLeftMMAuthState;
  420. pLeftMMAuthState = pTemp;
  421. }
  422. }
  423. else {
  424. pTemp = pMMAuthState;
  425. pMMAuthState = pMMAuthState->pNext;
  426. pTemp->pNext = pLeftMMAuthState;
  427. pLeftMMAuthState = pTemp;
  428. }
  429. }
  430. gpMMAuthState = pLeftMMAuthState;
  431. return (dwError);
  432. }
  433. DWORD
  434. EncodeName(
  435. LPWSTR pszSubjectName,
  436. PBYTE * ppEncodedName,
  437. PDWORD pdwEncodedLength
  438. )
  439. {
  440. DWORD dwError = ERROR_SUCCESS;
  441. *ppEncodedName = NULL;
  442. *pdwEncodedLength = 0;
  443. if (!CertStrToName(
  444. X509_ASN_ENCODING,
  445. pszSubjectName,
  446. CERT_X500_NAME_STR,
  447. NULL,
  448. NULL,
  449. pdwEncodedLength,
  450. NULL)) {
  451. dwError = GetLastError();
  452. BAIL_ON_WIN32_ERROR(dwError);
  453. }
  454. if (!*pdwEncodedLength) {
  455. dwError = ERROR_INVALID_DATA;
  456. BAIL_ON_WIN32_ERROR(dwError);
  457. }
  458. dwError = AllocateSPDMemory(
  459. *pdwEncodedLength,
  460. (PVOID) ppEncodedName
  461. );
  462. BAIL_ON_WIN32_ERROR(dwError);
  463. if (!CertStrToName(
  464. X509_ASN_ENCODING,
  465. pszSubjectName,
  466. CERT_X500_NAME_STR,
  467. NULL,
  468. (*ppEncodedName),
  469. pdwEncodedLength,
  470. NULL)) {
  471. dwError = GetLastError();
  472. BAIL_ON_WIN32_ERROR(dwError);
  473. }
  474. return (dwError);
  475. error:
  476. if (*ppEncodedName) {
  477. FreeSPDMemory(*ppEncodedName);
  478. *ppEncodedName = NULL;
  479. }
  480. *pdwEncodedLength = 0;
  481. return (dwError);
  482. }