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.
377 lines
8.6 KiB
377 lines
8.6 KiB
/*++
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
|
|
Module Name:
|
|
|
|
loopmgr.c
|
|
|
|
Abstract:
|
|
|
|
This module contains all of the code to drive the
|
|
Loop Manager of IPSecSPD Service.
|
|
|
|
Author:
|
|
|
|
abhisheV 30-September-1999
|
|
|
|
Environment
|
|
|
|
User Level: Win32
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
|
|
|
|
enum {
|
|
SERVICE_STOP_EVENT = 0,
|
|
INTERFACE_CHANGE_EVENT,
|
|
NEW_LOCAL_POLICY_EVENT,
|
|
NEW_DS_POLICY_EVENT,
|
|
FORCED_POLICY_RELOAD_EVENT,
|
|
WAIT_EVENT_COUNT,
|
|
};
|
|
|
|
|
|
DWORD
|
|
ServiceWait(
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
HANDLE hWaitForEvents[WAIT_EVENT_COUNT];
|
|
BOOL bDoneWaiting = FALSE;
|
|
DWORD dwWaitMilliseconds = 0;
|
|
DWORD dwStatus = 0;
|
|
time_t LastTimeOutTime = 0;
|
|
|
|
|
|
AuditEvent(
|
|
SE_CATEGID_POLICY_CHANGE,
|
|
SE_AUDITID_IPSEC_POLICY_CHANGED,
|
|
IPSECSVC_SUCCESSFUL_START,
|
|
NULL,
|
|
TRUE,
|
|
TRUE
|
|
);
|
|
|
|
hWaitForEvents[SERVICE_STOP_EVENT] = ghServiceStopEvent;
|
|
hWaitForEvents[INTERFACE_CHANGE_EVENT] = GetInterfaceChangeEvent();
|
|
hWaitForEvents[NEW_LOCAL_POLICY_EVENT] = ghNewLocalPolicyEvent;
|
|
hWaitForEvents[NEW_DS_POLICY_EVENT] = ghNewDSPolicyEvent;
|
|
hWaitForEvents[FORCED_POLICY_RELOAD_EVENT] = ghForcedPolicyReloadEvent;
|
|
|
|
|
|
//
|
|
// First load the default main mode policy.
|
|
//
|
|
|
|
(VOID) LoadDefaultISAKMPInformation(
|
|
gpszDefaultISAKMPPolicyDN
|
|
);
|
|
|
|
|
|
//
|
|
// Initialize Policy State Block.
|
|
//
|
|
|
|
InitializePolicyStateBlock(
|
|
gpIpsecPolicyState
|
|
);
|
|
|
|
|
|
//
|
|
// Call the Polling Manager for the first time.
|
|
//
|
|
|
|
(VOID) StartStatePollingManager(
|
|
gpIpsecPolicyState
|
|
);
|
|
|
|
|
|
NotifyIpsecPolicyChange();
|
|
|
|
|
|
ComputeRelativePollingTime(
|
|
LastTimeOutTime,
|
|
TRUE,
|
|
&dwWaitMilliseconds
|
|
);
|
|
|
|
|
|
time(&LastTimeOutTime);
|
|
|
|
|
|
while (!bDoneWaiting) {
|
|
|
|
dwStatus = WaitForMultipleObjects(
|
|
WAIT_EVENT_COUNT,
|
|
hWaitForEvents,
|
|
FALSE,
|
|
dwWaitMilliseconds
|
|
);
|
|
|
|
PADeleteInUsePolicies();
|
|
|
|
switch (dwStatus) {
|
|
|
|
case SERVICE_STOP_EVENT:
|
|
|
|
dwError = ERROR_SUCCESS;
|
|
bDoneWaiting = TRUE;
|
|
break;
|
|
|
|
case INTERFACE_CHANGE_EVENT:
|
|
|
|
(VOID) OnInterfaceChangeEvent(
|
|
);
|
|
(VOID) IKEInterfaceChange();
|
|
break;
|
|
|
|
case NEW_LOCAL_POLICY_EVENT:
|
|
|
|
ResetEvent(ghNewLocalPolicyEvent);
|
|
if ((gpIpsecPolicyState->dwCurrentState != POLL_STATE_DS_DOWNLOADED) &&
|
|
(gpIpsecPolicyState->dwCurrentState != POLL_STATE_CACHE_DOWNLOADED)) {
|
|
(VOID) ProcessLocalPolicyPollState(
|
|
gpIpsecPolicyState
|
|
);
|
|
NotifyIpsecPolicyChange();
|
|
}
|
|
break;
|
|
|
|
case NEW_DS_POLICY_EVENT:
|
|
|
|
ResetEvent(ghNewDSPolicyEvent);
|
|
(VOID) OnPolicyChanged(
|
|
gpIpsecPolicyState
|
|
);
|
|
NotifyIpsecPolicyChange();
|
|
break;
|
|
|
|
case FORCED_POLICY_RELOAD_EVENT:
|
|
|
|
ResetEvent(ghForcedPolicyReloadEvent);
|
|
(VOID) OnPolicyChanged(
|
|
gpIpsecPolicyState
|
|
);
|
|
NotifyIpsecPolicyChange();
|
|
AuditEvent(
|
|
SE_CATEGID_POLICY_CHANGE,
|
|
SE_AUDITID_IPSEC_POLICY_CHANGED,
|
|
PASTORE_FORCED_POLICY_RELOAD,
|
|
NULL,
|
|
TRUE,
|
|
TRUE
|
|
);
|
|
break;
|
|
|
|
case WAIT_TIMEOUT:
|
|
|
|
time(&LastTimeOutTime);
|
|
(VOID) OnPolicyPoll(
|
|
gpIpsecPolicyState
|
|
);
|
|
break;
|
|
|
|
case WAIT_FAILED:
|
|
|
|
dwError = GetLastError();
|
|
bDoneWaiting = TRUE;
|
|
break;
|
|
|
|
default:
|
|
|
|
dwError = ERROR_INVALID_EVENT_COUNT;
|
|
bDoneWaiting = TRUE;
|
|
break;
|
|
|
|
}
|
|
|
|
ComputeRelativePollingTime(
|
|
LastTimeOutTime,
|
|
FALSE,
|
|
&dwWaitMilliseconds
|
|
);
|
|
|
|
}
|
|
|
|
if (!dwError) {
|
|
AuditEvent(
|
|
SE_CATEGID_POLICY_CHANGE,
|
|
SE_AUDITID_IPSEC_POLICY_CHANGED,
|
|
IPSECSVC_SUCCESSFUL_SHUTDOWN,
|
|
NULL,
|
|
TRUE,
|
|
TRUE
|
|
);
|
|
}
|
|
else {
|
|
AuditOneArgErrorEvent(
|
|
SE_CATEGID_POLICY_CHANGE,
|
|
SE_AUDITID_IPSEC_POLICY_CHANGED,
|
|
IPSECSVC_ERROR_SHUTDOWN,
|
|
dwError,
|
|
FALSE,
|
|
TRUE
|
|
);
|
|
}
|
|
|
|
return (dwError);
|
|
}
|
|
|
|
|
|
VOID
|
|
ComputeRelativePollingTime(
|
|
time_t LastTimeOutTime,
|
|
BOOL bInitialLoad,
|
|
PDWORD pWaitMilliseconds
|
|
)
|
|
{
|
|
DWORD WaitMilliseconds = 0;
|
|
DWORD DSReconnectMilliseconds = 0;
|
|
time_t NextTimeOutTime = 0;
|
|
time_t PresentTime = 0;
|
|
long WaitSeconds = gDefaultPollingInterval;
|
|
|
|
|
|
WaitMilliseconds = gCurrentPollingInterval * 1000;
|
|
|
|
if (!WaitMilliseconds) {
|
|
WaitMilliseconds = INFINITE;
|
|
}
|
|
|
|
DSReconnectMilliseconds = gdwDSConnectivityCheck*60*1000;
|
|
|
|
if ((gpIpsecPolicyState->dwCurrentState != POLL_STATE_DS_DOWNLOADED) &&
|
|
(gpIpsecPolicyState->dwCurrentState != POLL_STATE_LOCAL_DOWNLOADED)) {
|
|
if (WaitMilliseconds > DSReconnectMilliseconds) {
|
|
WaitMilliseconds = DSReconnectMilliseconds;
|
|
}
|
|
}
|
|
|
|
if (!bInitialLoad && WaitMilliseconds != INFINITE) {
|
|
|
|
//
|
|
// LastTimeOutTime is the snapshot time value in the past when
|
|
// we timed out waiting for multiple events.
|
|
// Ideally, the time for the next time out, NextTimeOutTime, is
|
|
// the time value in future which is sum of the last time when
|
|
// we timed out + the current waiting time value.
|
|
//
|
|
|
|
NextTimeOutTime = LastTimeOutTime + (WaitMilliseconds/1000);
|
|
|
|
//
|
|
// However, the last time we may not have timed out waiting
|
|
// for multiple events but rather came out because one of the
|
|
// events other than WAIT_TIMEOUT happened.
|
|
// However, on that event we may not have done a policy
|
|
// poll to figure out whether there was a policy change or
|
|
// not. If we again wait for WaitMilliseconds, then we are
|
|
// un-knowingly making our net time for policy poll greater
|
|
// than the alloted time interval value = WaitMilliseconds.
|
|
// So, we need to adjust the WaitMilliseconds to such a value
|
|
// that no matter what happens, we always do a policy poll
|
|
// atmost every WaitMilliseconds time interval value.
|
|
// The current time is PresentTime.
|
|
//
|
|
|
|
time(&PresentTime);
|
|
|
|
WaitSeconds = (long) (NextTimeOutTime - PresentTime);
|
|
|
|
if (WaitSeconds < 0) {
|
|
WaitMilliseconds = 0;
|
|
}
|
|
else {
|
|
WaitMilliseconds = WaitSeconds * 1000;
|
|
}
|
|
|
|
}
|
|
|
|
*pWaitMilliseconds = WaitMilliseconds;
|
|
}
|
|
|
|
|
|
VOID
|
|
NotifyIpsecPolicyChange(
|
|
)
|
|
{
|
|
PulseEvent(ghPolicyChangeNotifyEvent);
|
|
|
|
SendPschedIoctl();
|
|
|
|
ResetEvent(ghPolicyChangeNotifyEvent);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
VOID
|
|
SendPschedIoctl(
|
|
)
|
|
{
|
|
HANDLE hPschedDriverHandle = NULL;
|
|
ULONG uBytesReturned = 0;
|
|
BOOL bIOStatus = FALSE;
|
|
|
|
|
|
#define DriverName TEXT("\\\\.\\PSCHED")
|
|
|
|
#define IOCTL_PSCHED_ZAW_EVENT CTL_CODE( \
|
|
FILE_DEVICE_NETWORK, \
|
|
20, \
|
|
METHOD_BUFFERED, \
|
|
FILE_ANY_ACCESS \
|
|
)
|
|
|
|
hPschedDriverHandle = CreateFile(
|
|
DriverName,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
|
|
NULL
|
|
);
|
|
|
|
if (hPschedDriverHandle != INVALID_HANDLE_VALUE) {
|
|
|
|
bIOStatus = DeviceIoControl(
|
|
hPschedDriverHandle,
|
|
IOCTL_PSCHED_ZAW_EVENT,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
0,
|
|
&uBytesReturned,
|
|
NULL
|
|
);
|
|
|
|
CloseHandle(hPschedDriverHandle);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
PADeleteInUsePolicies(
|
|
)
|
|
{
|
|
DWORD dwError = 0;
|
|
|
|
dwError = PADeleteInUseMMPolicies();
|
|
|
|
dwError = PADeleteInUseMMAuthMethods();
|
|
|
|
dwError = PADeleteInUseQMPolicies();
|
|
|
|
return;
|
|
}
|
|
|