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.
842 lines
22 KiB
842 lines
22 KiB
/*++
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
|
|
Module Name:
|
|
|
|
ipsecspd.c
|
|
|
|
Abstract:
|
|
|
|
This module contains all of the code to drive
|
|
the IPSecSPD Service.
|
|
|
|
Author:
|
|
|
|
abhisheV 30-September-1999
|
|
|
|
Environment
|
|
|
|
User Level: Win32
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
|
|
#ifdef TRACE_ON
|
|
#include "ipsecspd.tmh"
|
|
#endif
|
|
|
|
SERVICE_STATUS IPSecSPDStatus;
|
|
SERVICE_STATUS_HANDLE IPSecSPDStatusHandle = NULL;
|
|
|
|
|
|
#define IPSECSPD_SERVICE L"PolicyAgent"
|
|
|
|
|
|
void WINAPI
|
|
SPDServiceMain(
|
|
IN DWORD dwArgc,
|
|
IN LPTSTR * lpszArgv
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
DWORD dwTempError = 0;
|
|
|
|
WPP_INIT_TRACING(SPD_WPP_APPNAME);
|
|
|
|
// Sleep(30000);
|
|
|
|
InitMiscGlobals();
|
|
|
|
dwError = InitAuditing();
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
InitSPDThruRegistry();
|
|
|
|
//
|
|
// Open the IPSec Driver first, so that if we bail on error later,
|
|
// we can still set driver in block mode.
|
|
//
|
|
|
|
dwError = SPDOpenIPSecDriver(
|
|
&ghIPSecDriver
|
|
);
|
|
if (dwError) {
|
|
AuditOneArgErrorEvent(
|
|
SE_CATEGID_POLICY_CHANGE,
|
|
SE_AUDITID_IPSEC_POLICY_CHANGED,
|
|
IPSECSVC_DRIVER_INIT_FAILURE,
|
|
dwError,
|
|
FALSE,
|
|
TRUE
|
|
);
|
|
}
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
|
|
// Initialize all the status fields so that the subsequent calls
|
|
// to SetServiceStatus need to only update fields that changed.
|
|
|
|
IPSecSPDStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
|
|
IPSecSPDStatus.dwCurrentState = SERVICE_START_PENDING;
|
|
IPSecSPDStatus.dwControlsAccepted = 0;
|
|
IPSecSPDStatus.dwCheckPoint = 1;
|
|
IPSecSPDStatus.dwWaitHint = 5000;
|
|
IPSecSPDStatus.dwWin32ExitCode = NO_ERROR;
|
|
IPSecSPDStatus.dwServiceSpecificExitCode = 0;
|
|
|
|
// Initialize the workstation to receive service requests
|
|
// by registering the service control handler.
|
|
|
|
IPSecSPDStatusHandle = RegisterServiceCtrlHandlerExW(
|
|
IPSECSPD_SERVICE,
|
|
IPSecSPDControlHandler,
|
|
NULL
|
|
);
|
|
if (IPSecSPDStatusHandle == (SERVICE_STATUS_HANDLE) NULL) {
|
|
dwError = ERROR_INVALID_HANDLE;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
(void) IPSecSPDUpdateStatus();
|
|
|
|
dwError = InitSPDGlobals();
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
IPSecSPDStatus.dwCurrentState = SERVICE_RUNNING;
|
|
IPSecSPDStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
|
|
SERVICE_ACCEPT_SHUTDOWN |
|
|
SERVICE_ACCEPT_POWEREVENT;
|
|
IPSecSPDStatus.dwCheckPoint = 0;
|
|
IPSecSPDStatus.dwWaitHint = 0;
|
|
IPSecSPDStatus.dwWin32ExitCode = NO_ERROR;
|
|
IPSecSPDStatus.dwServiceSpecificExitCode = 0;
|
|
|
|
(void) IPSecSPDUpdateStatus();
|
|
|
|
|
|
//
|
|
// Get the current list of active interfaces on the machine.
|
|
//
|
|
(VOID) CreateInterfaceList(
|
|
&gpInterfaceList
|
|
);
|
|
|
|
//
|
|
// Get a list of DNS, DHCP, etc servers.
|
|
//
|
|
(VOID) GetSpecialAddrsList(
|
|
&gpSpecialAddrsList
|
|
);
|
|
|
|
gpIpsecPolicyState->PersIncarnationNumber = 0;
|
|
dwError = LoadPersistedIPSecInformation();
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = SPDSetIPSecDriverOpMode(
|
|
(DWORD) IPSEC_SECURE_MODE
|
|
);
|
|
if (dwError) {
|
|
AuditOneArgErrorEvent(
|
|
SE_CATEGID_POLICY_CHANGE,
|
|
SE_AUDITID_IPSEC_POLICY_CHANGED,
|
|
IPSECSVC_DRIVER_INIT_FAILURE,
|
|
dwError,
|
|
FALSE,
|
|
TRUE
|
|
);
|
|
}
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = SPDRegisterIPSecDriverProtocols(
|
|
(DWORD) IPSEC_REGISTER_PROTOCOLS
|
|
);
|
|
if (dwError) {
|
|
AuditOneArgErrorEvent(
|
|
SE_CATEGID_POLICY_CHANGE,
|
|
SE_AUDITID_IPSEC_POLICY_CHANGED,
|
|
IPSECSVC_DRIVER_INIT_FAILURE,
|
|
dwError,
|
|
FALSE,
|
|
TRUE
|
|
);
|
|
}
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
//
|
|
// Start IKE Service.
|
|
//
|
|
dwError = IKEInit();
|
|
if (dwError) {
|
|
AuditOneArgErrorEvent(
|
|
SE_CATEGID_POLICY_CHANGE,
|
|
SE_AUDITID_IPSEC_POLICY_CHANGED,
|
|
IPSECSVC_IKE_INIT_FAILURE,
|
|
dwError,
|
|
FALSE,
|
|
TRUE
|
|
);
|
|
TRACE(TRC_ERROR, (L"Failed to initialize IKE: %!winerr!", dwError));
|
|
}
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
gbIsIKEUp = TRUE;
|
|
gbIKENotify = TRUE;
|
|
|
|
//
|
|
// Start the RPC Server.
|
|
//
|
|
dwError = SPDStartRPCServer(
|
|
);
|
|
if (dwError) {
|
|
AuditOneArgErrorEvent(
|
|
SE_CATEGID_POLICY_CHANGE,
|
|
SE_AUDITID_IPSEC_POLICY_CHANGED,
|
|
IPSECSVC_RPC_INIT_FAILURE,
|
|
dwError,
|
|
FALSE,
|
|
TRUE
|
|
);
|
|
TRACE(TRC_ERROR, (L"Failed to start RPC server: %!winerr!", dwError));
|
|
}
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
dwError = ServiceWait();
|
|
|
|
error:
|
|
#ifdef TRACE_ON
|
|
if (dwError) {
|
|
TRACE(TRC_ERROR, (L"Failed to start IPSec PolicyAgent: %!winerr!", dwError));
|
|
}
|
|
#endif
|
|
|
|
if (dwError && ghIPSecDriver != INVALID_HANDLE_VALUE) {
|
|
dwTempError = SPDSetIPSecDriverOpMode(
|
|
(DWORD) IPSEC_BLOCK_MODE
|
|
);
|
|
if (gbAuditingInitialized) {
|
|
AuditOneArgErrorEvent(
|
|
SE_CATEGID_POLICY_CHANGE,
|
|
SE_AUDITID_IPSEC_POLICY_CHANGED,
|
|
IPSECSVC_SET_DRIVER_BLOCK,
|
|
dwError,
|
|
FALSE,
|
|
TRUE
|
|
);
|
|
}
|
|
}
|
|
|
|
IPSecSPDShutdown(dwError);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
DWORD
|
|
IPSecSPDUpdateStatus(
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
|
|
if (!SetServiceStatus(IPSecSPDStatusHandle, &IPSecSPDStatus)) {
|
|
dwError = GetLastError();
|
|
}
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
DWORD
|
|
IPSecSPDControlHandler(
|
|
IN DWORD dwOpCode,
|
|
IN DWORD dwEventType,
|
|
IN LPVOID lpEventData,
|
|
IN LPVOID lpContext
|
|
)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
switch (dwOpCode)
|
|
{
|
|
|
|
case SERVICE_CONTROL_STOP:
|
|
case SERVICE_CONTROL_SHUTDOWN:
|
|
|
|
if (dwOpCode == SERVICE_CONTROL_SHUTDOWN) {
|
|
gdwShutdownFlags = SPD_SHUTDOWN_MACHINE;
|
|
} else {
|
|
gdwShutdownFlags = SPD_SHUTDOWN_SERVICE;
|
|
}
|
|
|
|
if (IPSecSPDStatus.dwCurrentState != SERVICE_STOP_PENDING) {
|
|
|
|
IPSecSPDStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
|
IPSecSPDStatus.dwCheckPoint = 1;
|
|
IPSecSPDStatus.dwWaitHint = 60000;
|
|
|
|
(void) IPSecSPDUpdateStatus();
|
|
|
|
SetEvent(ghServiceStopEvent);
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
break;
|
|
case SERVICE_CONTROL_NEW_LOCAL_POLICY:
|
|
|
|
SetEvent(ghNewLocalPolicyEvent);
|
|
|
|
break;
|
|
|
|
case SERVICE_CONTROL_FORCED_POLICY_RELOAD:
|
|
|
|
SetEvent(ghForcedPolicyReloadEvent);
|
|
|
|
break;
|
|
|
|
case SERVICE_CONTROL_INTERROGATE:
|
|
|
|
break;
|
|
|
|
case SERVICE_CONTROL_POWEREVENT:
|
|
|
|
switch ( dwEventType ) {
|
|
|
|
case PBT_APMRESUMEAUTOMATIC:
|
|
case PBT_APMRESUMECRITICAL:
|
|
case PBT_APMRESUMESUSPEND:
|
|
// Notify IKE of power event, ignore error
|
|
if (gbIKENotify) {
|
|
IKENotifyPolicyChange(NULL,POLICY_GUID_POWEREVENT_RESUME);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
(void) IPSecSPDUpdateStatus();
|
|
|
|
return (dwErr);
|
|
}
|
|
|
|
|
|
VOID
|
|
IPSecSPDShutdown(
|
|
IN DWORD dwErrorCode
|
|
)
|
|
{
|
|
BOOL bMachineShutdown = FALSE;
|
|
|
|
TRACE(TRC_INFORMATION, (L"PolicyAgent shutting down."));
|
|
|
|
bMachineShutdown = gdwShutdownFlags & SPD_SHUTDOWN_MACHINE;
|
|
|
|
gbIKENotify = FALSE;
|
|
(VOID) DeleteAllPolicyInformation();
|
|
|
|
ClearPolicyStateBlock(
|
|
gpIpsecPolicyState
|
|
);
|
|
|
|
if (gbLoadedISAKMPDefaults) {
|
|
UnLoadDefaultISAKMPInformation(gpszDefaultISAKMPPolicyDN);
|
|
}
|
|
|
|
ClearPAStoreGlobals();
|
|
|
|
//
|
|
// Service stop still pending.
|
|
// Increment checkpoint counter and update
|
|
// the status with the Service Control Manager.
|
|
//
|
|
|
|
(IPSecSPDStatus.dwCheckPoint)++;
|
|
|
|
(void) IPSecSPDUpdateStatus();
|
|
|
|
if (gbSPDRPCServerUp) {
|
|
gbSPDRPCServerUp = FALSE;
|
|
SPDStopRPCServer();
|
|
}
|
|
|
|
if (gbIsIKEUp) {
|
|
gbIsIKEUp = FALSE;
|
|
if (bMachineShutdown) {
|
|
IKEShutdown(SPD_SHUTDOWN_MACHINE);
|
|
} else {
|
|
IKEShutdown(SPD_SHUTDOWN_SERVICE);
|
|
}
|
|
}
|
|
|
|
if (gpIniMMPolicy) {
|
|
FreeIniMMPolicyList(gpIniMMPolicy);
|
|
gpIniMMPolicy = NULL;
|
|
}
|
|
|
|
if (gpIniMMAuthMethods) {
|
|
FreeIniMMAuthMethodsList(gpIniMMAuthMethods);
|
|
gpIniMMAuthMethods = NULL;
|
|
}
|
|
|
|
if (gpIniQMPolicy) {
|
|
FreeIniQMPolicyList(gpIniQMPolicy);
|
|
gpIniQMPolicy = NULL;
|
|
}
|
|
|
|
if (gpIniMMSFilter) {
|
|
FreeIniMMSFilterList(gpIniMMSFilter);
|
|
gpIniMMSFilter = NULL;
|
|
}
|
|
|
|
if (gpMMFilterHandle) {
|
|
FreeMMFilterHandleList(gpMMFilterHandle);
|
|
gpMMFilterHandle = NULL;
|
|
}
|
|
|
|
if (gpIniMMFilter) {
|
|
FreeIniMMFilterList(gpIniMMFilter);
|
|
gpIniMMFilter = NULL;
|
|
}
|
|
|
|
if (gpIniTxSFilter) {
|
|
// Following call will check gShutdownFlags and
|
|
// not delete ipsec filters if shutting down machine
|
|
(VOID) DeleteTransportFiltersFromIPSec(gpIniTxSFilter);
|
|
|
|
FreeIniTxSFilterList(gpIniTxSFilter);
|
|
gpIniTxSFilter = NULL;
|
|
}
|
|
|
|
if (gpTxFilterHandle) {
|
|
FreeTxFilterHandleList(gpTxFilterHandle);
|
|
gpTxFilterHandle = NULL;
|
|
}
|
|
|
|
if (gpIniTxFilter) {
|
|
FreeIniTxFilterList(gpIniTxFilter);
|
|
gpIniTxFilter = NULL;
|
|
}
|
|
|
|
if (gpIniTnSFilter) {
|
|
// Following call will check gShutdownFlags and
|
|
// not delete ipsec filters if shutting down machine
|
|
(VOID) DeleteTunnelFiltersFromIPSec(gpIniTnSFilter);
|
|
|
|
FreeIniTnSFilterList(gpIniTnSFilter);
|
|
gpIniTnSFilter = NULL;
|
|
}
|
|
|
|
if (gpTnFilterHandle) {
|
|
FreeTnFilterHandleList(gpTnFilterHandle);
|
|
gpTnFilterHandle = NULL;
|
|
}
|
|
|
|
if (gpIniTnFilter) {
|
|
FreeIniTnFilterList(gpIniTnFilter);
|
|
gpIniTnFilter = NULL;
|
|
}
|
|
|
|
if (!bMachineShutdown) {
|
|
(VOID) SPDRegisterIPSecDriverProtocols(
|
|
(DWORD) IPSEC_DEREGISTER_PROTOCOLS
|
|
);
|
|
}
|
|
|
|
if (ghIPSecDriver != INVALID_HANDLE_VALUE) {
|
|
SPDCloseIPSecDriver(ghIPSecDriver);
|
|
ghIPSecDriver = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
if (gpInterfaceList) {
|
|
DestroyInterfaceList(
|
|
gpInterfaceList
|
|
);
|
|
gpInterfaceList = NULL;
|
|
}
|
|
|
|
if (gpSpecialAddrsList) {
|
|
FreeSpecialAddrList(
|
|
&gpSpecialAddrsList
|
|
);
|
|
gpSpecialAddrsList = NULL;
|
|
}
|
|
|
|
ClearSPDGlobals();
|
|
|
|
IPSecSPDStatus.dwCurrentState = SERVICE_STOPPED;
|
|
IPSecSPDStatus.dwControlsAccepted = 0;
|
|
IPSecSPDStatus.dwCheckPoint = 0;
|
|
IPSecSPDStatus.dwWaitHint = 0;
|
|
IPSecSPDStatus.dwWin32ExitCode = dwErrorCode;
|
|
IPSecSPDStatus.dwServiceSpecificExitCode = 0;
|
|
|
|
(void) IPSecSPDUpdateStatus();
|
|
|
|
WPP_CLEANUP();
|
|
return;
|
|
}
|
|
|
|
|
|
VOID
|
|
ClearSPDGlobals(
|
|
)
|
|
{
|
|
DestroyInterfaceChangeEvent();
|
|
|
|
if (gbSPDSection) {
|
|
DeleteCriticalSection(&gcSPDSection);
|
|
}
|
|
|
|
if (gbServerListenSection == TRUE) {
|
|
DeleteCriticalSection(&gcServerListenSection);
|
|
}
|
|
|
|
if (ghServiceStopEvent) {
|
|
CloseHandle(ghServiceStopEvent);
|
|
ghServiceStopEvent = NULL;
|
|
}
|
|
|
|
if (ghNewDSPolicyEvent) {
|
|
CloseHandle(ghNewDSPolicyEvent);
|
|
ghNewDSPolicyEvent = NULL;
|
|
}
|
|
|
|
if (ghNewLocalPolicyEvent) {
|
|
CloseHandle(ghNewLocalPolicyEvent);
|
|
ghNewLocalPolicyEvent = NULL;
|
|
}
|
|
|
|
if (ghForcedPolicyReloadEvent) {
|
|
CloseHandle(ghForcedPolicyReloadEvent);
|
|
ghForcedPolicyReloadEvent = NULL;
|
|
}
|
|
|
|
if (ghPolicyChangeNotifyEvent) {
|
|
CloseHandle(ghPolicyChangeNotifyEvent);
|
|
ghPolicyChangeNotifyEvent = NULL;
|
|
}
|
|
|
|
if (ghGpupdateRefreshEvent) {
|
|
CloseHandle(ghGpupdateRefreshEvent);
|
|
ghGpupdateRefreshEvent = NULL;
|
|
}
|
|
|
|
if (gbSPDAuditSection) {
|
|
DeleteCriticalSection(&gcSPDAuditSection);
|
|
}
|
|
gbAuditingInitialized = FALSE;
|
|
|
|
if (gpSPDSD) {
|
|
LocalFree(gpSPDSD);
|
|
gpSPDSD = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
ClearPAStoreGlobals(
|
|
)
|
|
{
|
|
if (gpMMFilterState) {
|
|
PAFreeMMFilterStateList(gpMMFilterState);
|
|
gpMMFilterState = NULL;
|
|
}
|
|
|
|
if (gpMMPolicyState) {
|
|
PAFreeMMPolicyStateList(gpMMPolicyState);
|
|
gpMMPolicyState = NULL;
|
|
}
|
|
|
|
if (gpMMAuthState) {
|
|
PAFreeMMAuthStateList(gpMMAuthState);
|
|
gpMMAuthState = NULL;
|
|
}
|
|
|
|
if (gpTxFilterState) {
|
|
PAFreeTxFilterStateList(gpTxFilterState);
|
|
gpTxFilterState = NULL;
|
|
}
|
|
|
|
if (gpTnFilterState) {
|
|
PAFreeTnFilterStateList(gpTnFilterState);
|
|
gpTnFilterState = NULL;
|
|
}
|
|
|
|
if (gpQMPolicyState) {
|
|
PAFreeQMPolicyStateList(gpQMPolicyState);
|
|
gpQMPolicyState = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
InitMiscGlobals(
|
|
)
|
|
{
|
|
//
|
|
// Init globals that aren't cleared on service stop to make sure
|
|
// everything's in a known state on start. This allows us to
|
|
// stop/restart without having our DLL unloaded/reloaded first.
|
|
//
|
|
|
|
gbSPDRPCServerUp = FALSE;
|
|
ghServiceStopEvent = NULL;
|
|
gdwServersListening = 0;
|
|
gbServerListenSection = FALSE;
|
|
|
|
gpInterfaceList = NULL;
|
|
gpSpecialAddrsList = NULL;
|
|
gbwsaStarted = FALSE;
|
|
gIfChangeEventSocket = INVALID_SOCKET;
|
|
ghIfChangeEvent = NULL;
|
|
ghOverlapEvent = NULL;
|
|
|
|
gpIniTxFilter = NULL;
|
|
gpIniTxSFilter = NULL;
|
|
gpTxFilterHandle = NULL;
|
|
|
|
gbSPDSection = FALSE;
|
|
|
|
gpIniQMPolicy = NULL;
|
|
gpIniDefaultQMPolicy = NULL;
|
|
|
|
gpIniMMPolicy = NULL;
|
|
gpIniDefaultMMPolicy = NULL;
|
|
|
|
gpIniMMFilter = NULL;
|
|
gpIniMMSFilter = NULL;
|
|
gpMMFilterHandle = NULL;
|
|
|
|
gpIniMMAuthMethods = NULL;
|
|
gpIniDefaultMMAuthMethods = NULL;
|
|
|
|
gpIpsecPolicyState = &gIpsecPolicyState;
|
|
gCurrentPollingInterval = 0;
|
|
gDefaultPollingInterval = 166*60; // (seconds).
|
|
gdwRetryCount = 0;
|
|
gpszIpsecDSPolicyKey = L"SOFTWARE\\Policies\\Microsoft\\Windows\\IPSec\\GPTIPSECPolicy";
|
|
gpszIpsecLocalPolicyKey = L"SOFTWARE\\Policies\\Microsoft\\Windows\\IPSec\\Policy\\Local";
|
|
gpszIpsecPersistentPolicyKey = L"SOFTWARE\\Policies\\Microsoft\\Windows\\IPSec\\Policy\\Persistent";
|
|
gpszIpsecCachePolicyKey = L"SOFTWARE\\Policies\\Microsoft\\Windows\\IPSec\\Policy\\Cache";
|
|
gpszDefaultISAKMPPolicyDN = L"SOFTWARE\\Policies\\Microsoft\\Windows\\IPSec\\Policy\\Local\\ipsecISAKMPPolicy{72385234-70FA-11D1-864C-14A300000000}";
|
|
gpszLocPolicyAgent = L"SYSTEM\\CurrentControlSet\\Services\\PolicyAgent";
|
|
ghNewDSPolicyEvent = NULL;
|
|
ghNewLocalPolicyEvent = NULL;
|
|
ghForcedPolicyReloadEvent = NULL;
|
|
ghPolicyChangeNotifyEvent = NULL;
|
|
ghGpupdateRefreshEvent = NULL;
|
|
gbLoadedISAKMPDefaults = FALSE;
|
|
|
|
gpMMPolicyState = NULL;
|
|
gpMMAuthState = NULL;
|
|
gpMMFilterState = NULL;
|
|
gdwMMPolicyCounter = 0;
|
|
gdwMMFilterCounter = 0;
|
|
gpQMPolicyState = NULL;
|
|
gdwQMPolicyCounter = 0;
|
|
gpTxFilterState = NULL;
|
|
gdwTxFilterCounter = 0;
|
|
|
|
gpIniTnFilter = NULL;
|
|
gpIniTnSFilter = NULL;
|
|
gpTnFilterHandle = NULL;
|
|
gpTnFilterState = NULL;
|
|
gdwTnFilterCounter = 0;
|
|
|
|
gbIsIKEUp = FALSE;
|
|
gpSPDSD = NULL;
|
|
gbIKENotify = FALSE;
|
|
ghIPSecDriver = INVALID_HANDLE_VALUE;
|
|
|
|
gbSPDAuditSection = FALSE;
|
|
ghIpsecServerModule = NULL;
|
|
gbAuditingInitialized = FALSE;
|
|
gbIsIoctlPended = FALSE;
|
|
|
|
gbBackwardSoftSA = FALSE;
|
|
|
|
gdwShutdownFlags = 0;
|
|
|
|
gbPersistentPolicyApplied = FALSE;
|
|
return;
|
|
}
|
|
|
|
DWORD
|
|
QuerySpdPolicyState(
|
|
LPWSTR pServerName,
|
|
DWORD dwVersion,
|
|
PSPD_POLICY_STATE * ppSpdPolicyState,
|
|
LPVOID pvReserved
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
PSPD_POLICY_STATE pSpdPolicyState = NULL;
|
|
|
|
dwError = SPDApiBufferAllocate(
|
|
sizeof(SPD_POLICY_STATE),
|
|
&pSpdPolicyState
|
|
);
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
|
|
ENTER_SPD_SECTION();
|
|
dwError = ValidateSecurity(
|
|
SPD_OBJECT_SERVER,
|
|
SERVER_ACCESS_ADMINISTER,
|
|
NULL,
|
|
NULL
|
|
);
|
|
BAIL_ON_LOCK_ERROR(dwError);
|
|
|
|
pSpdPolicyState->PolicyLoadState = gpIpsecPolicyState->CurrentState;
|
|
|
|
switch (gpIpsecPolicyState->CurrentState) {
|
|
case SPD_STATE_DS_APPLY_SUCCESS:
|
|
pSpdPolicyState->dwWhenChanged = gpIpsecPolicyState->DSIncarnationNumber;
|
|
break;
|
|
case SPD_STATE_LOCAL_APPLY_SUCCESS:
|
|
case SPD_STATE_CACHE_APPLY_SUCCESS:
|
|
pSpdPolicyState->dwWhenChanged = gpIpsecPolicyState->RegIncarnationNumber;
|
|
break;
|
|
case SPD_STATE_PERSISTENT_APPLY_SUCCESS:
|
|
pSpdPolicyState->dwWhenChanged = gpIpsecPolicyState->PersIncarnationNumber;
|
|
break;
|
|
default:
|
|
pSpdPolicyState->dwWhenChanged = 0;
|
|
break;
|
|
}
|
|
LEAVE_SPD_SECTION();
|
|
|
|
*ppSpdPolicyState = pSpdPolicyState;
|
|
return (dwError);
|
|
|
|
lock:
|
|
|
|
LEAVE_SPD_SECTION();
|
|
|
|
error:
|
|
if (pSpdPolicyState) {
|
|
SPDApiBufferFree(pSpdPolicyState);
|
|
}
|
|
|
|
*ppSpdPolicyState = NULL;
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
DWORD
|
|
SetSpdStateOnError(
|
|
DWORD dwPolicySource,
|
|
SPD_ACTION SpdAction,
|
|
DWORD ActionError,
|
|
SPD_STATE * pSpdState
|
|
)
|
|
{
|
|
SPD_STATE SpdPolicyState = 0;
|
|
DWORD dwError = ERROR_SUCCESS;
|
|
|
|
if (!pSpdState) {
|
|
dwError = ERROR_INVALID_PARAMETER;
|
|
BAIL_ON_WIN32_ERROR(dwError);
|
|
}
|
|
|
|
// Collapse triplet into one flag:
|
|
// Long-winded, but by doing it like this we simplify readability
|
|
// of other parts of code.
|
|
|
|
if (!ActionError) {
|
|
if (SpdAction == SPD_POLICY_APPLY) {
|
|
switch(dwPolicySource) {
|
|
case IPSEC_SOURCE_PERSISTENT:
|
|
SpdPolicyState = SPD_STATE_PERSISTENT_APPLY_SUCCESS;
|
|
break;
|
|
case IPSEC_SOURCE_LOCAL:
|
|
SpdPolicyState = SPD_STATE_LOCAL_APPLY_SUCCESS;
|
|
break;
|
|
case IPSEC_SOURCE_DOMAIN:
|
|
SpdPolicyState = SPD_STATE_DS_APPLY_SUCCESS;
|
|
break;
|
|
case IPSEC_SOURCE_CACHE:
|
|
SpdPolicyState = SPD_STATE_CACHE_APPLY_SUCCESS;
|
|
break;
|
|
}
|
|
} else if (SpdAction == SPD_POLICY_LOAD) {
|
|
switch(dwPolicySource) {
|
|
case IPSEC_SOURCE_PERSISTENT:
|
|
SpdPolicyState = SPD_STATE_PERSISTENT_LOAD_SUCCESS;
|
|
break;
|
|
case IPSEC_SOURCE_LOCAL:
|
|
SpdPolicyState = SPD_STATE_LOCAL_LOAD_SUCCESS;
|
|
break;
|
|
case IPSEC_SOURCE_DOMAIN:
|
|
SpdPolicyState = SPD_STATE_DS_LOAD_SUCCESS;
|
|
break;
|
|
case IPSEC_SOURCE_CACHE:
|
|
SpdPolicyState = SPD_STATE_CACHE_LOAD_SUCCESS;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
if (SpdAction == SPD_POLICY_APPLY) {
|
|
switch(dwPolicySource) {
|
|
case IPSEC_SOURCE_PERSISTENT:
|
|
SpdPolicyState = SPD_STATE_PERSISTENT_APPLY_FAIL;
|
|
break;
|
|
case IPSEC_SOURCE_LOCAL:
|
|
SpdPolicyState = SPD_STATE_LOCAL_APPLY_FAIL;
|
|
break;
|
|
case IPSEC_SOURCE_DOMAIN:
|
|
SpdPolicyState = SPD_STATE_DS_APPLY_FAIL;
|
|
break;
|
|
case IPSEC_SOURCE_CACHE:
|
|
SpdPolicyState = SPD_STATE_CACHE_APPLY_FAIL;
|
|
break;
|
|
}
|
|
} else if (SpdAction == SPD_POLICY_LOAD) {
|
|
switch(dwPolicySource) {
|
|
case IPSEC_SOURCE_PERSISTENT:
|
|
SpdPolicyState = SPD_STATE_PERSISTENT_LOAD_FAIL;
|
|
break;
|
|
case IPSEC_SOURCE_LOCAL:
|
|
SpdPolicyState = SPD_STATE_LOCAL_LOAD_FAIL;
|
|
break;
|
|
case IPSEC_SOURCE_DOMAIN:
|
|
SpdPolicyState = SPD_STATE_DS_LOAD_FAIL;
|
|
break;
|
|
case IPSEC_SOURCE_CACHE:
|
|
SpdPolicyState = SPD_STATE_CACHE_LOAD_FAIL;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
(*pSpdState) = SpdPolicyState;
|
|
|
|
error:
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
BOOL
|
|
InAcceptableState(
|
|
SPD_STATE SpdState
|
|
)
|
|
{
|
|
BOOL AcceptableState = FALSE;
|
|
|
|
switch (SpdState) {
|
|
case SPD_STATE_LOCAL_APPLY_SUCCESS:
|
|
case SPD_STATE_DS_APPLY_SUCCESS:
|
|
case SPD_STATE_PERSISTENT_APPLY_SUCCESS:
|
|
case SPD_STATE_INITIAL:
|
|
AcceptableState = TRUE;
|
|
break;
|
|
}
|
|
|
|
return AcceptableState;
|
|
}
|