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.

1170 lines
24 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. mmauth.c
  5. Abstract:
  6. Author:
  7. abhishev 06-January-2000
  8. Environment: User Mode
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. DWORD
  13. WINAPI
  14. AddMMAuthMethods(
  15. LPWSTR pServerName,
  16. DWORD dwFlags,
  17. PMM_AUTH_METHODS pMMAuthMethods
  18. )
  19. /*++
  20. Routine Description:
  21. This function adds main mode auths to the SPD.
  22. Arguments:
  23. pServerName - Server on which the main mode auths are to be added.
  24. pMMAuthMethods - Main mode auths to be added.
  25. Return Value:
  26. ERROR_SUCCESS - Success.
  27. Win32 Error - Failure.
  28. --*/
  29. {
  30. DWORD dwError = 0;
  31. PINIMMAUTHMETHODS pIniMMAuthMethods = NULL;
  32. BOOL bPersist = FALSE;
  33. bPersist = (BOOL) (dwFlags & PERSIST_SPD_OBJECT);
  34. //
  35. // Validate the main mode auth methods.
  36. //
  37. dwError = ValidateMMAuthMethods(
  38. pMMAuthMethods
  39. );
  40. BAIL_ON_WIN32_ERROR(dwError);
  41. ENTER_SPD_SECTION();
  42. dwError = ValidateSecurity(
  43. SPD_OBJECT_SERVER,
  44. SERVER_ACCESS_ADMINISTER,
  45. NULL,
  46. NULL
  47. );
  48. BAIL_ON_LOCK_ERROR(dwError);
  49. pIniMMAuthMethods = FindMMAuthMethods(
  50. gpIniMMAuthMethods,
  51. pMMAuthMethods->gMMAuthID
  52. );
  53. if (pIniMMAuthMethods) {
  54. dwError = ERROR_IPSEC_MM_AUTH_EXISTS;
  55. BAIL_ON_LOCK_ERROR(dwError);
  56. }
  57. if (bPersist && !gbLoadingPersistence) {
  58. dwError = PersistMMAuthMethods(
  59. pMMAuthMethods
  60. );
  61. BAIL_ON_LOCK_ERROR(dwError);
  62. }
  63. dwError = CreateIniMMAuthMethods(
  64. pMMAuthMethods,
  65. &pIniMMAuthMethods
  66. );
  67. BAIL_ON_LOCK_ERROR(dwError);
  68. pIniMMAuthMethods->bIsPersisted = bPersist;
  69. pIniMMAuthMethods->pNext = gpIniMMAuthMethods;
  70. gpIniMMAuthMethods = pIniMMAuthMethods;
  71. if ((pIniMMAuthMethods->dwFlags) & IPSEC_MM_AUTH_DEFAULT_AUTH) {
  72. gpIniDefaultMMAuthMethods = pIniMMAuthMethods;
  73. }
  74. LEAVE_SPD_SECTION();
  75. return (dwError);
  76. lock:
  77. LEAVE_SPD_SECTION();
  78. error:
  79. if (pMMAuthMethods && bPersist && !gbLoadingPersistence) {
  80. (VOID) SPDPurgeMMAuthMethods(
  81. pMMAuthMethods->gMMAuthID
  82. );
  83. }
  84. return (dwError);
  85. }
  86. DWORD
  87. ValidateMMAuthMethods(
  88. PMM_AUTH_METHODS pMMAuthMethods
  89. )
  90. {
  91. DWORD dwError = 0;
  92. DWORD i = 0;
  93. PIPSEC_MM_AUTH_INFO pTemp = NULL;
  94. DWORD dwNumAuthInfos = 0;
  95. PIPSEC_MM_AUTH_INFO pAuthenticationInfo = NULL;
  96. BOOL bSSPI = FALSE;
  97. BOOL bPresharedKey = FALSE;
  98. if (!pMMAuthMethods) {
  99. dwError = ERROR_INVALID_PARAMETER;
  100. BAIL_ON_WIN32_ERROR(dwError);
  101. }
  102. dwNumAuthInfos = pMMAuthMethods->dwNumAuthInfos;
  103. pAuthenticationInfo = pMMAuthMethods->pAuthenticationInfo;
  104. if (!dwNumAuthInfos || !pAuthenticationInfo) {
  105. dwError = ERROR_INVALID_PARAMETER;
  106. BAIL_ON_WIN32_ERROR(dwError);
  107. }
  108. //
  109. // Need to catch the exception when the number of auth infos
  110. // specified is more than the actual number of auth infos.
  111. //
  112. pTemp = pAuthenticationInfo;
  113. for (i = 0; i < dwNumAuthInfos; i++) {
  114. if ((pTemp->AuthMethod != IKE_PRESHARED_KEY) &&
  115. (pTemp->AuthMethod != IKE_RSA_SIGNATURE) &&
  116. (pTemp->AuthMethod != IKE_SSPI)) {
  117. dwError = ERROR_INVALID_PARAMETER;
  118. BAIL_ON_WIN32_ERROR(dwError);
  119. }
  120. if (pTemp->AuthMethod != IKE_SSPI) {
  121. if (!(pTemp->dwAuthInfoSize) || !(pTemp->pAuthInfo)) {
  122. dwError = ERROR_INVALID_PARAMETER;
  123. BAIL_ON_WIN32_ERROR(dwError);
  124. }
  125. }
  126. if (pTemp->AuthMethod == IKE_SSPI) {
  127. if (bSSPI) {
  128. dwError = ERROR_INVALID_PARAMETER;
  129. BAIL_ON_WIN32_ERROR(dwError);
  130. }
  131. bSSPI = TRUE;
  132. }
  133. if (pTemp->AuthMethod == IKE_PRESHARED_KEY) {
  134. if (bPresharedKey) {
  135. dwError = ERROR_INVALID_PARAMETER;
  136. BAIL_ON_WIN32_ERROR(dwError);
  137. }
  138. bPresharedKey = TRUE;
  139. }
  140. pTemp++;
  141. }
  142. error:
  143. return (dwError);
  144. }
  145. PINIMMAUTHMETHODS
  146. FindMMAuthMethods(
  147. PINIMMAUTHMETHODS pIniMMAuthMethods,
  148. GUID gMMAuthID
  149. )
  150. {
  151. DWORD dwError = 0;
  152. PINIMMAUTHMETHODS pTemp = NULL;
  153. pTemp = pIniMMAuthMethods;
  154. while (pTemp) {
  155. if (!memcmp(&(pTemp->gMMAuthID), &gMMAuthID, sizeof(GUID))) {
  156. return (pTemp);
  157. }
  158. pTemp = pTemp->pNext;
  159. }
  160. return (NULL);
  161. }
  162. DWORD
  163. CreateIniMMAuthMethods(
  164. PMM_AUTH_METHODS pMMAuthMethods,
  165. PINIMMAUTHMETHODS * ppIniMMAuthMethods
  166. )
  167. {
  168. DWORD dwError = 0;
  169. PINIMMAUTHMETHODS pIniMMAuthMethods = NULL;
  170. dwError = AllocateSPDMemory(
  171. sizeof(INIMMAUTHMETHODS),
  172. &pIniMMAuthMethods
  173. );
  174. BAIL_ON_WIN32_ERROR(dwError);
  175. memcpy(
  176. &(pIniMMAuthMethods->gMMAuthID),
  177. &(pMMAuthMethods->gMMAuthID),
  178. sizeof(GUID)
  179. );
  180. pIniMMAuthMethods->dwFlags = pMMAuthMethods->dwFlags;
  181. pIniMMAuthMethods->cRef = 0;
  182. pIniMMAuthMethods->bIsPersisted = FALSE;
  183. pIniMMAuthMethods->pNext = NULL;
  184. dwError = CreateIniMMAuthInfos(
  185. pMMAuthMethods->dwNumAuthInfos,
  186. pMMAuthMethods->pAuthenticationInfo,
  187. &(pIniMMAuthMethods->dwNumAuthInfos),
  188. &(pIniMMAuthMethods->pAuthenticationInfo)
  189. );
  190. BAIL_ON_WIN32_ERROR(dwError);
  191. *ppIniMMAuthMethods = pIniMMAuthMethods;
  192. return (dwError);
  193. error:
  194. if (pIniMMAuthMethods) {
  195. FreeIniMMAuthMethods(
  196. pIniMMAuthMethods
  197. );
  198. }
  199. *ppIniMMAuthMethods = NULL;
  200. return (dwError);
  201. }
  202. DWORD
  203. CreateIniMMAuthInfos(
  204. DWORD dwInNumAuthInfos,
  205. PIPSEC_MM_AUTH_INFO pInAuthenticationInfo,
  206. PDWORD pdwNumAuthInfos,
  207. PIPSEC_MM_AUTH_INFO * ppAuthenticationInfo
  208. )
  209. {
  210. DWORD dwError = 0;
  211. PIPSEC_MM_AUTH_INFO pAuthenticationInfo = NULL;
  212. PIPSEC_MM_AUTH_INFO pTemp = NULL;
  213. PIPSEC_MM_AUTH_INFO pInTemp = NULL;
  214. DWORD i = 0;
  215. //
  216. // Number of auth infos and the auth infos themselves
  217. // have already been validated.
  218. //
  219. dwError = AllocateSPDMemory(
  220. sizeof(IPSEC_MM_AUTH_INFO) * dwInNumAuthInfos,
  221. &(pAuthenticationInfo)
  222. );
  223. BAIL_ON_WIN32_ERROR(dwError);
  224. pTemp = pAuthenticationInfo;
  225. pInTemp = pInAuthenticationInfo;
  226. for (i = 0; i < dwInNumAuthInfos; i++) {
  227. pTemp->AuthMethod = pInTemp->AuthMethod;
  228. if (pInTemp->AuthMethod == IKE_SSPI) {
  229. pTemp->dwAuthInfoSize = 0;
  230. pTemp->pAuthInfo = NULL;
  231. }
  232. else {
  233. if (!(pInTemp->dwAuthInfoSize) || !(pInTemp->pAuthInfo)) {
  234. dwError = ERROR_INVALID_PARAMETER;
  235. BAIL_ON_WIN32_ERROR(dwError);
  236. }
  237. dwError = AllocateSPDMemory(
  238. pInTemp->dwAuthInfoSize,
  239. &(pTemp->pAuthInfo)
  240. );
  241. BAIL_ON_WIN32_ERROR(dwError);
  242. pTemp->dwAuthInfoSize = pInTemp->dwAuthInfoSize;
  243. //
  244. // Need to catch the exception when the size of auth info
  245. // specified is more than the actual size. This can
  246. // not be checked earlier in the validation routine.
  247. //
  248. //
  249. memcpy(
  250. pTemp->pAuthInfo,
  251. pInTemp->pAuthInfo,
  252. pInTemp->dwAuthInfoSize
  253. );
  254. }
  255. pInTemp++;
  256. pTemp++;
  257. }
  258. *pdwNumAuthInfos = dwInNumAuthInfos;
  259. *ppAuthenticationInfo = pAuthenticationInfo;
  260. return (dwError);
  261. error:
  262. if (pAuthenticationInfo) {
  263. FreeIniMMAuthInfos(
  264. i,
  265. pAuthenticationInfo
  266. );
  267. }
  268. *pdwNumAuthInfos = 0;
  269. *ppAuthenticationInfo = NULL;
  270. return (dwError);
  271. }
  272. VOID
  273. FreeIniMMAuthMethods(
  274. PINIMMAUTHMETHODS pIniMMAuthMethods
  275. )
  276. {
  277. if (pIniMMAuthMethods) {
  278. FreeIniMMAuthInfos(
  279. pIniMMAuthMethods->dwNumAuthInfos,
  280. pIniMMAuthMethods->pAuthenticationInfo
  281. );
  282. FreeSPDMemory(pIniMMAuthMethods);
  283. }
  284. }
  285. VOID
  286. FreeIniMMAuthInfos(
  287. DWORD dwNumAuthInfos,
  288. PIPSEC_MM_AUTH_INFO pAuthenticationInfo
  289. )
  290. {
  291. DWORD i = 0;
  292. PIPSEC_MM_AUTH_INFO pTemp = NULL;
  293. if (pAuthenticationInfo) {
  294. pTemp = pAuthenticationInfo;
  295. for (i = 0; i < dwNumAuthInfos; i++) {
  296. if (pTemp->pAuthInfo) {
  297. FreeSPDMemory(pTemp->pAuthInfo);
  298. }
  299. pTemp++;
  300. }
  301. FreeSPDMemory(pAuthenticationInfo);
  302. }
  303. }
  304. DWORD
  305. WINAPI
  306. DeleteMMAuthMethods(
  307. LPWSTR pServerName,
  308. GUID gMMAuthID
  309. )
  310. /*++
  311. Routine Description:
  312. This function deletes main mode auth methods from the SPD.
  313. Arguments:
  314. pServerName - Server on which the main mode auth methods
  315. are to be deleted.
  316. gMMAuthID - Main mode methods to be deleted.
  317. Return Value:
  318. ERROR_SUCCESS - Success.
  319. Win32 Error - Failure.
  320. --*/
  321. {
  322. DWORD dwError = 0;
  323. PINIMMAUTHMETHODS pIniMMAuthMethods = NULL;
  324. ENTER_SPD_SECTION();
  325. dwError = ValidateSecurity(
  326. SPD_OBJECT_SERVER,
  327. SERVER_ACCESS_ADMINISTER,
  328. NULL,
  329. NULL
  330. );
  331. BAIL_ON_LOCK_ERROR(dwError);
  332. pIniMMAuthMethods = FindMMAuthMethods(
  333. gpIniMMAuthMethods,
  334. gMMAuthID
  335. );
  336. if (!pIniMMAuthMethods) {
  337. dwError = ERROR_IPSEC_MM_AUTH_NOT_FOUND;
  338. BAIL_ON_LOCK_ERROR(dwError);
  339. }
  340. if (pIniMMAuthMethods->cRef) {
  341. dwError = ERROR_IPSEC_MM_AUTH_IN_USE;
  342. BAIL_ON_LOCK_ERROR(dwError);
  343. }
  344. if (pIniMMAuthMethods->bIsPersisted) {
  345. dwError = SPDPurgeMMAuthMethods(
  346. gMMAuthID
  347. );
  348. BAIL_ON_LOCK_ERROR(dwError);
  349. }
  350. dwError = DeleteIniMMAuthMethods(
  351. pIniMMAuthMethods
  352. );
  353. BAIL_ON_LOCK_ERROR(dwError);
  354. LEAVE_SPD_SECTION();
  355. if (gbIKENotify) {
  356. (VOID) IKENotifyPolicyChange(
  357. &(gMMAuthID),
  358. POLICY_GUID_AUTH
  359. );
  360. }
  361. return (dwError);
  362. lock:
  363. LEAVE_SPD_SECTION();
  364. if ((dwError == ERROR_IPSEC_MM_AUTH_IN_USE) && gbIKENotify) {
  365. (VOID) IKENotifyPolicyChange(
  366. &(gMMAuthID),
  367. POLICY_GUID_AUTH
  368. );
  369. }
  370. return (dwError);
  371. }
  372. DWORD
  373. DeleteIniMMAuthMethods(
  374. PINIMMAUTHMETHODS pIniMMAuthMethods
  375. )
  376. {
  377. DWORD dwError = 0;
  378. PINIMMAUTHMETHODS * ppTemp = NULL;
  379. ppTemp = &gpIniMMAuthMethods;
  380. while (*ppTemp) {
  381. if (*ppTemp == pIniMMAuthMethods) {
  382. break;
  383. }
  384. ppTemp = &((*ppTemp)->pNext);
  385. }
  386. if (*ppTemp) {
  387. *ppTemp = pIniMMAuthMethods->pNext;
  388. }
  389. if ((pIniMMAuthMethods->dwFlags) & IPSEC_MM_AUTH_DEFAULT_AUTH) {
  390. gpIniDefaultMMAuthMethods = NULL;
  391. }
  392. FreeIniMMAuthMethods(pIniMMAuthMethods);
  393. return (dwError);
  394. }
  395. DWORD
  396. WINAPI
  397. EnumMMAuthMethods(
  398. LPWSTR pServerName,
  399. PMM_AUTH_METHODS * ppMMAuthMethods,
  400. DWORD dwPreferredNumEntries,
  401. LPDWORD pdwNumAuthMethods,
  402. LPDWORD pdwResumeHandle
  403. )
  404. /*++
  405. Routine Description:
  406. This function enumerates main mode auth methods from the SPD.
  407. Arguments:
  408. pServerName - Server on which the main mode auth methods are to
  409. be enumerated.
  410. ppMMAuthMethods - Enumerated main mode auth methods returned to
  411. the caller.
  412. dwPreferredNumEntries - Preferred number of enumeration entries.
  413. pdwNumAuthMethods - Number of main mode auth methods actually
  414. enumerated.
  415. pdwResumeHandle - Handle to the location in the main mode auth
  416. methods list from which to resume enumeration.
  417. Return Value:
  418. ERROR_SUCCESS - Success.
  419. Win32 Error - Failure.
  420. --*/
  421. {
  422. DWORD dwError = 0;
  423. DWORD dwResumeHandle = 0;
  424. DWORD dwNumToEnum = 0;
  425. PINIMMAUTHMETHODS pIniMMAuthMethods = NULL;
  426. DWORD i = 0;
  427. PINIMMAUTHMETHODS pTemp = NULL;
  428. DWORD dwNumAuthMethods = 0;
  429. PMM_AUTH_METHODS pMMAuthMethods = NULL;
  430. PMM_AUTH_METHODS pTempMMAuthMethods = NULL;
  431. dwResumeHandle = *pdwResumeHandle;
  432. if (!dwPreferredNumEntries || (dwPreferredNumEntries > MAX_MMAUTH_ENUM_COUNT)) {
  433. dwNumToEnum = MAX_MMAUTH_ENUM_COUNT;
  434. }
  435. else {
  436. dwNumToEnum = dwPreferredNumEntries;
  437. }
  438. ENTER_SPD_SECTION();
  439. dwError = ValidateSecurity(
  440. SPD_OBJECT_SERVER,
  441. SERVER_ACCESS_ADMINISTER,
  442. NULL,
  443. NULL
  444. );
  445. BAIL_ON_LOCK_ERROR(dwError);
  446. pIniMMAuthMethods = gpIniMMAuthMethods;
  447. for (i = 0; (i < dwResumeHandle) && (pIniMMAuthMethods != NULL); i++) {
  448. pIniMMAuthMethods = pIniMMAuthMethods->pNext;
  449. }
  450. if (!pIniMMAuthMethods) {
  451. dwError = ERROR_NO_DATA;
  452. BAIL_ON_LOCK_ERROR(dwError);
  453. }
  454. pTemp = pIniMMAuthMethods;
  455. while (pTemp && (dwNumAuthMethods < dwNumToEnum)) {
  456. dwNumAuthMethods++;
  457. pTemp = pTemp->pNext;
  458. }
  459. dwError = SPDApiBufferAllocate(
  460. sizeof(MM_AUTH_METHODS)*dwNumAuthMethods,
  461. &pMMAuthMethods
  462. );
  463. BAIL_ON_LOCK_ERROR(dwError);
  464. pTemp = pIniMMAuthMethods;
  465. pTempMMAuthMethods = pMMAuthMethods;
  466. for (i = 0; i < dwNumAuthMethods; i++) {
  467. dwError = CopyMMAuthMethods(
  468. pTemp,
  469. pTempMMAuthMethods
  470. );
  471. BAIL_ON_LOCK_ERROR(dwError);
  472. pTemp = pTemp->pNext;
  473. pTempMMAuthMethods++;
  474. }
  475. *ppMMAuthMethods = pMMAuthMethods;
  476. *pdwResumeHandle = dwResumeHandle + dwNumAuthMethods;
  477. *pdwNumAuthMethods = dwNumAuthMethods;
  478. LEAVE_SPD_SECTION();
  479. return (dwError);
  480. lock:
  481. LEAVE_SPD_SECTION();
  482. if (pMMAuthMethods) {
  483. FreeMMAuthMethods(
  484. i,
  485. pMMAuthMethods
  486. );
  487. }
  488. *ppMMAuthMethods = NULL;
  489. *pdwResumeHandle = dwResumeHandle;
  490. *pdwNumAuthMethods = 0;
  491. return (dwError);
  492. }
  493. DWORD
  494. WINAPI
  495. SetMMAuthMethods(
  496. LPWSTR pServerName,
  497. GUID gMMAuthID,
  498. PMM_AUTH_METHODS pMMAuthMethods
  499. )
  500. /*++
  501. Routine Description:
  502. This function updates main mode auth methods in the SPD.
  503. Arguments:
  504. pServerName - Server on which the main mode auth methods are to
  505. be updated.
  506. gMMAuthID - Guid of the main mode auth methods to be updated.
  507. pMMAuthMethods - New main mode auth methods which will replace
  508. the existing methods.
  509. Return Value:
  510. ERROR_SUCCESS - Success.
  511. Win32 Error - Failure.
  512. --*/
  513. {
  514. DWORD dwError = 0;
  515. PINIMMAUTHMETHODS pIniMMAuthMethods = NULL;
  516. //
  517. // Validate main mode auth methods.
  518. //
  519. dwError = ValidateMMAuthMethods(
  520. pMMAuthMethods
  521. );
  522. BAIL_ON_WIN32_ERROR(dwError);
  523. ENTER_SPD_SECTION();
  524. dwError = ValidateSecurity(
  525. SPD_OBJECT_SERVER,
  526. SERVER_ACCESS_ADMINISTER,
  527. NULL,
  528. NULL
  529. );
  530. BAIL_ON_LOCK_ERROR(dwError);
  531. pIniMMAuthMethods = FindMMAuthMethods(
  532. gpIniMMAuthMethods,
  533. gMMAuthID
  534. );
  535. if (!pIniMMAuthMethods) {
  536. dwError = ERROR_IPSEC_MM_AUTH_NOT_FOUND;
  537. BAIL_ON_LOCK_ERROR(dwError);
  538. }
  539. dwError = SetIniMMAuthMethods(
  540. pIniMMAuthMethods,
  541. pMMAuthMethods
  542. );
  543. BAIL_ON_LOCK_ERROR(dwError);
  544. if (pIniMMAuthMethods->bIsPersisted) {
  545. dwError = PersistMMAuthMethods(
  546. pMMAuthMethods
  547. );
  548. BAIL_ON_LOCK_ERROR(dwError);
  549. }
  550. LEAVE_SPD_SECTION();
  551. (VOID) IKENotifyPolicyChange(
  552. &(pMMAuthMethods->gMMAuthID),
  553. POLICY_GUID_AUTH
  554. );
  555. return (dwError);
  556. lock:
  557. LEAVE_SPD_SECTION();
  558. error:
  559. return (dwError);
  560. }
  561. DWORD
  562. SetIniMMAuthMethods(
  563. PINIMMAUTHMETHODS pIniMMAuthMethods,
  564. PMM_AUTH_METHODS pMMAuthMethods
  565. )
  566. {
  567. DWORD dwError = 0;
  568. DWORD dwNumAuthInfos = 0;
  569. PIPSEC_MM_AUTH_INFO pAuthenticationInfo = NULL;
  570. dwError = CreateIniMMAuthInfos(
  571. pMMAuthMethods->dwNumAuthInfos,
  572. pMMAuthMethods->pAuthenticationInfo,
  573. &dwNumAuthInfos,
  574. &pAuthenticationInfo
  575. );
  576. BAIL_ON_WIN32_ERROR(dwError);
  577. FreeIniMMAuthInfos(
  578. pIniMMAuthMethods->dwNumAuthInfos,
  579. pIniMMAuthMethods->pAuthenticationInfo
  580. );
  581. if ((pIniMMAuthMethods->dwFlags) & IPSEC_MM_AUTH_DEFAULT_AUTH) {
  582. gpIniDefaultMMAuthMethods = NULL;
  583. }
  584. pIniMMAuthMethods->dwFlags = pMMAuthMethods->dwFlags;
  585. pIniMMAuthMethods->dwNumAuthInfos = dwNumAuthInfos;
  586. pIniMMAuthMethods->pAuthenticationInfo = pAuthenticationInfo;
  587. if ((pIniMMAuthMethods->dwFlags) & IPSEC_MM_AUTH_DEFAULT_AUTH) {
  588. gpIniDefaultMMAuthMethods = pIniMMAuthMethods;
  589. }
  590. error:
  591. return (dwError);
  592. }
  593. DWORD
  594. WINAPI
  595. GetMMAuthMethods(
  596. LPWSTR pServerName,
  597. GUID gMMAuthID,
  598. PMM_AUTH_METHODS * ppMMAuthMethods
  599. )
  600. /*++
  601. Routine Description:
  602. This function gets main mode auth methods from the SPD.
  603. Arguments:
  604. pServerName - Server from which to get the main mode auth methods.
  605. gMMAuthID - Guid of the main mode auth methods to get.
  606. ppMMAuthMethods - Main mode auth methods found returned to the
  607. caller.
  608. Return Value:
  609. ERROR_SUCCESS - Success.
  610. Win32 Error - Failure.
  611. --*/
  612. {
  613. DWORD dwError = 0;
  614. PINIMMAUTHMETHODS pIniMMAuthMethods = NULL;
  615. PMM_AUTH_METHODS pMMAuthMethods = NULL;
  616. ENTER_SPD_SECTION();
  617. dwError = ValidateSecurity(
  618. SPD_OBJECT_SERVER,
  619. SERVER_ACCESS_ADMINISTER,
  620. NULL,
  621. NULL
  622. );
  623. BAIL_ON_LOCK_ERROR(dwError);
  624. pIniMMAuthMethods = FindMMAuthMethods(
  625. gpIniMMAuthMethods,
  626. gMMAuthID
  627. );
  628. if (!pIniMMAuthMethods) {
  629. dwError = ERROR_IPSEC_MM_AUTH_NOT_FOUND;
  630. BAIL_ON_LOCK_ERROR(dwError);
  631. }
  632. dwError = GetIniMMAuthMethods(
  633. pIniMMAuthMethods,
  634. &pMMAuthMethods
  635. );
  636. BAIL_ON_LOCK_ERROR(dwError);
  637. *ppMMAuthMethods = pMMAuthMethods;
  638. LEAVE_SPD_SECTION();
  639. return (dwError);
  640. lock:
  641. LEAVE_SPD_SECTION();
  642. *ppMMAuthMethods = NULL;
  643. return (dwError);
  644. }
  645. DWORD
  646. GetIniMMAuthMethods(
  647. PINIMMAUTHMETHODS pIniMMAuthMethods,
  648. PMM_AUTH_METHODS * ppMMAuthMethods
  649. )
  650. {
  651. DWORD dwError = 0;
  652. PMM_AUTH_METHODS pMMAuthMethods = NULL;
  653. dwError = SPDApiBufferAllocate(
  654. sizeof(MM_AUTH_METHODS),
  655. &pMMAuthMethods
  656. );
  657. BAIL_ON_WIN32_ERROR(dwError);
  658. dwError = CopyMMAuthMethods(
  659. pIniMMAuthMethods,
  660. pMMAuthMethods
  661. );
  662. BAIL_ON_WIN32_ERROR(dwError);
  663. *ppMMAuthMethods = pMMAuthMethods;
  664. return (dwError);
  665. error:
  666. if (pMMAuthMethods) {
  667. SPDApiBufferFree(pMMAuthMethods);
  668. }
  669. *ppMMAuthMethods = NULL;
  670. return (dwError);
  671. }
  672. DWORD
  673. CopyMMAuthMethods(
  674. PINIMMAUTHMETHODS pIniMMAuthMethods,
  675. PMM_AUTH_METHODS pMMAuthMethods
  676. )
  677. {
  678. DWORD dwError = 0;
  679. memcpy(
  680. &(pMMAuthMethods->gMMAuthID),
  681. &(pIniMMAuthMethods->gMMAuthID),
  682. sizeof(GUID)
  683. );
  684. pMMAuthMethods->dwFlags = pIniMMAuthMethods->dwFlags;
  685. dwError = CreateMMAuthInfos(
  686. pIniMMAuthMethods->dwNumAuthInfos,
  687. pIniMMAuthMethods->pAuthenticationInfo,
  688. &(pMMAuthMethods->dwNumAuthInfos),
  689. &(pMMAuthMethods->pAuthenticationInfo)
  690. );
  691. BAIL_ON_WIN32_ERROR(dwError);
  692. error:
  693. return (dwError);
  694. }
  695. DWORD
  696. CreateMMAuthInfos(
  697. DWORD dwInNumAuthInfos,
  698. PIPSEC_MM_AUTH_INFO pInAuthenticationInfo,
  699. PDWORD pdwNumAuthInfos,
  700. PIPSEC_MM_AUTH_INFO * ppAuthenticationInfo
  701. )
  702. {
  703. DWORD dwError = 0;
  704. PIPSEC_MM_AUTH_INFO pAuthenticationInfo = NULL;
  705. PIPSEC_MM_AUTH_INFO pTemp = NULL;
  706. PIPSEC_MM_AUTH_INFO pInTemp = NULL;
  707. DWORD i = 0;
  708. //
  709. // Number of auth infos and the auth infos themselves
  710. // have already been validated.
  711. //
  712. dwError = SPDApiBufferAllocate(
  713. sizeof(IPSEC_MM_AUTH_INFO) * dwInNumAuthInfos,
  714. &(pAuthenticationInfo)
  715. );
  716. BAIL_ON_WIN32_ERROR(dwError);
  717. pTemp = pAuthenticationInfo;
  718. pInTemp = pInAuthenticationInfo;
  719. for (i = 0; i < dwInNumAuthInfos; i++) {
  720. pTemp->AuthMethod = pInTemp->AuthMethod;
  721. //
  722. // Auth info size and the auth info have already
  723. // been validated.
  724. //
  725. if (pInTemp->AuthMethod == IKE_SSPI) {
  726. pTemp->dwAuthInfoSize = 0;
  727. pTemp->pAuthInfo = NULL;
  728. }
  729. else {
  730. dwError = SPDApiBufferAllocate(
  731. pInTemp->dwAuthInfoSize,
  732. &(pTemp->pAuthInfo)
  733. );
  734. BAIL_ON_WIN32_ERROR(dwError);
  735. pTemp->dwAuthInfoSize = pInTemp->dwAuthInfoSize;
  736. //
  737. // Need to catch the exception when the size of auth info
  738. // specified is more than the actual size. This can
  739. // not be checked earlier in the validation routine.
  740. //
  741. //
  742. memcpy(
  743. pTemp->pAuthInfo,
  744. pInTemp->pAuthInfo,
  745. pInTemp->dwAuthInfoSize
  746. );
  747. }
  748. pInTemp++;
  749. pTemp++;
  750. }
  751. *pdwNumAuthInfos = dwInNumAuthInfos;
  752. *ppAuthenticationInfo = pAuthenticationInfo;
  753. return (dwError);
  754. error:
  755. if (pAuthenticationInfo) {
  756. FreeMMAuthInfos(
  757. i,
  758. pAuthenticationInfo
  759. );
  760. }
  761. *pdwNumAuthInfos = 0;
  762. *ppAuthenticationInfo = NULL;
  763. return (dwError);
  764. }
  765. VOID
  766. FreeMMAuthInfos(
  767. DWORD dwNumAuthInfos,
  768. PIPSEC_MM_AUTH_INFO pAuthenticationInfo
  769. )
  770. {
  771. DWORD i = 0;
  772. PIPSEC_MM_AUTH_INFO pTemp = NULL;
  773. if (pAuthenticationInfo) {
  774. pTemp = pAuthenticationInfo;
  775. for (i = 0; i < dwNumAuthInfos; i++) {
  776. if (pTemp->pAuthInfo) {
  777. SPDApiBufferFree(pTemp->pAuthInfo);
  778. }
  779. pTemp++;
  780. }
  781. SPDApiBufferFree(pAuthenticationInfo);
  782. }
  783. }
  784. VOID
  785. FreeIniMMAuthMethodsList(
  786. PINIMMAUTHMETHODS pIniMMAuthMethodsList
  787. )
  788. {
  789. PINIMMAUTHMETHODS pTemp = NULL;
  790. PINIMMAUTHMETHODS pIniMMAuthMethods = NULL;
  791. pTemp = pIniMMAuthMethodsList;
  792. while (pTemp) {
  793. pIniMMAuthMethods = pTemp;
  794. pTemp = pTemp->pNext;
  795. FreeIniMMAuthMethods(pIniMMAuthMethods);
  796. }
  797. }
  798. VOID
  799. FreeMMAuthMethods(
  800. DWORD dwNumAuthMethods,
  801. PMM_AUTH_METHODS pMMAuthMethods
  802. )
  803. {
  804. DWORD i = 0;
  805. if (pMMAuthMethods) {
  806. for (i = 0; i < dwNumAuthMethods; i++) {
  807. FreeMMAuthInfos(
  808. pMMAuthMethods[i].dwNumAuthInfos,
  809. pMMAuthMethods[i].pAuthenticationInfo
  810. );
  811. }
  812. SPDApiBufferFree(pMMAuthMethods);
  813. }
  814. }
  815. DWORD
  816. LocateMMAuthMethods(
  817. PMM_FILTER pMMFilter,
  818. PINIMMAUTHMETHODS * ppIniMMAuthMethods
  819. )
  820. {
  821. DWORD dwError = 0;
  822. PINIMMAUTHMETHODS pIniMMAuthMethods = NULL;
  823. if ((pMMFilter->dwFlags) & IPSEC_MM_AUTH_DEFAULT_AUTH) {
  824. if (!gpIniDefaultMMAuthMethods) {
  825. dwError = ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND;
  826. BAIL_ON_WIN32_ERROR(dwError);
  827. }
  828. pIniMMAuthMethods = gpIniDefaultMMAuthMethods;
  829. }
  830. else {
  831. pIniMMAuthMethods = FindMMAuthMethods(
  832. gpIniMMAuthMethods,
  833. pMMFilter->gMMAuthID
  834. );
  835. if (!pIniMMAuthMethods) {
  836. dwError = ERROR_IPSEC_MM_AUTH_NOT_FOUND;
  837. BAIL_ON_WIN32_ERROR(dwError);
  838. }
  839. }
  840. *ppIniMMAuthMethods = pIniMMAuthMethods;
  841. return (dwError);
  842. error:
  843. *ppIniMMAuthMethods = NULL;
  844. return (dwError);
  845. }