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.

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