mirror of https://github.com/tongzx/nt5src
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
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);
|
|
}
|
|
}
|
|
|