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.

697 lines
16 KiB

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