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.
337 lines
9.5 KiB
337 lines
9.5 KiB
/********************************************************************/
|
|
/* Copyright(c) 1995 Microsoft Corporation */
|
|
/********************************************************************/
|
|
|
|
//***
|
|
//
|
|
// Filename: evdsptch.c
|
|
//
|
|
// Description: This module contains the event dispatcher for the
|
|
// DDM's procedure-driven state machine
|
|
//
|
|
// Author: Stefan Solomon (stefans) June 9, 1992.
|
|
//
|
|
//***
|
|
#include "ddm.h"
|
|
#include "handlers.h"
|
|
#include "objects.h"
|
|
#include "timer.h"
|
|
#include "util.h"
|
|
#include <raserror.h>
|
|
#include <ddmif.h>
|
|
#include <sechost.h>
|
|
#include <stdlib.h>
|
|
#include "rasmanif.h"
|
|
|
|
//***
|
|
//
|
|
// Function: EventDispatcher
|
|
//
|
|
// Descr: Waits for events to be signaled and invokes the proper
|
|
// event handler. Returns when DDM has terminated.
|
|
//
|
|
//***
|
|
DWORD
|
|
EventDispatcher(
|
|
IN LPVOID arg
|
|
)
|
|
{
|
|
EVENT_HANDLER * pEventHandler;
|
|
DWORD dwSignaledEvent;
|
|
|
|
//
|
|
// Indicate that this thread is running
|
|
//
|
|
|
|
InterlockedIncrement( gblDDMConfigInfo.lpdwNumThreadsRunning );
|
|
|
|
RegNotifyChangeKeyValue( gblDDMConfigInfo.hkeyParameters,
|
|
TRUE,
|
|
REG_NOTIFY_CHANGE_LAST_SET,
|
|
gblSupervisorEvents[DDM_EVENT_CHANGE_NOTIFICATION],
|
|
TRUE );
|
|
RegNotifyChangeKeyValue( gblDDMConfigInfo.hkeyAccounting,
|
|
TRUE,
|
|
REG_NOTIFY_CHANGE_LAST_SET,
|
|
gblSupervisorEvents[DDM_EVENT_CHANGE_NOTIFICATION1],
|
|
TRUE );
|
|
|
|
RegNotifyChangeKeyValue( gblDDMConfigInfo.hkeyAuthentication,
|
|
TRUE,
|
|
REG_NOTIFY_CHANGE_LAST_SET,
|
|
gblSupervisorEvents[DDM_EVENT_CHANGE_NOTIFICATION2],
|
|
TRUE );
|
|
while( TRUE )
|
|
{
|
|
dwSignaledEvent = WaitForMultipleObjectsEx(
|
|
NUM_DDM_EVENTS
|
|
+ ( gblDeviceTable.NumDeviceBuckets * 3 ),
|
|
gblSupervisorEvents,
|
|
FALSE,
|
|
INFINITE,
|
|
TRUE);
|
|
|
|
if ( ( dwSignaledEvent == 0xFFFFFFFF ) ||
|
|
( dwSignaledEvent == WAIT_TIMEOUT ) )
|
|
{
|
|
DDMTRACE2("WaitForMultipleObjectsEx returned %d, GetLastError=%d",
|
|
dwSignaledEvent, GetLastError() );
|
|
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// DDM has terminated so return
|
|
//
|
|
|
|
if ( dwSignaledEvent == DDM_EVENT_SVC_TERMINATED )
|
|
{
|
|
LPDWORD lpdwNumThreadsRunning =
|
|
gblDDMConfigInfo.lpdwNumThreadsRunning;
|
|
|
|
//
|
|
// If we were running and we are now shutting down, clean up
|
|
// gracefully
|
|
//
|
|
|
|
if ( gblDDMConfigInfo.pServiceStatus->dwCurrentState
|
|
== SERVICE_STOP_PENDING )
|
|
{
|
|
DDMCleanUp();
|
|
}
|
|
|
|
//
|
|
// Decrease the count for this thread
|
|
//
|
|
|
|
InterlockedDecrement( lpdwNumThreadsRunning );
|
|
|
|
return( NO_ERROR );
|
|
}
|
|
|
|
//
|
|
// invoke the handler associated with the signaled event
|
|
//
|
|
|
|
if ( dwSignaledEvent < NUM_DDM_EVENTS )
|
|
{
|
|
//
|
|
// Some DDM event
|
|
//
|
|
|
|
gblEventHandlerTable[dwSignaledEvent].EventHandler();
|
|
}
|
|
else if ( dwSignaledEvent < ( NUM_DDM_EVENTS
|
|
+ gblDeviceTable.NumDeviceBuckets ) )
|
|
{
|
|
//
|
|
// The event was a RASMAN event
|
|
//
|
|
|
|
RmEventHandler( dwSignaledEvent );
|
|
}
|
|
else if ( dwSignaledEvent < ( NUM_DDM_EVENTS
|
|
+ gblDeviceTable.NumDeviceBuckets * 2 ) )
|
|
{
|
|
//
|
|
// A frame was received on a port
|
|
//
|
|
|
|
RmRecvFrameEventHandler( dwSignaledEvent );
|
|
}
|
|
else if ( dwSignaledEvent != WAIT_IO_COMPLETION )
|
|
{
|
|
//
|
|
// We got a disconnect on a dialed out port
|
|
//
|
|
|
|
RasApiDisconnectHandler( dwSignaledEvent );
|
|
}
|
|
}
|
|
|
|
return( NO_ERROR );
|
|
}
|
|
|
|
//***
|
|
//
|
|
// Function: SecurityDllEventHandler
|
|
//
|
|
// Descr: This will handle all events from the 3rd party security Dll.
|
|
// Either the security dialog with the client completed
|
|
// successfully, in which case we continue on with the connection,
|
|
// or we log the error and bring down the line.
|
|
//
|
|
//***
|
|
|
|
VOID
|
|
SecurityDllEventHandler(
|
|
VOID
|
|
)
|
|
{
|
|
LPWSTR auditstrp[3];
|
|
SECURITY_MESSAGE message;
|
|
PDEVICE_OBJECT pDevObj;
|
|
DWORD dwBucketIndex;
|
|
WCHAR wchUserName[UNLEN+1];
|
|
|
|
//
|
|
// loop to get all messages
|
|
//
|
|
|
|
while( ServerReceiveMessage( MESSAGEQ_ID_SECURITY, (BYTE *) &message ) )
|
|
{
|
|
|
|
EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
|
|
|
|
//
|
|
// identify the message recipient
|
|
//
|
|
|
|
if ( ( pDevObj = DeviceObjGetPointer( message.hPort ) ) == NULL )
|
|
{
|
|
|
|
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// action on the message type
|
|
//
|
|
|
|
switch( message.dwMsgId )
|
|
{
|
|
|
|
case SECURITYMSG_SUCCESS:
|
|
|
|
//
|
|
// Stop timer for 3rd party security
|
|
//
|
|
|
|
TimerQRemove( (HANDLE)pDevObj->hPort, SvSecurityTimeout );
|
|
|
|
if ( pDevObj->pRasmanSendBuffer != NULL )
|
|
{
|
|
RasFreeBuffer( pDevObj->pRasmanSendBuffer );
|
|
|
|
pDevObj->pRasmanSendBuffer = NULL;
|
|
}
|
|
|
|
//
|
|
// copy the user name
|
|
//
|
|
|
|
MultiByteToWideChar( CP_ACP,
|
|
0,
|
|
message.UserName,
|
|
-1,
|
|
pDevObj->wchUserName,
|
|
UNLEN+1 );
|
|
|
|
//
|
|
// copy the domain name
|
|
//
|
|
|
|
MultiByteToWideChar( CP_ACP,
|
|
0,
|
|
message.Domain,
|
|
-1,
|
|
pDevObj->wchDomainName,
|
|
DNLEN+1 );
|
|
|
|
pDevObj->SecurityState = DEV_OBJ_SECURITY_DIALOG_INACTIVE;
|
|
|
|
//
|
|
// Change RASMAN state to CONNECTED from LISTENCOMPLETE and signal
|
|
// RmEventHandler
|
|
//
|
|
|
|
RasPortConnectComplete(pDevObj->hPort);
|
|
|
|
dwBucketIndex = DeviceObjHashPortToBucket( pDevObj->hPort );
|
|
|
|
SetEvent( gblSupervisorEvents[NUM_DDM_EVENTS+dwBucketIndex] );
|
|
|
|
DDM_PRINT(
|
|
gblDDMConfigInfo.dwTraceId,
|
|
TRACE_FSM,
|
|
"SecurityDllEventHandler: Security DLL success \n" );
|
|
|
|
break;
|
|
|
|
case SECURITYMSG_FAILURE:
|
|
|
|
//
|
|
// Log the fact that the use failed to pass 3rd party security.
|
|
//
|
|
|
|
MultiByteToWideChar( CP_ACP,
|
|
0,
|
|
message.UserName,
|
|
-1,
|
|
wchUserName,
|
|
UNLEN+1 );
|
|
|
|
auditstrp[0] = wchUserName;
|
|
auditstrp[1] = pDevObj->wchPortName;
|
|
|
|
DDMLogError( ROUTERLOG_SEC_AUTH_FAILURE, 2, auditstrp, NO_ERROR );
|
|
|
|
//
|
|
// Hang up the line
|
|
//
|
|
|
|
DDM_PRINT(
|
|
gblDDMConfigInfo.dwTraceId,
|
|
TRACE_FSM,
|
|
"SecurityDllEventHandler:Security DLL failure %s\n",
|
|
message.UserName );
|
|
|
|
if ( pDevObj->SecurityState == DEV_OBJ_SECURITY_DIALOG_ACTIVE )
|
|
{
|
|
DevStartClosing(pDevObj);
|
|
}
|
|
else if ( pDevObj->SecurityState==DEV_OBJ_SECURITY_DIALOG_STOPPING )
|
|
{
|
|
pDevObj->SecurityState = DEV_OBJ_SECURITY_DIALOG_INACTIVE;
|
|
|
|
DevCloseComplete(pDevObj);
|
|
}
|
|
|
|
break;
|
|
|
|
case SECURITYMSG_ERROR:
|
|
|
|
auditstrp[0] = pDevObj->wchPortName;
|
|
|
|
DDMLogErrorString( ROUTERLOG_SEC_AUTH_INTERNAL_ERROR, 1, auditstrp,
|
|
message.dwError, 1);
|
|
|
|
DDM_PRINT(
|
|
gblDDMConfigInfo.dwTraceId,
|
|
TRACE_FSM,
|
|
"SecurityDllEventHandler:Security DLL failure %x\n",
|
|
message.dwError );
|
|
|
|
if ( pDevObj->SecurityState == DEV_OBJ_SECURITY_DIALOG_ACTIVE )
|
|
{
|
|
DevStartClosing(pDevObj);
|
|
}
|
|
else if ( pDevObj->SecurityState==DEV_OBJ_SECURITY_DIALOG_STOPPING )
|
|
{
|
|
pDevObj->SecurityState = DEV_OBJ_SECURITY_DIALOG_INACTIVE;
|
|
|
|
DevCloseComplete(pDevObj);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
RTASSERT(FALSE);
|
|
break;
|
|
}
|
|
|
|
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
|
|
}
|
|
}
|