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.

1994 lines
42 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. driver.c
  5. Abstract:
  6. This module contains all of the code to drive the
  7. management of specific filters in the IPSec driver.
  8. Author:
  9. abhisheV 05-November-1999
  10. Environment
  11. User Level: Win32
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. DWORD
  16. SPDStartIPSecDriver(
  17. )
  18. /*++
  19. Routine Description:
  20. Starts the IPSec Driver service.
  21. Arguments:
  22. None.
  23. Return Value:
  24. ERROR_SUCCESS - Success.
  25. Win32 Error - Failure.
  26. --*/
  27. {
  28. SC_HANDLE ServiceDatabase = NULL;
  29. SC_HANDLE ServiceHandle = NULL;
  30. BOOL bStatus = FALSE;
  31. DWORD dwError = 0;
  32. SERVICE_STATUS IpsecStatus;
  33. memset(&IpsecStatus, 0, sizeof(SERVICE_STATUS));
  34. ServiceDatabase = OpenSCManager(
  35. NULL,
  36. NULL,
  37. SC_MANAGER_ALL_ACCESS
  38. );
  39. if (ServiceDatabase == NULL) {
  40. dwError = GetLastError();
  41. BAIL_ON_WIN32_ERROR(dwError);
  42. }
  43. ServiceHandle = OpenService(
  44. ServiceDatabase,
  45. IPSEC_SERVICE_NAME,
  46. SERVICE_START | SERVICE_QUERY_STATUS
  47. );
  48. if (ServiceHandle == NULL) {
  49. dwError = GetLastError();
  50. BAIL_ON_WIN32_ERROR(dwError);
  51. }
  52. bStatus = QueryServiceStatus(
  53. ServiceHandle,
  54. &IpsecStatus
  55. );
  56. if (bStatus == FALSE) {
  57. dwError = GetLastError();
  58. BAIL_ON_WIN32_ERROR(dwError);
  59. }
  60. if (IpsecStatus.dwCurrentState == SERVICE_STOPPED) {
  61. bStatus = StartService(
  62. ServiceHandle,
  63. 0,
  64. NULL
  65. );
  66. if (bStatus == FALSE) {
  67. dwError = GetLastError();
  68. BAIL_ON_WIN32_ERROR(dwError);
  69. }
  70. }
  71. error:
  72. if (ServiceDatabase != NULL) {
  73. CloseServiceHandle(ServiceDatabase);
  74. }
  75. if (ServiceHandle != NULL) {
  76. CloseServiceHandle(ServiceHandle);
  77. }
  78. return (dwError);
  79. }
  80. DWORD
  81. SPDStopIPSecDriver(
  82. )
  83. /*++
  84. Routine Description:
  85. Stops the IPSec Driver service.
  86. Arguments:
  87. None.
  88. Return Value:
  89. ERROR_SUCCESS - Success.
  90. Win32 Error - Failure.
  91. --*/
  92. {
  93. SC_HANDLE ServiceDatabase = NULL;
  94. SC_HANDLE ServiceHandle = NULL;
  95. BOOL bStatus = FALSE;
  96. DWORD dwError = 0;
  97. SERVICE_STATUS IpsecStatus;
  98. memset(&IpsecStatus, 0, sizeof(SERVICE_STATUS));
  99. ServiceDatabase = OpenSCManager(
  100. NULL,
  101. NULL,
  102. SC_MANAGER_ALL_ACCESS
  103. );
  104. if (ServiceDatabase == NULL) {
  105. dwError = GetLastError();
  106. BAIL_ON_WIN32_ERROR(dwError);
  107. }
  108. ServiceHandle = OpenService(
  109. ServiceDatabase,
  110. IPSEC_SERVICE_NAME,
  111. SERVICE_STOP | SERVICE_QUERY_STATUS
  112. );
  113. if (ServiceHandle == NULL) {
  114. dwError = GetLastError();
  115. BAIL_ON_WIN32_ERROR(dwError);
  116. }
  117. bStatus = QueryServiceStatus(
  118. ServiceHandle,
  119. &IpsecStatus
  120. );
  121. if (bStatus == FALSE) {
  122. dwError = GetLastError();
  123. BAIL_ON_WIN32_ERROR(dwError);
  124. }
  125. if (IpsecStatus.dwCurrentState == SERVICE_RUNNING) {
  126. bStatus = ControlService(
  127. ServiceHandle,
  128. SERVICE_CONTROL_STOP,
  129. &IpsecStatus
  130. );
  131. if (bStatus == FALSE) {
  132. dwError = GetLastError();
  133. BAIL_ON_WIN32_ERROR(dwError);
  134. }
  135. }
  136. error:
  137. if (ServiceDatabase != NULL) {
  138. CloseServiceHandle(ServiceDatabase);
  139. }
  140. if (ServiceHandle != NULL) {
  141. CloseServiceHandle(ServiceHandle);
  142. }
  143. return (dwError);
  144. }
  145. DWORD
  146. SPDOpenIPSecDriver(
  147. PHANDLE phIPSecDriver
  148. )
  149. /*++
  150. Routine Description:
  151. Opens a handle to the IPSec Driver.
  152. Arguments:
  153. phIPSecDriver - pointer to a handle to the IPSec Driver.
  154. Return Value:
  155. ERROR_SUCCESS - Success.
  156. Win32 Error - Failure.
  157. --*/
  158. {
  159. DWORD dwError = 0;
  160. HANDLE hIPSecDriver = NULL;
  161. hIPSecDriver = CreateFile(
  162. DEVICE_NAME, // File name.
  163. GENERIC_READ | GENERIC_WRITE, // Access mode.
  164. 0, // Share mode.
  165. NULL, // Security attributes.
  166. OPEN_EXISTING, // How to create.
  167. 0, // File attributes.
  168. NULL // Handle to file.
  169. );
  170. if (hIPSecDriver == INVALID_HANDLE_VALUE) {
  171. dwError = GetLastError();
  172. BAIL_ON_WIN32_ERROR(dwError);
  173. }
  174. *phIPSecDriver = hIPSecDriver;
  175. return (dwError);
  176. error:
  177. *phIPSecDriver = INVALID_HANDLE_VALUE;
  178. return (dwError);
  179. }
  180. VOID
  181. SPDCloseIPSecDriver(
  182. HANDLE hIPSecDriver
  183. )
  184. /*++
  185. Routine Description:
  186. Closes the handle to the IPSec Driver.
  187. Arguments:
  188. hIPSecDriver - handle to the IPSec Driver to close.
  189. Return Value:
  190. None.
  191. --*/
  192. {
  193. if (hIPSecDriver) {
  194. CloseHandle(hIPSecDriver);
  195. }
  196. }
  197. DWORD
  198. InsertTransportFiltersIntoIPSec(
  199. PINITXSFILTER pSpecificFilters
  200. )
  201. /*++
  202. Routine Description:
  203. Insert a list of specific filters into the
  204. IPSec Driver.
  205. Arguments:
  206. pSpecificFilters - list of filters to insert.
  207. Return Value:
  208. ERROR_SUCCESS - Success.
  209. Win32 Error - Failure.
  210. --*/
  211. {
  212. DWORD dwError = 0;
  213. HANDLE hIPSecDriver = NULL;
  214. LPBYTE pInBuffer = NULL;
  215. DWORD dwInBufferSize = 0;
  216. BOOL bStatus = FALSE;
  217. LPBYTE pOutBuffer = NULL;
  218. DWORD dwOutBufferSize = 0;
  219. DWORD dwBytesReturned = 0;
  220. DWORD dwNumFilters = 0;
  221. PIPSEC_FILTER_INFO pInternalFilters = NULL;
  222. LPBYTE pTemp = NULL;
  223. DWORD i = 0;
  224. if (!pSpecificFilters) {
  225. return (dwError);
  226. }
  227. dwError = SPDOpenIPSecDriver(
  228. &hIPSecDriver
  229. );
  230. BAIL_ON_WIN32_ERROR(dwError);
  231. dwError = WrapTransportFilters(
  232. pSpecificFilters,
  233. &pInternalFilters,
  234. &dwNumFilters
  235. );
  236. BAIL_ON_WIN32_ERROR(dwError);
  237. dwInBufferSize = sizeof(DWORD) +
  238. sizeof(IPSEC_FILTER_INFO)*dwNumFilters;
  239. dwError = AllocateSPDMemory(
  240. dwInBufferSize,
  241. &pInBuffer
  242. );
  243. BAIL_ON_WIN32_ERROR(dwError);
  244. pTemp = pInBuffer;
  245. memcpy(pTemp, &dwNumFilters, sizeof(DWORD));
  246. pTemp += sizeof(DWORD);
  247. for (i = 0 ; i < dwNumFilters; i++) {
  248. memcpy(pTemp, &(pInternalFilters[i]), sizeof(IPSEC_FILTER_INFO));
  249. pTemp += sizeof(IPSEC_FILTER_INFO);
  250. }
  251. bStatus = DeviceIoControl(
  252. hIPSecDriver,
  253. IOCTL_IPSEC_ADD_FILTER,
  254. pInBuffer,
  255. dwInBufferSize,
  256. pOutBuffer,
  257. dwOutBufferSize,
  258. &dwBytesReturned,
  259. NULL
  260. );
  261. if (bStatus == FALSE) {
  262. dwError = GetLastError();
  263. BAIL_ON_WIN32_ERROR(dwError);
  264. }
  265. error:
  266. if (hIPSecDriver != INVALID_HANDLE_VALUE) {
  267. SPDCloseIPSecDriver(hIPSecDriver);
  268. }
  269. if (pInternalFilters) {
  270. FreeSPDMemory(pInternalFilters);
  271. }
  272. if (pInBuffer) {
  273. FreeSPDMemory(pInBuffer);
  274. }
  275. if (pOutBuffer) {
  276. LocalFree(pOutBuffer);
  277. }
  278. return (dwError);
  279. }
  280. DWORD
  281. DeleteTransportFiltersFromIPSec(
  282. PINITXSFILTER pSpecificFilters
  283. )
  284. /*++
  285. Routine Description:
  286. Delete a list of filters from the IPSec Driver.
  287. Arguments:
  288. pSpecificFilters - list of filters to delete.
  289. Return Value:
  290. ERROR_SUCCESS - Success.
  291. Win32 Error - Failure.
  292. --*/
  293. {
  294. DWORD dwError = 0;
  295. HANDLE hIPSecDriver = NULL;
  296. LPBYTE pInBuffer = NULL;
  297. DWORD dwInBufferSize = 0;
  298. BOOL bStatus = FALSE;
  299. LPBYTE pOutBuffer = NULL;
  300. DWORD dwOutBufferSize = 0;
  301. DWORD dwBytesReturned = 0;
  302. DWORD dwNumFilters = 0;
  303. PIPSEC_FILTER_INFO pInternalFilters = NULL;
  304. LPBYTE pTemp = NULL;
  305. DWORD i = 0;
  306. if (!pSpecificFilters) {
  307. return (dwError);
  308. }
  309. dwError = SPDOpenIPSecDriver(
  310. &hIPSecDriver
  311. );
  312. BAIL_ON_WIN32_ERROR(dwError);
  313. dwError = WrapTransportFilters(
  314. pSpecificFilters,
  315. &pInternalFilters,
  316. &dwNumFilters
  317. );
  318. BAIL_ON_WIN32_ERROR(dwError);
  319. dwInBufferSize = sizeof(DWORD) +
  320. sizeof(IPSEC_FILTER_INFO)*dwNumFilters;
  321. dwError = AllocateSPDMemory(
  322. dwInBufferSize,
  323. &pInBuffer
  324. );
  325. BAIL_ON_WIN32_ERROR(dwError);
  326. pTemp = pInBuffer;
  327. memcpy(pTemp, &dwNumFilters, sizeof(DWORD));
  328. pTemp += sizeof(DWORD);
  329. for (i = 0 ; i < dwNumFilters; i++) {
  330. memcpy(pTemp, &(pInternalFilters[i]), sizeof(IPSEC_FILTER_INFO));
  331. pTemp += sizeof(IPSEC_FILTER_INFO);
  332. }
  333. bStatus = DeviceIoControl(
  334. hIPSecDriver,
  335. IOCTL_IPSEC_DELETE_FILTER,
  336. pInBuffer,
  337. dwInBufferSize,
  338. pOutBuffer,
  339. dwOutBufferSize,
  340. &dwBytesReturned,
  341. NULL
  342. );
  343. if (bStatus == FALSE) {
  344. dwError = GetLastError();
  345. BAIL_ON_WIN32_ERROR(dwError);
  346. }
  347. error:
  348. if (hIPSecDriver != INVALID_HANDLE_VALUE) {
  349. SPDCloseIPSecDriver(hIPSecDriver);
  350. }
  351. if (pInternalFilters) {
  352. FreeSPDMemory(pInternalFilters);
  353. }
  354. if (pInBuffer) {
  355. FreeSPDMemory(pInBuffer);
  356. }
  357. if (pOutBuffer) {
  358. LocalFree(pOutBuffer);
  359. }
  360. return (dwError);
  361. }
  362. DWORD
  363. WrapTransportFilters(
  364. PINITXSFILTER pSpecificFilters,
  365. PIPSEC_FILTER_INFO * ppInternalFilters,
  366. PDWORD pdwNumFilters
  367. )
  368. /*++
  369. Routine Description:
  370. Transforms a list of specific transport filters to
  371. an equivalent list of filters acceptable to the
  372. IPSec Driver.
  373. Arguments:
  374. pSpecificFilters - list of filters to convert.
  375. ppInternalFilters - list of transformed filters.
  376. pdwNumFilters - count of the filters in the transformed
  377. list.
  378. Return Value:
  379. ERROR_SUCCESS - Success.
  380. Win32 Error - Failure.
  381. --*/
  382. {
  383. DWORD dwError = 0;
  384. PINITXSFILTER pTempFilter = NULL;
  385. PIPSEC_FILTER_INFO pInternalFilters = NULL;
  386. DWORD dwNumFilters = 0;
  387. DWORD i = 0;
  388. //
  389. // At this point, there's atleast one filter in the
  390. // specific filter list.
  391. //
  392. pTempFilter = pSpecificFilters;
  393. while(pTempFilter) {
  394. pTempFilter = pTempFilter->pNext;
  395. dwNumFilters++;
  396. }
  397. dwError = AllocateSPDMemory(
  398. sizeof(IPSEC_FILTER_INFO)*dwNumFilters,
  399. &pInternalFilters
  400. );
  401. BAIL_ON_WIN32_ERROR(dwError);
  402. pTempFilter = pSpecificFilters;
  403. while(pTempFilter) {
  404. FormIPSecTransportFilter(
  405. pTempFilter,
  406. &(pInternalFilters[i])
  407. );
  408. pTempFilter = pTempFilter->pNext;
  409. i++;
  410. }
  411. *ppInternalFilters = pInternalFilters;
  412. *pdwNumFilters = dwNumFilters;
  413. return (dwError);
  414. error:
  415. *ppInternalFilters = NULL;
  416. *pdwNumFilters = 0;
  417. return (dwError);
  418. }
  419. VOID
  420. FormIPSecTransportFilter(
  421. PINITXSFILTER pSpecificFilter,
  422. PIPSEC_FILTER_INFO pIpsecFilter
  423. )
  424. /*++
  425. Routine Description:
  426. Transforms a specific transport filter to an
  427. equivalent filter acceptable to the IPSec Driver.
  428. Arguments:
  429. pSpecificFilter - filter to convert.
  430. pIpsecFilter - transformed filter.
  431. Return Value:
  432. NONE.
  433. --*/
  434. {
  435. memcpy(
  436. &(pIpsecFilter->FilterId),
  437. &(pSpecificFilter->gParentID),
  438. sizeof(GUID)
  439. );
  440. memcpy(
  441. &(pIpsecFilter->PolicyId),
  442. &(pSpecificFilter->gPolicyID),
  443. sizeof(GUID)
  444. );
  445. pIpsecFilter->Index = pSpecificFilter->dwWeight;
  446. pIpsecFilter->AssociatedFilter.SrcAddr = pSpecificFilter->SrcAddr.uIpAddr;
  447. pIpsecFilter->AssociatedFilter.SrcMask = pSpecificFilter->SrcAddr.uSubNetMask;
  448. pIpsecFilter->AssociatedFilter.DestAddr = pSpecificFilter->DesAddr.uIpAddr;
  449. pIpsecFilter->AssociatedFilter.DestMask = pSpecificFilter->DesAddr.uSubNetMask;
  450. pIpsecFilter->AssociatedFilter.Protocol = pSpecificFilter->Protocol.dwProtocol;
  451. pIpsecFilter->AssociatedFilter.SrcPort = pSpecificFilter->SrcPort.wPort;
  452. pIpsecFilter->AssociatedFilter.DestPort = pSpecificFilter->DesPort.wPort;
  453. pIpsecFilter->AssociatedFilter.TunnelFilter = FALSE;
  454. pIpsecFilter->AssociatedFilter.TunnelAddr = 0;
  455. pIpsecFilter->AssociatedFilter.Flags = 0;
  456. if (pSpecificFilter->dwDirection == FILTER_DIRECTION_INBOUND) {
  457. pIpsecFilter->AssociatedFilter.Flags |= FILTER_FLAGS_INBOUND;
  458. switch (pSpecificFilter->InboundFilterFlag) {
  459. case PASS_THRU:
  460. pIpsecFilter->AssociatedFilter.Flags |= FILTER_FLAGS_PASS_THRU;
  461. break;
  462. case BLOCKING:
  463. pIpsecFilter->AssociatedFilter.Flags |= FILTER_FLAGS_DROP;
  464. break;
  465. default:
  466. break;
  467. }
  468. }
  469. else {
  470. pIpsecFilter->AssociatedFilter.Flags |= FILTER_FLAGS_OUTBOUND;
  471. switch (pSpecificFilter->OutboundFilterFlag) {
  472. case PASS_THRU:
  473. pIpsecFilter->AssociatedFilter.Flags |= FILTER_FLAGS_PASS_THRU;
  474. break;
  475. case BLOCKING:
  476. pIpsecFilter->AssociatedFilter.Flags |= FILTER_FLAGS_DROP;
  477. break;
  478. default:
  479. break;
  480. }
  481. }
  482. }
  483. DWORD
  484. QueryIPSecStatistics(
  485. LPWSTR pServerName,
  486. PIPSEC_STATISTICS * ppIpsecStatistics
  487. )
  488. {
  489. DWORD dwError = 0;
  490. PIPSEC_STATISTICS pIpsecStatistics = NULL;
  491. ENTER_SPD_SECTION();
  492. dwError = ValidateSecurity(
  493. SPD_OBJECT_SERVER,
  494. SERVER_ACCESS_ADMINISTER,
  495. NULL,
  496. NULL
  497. );
  498. LEAVE_SPD_SECTION();
  499. BAIL_ON_WIN32_ERROR(dwError);
  500. dwError = QueryDriverForIpsecStats(
  501. &pIpsecStatistics
  502. );
  503. BAIL_ON_WIN32_ERROR(dwError);
  504. *ppIpsecStatistics = pIpsecStatistics;
  505. cleanup:
  506. return (dwError);
  507. error:
  508. *ppIpsecStatistics = NULL;
  509. goto cleanup;
  510. }
  511. DWORD
  512. QueryDriverForIpsecStats(
  513. PIPSEC_QUERY_STATS * ppQueryStats
  514. )
  515. {
  516. DWORD dwError = 0;
  517. PIPSEC_QUERY_STATS pQueryStats = NULL;
  518. HANDLE hIPSecDriver = NULL;
  519. LPBYTE pInBuffer = NULL;
  520. DWORD dwInBufferSize = 0;
  521. BOOL bStatus = FALSE;
  522. LPBYTE pOutBuffer = NULL;
  523. DWORD dwOutBufferSize = 0;
  524. DWORD dwBytesReturned = 0;
  525. dwError = SPDApiBufferAllocate(
  526. sizeof(IPSEC_QUERY_STATS),
  527. &pQueryStats
  528. );
  529. BAIL_ON_WIN32_ERROR(dwError);
  530. dwError = SPDOpenIPSecDriver(
  531. &hIPSecDriver
  532. );
  533. BAIL_ON_WIN32_ERROR(dwError);
  534. pInBuffer = (LPBYTE) pQueryStats;
  535. dwInBufferSize = sizeof(IPSEC_QUERY_STATS);
  536. pOutBuffer = (LPBYTE) pQueryStats;
  537. dwOutBufferSize = sizeof(IPSEC_QUERY_STATS);
  538. dwBytesReturned = dwOutBufferSize;
  539. bStatus = DeviceIoControl(
  540. hIPSecDriver,
  541. IOCTL_IPSEC_QUERY_STATS,
  542. pInBuffer,
  543. dwInBufferSize,
  544. pOutBuffer,
  545. dwOutBufferSize,
  546. &dwBytesReturned,
  547. NULL
  548. );
  549. if (bStatus == FALSE) {
  550. dwError = GetLastError();
  551. BAIL_ON_WIN32_ERROR(dwError);
  552. }
  553. *ppQueryStats = pQueryStats;
  554. cleanup:
  555. if (hIPSecDriver != INVALID_HANDLE_VALUE) {
  556. SPDCloseIPSecDriver(hIPSecDriver);
  557. }
  558. return (dwError);
  559. error:
  560. if (pQueryStats) {
  561. SPDApiBufferFree(pQueryStats);
  562. }
  563. *ppQueryStats = NULL;
  564. goto cleanup;
  565. }
  566. DWORD
  567. EnumQMSAs(
  568. LPWSTR pServerName,
  569. PIPSEC_QM_SA pQMSATemplate,
  570. PIPSEC_QM_SA * ppQMSAs,
  571. DWORD dwPreferredNumEntries,
  572. LPDWORD pdwNumQMSAs,
  573. LPDWORD pdwNumTotalQMSAs,
  574. LPDWORD pdwResumeHandle,
  575. DWORD dwFlags
  576. )
  577. {
  578. DWORD dwError = 0;
  579. DWORD dwResumeHandle = 0;
  580. DWORD dwNumToEnum = 0;
  581. DWORD dwNumTotalQMSAs = 0;
  582. PIPSEC_ENUM_SAS pIpsecEnumSAs = NULL;
  583. PIPSEC_SA_INFO pInfo = NULL;
  584. DWORD i = 0;
  585. DWORD dwNumQMSAs = 0;
  586. PIPSEC_QM_SA pQMSAs = NULL;
  587. PIPSEC_SA_INFO pTemp = NULL;
  588. PIPSEC_QM_SA pTempQMSA = NULL;
  589. dwResumeHandle = *pdwResumeHandle;
  590. if (!dwPreferredNumEntries || (dwPreferredNumEntries > MAX_QMSA_ENUM_COUNT)) {
  591. dwNumToEnum = MAX_QMSA_ENUM_COUNT;
  592. }
  593. else {
  594. dwNumToEnum = dwPreferredNumEntries;
  595. }
  596. ENTER_SPD_SECTION();
  597. dwError = ValidateSecurity(
  598. SPD_OBJECT_SERVER,
  599. SERVER_ACCESS_ADMINISTER,
  600. NULL,
  601. NULL
  602. );
  603. LEAVE_SPD_SECTION();
  604. BAIL_ON_WIN32_ERROR(dwError);
  605. dwError = IpsecEnumSAs(
  606. &dwNumTotalQMSAs,
  607. &pIpsecEnumSAs
  608. );
  609. BAIL_ON_WIN32_ERROR(dwError);
  610. if (dwNumTotalQMSAs <= dwResumeHandle) {
  611. dwError = ERROR_NO_DATA;
  612. BAIL_ON_WIN32_ERROR(dwError);
  613. }
  614. pInfo = pIpsecEnumSAs->pInfo;
  615. for (i = 0; i < dwResumeHandle; i++) {
  616. pInfo++;
  617. }
  618. dwNumQMSAs = dwNumTotalQMSAs - dwResumeHandle;
  619. if (dwNumQMSAs > dwNumToEnum) {
  620. dwNumQMSAs = dwNumToEnum;
  621. }
  622. dwError = SPDApiBufferAllocate(
  623. sizeof(IPSEC_QM_SA)*dwNumQMSAs,
  624. &pQMSAs
  625. );
  626. BAIL_ON_WIN32_ERROR(dwError);
  627. pTemp = pInfo;
  628. pTempQMSA = pQMSAs;
  629. for (i = 0; i < dwNumQMSAs; i++) {
  630. dwError = CopyQMSA(
  631. pTemp,
  632. pTempQMSA
  633. );
  634. BAIL_ON_WIN32_ERROR(dwError);
  635. pTemp++;
  636. pTempQMSA++;
  637. }
  638. *ppQMSAs = pQMSAs;
  639. *pdwResumeHandle = dwResumeHandle + dwNumQMSAs;
  640. *pdwNumQMSAs = dwNumQMSAs;
  641. *pdwNumTotalQMSAs = dwNumTotalQMSAs;
  642. cleanup:
  643. if (pIpsecEnumSAs) {
  644. FreeSPDMem(pIpsecEnumSAs);
  645. }
  646. return (dwError);
  647. error:
  648. if (pQMSAs) {
  649. FreeQMSAs(
  650. i,
  651. pQMSAs
  652. );
  653. }
  654. *ppQMSAs = NULL;
  655. *pdwResumeHandle = dwResumeHandle;
  656. *pdwNumQMSAs = 0;
  657. *pdwNumTotalQMSAs = 0;
  658. goto cleanup;
  659. }
  660. DWORD
  661. IpsecEnumSAs(
  662. PDWORD pdwNumberOfSAs,
  663. PIPSEC_ENUM_SAS * ppIpsecEnumSAs
  664. )
  665. {
  666. DWORD dwError = 0;
  667. DWORD dwNumberOfSAs = 0;
  668. PIPSEC_ENUM_SAS pIpsecEnumSAs = NULL;
  669. HANDLE hIPSecDriver = NULL;
  670. BOOL bStatus = FALSE;
  671. PIPSEC_ENUM_SAS pOutBuffer = NULL;
  672. DWORD dwOutBufferSize = 0;
  673. DWORD dwBytesReturned = 0;
  674. dwError = SPDOpenIPSecDriver(
  675. &hIPSecDriver
  676. );
  677. BAIL_ON_WIN32_ERROR(dwError);
  678. //
  679. // The first call passes in a return buffer of size IPSEC_ENUM_SAS.
  680. // The idea here is to determine the number of SAs and then pass
  681. // a second buffer with the correct size.
  682. //
  683. dwOutBufferSize = sizeof(IPSEC_ENUM_SAS);
  684. pOutBuffer = (PIPSEC_ENUM_SAS) AllocSPDMem(
  685. sizeof(IPSEC_ENUM_SAS)
  686. );
  687. if (!pOutBuffer) {
  688. dwError = ERROR_OUTOFMEMORY;
  689. BAIL_ON_WIN32_ERROR(dwError);
  690. }
  691. memset(pOutBuffer, 0, dwOutBufferSize);
  692. dwBytesReturned = dwOutBufferSize;
  693. bStatus = DeviceIoControl(
  694. hIPSecDriver,
  695. IOCTL_IPSEC_ENUM_SAS,
  696. NULL,
  697. 0,
  698. (PVOID) pOutBuffer,
  699. dwOutBufferSize,
  700. &dwBytesReturned,
  701. NULL
  702. );
  703. //
  704. // The error code here should be either ERROR_BUFFER_OVERFLOW
  705. // or ERROR_MORE_DATA or ERROR_SUCCESS.
  706. //
  707. if (!bStatus) {
  708. dwError = GetLastError();
  709. }
  710. else {
  711. dwError = ERROR_SUCCESS;
  712. }
  713. while (dwError == ERROR_BUFFER_OVERFLOW || dwError == ERROR_MORE_DATA) {
  714. //
  715. // Determine the number of SAs that the driver currently has.
  716. //
  717. pIpsecEnumSAs = (PIPSEC_ENUM_SAS) pOutBuffer;
  718. dwNumberOfSAs = pIpsecEnumSAs->NumEntriesPresent;
  719. if (dwNumberOfSAs == 0) {
  720. dwError = ERROR_NO_DATA;
  721. BAIL_ON_WIN32_ERROR(dwError);
  722. }
  723. if (pOutBuffer) {
  724. FreeSPDMem(pOutBuffer);
  725. pOutBuffer = NULL;
  726. }
  727. dwOutBufferSize = sizeof(IPSEC_ENUM_SAS)
  728. + (dwNumberOfSAs -1)*sizeof(IPSEC_SA_INFO);
  729. pOutBuffer = (PIPSEC_ENUM_SAS) AllocSPDMem(
  730. dwOutBufferSize
  731. );
  732. if (!pOutBuffer) {
  733. dwError = ERROR_OUTOFMEMORY;
  734. BAIL_ON_WIN32_ERROR(dwError);
  735. }
  736. memset(pOutBuffer, 0, dwOutBufferSize);
  737. dwBytesReturned = dwOutBufferSize;
  738. bStatus = DeviceIoControl(
  739. hIPSecDriver,
  740. IOCTL_IPSEC_ENUM_SAS,
  741. NULL,
  742. 0,
  743. (PVOID) pOutBuffer,
  744. dwOutBufferSize,
  745. &dwBytesReturned,
  746. NULL
  747. );
  748. if (!bStatus) {
  749. dwError = GetLastError();
  750. }
  751. else {
  752. dwError = ERROR_SUCCESS;
  753. }
  754. }
  755. pIpsecEnumSAs = (PIPSEC_ENUM_SAS) pOutBuffer;
  756. dwNumberOfSAs = pIpsecEnumSAs->NumEntries;
  757. if (dwNumberOfSAs == 0) {
  758. dwError = ERROR_NO_DATA;
  759. BAIL_ON_WIN32_ERROR(dwError);
  760. }
  761. *pdwNumberOfSAs = dwNumberOfSAs;
  762. *ppIpsecEnumSAs = pIpsecEnumSAs;
  763. cleanup:
  764. if (hIPSecDriver != INVALID_HANDLE_VALUE) {
  765. SPDCloseIPSecDriver(hIPSecDriver);
  766. }
  767. return (dwError);
  768. error:
  769. *pdwNumberOfSAs = 0;
  770. *ppIpsecEnumSAs = NULL;
  771. if (pOutBuffer) {
  772. FreeSPDMem(pOutBuffer);
  773. }
  774. goto cleanup;
  775. }
  776. DWORD
  777. CopyQMSA(
  778. PIPSEC_SA_INFO pInfo,
  779. PIPSEC_QM_SA pQMSA
  780. )
  781. {
  782. DWORD dwError = 0;
  783. memcpy(
  784. &(pQMSA->gQMPolicyID),
  785. &(pInfo->PolicyId),
  786. sizeof(GUID)
  787. );
  788. memcpy(
  789. &(pQMSA->gQMFilterID),
  790. &(pInfo->FilterId),
  791. sizeof(GUID)
  792. );
  793. CopyQMSAOffer(
  794. pInfo,
  795. &(pQMSA->SelectedQMOffer)
  796. );
  797. CopyQMSAFilter(
  798. pInfo->InboundTunnelAddr,
  799. &(pInfo->AssociatedFilter),
  800. &(pQMSA->IpsecQMFilter)
  801. );
  802. CopyQMSAMMSpi(
  803. pInfo->CookiePair,
  804. &(pQMSA->MMSpi)
  805. );
  806. return (dwError);
  807. }
  808. VOID
  809. CopyQMSAOffer(
  810. PIPSEC_SA_INFO pInfo,
  811. PIPSEC_QM_OFFER pOffer
  812. )
  813. {
  814. DWORD i = 0;
  815. DWORD j = 0;
  816. DWORD k = 0;
  817. pOffer->Lifetime.uKeyExpirationTime =
  818. pInfo->Lifetime.KeyExpirationTime;
  819. pOffer->Lifetime.uKeyExpirationKBytes =
  820. pInfo->Lifetime.KeyExpirationBytes;
  821. pOffer->dwFlags = 0;
  822. pOffer->dwPFSGroup = pInfo->dwQMPFSGroup;
  823. if ((pOffer->dwPFSGroup != PFS_GROUP_1) &&
  824. (pOffer->dwPFSGroup != PFS_GROUP_2) &&
  825. (pOffer->dwPFSGroup != PFS_GROUP_MM)) {
  826. pOffer->dwPFSGroup = PFS_GROUP_NONE;
  827. pOffer->bPFSRequired = FALSE;
  828. }
  829. else {
  830. pOffer->bPFSRequired = TRUE;
  831. }
  832. i = 0;
  833. for (j = 0; (j < pInfo->NumOps) && (i < QM_MAX_ALGOS) ; j++) {
  834. switch (pInfo->Operation[j]) {
  835. case Auth:
  836. switch (pInfo->AlgoInfo[j].IntegrityAlgo.algoIdentifier) {
  837. case IPSEC_AH_MD5:
  838. pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_AH_MD5;
  839. break;
  840. case IPSEC_AH_SHA:
  841. pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_AH_SHA1;
  842. break;
  843. default:
  844. pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_AH_NONE;
  845. break;
  846. }
  847. pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AH_NONE;
  848. pOffer->Algos[i].Operation = AUTHENTICATION;
  849. pOffer->Algos[i].uAlgoKeyLen =
  850. pInfo->AlgoInfo[j].IntegrityAlgo.algoKeylen;
  851. pOffer->Algos[i].uAlgoRounds =
  852. pInfo->AlgoInfo[j].IntegrityAlgo.algoRounds;
  853. pOffer->Algos[i].MySpi = pInfo->InboundSPI[j];
  854. pOffer->Algos[i].PeerSpi = pInfo->OutboundSPI[j];
  855. i++;
  856. break;
  857. case Encrypt:
  858. switch (pInfo->AlgoInfo[j].ConfAlgo.algoIdentifier) {
  859. case IPSEC_ESP_DES:
  860. pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_ESP_DES;
  861. break;
  862. case IPSEC_ESP_DES_40:
  863. pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_ESP_DES;
  864. break;
  865. case IPSEC_ESP_3_DES:
  866. pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_ESP_3_DES;
  867. break;
  868. default:
  869. pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_ESP_NONE;
  870. break;
  871. }
  872. switch (pInfo->AlgoInfo[j].IntegrityAlgo.algoIdentifier) {
  873. case IPSEC_AH_MD5:
  874. pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AH_MD5;
  875. break;
  876. case IPSEC_AH_SHA:
  877. pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AH_SHA1;
  878. break;
  879. default:
  880. pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AH_NONE;
  881. break;
  882. }
  883. pOffer->Algos[i].Operation = ENCRYPTION;
  884. pOffer->Algos[i].uAlgoKeyLen =
  885. pInfo->AlgoInfo[j].ConfAlgo.algoKeylen;
  886. pOffer->Algos[i].uAlgoRounds =
  887. pInfo->AlgoInfo[j].ConfAlgo.algoRounds;
  888. pOffer->Algos[i].MySpi = pInfo->InboundSPI[j];
  889. pOffer->Algos[i].PeerSpi = pInfo->OutboundSPI[j];
  890. i++;
  891. break;
  892. case None:
  893. pOffer->Algos[i].Operation = NONE;
  894. pOffer->Algos[i].uAlgoIdentifier = IPSEC_DOI_ESP_NONE;
  895. pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AH_NONE;
  896. pOffer->Algos[i].uAlgoKeyLen = 0;
  897. pOffer->Algos[i].uAlgoRounds = 0;
  898. pOffer->Algos[i].MySpi = pInfo->InboundSPI[j];
  899. pOffer->Algos[i].PeerSpi = pInfo->OutboundSPI[j];
  900. i++;
  901. break;
  902. case Compress:
  903. default:
  904. break;
  905. }
  906. }
  907. for (k = i; k < QM_MAX_ALGOS; k++) {
  908. memset(&(pOffer->Algos[k]), 0, sizeof(IPSEC_QM_ALGO));
  909. }
  910. pOffer->dwNumAlgos = i;
  911. return;
  912. }
  913. VOID
  914. CopyQMSAFilter(
  915. IPAddr MyTunnelEndpt,
  916. PIPSEC_FILTER pIpsecFilter,
  917. PIPSEC_QM_FILTER pIpsecQMFilter
  918. )
  919. {
  920. if (pIpsecFilter->TunnelFilter) {
  921. pIpsecQMFilter->QMFilterType = QM_TUNNEL_FILTER;
  922. }
  923. else {
  924. pIpsecQMFilter->QMFilterType = QM_TRANSPORT_FILTER;
  925. }
  926. PASetAddress(
  927. pIpsecFilter->SrcMask,
  928. pIpsecFilter->SrcAddr,
  929. &(pIpsecQMFilter->SrcAddr)
  930. );
  931. PASetAddress(
  932. pIpsecFilter->DestMask,
  933. pIpsecFilter->DestAddr,
  934. &(pIpsecQMFilter->DesAddr)
  935. );
  936. pIpsecQMFilter->Protocol.ProtocolType = PROTOCOL_UNIQUE;
  937. pIpsecQMFilter->Protocol.dwProtocol = pIpsecFilter->Protocol;
  938. pIpsecQMFilter->SrcPort.PortType = PORT_UNIQUE;
  939. pIpsecQMFilter->SrcPort.wPort = ntohs(pIpsecFilter->SrcPort);
  940. pIpsecQMFilter->DesPort.PortType = PORT_UNIQUE;
  941. pIpsecQMFilter->DesPort.wPort = ntohs(pIpsecFilter->DestPort);
  942. if (pIpsecFilter->TunnelFilter) {
  943. PASetTunnelAddress(
  944. MyTunnelEndpt,
  945. &(pIpsecQMFilter->MyTunnelEndpt)
  946. );
  947. PASetTunnelAddress(
  948. pIpsecFilter->TunnelAddr,
  949. &(pIpsecQMFilter->PeerTunnelEndpt)
  950. );
  951. }
  952. else {
  953. PASetAddress(
  954. SUBNET_MASK_ANY,
  955. SUBNET_ADDRESS_ANY,
  956. &(pIpsecQMFilter->MyTunnelEndpt)
  957. );
  958. PASetAddress(
  959. SUBNET_MASK_ANY,
  960. SUBNET_ADDRESS_ANY,
  961. &(pIpsecQMFilter->PeerTunnelEndpt)
  962. );
  963. }
  964. pIpsecQMFilter->dwFlags = 0;
  965. if ((pIpsecFilter->Flags) & FILTER_FLAGS_INBOUND) {
  966. pIpsecQMFilter->dwFlags |= FILTER_DIRECTION_INBOUND;
  967. }
  968. else {
  969. pIpsecQMFilter->dwFlags |= FILTER_DIRECTION_OUTBOUND;
  970. }
  971. if ((pIpsecFilter->Flags) & FILTER_FLAGS_PASS_THRU) {
  972. pIpsecQMFilter->dwFlags |= FILTER_NATURE_PASS_THRU;
  973. }
  974. else if ((pIpsecFilter->Flags) & FILTER_FLAGS_DROP) {
  975. pIpsecQMFilter->dwFlags |= FILTER_NATURE_BLOCKING;
  976. }
  977. else {
  978. pIpsecQMFilter->dwFlags |= 0;
  979. }
  980. return;
  981. }
  982. VOID
  983. CopyQMSAMMSpi(
  984. IKE_COOKIE_PAIR CookiePair,
  985. PIKE_COOKIE_PAIR pMMSpi
  986. )
  987. {
  988. pMMSpi->Initiator = CookiePair.Initiator;
  989. pMMSpi->Responder = CookiePair.Responder;
  990. return;
  991. }
  992. VOID
  993. FreeQMSAs(
  994. DWORD dwCnt,
  995. PIPSEC_QM_SA pQMSAs
  996. )
  997. {
  998. if (pQMSAs) {
  999. SPDApiBufferFree(pQMSAs);
  1000. }
  1001. }
  1002. DWORD
  1003. InsertTunnelFiltersIntoIPSec(
  1004. PINITNSFILTER pSpecificFilters
  1005. )
  1006. /*++
  1007. Routine Description:
  1008. Insert a list of specific filters into the
  1009. IPSec Driver.
  1010. Arguments:
  1011. pSpecificFilters - list of filters to insert.
  1012. Return Value:
  1013. ERROR_SUCCESS - Success.
  1014. Win32 Error - Failure.
  1015. --*/
  1016. {
  1017. DWORD dwError = 0;
  1018. HANDLE hIPSecDriver = NULL;
  1019. LPBYTE pInBuffer = NULL;
  1020. DWORD dwInBufferSize = 0;
  1021. BOOL bStatus = FALSE;
  1022. LPBYTE pOutBuffer = NULL;
  1023. DWORD dwOutBufferSize = 0;
  1024. DWORD dwBytesReturned = 0;
  1025. DWORD dwNumFilters = 0;
  1026. PIPSEC_FILTER_INFO pInternalFilters = NULL;
  1027. LPBYTE pTemp = NULL;
  1028. DWORD i = 0;
  1029. if (!pSpecificFilters) {
  1030. return (dwError);
  1031. }
  1032. dwError = SPDOpenIPSecDriver(
  1033. &hIPSecDriver
  1034. );
  1035. BAIL_ON_WIN32_ERROR(dwError);
  1036. dwError = WrapTunnelFilters(
  1037. pSpecificFilters,
  1038. &pInternalFilters,
  1039. &dwNumFilters
  1040. );
  1041. BAIL_ON_WIN32_ERROR(dwError);
  1042. dwInBufferSize = sizeof(DWORD) +
  1043. sizeof(IPSEC_FILTER_INFO)*dwNumFilters;
  1044. dwError = AllocateSPDMemory(
  1045. dwInBufferSize,
  1046. &pInBuffer
  1047. );
  1048. BAIL_ON_WIN32_ERROR(dwError);
  1049. pTemp = pInBuffer;
  1050. memcpy(pTemp, &dwNumFilters, sizeof(DWORD));
  1051. pTemp += sizeof(DWORD);
  1052. for (i = 0 ; i < dwNumFilters; i++) {
  1053. memcpy(pTemp, &(pInternalFilters[i]), sizeof(IPSEC_FILTER_INFO));
  1054. pTemp += sizeof(IPSEC_FILTER_INFO);
  1055. }
  1056. bStatus = DeviceIoControl(
  1057. hIPSecDriver,
  1058. IOCTL_IPSEC_ADD_FILTER,
  1059. pInBuffer,
  1060. dwInBufferSize,
  1061. pOutBuffer,
  1062. dwOutBufferSize,
  1063. &dwBytesReturned,
  1064. NULL
  1065. );
  1066. if (bStatus == FALSE) {
  1067. dwError = GetLastError();
  1068. BAIL_ON_WIN32_ERROR(dwError);
  1069. }
  1070. error:
  1071. if (hIPSecDriver != INVALID_HANDLE_VALUE) {
  1072. SPDCloseIPSecDriver(hIPSecDriver);
  1073. }
  1074. if (pInternalFilters) {
  1075. FreeSPDMemory(pInternalFilters);
  1076. }
  1077. if (pInBuffer) {
  1078. FreeSPDMemory(pInBuffer);
  1079. }
  1080. if (pOutBuffer) {
  1081. LocalFree(pOutBuffer);
  1082. }
  1083. return (dwError);
  1084. }
  1085. DWORD
  1086. DeleteTunnelFiltersFromIPSec(
  1087. PINITNSFILTER pSpecificFilters
  1088. )
  1089. /*++
  1090. Routine Description:
  1091. Delete a list of filters from the IPSec Driver.
  1092. Arguments:
  1093. pSpecificFilters - list of filters to delete.
  1094. Return Value:
  1095. ERROR_SUCCESS - Success.
  1096. Win32 Error - Failure.
  1097. --*/
  1098. {
  1099. DWORD dwError = 0;
  1100. HANDLE hIPSecDriver = NULL;
  1101. LPBYTE pInBuffer = NULL;
  1102. DWORD dwInBufferSize = 0;
  1103. BOOL bStatus = FALSE;
  1104. LPBYTE pOutBuffer = NULL;
  1105. DWORD dwOutBufferSize = 0;
  1106. DWORD dwBytesReturned = 0;
  1107. DWORD dwNumFilters = 0;
  1108. PIPSEC_FILTER_INFO pInternalFilters = NULL;
  1109. LPBYTE pTemp = NULL;
  1110. DWORD i = 0;
  1111. if (!pSpecificFilters) {
  1112. return (dwError);
  1113. }
  1114. dwError = SPDOpenIPSecDriver(
  1115. &hIPSecDriver
  1116. );
  1117. BAIL_ON_WIN32_ERROR(dwError);
  1118. dwError = WrapTunnelFilters(
  1119. pSpecificFilters,
  1120. &pInternalFilters,
  1121. &dwNumFilters
  1122. );
  1123. BAIL_ON_WIN32_ERROR(dwError);
  1124. dwInBufferSize = sizeof(DWORD) +
  1125. sizeof(IPSEC_FILTER_INFO)*dwNumFilters;
  1126. dwError = AllocateSPDMemory(
  1127. dwInBufferSize,
  1128. &pInBuffer
  1129. );
  1130. BAIL_ON_WIN32_ERROR(dwError);
  1131. pTemp = pInBuffer;
  1132. memcpy(pTemp, &dwNumFilters, sizeof(DWORD));
  1133. pTemp += sizeof(DWORD);
  1134. for (i = 0 ; i < dwNumFilters; i++) {
  1135. memcpy(pTemp, &(pInternalFilters[i]), sizeof(IPSEC_FILTER_INFO));
  1136. pTemp += sizeof(IPSEC_FILTER_INFO);
  1137. }
  1138. bStatus = DeviceIoControl(
  1139. hIPSecDriver,
  1140. IOCTL_IPSEC_DELETE_FILTER,
  1141. pInBuffer,
  1142. dwInBufferSize,
  1143. pOutBuffer,
  1144. dwOutBufferSize,
  1145. &dwBytesReturned,
  1146. NULL
  1147. );
  1148. if (bStatus == FALSE) {
  1149. dwError = GetLastError();
  1150. BAIL_ON_WIN32_ERROR(dwError);
  1151. }
  1152. error:
  1153. if (hIPSecDriver != INVALID_HANDLE_VALUE) {
  1154. SPDCloseIPSecDriver(hIPSecDriver);
  1155. }
  1156. if (pInternalFilters) {
  1157. FreeSPDMemory(pInternalFilters);
  1158. }
  1159. if (pInBuffer) {
  1160. FreeSPDMemory(pInBuffer);
  1161. }
  1162. if (pOutBuffer) {
  1163. LocalFree(pOutBuffer);
  1164. }
  1165. return (dwError);
  1166. }
  1167. DWORD
  1168. WrapTunnelFilters(
  1169. PINITNSFILTER pSpecificFilters,
  1170. PIPSEC_FILTER_INFO * ppInternalFilters,
  1171. PDWORD pdwNumFilters
  1172. )
  1173. /*++
  1174. Routine Description:
  1175. Transforms a list of specific tunnel filters to
  1176. an equivalent list of filters acceptable to the
  1177. IPSec Driver.
  1178. Arguments:
  1179. pSpecificFilters - list of filters to convert.
  1180. ppInternalFilters - list of transformed filters.
  1181. pdwNumFilters - count of the filters in the transformed
  1182. list.
  1183. Return Value:
  1184. ERROR_SUCCESS - Success.
  1185. Win32 Error - Failure.
  1186. --*/
  1187. {
  1188. DWORD dwError = 0;
  1189. PINITNSFILTER pTempFilter = NULL;
  1190. PIPSEC_FILTER_INFO pInternalFilters = NULL;
  1191. DWORD dwNumFilters = 0;
  1192. DWORD i = 0;
  1193. //
  1194. // At this point, there's atleast one filter in the
  1195. // specific filter list.
  1196. //
  1197. pTempFilter = pSpecificFilters;
  1198. while(pTempFilter) {
  1199. pTempFilter = pTempFilter->pNext;
  1200. dwNumFilters++;
  1201. }
  1202. dwError = AllocateSPDMemory(
  1203. sizeof(IPSEC_FILTER_INFO)*dwNumFilters,
  1204. &pInternalFilters
  1205. );
  1206. BAIL_ON_WIN32_ERROR(dwError);
  1207. pTempFilter = pSpecificFilters;
  1208. while(pTempFilter) {
  1209. FormIPSecTunnelFilter(
  1210. pTempFilter,
  1211. &(pInternalFilters[i])
  1212. );
  1213. pTempFilter = pTempFilter->pNext;
  1214. i++;
  1215. }
  1216. *ppInternalFilters = pInternalFilters;
  1217. *pdwNumFilters = dwNumFilters;
  1218. return (dwError);
  1219. error:
  1220. *ppInternalFilters = NULL;
  1221. *pdwNumFilters = 0;
  1222. return (dwError);
  1223. }
  1224. VOID
  1225. FormIPSecTunnelFilter(
  1226. PINITNSFILTER pSpecificFilter,
  1227. PIPSEC_FILTER_INFO pIpsecFilter
  1228. )
  1229. /*++
  1230. Routine Description:
  1231. Transforms a specific tunnel filter to an
  1232. equivalent filter acceptable to the IPSec Driver.
  1233. Arguments:
  1234. pSpecificFilter - filter to convert.
  1235. pIpsecFilter - transformed filter.
  1236. Return Value:
  1237. NONE.
  1238. --*/
  1239. {
  1240. memcpy(
  1241. &(pIpsecFilter->FilterId),
  1242. &(pSpecificFilter->gParentID),
  1243. sizeof(GUID)
  1244. );
  1245. memcpy(
  1246. &(pIpsecFilter->PolicyId),
  1247. &(pSpecificFilter->gPolicyID),
  1248. sizeof(GUID)
  1249. );
  1250. pIpsecFilter->Index = pSpecificFilter->dwWeight;
  1251. pIpsecFilter->AssociatedFilter.SrcAddr = pSpecificFilter->SrcAddr.uIpAddr;
  1252. pIpsecFilter->AssociatedFilter.SrcMask = pSpecificFilter->SrcAddr.uSubNetMask;
  1253. pIpsecFilter->AssociatedFilter.DestAddr = pSpecificFilter->DesAddr.uIpAddr;
  1254. pIpsecFilter->AssociatedFilter.DestMask = pSpecificFilter->DesAddr.uSubNetMask;
  1255. pIpsecFilter->AssociatedFilter.Protocol = pSpecificFilter->Protocol.dwProtocol;
  1256. pIpsecFilter->AssociatedFilter.SrcPort = pSpecificFilter->SrcPort.wPort;
  1257. pIpsecFilter->AssociatedFilter.DestPort = pSpecificFilter->DesPort.wPort;
  1258. pIpsecFilter->AssociatedFilter.TunnelFilter = TRUE;
  1259. pIpsecFilter->AssociatedFilter.TunnelAddr = pSpecificFilter->DesTunnelAddr.uIpAddr;
  1260. pIpsecFilter->AssociatedFilter.Flags = 0;
  1261. if (pSpecificFilter->dwDirection == FILTER_DIRECTION_INBOUND) {
  1262. pIpsecFilter->AssociatedFilter.Flags |= FILTER_FLAGS_INBOUND;
  1263. switch (pSpecificFilter->InboundFilterFlag) {
  1264. case PASS_THRU:
  1265. pIpsecFilter->AssociatedFilter.Flags |= FILTER_FLAGS_PASS_THRU;
  1266. break;
  1267. case BLOCKING:
  1268. pIpsecFilter->AssociatedFilter.Flags |= FILTER_FLAGS_DROP;
  1269. break;
  1270. default:
  1271. break;
  1272. }
  1273. }
  1274. else {
  1275. pIpsecFilter->AssociatedFilter.Flags |= FILTER_FLAGS_OUTBOUND;
  1276. switch (pSpecificFilter->OutboundFilterFlag) {
  1277. case PASS_THRU:
  1278. pIpsecFilter->AssociatedFilter.Flags |= FILTER_FLAGS_PASS_THRU;
  1279. break;
  1280. case BLOCKING:
  1281. pIpsecFilter->AssociatedFilter.Flags |= FILTER_FLAGS_DROP;
  1282. break;
  1283. default:
  1284. break;
  1285. }
  1286. }
  1287. }
  1288. DWORD
  1289. SPDSetIPSecDriverOpMode(
  1290. DWORD dwOpMode
  1291. )
  1292. {
  1293. DWORD dwError = 0;
  1294. HANDLE hIPSecDriver = NULL;
  1295. PIPSEC_SET_OPERATION_MODE pIpsecSetOpMode = NULL;
  1296. LPBYTE pInBuffer = NULL;
  1297. DWORD dwInBufferSize = 0;
  1298. LPBYTE pOutBuffer = NULL;
  1299. DWORD dwOutBufferSize = 0;
  1300. DWORD dwBytesReturned = 0;
  1301. BOOL bStatus = FALSE;
  1302. dwError = SPDOpenIPSecDriver(
  1303. &hIPSecDriver
  1304. );
  1305. BAIL_ON_WIN32_ERROR(dwError);
  1306. dwError = AllocateSPDMemory(
  1307. sizeof(IPSEC_SET_OPERATION_MODE),
  1308. &pIpsecSetOpMode
  1309. );
  1310. BAIL_ON_WIN32_ERROR(dwError);
  1311. pIpsecSetOpMode->OperationMode = (OPERATION_MODE) dwOpMode;
  1312. pInBuffer = (LPBYTE) pIpsecSetOpMode;
  1313. dwInBufferSize = sizeof(IPSEC_SET_OPERATION_MODE);
  1314. pOutBuffer = (LPBYTE) pIpsecSetOpMode;
  1315. dwOutBufferSize = sizeof(IPSEC_SET_OPERATION_MODE);
  1316. dwBytesReturned = dwOutBufferSize;
  1317. bStatus = DeviceIoControl(
  1318. hIPSecDriver,
  1319. IOCTL_IPSEC_SET_OPERATION_MODE,
  1320. pInBuffer,
  1321. dwInBufferSize,
  1322. pOutBuffer,
  1323. dwOutBufferSize,
  1324. &dwBytesReturned,
  1325. NULL
  1326. );
  1327. if (bStatus == FALSE) {
  1328. dwError = GetLastError();
  1329. BAIL_ON_WIN32_ERROR(dwError);
  1330. }
  1331. error:
  1332. if (hIPSecDriver != INVALID_HANDLE_VALUE) {
  1333. SPDCloseIPSecDriver(hIPSecDriver);
  1334. }
  1335. if (pIpsecSetOpMode) {
  1336. FreeSPDMemory(pIpsecSetOpMode);
  1337. }
  1338. return (dwError);
  1339. }
  1340. DWORD
  1341. IPSecDeleteQMSAs(
  1342. LPWSTR pServerName,
  1343. PIPSEC_QM_SA pIpsecQMSA,
  1344. DWORD dwFlags
  1345. )
  1346. {
  1347. DWORD dwError = ERROR_SUCCESS;
  1348. HANDLE hIPSecDriver = NULL;
  1349. IPSEC_DELETE_SA IpsecDeleteSA;
  1350. LPBYTE pInBuffer = NULL;
  1351. DWORD dwInBufferSize = 0;
  1352. LPBYTE pOutBuffer = NULL;
  1353. DWORD dwOutBufferSize = 0;
  1354. DWORD dwBytesReturned = 0;
  1355. BOOL bStatus = FALSE;
  1356. ENTER_SPD_SECTION();
  1357. dwError = ValidateSecurity(
  1358. SPD_OBJECT_SERVER,
  1359. SERVER_ACCESS_ADMINISTER,
  1360. NULL,
  1361. NULL
  1362. );
  1363. LEAVE_SPD_SECTION();
  1364. BAIL_ON_WIN32_ERROR(dwError);
  1365. dwError = SPDOpenIPSecDriver(
  1366. &hIPSecDriver
  1367. );
  1368. BAIL_ON_WIN32_ERROR(dwError);
  1369. memcpy(
  1370. &IpsecDeleteSA.SATemplate,
  1371. pIpsecQMSA,
  1372. sizeof(IPSEC_QM_SA)
  1373. );
  1374. pInBuffer = (LPBYTE) &IpsecDeleteSA;
  1375. dwInBufferSize = sizeof(IPSEC_DELETE_SA);
  1376. pOutBuffer = (LPBYTE) &IpsecDeleteSA;
  1377. dwOutBufferSize = sizeof(IPSEC_DELETE_SA);
  1378. dwBytesReturned = dwOutBufferSize;
  1379. bStatus = DeviceIoControl(
  1380. hIPSecDriver,
  1381. IOCTL_IPSEC_DELETE_SA,
  1382. pInBuffer,
  1383. dwInBufferSize,
  1384. pOutBuffer,
  1385. dwOutBufferSize,
  1386. &dwBytesReturned,
  1387. NULL
  1388. );
  1389. if (bStatus == FALSE) {
  1390. dwError = GetLastError();
  1391. BAIL_ON_WIN32_ERROR(dwError);
  1392. }
  1393. error:
  1394. if (hIPSecDriver != INVALID_HANDLE_VALUE) {
  1395. SPDCloseIPSecDriver(hIPSecDriver);
  1396. }
  1397. return (dwError);
  1398. }
  1399. DWORD
  1400. SPDRegisterIPSecDriverProtocols(
  1401. DWORD dwRegisterMode
  1402. )
  1403. {
  1404. DWORD dwError = 0;
  1405. HANDLE hIPSecDriver = NULL;
  1406. PIPSEC_REGISTER_PROTOCOL pIpsecRegisterProtocol = NULL;
  1407. LPBYTE pInBuffer = NULL;
  1408. DWORD dwInBufferSize = 0;
  1409. LPBYTE pOutBuffer = NULL;
  1410. DWORD dwOutBufferSize = 0;
  1411. DWORD dwBytesReturned = 0;
  1412. BOOL bStatus = FALSE;
  1413. dwError = SPDOpenIPSecDriver(
  1414. &hIPSecDriver
  1415. );
  1416. BAIL_ON_WIN32_ERROR(dwError);
  1417. dwError = AllocateSPDMemory(
  1418. sizeof(IPSEC_REGISTER_PROTOCOL),
  1419. &pIpsecRegisterProtocol
  1420. );
  1421. BAIL_ON_WIN32_ERROR(dwError);
  1422. pIpsecRegisterProtocol->RegisterProtocol = (REGISTER_PROTOCOL) dwRegisterMode;
  1423. pInBuffer = (LPBYTE) pIpsecRegisterProtocol;
  1424. dwInBufferSize = sizeof(IPSEC_REGISTER_PROTOCOL);
  1425. pOutBuffer = (LPBYTE) pIpsecRegisterProtocol;
  1426. dwOutBufferSize = sizeof(IPSEC_REGISTER_PROTOCOL);
  1427. dwBytesReturned = dwOutBufferSize;
  1428. bStatus = DeviceIoControl(
  1429. hIPSecDriver,
  1430. IOCTL_IPSEC_REGISTER_PROTOCOL,
  1431. pInBuffer,
  1432. dwInBufferSize,
  1433. pOutBuffer,
  1434. dwOutBufferSize,
  1435. &dwBytesReturned,
  1436. NULL
  1437. );
  1438. if (bStatus == FALSE) {
  1439. dwError = GetLastError();
  1440. BAIL_ON_WIN32_ERROR(dwError);
  1441. }
  1442. error:
  1443. if (hIPSecDriver != INVALID_HANDLE_VALUE) {
  1444. SPDCloseIPSecDriver(hIPSecDriver);
  1445. }
  1446. if (pIpsecRegisterProtocol) {
  1447. FreeSPDMemory(pIpsecRegisterProtocol);
  1448. }
  1449. return (dwError);
  1450. }