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.

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