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.
 
 
 
 
 
 

448 lines
9.0 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"
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;
// Sleep(30000);
dwError = InitSPDThruRegistry();
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 = RegisterServiceCtrlHandlerW(
IPSECSPD_SERVICE,
IPSecSPDControlHandler
);
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;
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
);
//
// Open the IPSec Driver.
//
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);
(VOID) LoadPersistedIPSecInformation();
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
);
}
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
);
}
BAIL_ON_WIN32_ERROR(dwError);
dwError = ServiceWait();
error:
IPSecSPDShutdown(dwError);
return;
}
DWORD
IPSecSPDUpdateStatus(
)
{
DWORD dwError = 0;
if (!SetServiceStatus(IPSecSPDStatusHandle, &IPSecSPDStatus)) {
dwError = GetLastError();
}
return (dwError);
}
VOID
IPSecSPDControlHandler(
IN DWORD dwOpCode
)
{
switch (dwOpCode)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
if (IPSecSPDStatus.dwCurrentState != SERVICE_STOP_PENDING) {
IPSecSPDStatus.dwCurrentState = SERVICE_STOP_PENDING;
IPSecSPDStatus.dwCheckPoint = 1;
IPSecSPDStatus.dwWaitHint = 60000;
(void) IPSecSPDUpdateStatus();
SetEvent(ghServiceStopEvent);
return;
}
break;
case SERVICE_CONTROL_NEW_LOCAL_POLICY:
SetEvent(ghNewLocalPolicyEvent);
break;
case SERVICE_CONTROL_FORCED_POLICY_RELOAD:
SetEvent(ghForcedPolicyReloadEvent);
break;
case SERVICE_CONTROL_INTERROGATE:
break;
}
(void) IPSecSPDUpdateStatus();
return;
}
VOID
IPSecSPDShutdown(
IN DWORD dwErrorCode
)
{
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;
IKEShutdown();
}
if (gpIniMMPolicy) {
FreeIniMMPolicyList(gpIniMMPolicy);
}
if (gpIniMMAuthMethods) {
FreeIniMMAuthMethodsList(gpIniMMAuthMethods);
}
if (gpIniQMPolicy) {
FreeIniQMPolicyList(gpIniQMPolicy);
}
if (gpIniMMSFilter) {
FreeIniMMSFilterList(gpIniMMSFilter);
}
if (gpMMFilterHandle) {
FreeMMFilterHandleList(gpMMFilterHandle);
}
if (gpIniMMFilter) {
FreeIniMMFilterList(gpIniMMFilter);
}
if (gpIniTxSFilter) {
(VOID) DeleteTransportFiltersFromIPSec(gpIniTxSFilter);
FreeIniTxSFilterList(gpIniTxSFilter);
}
if (gpTxFilterHandle) {
FreeTxFilterHandleList(gpTxFilterHandle);
}
if (gpIniTxFilter) {
FreeIniTxFilterList(gpIniTxFilter);
}
if (gpIniTnSFilter) {
(VOID) DeleteTunnelFiltersFromIPSec(gpIniTnSFilter);
FreeIniTnSFilterList(gpIniTnSFilter);
}
if (gpTnFilterHandle) {
FreeTnFilterHandleList(gpTnFilterHandle);
}
if (gpIniTnFilter) {
FreeIniTnFilterList(gpIniTnFilter);
}
(VOID) SPDRegisterIPSecDriverProtocols(
(DWORD) IPSEC_DEREGISTER_PROTOCOLS
);
if (ghIPSecDriver != INVALID_HANDLE_VALUE) {
SPDCloseIPSecDriver(ghIPSecDriver);
}
if (gpInterfaceList) {
DestroyInterfaceList(
gpInterfaceList
);
}
ClearSPDGlobals();
IPSecSPDStatus.dwCurrentState = SERVICE_STOPPED;
IPSecSPDStatus.dwControlsAccepted = 0;
IPSecSPDStatus.dwCheckPoint = 0;
IPSecSPDStatus.dwWaitHint = 0;
IPSecSPDStatus.dwWin32ExitCode = dwErrorCode;
IPSecSPDStatus.dwServiceSpecificExitCode = 0;
(void) IPSecSPDUpdateStatus();
return;
}
VOID
ClearSPDGlobals(
)
{
DestroyInterfaceChangeEvent();
if (gbSPDSection) {
DeleteCriticalSection(&gcSPDSection);
}
if (gbServerListenSection == TRUE) {
DeleteCriticalSection(&gcServerListenSection);
}
if (ghServiceStopEvent) {
CloseHandle(ghServiceStopEvent);
}
if (ghNewDSPolicyEvent) {
CloseHandle(ghNewDSPolicyEvent);
}
if (ghNewLocalPolicyEvent) {
CloseHandle(ghNewLocalPolicyEvent);
}
if (ghForcedPolicyReloadEvent) {
CloseHandle(ghForcedPolicyReloadEvent);
}
if (ghPolicyChangeNotifyEvent) {
CloseHandle(ghPolicyChangeNotifyEvent);
}
if (gbSPDAuditSection) {
DeleteCriticalSection(&gcSPDAuditSection);
}
if (gpSPDSD) {
LocalFree(gpSPDSD);
}
}
VOID
ClearPAStoreGlobals(
)
{
if (gpMMFilterState) {
PAFreeMMFilterStateList(gpMMFilterState);
}
if (gpMMPolicyState) {
PAFreeMMPolicyStateList(gpMMPolicyState);
}
if (gpMMAuthState) {
PAFreeMMAuthStateList(gpMMAuthState);
}
if (gpTxFilterState) {
PAFreeTxFilterStateList(gpTxFilterState);
}
if (gpTnFilterState) {
PAFreeTnFilterStateList(gpTnFilterState);
}
if (gpQMPolicyState) {
PAFreeQMPolicyStateList(gpQMPolicyState);
}
}