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.
1535 lines
43 KiB
1535 lines
43 KiB
/*******************************************************************/
|
|
/* Copyright(c) 1992 Microsoft Corporation */
|
|
/*******************************************************************/
|
|
|
|
//***
|
|
//
|
|
// Filename: ppphand.c
|
|
//
|
|
// Description: This module contains the procedures for the
|
|
// supervisor's procedure-driven state machine
|
|
// that handle PPP events.
|
|
//
|
|
// Author: Stefan Solomon (stefans) May 26, 1992.
|
|
//
|
|
//***
|
|
#include "ddm.h"
|
|
#include "timer.h"
|
|
#include "handlers.h"
|
|
#include "objects.h"
|
|
#include "util.h"
|
|
#include "routerif.h"
|
|
#include <raserror.h>
|
|
#include <rasppp.h>
|
|
#include <ddmif.h>
|
|
#include <serial.h>
|
|
#include "rasmanif.h"
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <memory.h>
|
|
|
|
//
|
|
// This lives in rasapi32.dll
|
|
//
|
|
|
|
DWORD
|
|
DDMGetPppParameters(
|
|
LPWSTR lpwsPhonebookName,
|
|
LPWSTR lpwsPhonebookEntry,
|
|
CHAR * szzPppParameters
|
|
);
|
|
|
|
//***
|
|
//
|
|
// Function: SvPppSendInterfaceInfo
|
|
//
|
|
// Description: Ppp engine wants to get the interface handles for this
|
|
// connection.
|
|
//
|
|
VOID
|
|
SvPppSendInterfaceInfo(
|
|
IN PDEVICE_OBJECT pDeviceObj
|
|
)
|
|
{
|
|
ROUTER_INTERFACE_OBJECT * pIfObject;
|
|
PPP_INTERFACE_INFO PppInterfaceInfo;
|
|
DWORD dwXportIndex;
|
|
PCONNECTION_OBJECT pConnObj;
|
|
|
|
DDM_PRINT(gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"SvPppSendInterfaceHandles: Entered, hPort=%d",pDeviceObj->hPort);
|
|
|
|
ZeroMemory( &PppInterfaceInfo, sizeof( PppInterfaceInfo ) );
|
|
|
|
if ( ( pConnObj = ConnObjGetPointer( pDeviceObj->hConnection ) ) == NULL )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM, "No ConnObj" );
|
|
|
|
return;
|
|
}
|
|
|
|
EnterCriticalSection( &(gblpInterfaceTable->CriticalSection) );
|
|
|
|
if ( ( pIfObject = IfObjectGetPointer( pConnObj->hDIMInterface ) ) == NULL )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM, "No IfObject" );
|
|
|
|
LeaveCriticalSection( &(gblpInterfaceTable->CriticalSection) );
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Get handles to this interface for each transport and notify PPP.
|
|
//
|
|
|
|
for ( dwXportIndex = 0;
|
|
dwXportIndex < gblDDMConfigInfo.dwNumRouterManagers;
|
|
dwXportIndex++ )
|
|
{
|
|
switch( gblRouterManagers[dwXportIndex].DdmRouterIf.dwProtocolId )
|
|
{
|
|
case PID_IPX:
|
|
|
|
if (pIfObject->Transport[dwXportIndex].fState & RITRANSPORT_ENABLED)
|
|
{
|
|
PppInterfaceInfo.hIPXInterface =
|
|
pIfObject->Transport[dwXportIndex].hInterface;
|
|
}
|
|
else
|
|
{
|
|
PppInterfaceInfo.hIPXInterface = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
break;
|
|
|
|
case PID_IP:
|
|
|
|
if (pIfObject->Transport[dwXportIndex].fState & RITRANSPORT_ENABLED)
|
|
{
|
|
PppInterfaceInfo.hIPInterface =
|
|
pIfObject->Transport[dwXportIndex].hInterface;
|
|
|
|
CopyMemory( PppInterfaceInfo.szzParameters,
|
|
pIfObject->PppInterfaceInfo.szzParameters,
|
|
sizeof( PppInterfaceInfo.szzParameters ) );
|
|
}
|
|
else
|
|
{
|
|
PppInterfaceInfo.hIPInterface = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
PppInterfaceInfo.IfType = pIfObject->IfType;
|
|
|
|
LeaveCriticalSection( &(gblpInterfaceTable->CriticalSection) );
|
|
|
|
PppDdmSendInterfaceInfo( pDeviceObj->hConnection, &PppInterfaceInfo );
|
|
}
|
|
|
|
//***
|
|
//
|
|
// Function: SvPppUserOK
|
|
//
|
|
// Description: User has passed security verification and entered the
|
|
// configuration conversation phase. Stops auth timer and
|
|
// logs the user.
|
|
//
|
|
//***
|
|
VOID
|
|
SvPppUserOK(
|
|
IN PDEVICE_OBJECT pDeviceObj,
|
|
IN PPPDDM_AUTH_RESULT * pAuthResult
|
|
)
|
|
{
|
|
LPWSTR lpstrAudit[2];
|
|
ROUTER_INTERFACE_OBJECT * pIfObject;
|
|
PCONNECTION_OBJECT pConnObj;
|
|
DWORD dwRetCode = NO_ERROR;
|
|
WCHAR wchUserName[UNLEN+1];
|
|
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"SvPppUserOK: Entered, hPort=%d", pDeviceObj->hPort);
|
|
|
|
if ( pDeviceObj->DeviceState != DEV_OBJ_AUTH_IS_ACTIVE )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM, "Auth not started" );
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Stop authentication timer
|
|
//
|
|
|
|
TimerQRemove( (HANDLE)pDeviceObj->hPort, SvAuthTimeout );
|
|
|
|
if ( strlen( pAuthResult->szUserName ) > 0 )
|
|
{
|
|
MultiByteToWideChar( CP_ACP,
|
|
0,
|
|
pAuthResult->szUserName,
|
|
-1,
|
|
wchUserName,
|
|
UNLEN+1 );
|
|
}
|
|
else
|
|
{
|
|
wcscpy( wchUserName, gblpszUnknown );
|
|
}
|
|
|
|
//
|
|
// Check to see if the username and domain are the same if the 3rd party
|
|
// security DLL is installed..
|
|
//
|
|
|
|
if ( ( gblDDMConfigInfo.lpfnRasBeginSecurityDialog != NULL ) &&
|
|
( gblDDMConfigInfo.lpfnRasEndSecurityDialog != NULL ) &&
|
|
( pDeviceObj->fFlags & DEV_OBJ_SECURITY_DLL_USED ) )
|
|
{
|
|
//
|
|
// If there is no match then hangup the line
|
|
//
|
|
|
|
if ( _wcsicmp( pDeviceObj->wchUserName, wchUserName ) != 0 )
|
|
{
|
|
lpstrAudit[0] = pDeviceObj->wchUserName;
|
|
lpstrAudit[1] = wchUserName;
|
|
|
|
DDMLogWarning( ROUTERLOG_AUTH_DIFFUSER_FAILURE, 2, lpstrAudit );
|
|
|
|
PppDdmStop( pDeviceObj->hPort, ERROR_ACCESS_DENIED );
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// copy the user name
|
|
//
|
|
|
|
wcscpy( pDeviceObj->wchUserName, wchUserName );
|
|
|
|
//
|
|
// copy the domain name
|
|
//
|
|
|
|
MultiByteToWideChar( CP_ACP,
|
|
0,
|
|
pAuthResult->szLogonDomain,
|
|
-1,
|
|
pDeviceObj->wchDomainName,
|
|
DNLEN+1 );
|
|
|
|
//
|
|
// copy the advanced server flag
|
|
//
|
|
|
|
if ( pAuthResult->fAdvancedServer )
|
|
{
|
|
pDeviceObj->fFlags |= DEV_OBJ_IS_ADVANCED_SERVER;
|
|
}
|
|
|
|
EnterCriticalSection( &(gblpInterfaceTable->CriticalSection) );
|
|
|
|
do
|
|
{
|
|
//
|
|
// Check to see if there are any non-client intefaces with this
|
|
// name.
|
|
//
|
|
|
|
pIfObject = IfObjectGetPointerByName( pDeviceObj->wchUserName, FALSE );
|
|
|
|
if ( pIfObject == (ROUTER_INTERFACE_OBJECT *)NULL )
|
|
{
|
|
//
|
|
// If this is a client dialing in and clients are not allowed
|
|
// to dialin to this port, then disconnect them.
|
|
//
|
|
|
|
if ( !( pDeviceObj->fFlags & DEV_OBJ_ALLOW_CLIENTS ) )
|
|
{
|
|
dwRetCode = ERROR_NOT_CLIENT_PORT;
|
|
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"A client tried to connect on a router only port=%d",
|
|
pDeviceObj->hPort);
|
|
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// If a call came in for an interface that is not dynamic
|
|
// then do not accept the line
|
|
//
|
|
|
|
if ( ( pIfObject->IfType == ROUTER_IF_TYPE_DEDICATED ) ||
|
|
( pIfObject->IfType == ROUTER_IF_TYPE_INTERNAL ) )
|
|
{
|
|
//
|
|
// Notify PPP not to accept the connection
|
|
//
|
|
|
|
dwRetCode = ERROR_ALREADY_CONNECTED;
|
|
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"The interface %ws is already connected port=%d",
|
|
pIfObject->lpwsInterfaceName, pDeviceObj->hPort );
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Allow the connection only if the interface is enabled
|
|
//
|
|
|
|
if ( !( pIfObject->fFlags & IFFLAG_ENABLED ) )
|
|
{
|
|
dwRetCode = ERROR_INTERFACE_DISABLED;
|
|
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"The interface %ws is disabled",
|
|
pIfObject->lpwsInterfaceName );
|
|
|
|
break;
|
|
}
|
|
|
|
if ( !( pDeviceObj->fFlags & DEV_OBJ_ALLOW_ROUTERS ) )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"A router tried to connect on a client only port=%d",
|
|
pDeviceObj->hPort);
|
|
|
|
dwRetCode = ERROR_NOT_ROUTER_PORT;
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Set current usage in rasman to ROUTER
|
|
//
|
|
|
|
RasSetRouterUsage( pDeviceObj->hPort, TRUE );
|
|
}
|
|
|
|
} while( FALSE );
|
|
|
|
LeaveCriticalSection( &(gblpInterfaceTable->CriticalSection) );
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
lpstrAudit[0] = pDeviceObj->wchUserName;
|
|
lpstrAudit[1] = pDeviceObj->wchPortName;
|
|
|
|
DDMLogWarningString( ROUTERLOG_CONNECTION_ATTEMPT_FAILURE,
|
|
2,
|
|
lpstrAudit,
|
|
dwRetCode,
|
|
2 );
|
|
|
|
PppDdmStop( pDeviceObj->hPort, dwRetCode );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//***
|
|
//
|
|
// Function: SvPppNewLinkOrBundle
|
|
//
|
|
// Description: User has passed security verification and entered the
|
|
// configuration conversation phase. Stops auth timer and
|
|
// logs the user.
|
|
//
|
|
//***
|
|
VOID
|
|
SvPppNewLinkOrBundle(
|
|
IN PDEVICE_OBJECT pDeviceObj,
|
|
IN BOOL fNewBundle,
|
|
IN PBYTE pClientInterface,
|
|
IN PBYTE pQuarantineIPFilter,
|
|
IN PBYTE pFilter,
|
|
IN BOOL fQuarantinePresent
|
|
)
|
|
{
|
|
LPWSTR lpstrAudit[2];
|
|
ROUTER_INTERFACE_OBJECT * pIfObject;
|
|
PCONNECTION_OBJECT pConnObj;
|
|
DWORD dwRetCode = NO_ERROR;
|
|
WCHAR wchUserName[UNLEN+1];
|
|
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"SvPppNewLinkOrBundle: Entered, hPort=%d", pDeviceObj->hPort);
|
|
|
|
if ( pDeviceObj->DeviceState != DEV_OBJ_AUTH_IS_ACTIVE )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM, "Auth not started" );
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Get handle to the connection or bundle for this link
|
|
//
|
|
|
|
if ( ( dwRetCode = RasPortGetBundle( NULL, pDeviceObj->hPort,
|
|
&(pDeviceObj->hConnection) ) ) != NO_ERROR )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"RasPortGetBundle failed: %d", dwRetCode );
|
|
|
|
PppDdmStop( pDeviceObj->hPort, dwRetCode );
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Allocate a connection object if it does not exist yet
|
|
//
|
|
|
|
pConnObj = ConnObjGetPointer( pDeviceObj->hConnection );
|
|
|
|
if ( pConnObj == (CONNECTION_OBJECT *)NULL )
|
|
{
|
|
pConnObj = ConnObjAllocateAndInit( INVALID_HANDLE_VALUE,
|
|
pDeviceObj->hConnection );
|
|
|
|
if ( pConnObj == (CONNECTION_OBJECT *)NULL )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"ConnObjAllocateAndInit failed" );
|
|
|
|
PppDdmStop( pDeviceObj->hPort, ERROR_NOT_ENOUGH_MEMORY );
|
|
|
|
return;
|
|
}
|
|
|
|
pConnObj->fFlags = CONN_OBJ_IS_PPP;
|
|
pConnObj->hPort = pDeviceObj->hPort;
|
|
pConnObj->pQuarantineFilter = pQuarantineIPFilter;
|
|
pConnObj->pFilter = pFilter;
|
|
|
|
wcscpy( pConnObj->wchInterfaceName, pDeviceObj->wchUserName );
|
|
|
|
//
|
|
// copy the user name
|
|
//
|
|
|
|
wcscpy( pConnObj->wchUserName, pDeviceObj->wchUserName );
|
|
|
|
//
|
|
// copy the domain name
|
|
//
|
|
|
|
wcscpy( pConnObj->wchDomainName, pDeviceObj->wchDomainName );
|
|
|
|
//
|
|
// If it is a router, check to see if we have an interface for this
|
|
// router, otherwise reject this connection.
|
|
//
|
|
|
|
EnterCriticalSection( &(gblpInterfaceTable->CriticalSection) );
|
|
|
|
do
|
|
{
|
|
//
|
|
// Check to see if there are any non-client intefaces with this
|
|
// name.
|
|
//
|
|
|
|
pIfObject = IfObjectGetPointerByName( pConnObj->wchInterfaceName,
|
|
FALSE );
|
|
|
|
//
|
|
// We do not have this interface in our database so assume that
|
|
// this is a client so we need to create and interface and add it
|
|
// to all the router managers. Also if this interface exists but
|
|
// is for a client we need to add this interface again.
|
|
//
|
|
|
|
if ( pIfObject == (ROUTER_INTERFACE_OBJECT *)NULL )
|
|
{
|
|
pIfObject = IfObjectAllocateAndInit(
|
|
pConnObj->wchUserName,
|
|
RISTATE_CONNECTING,
|
|
ROUTER_IF_TYPE_CLIENT,
|
|
pConnObj->hConnection,
|
|
TRUE,
|
|
0,
|
|
0,
|
|
NULL,
|
|
NULL);
|
|
|
|
if ( pIfObject == (ROUTER_INTERFACE_OBJECT *)NULL )
|
|
{
|
|
//
|
|
// Error log this and stop the connection.
|
|
//
|
|
|
|
dwRetCode = GetLastError();
|
|
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"IfObjectAllocateAndInit failed: %d", dwRetCode);
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// Add interfaces to router managers, insert in table now
|
|
// because of the table lookup within the InterfaceEnabled
|
|
// call made in the context of AddInterface.
|
|
//
|
|
|
|
dwRetCode = IfObjectInsertInTable( pIfObject );
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
LOCAL_FREE( pIfObject );
|
|
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"IfObjectInsertInTable failed: %d", dwRetCode );
|
|
|
|
break;
|
|
}
|
|
|
|
dwRetCode = IfObjectAddClientInterface( pIfObject,
|
|
pClientInterface );
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"IfObjectAddClientInterface failed: %d",
|
|
dwRetCode );
|
|
|
|
IfObjectRemove( pIfObject->hDIMInterface );
|
|
|
|
break;
|
|
}
|
|
|
|
if(fQuarantinePresent)
|
|
{
|
|
pConnObj->fFlags |= CONN_OBJ_QUARANTINE_PRESENT;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// If the interface is already connecting or connected
|
|
// and this is a new bundle then we need to reject this
|
|
// connection.
|
|
//
|
|
|
|
if ( pIfObject->State != RISTATE_DISCONNECTED )
|
|
{
|
|
//
|
|
// Notify PPP not to accept the connection
|
|
//
|
|
|
|
dwRetCode = ERROR_ALREADY_CONNECTED;
|
|
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"The interface %ws is already connected port=%d",
|
|
pIfObject->lpwsInterfaceName, pDeviceObj->hPort );
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
ConnObjInsertInTable( pConnObj );
|
|
|
|
pIfObject->State = RISTATE_CONNECTING;
|
|
|
|
pConnObj->hDIMInterface = pIfObject->hDIMInterface;
|
|
pConnObj->InterfaceType = pIfObject->IfType;
|
|
|
|
} while( FALSE );
|
|
|
|
LeaveCriticalSection( &(gblpInterfaceTable->CriticalSection) );
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
PppDdmStop( pDeviceObj->hPort, dwRetCode );
|
|
|
|
LOCAL_FREE( pConnObj );
|
|
|
|
return;
|
|
}
|
|
|
|
}
|
|
//
|
|
// Since this is a new bundle also send the interface handles
|
|
//
|
|
|
|
if ( fNewBundle )
|
|
{
|
|
SvPppSendInterfaceInfo( pDeviceObj );
|
|
}
|
|
|
|
|
|
//
|
|
// Add this link to the connection block.
|
|
//
|
|
|
|
if ( ( dwRetCode = ConnObjAddLink( pConnObj, pDeviceObj ) ) != NO_ERROR )
|
|
{
|
|
PppDdmStop( pDeviceObj->hPort, ERROR_NOT_ENOUGH_MEMORY );
|
|
|
|
DDMLogError( ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, dwRetCode );
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
//***
|
|
//
|
|
// Function: SvPppFailure
|
|
//
|
|
// Descr: Ppp will let us know of any failure while active on a port.
|
|
// An error message is sent to us and we merely log it and
|
|
// disconnect the port.
|
|
//
|
|
//***
|
|
VOID
|
|
SvPppFailure(
|
|
IN PDEVICE_OBJECT pDeviceObj,
|
|
IN PPPDDM_FAILURE *afp
|
|
)
|
|
{
|
|
LPWSTR auditstrp[3];
|
|
WCHAR wchErrorString[256+1];
|
|
WCHAR wchUserName[UNLEN+DNLEN+1];
|
|
WCHAR wchDomainName[DNLEN+1];
|
|
DWORD dwRetCode;
|
|
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"SvPppFailure: Entered, hPort=%d, Error=%d",
|
|
pDeviceObj->hPort, afp->dwError );
|
|
|
|
//
|
|
// Was this a failure for a BAP callback?
|
|
//
|
|
|
|
if ( pDeviceObj->fFlags & DEV_OBJ_BAP_CALLBACK )
|
|
{
|
|
PppDdmBapCallbackResult( pDeviceObj->hBapConnection, afp->dwError );
|
|
|
|
pDeviceObj->fFlags &= ~DEV_OBJ_BAP_CALLBACK;
|
|
}
|
|
|
|
if ( afp->szUserName[0] != (CHAR)NULL )
|
|
{
|
|
MultiByteToWideChar( CP_ACP, 0, afp->szUserName, -1, wchUserName, UNLEN+1 );
|
|
}
|
|
else
|
|
{
|
|
wcscpy( wchUserName, gblpszUnknown );
|
|
}
|
|
|
|
//
|
|
// We ignore the DeviceState here because a Ppp failure can occur at
|
|
// any time during the connection.
|
|
//
|
|
|
|
switch( afp->dwError )
|
|
{
|
|
case ERROR_AUTHENTICATION_FAILURE:
|
|
|
|
auditstrp[0] = wchUserName;
|
|
auditstrp[1] = pDeviceObj->wchPortName;
|
|
|
|
DDMLogWarning( ROUTERLOG_AUTH_FAILURE,2,auditstrp );
|
|
|
|
break;
|
|
|
|
case ERROR_PASSWD_EXPIRED:
|
|
|
|
MultiByteToWideChar( CP_ACP, 0, afp->szLogonDomain, -1, wchDomainName, DNLEN+1 );
|
|
|
|
auditstrp[0] = wchDomainName;
|
|
auditstrp[1] = wchUserName;
|
|
auditstrp[2] = pDeviceObj->wchPortName;
|
|
|
|
DDMLogWarning( ROUTERLOG_PASSWORD_EXPIRED, 3, auditstrp );
|
|
|
|
break;
|
|
|
|
case ERROR_ACCT_EXPIRED:
|
|
case ERROR_ACCOUNT_EXPIRED:
|
|
|
|
MultiByteToWideChar( CP_ACP, 0, afp->szLogonDomain, -1, wchDomainName, DNLEN+1 );
|
|
|
|
auditstrp[0] = wchDomainName;
|
|
auditstrp[1] = wchUserName;
|
|
auditstrp[2] = pDeviceObj->wchPortName;
|
|
|
|
DDMLogWarning( ROUTERLOG_ACCT_EXPIRED, 3, auditstrp );
|
|
|
|
break;
|
|
|
|
case ERROR_NO_DIALIN_PERMISSION:
|
|
|
|
MultiByteToWideChar( CP_ACP, 0, afp->szLogonDomain, -1, wchDomainName, DNLEN+1 );
|
|
|
|
auditstrp[0] = wchDomainName;
|
|
auditstrp[1] = wchUserName;
|
|
auditstrp[2] = pDeviceObj->wchPortName;
|
|
|
|
DDMLogWarning( ROUTERLOG_NO_DIALIN_PRIVILEGE, 3, auditstrp );
|
|
|
|
break;
|
|
|
|
|
|
case ERROR_REQ_NOT_ACCEP:
|
|
|
|
auditstrp[0] = pDeviceObj->wchPortName;
|
|
|
|
DDMLogWarning( ROUTERLOG_LICENSE_LIMIT_EXCEEDED, 1, auditstrp );
|
|
|
|
break;
|
|
|
|
case ERROR_BAP_DISCONNECTED:
|
|
case ERROR_BAP_REQUIRED:
|
|
|
|
auditstrp[0] = wchUserName;
|
|
auditstrp[1] = pDeviceObj->wchPortName;
|
|
|
|
DDMLogWarningString( ROUTERLOG_BAP_DISCONNECT, 2, auditstrp,
|
|
afp->dwError, 2 );
|
|
|
|
break;
|
|
|
|
case ERROR_PORT_NOT_CONNECTED:
|
|
case ERROR_PPP_TIMEOUT:
|
|
case ERROR_PPP_LCP_TERMINATED:
|
|
case ERROR_NOT_CONNECTED:
|
|
|
|
//
|
|
// Ignore this error
|
|
//
|
|
|
|
break;
|
|
|
|
case ERROR_PPP_NOT_CONVERGING:
|
|
default:
|
|
|
|
if ( afp->szUserName[0] != (CHAR)NULL )
|
|
{
|
|
if ( afp->szLogonDomain[0] != (CHAR)NULL )
|
|
{
|
|
MultiByteToWideChar(CP_ACP,0,afp->szLogonDomain,-1,wchUserName,UNLEN+1);
|
|
wcscat( wchUserName, L"\\" );
|
|
|
|
MultiByteToWideChar(CP_ACP,0,afp->szUserName,-1,wchDomainName,DNLEN+1);
|
|
wcscat( wchUserName, wchDomainName );
|
|
}
|
|
else
|
|
{
|
|
MultiByteToWideChar(CP_ACP,0,afp->szUserName,-1,wchUserName,UNLEN+1);
|
|
}
|
|
}
|
|
else if ( pDeviceObj->wchUserName[0] != (WCHAR)NULL )
|
|
{
|
|
if ( pDeviceObj->wchDomainName[0] != (WCHAR)NULL )
|
|
{
|
|
wcscpy( wchUserName, pDeviceObj->wchDomainName );
|
|
wcscat( wchUserName, L"\\" );
|
|
wcscat( wchUserName, pDeviceObj->wchUserName );
|
|
}
|
|
else
|
|
{
|
|
wcscpy( wchUserName, pDeviceObj->wchUserName );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wcscpy( wchUserName, gblpszUnknown );
|
|
}
|
|
|
|
auditstrp[0] = pDeviceObj->wchPortName;
|
|
auditstrp[1] = wchUserName;
|
|
|
|
DDMLogErrorString(ROUTERLOG_PPP_FAILURE, 2, auditstrp, afp->dwError, 2);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
//***
|
|
//
|
|
// Function: SvPppCallbackRequest
|
|
//
|
|
// Description:
|
|
//
|
|
//***
|
|
VOID
|
|
SvPppCallbackRequest(
|
|
IN PDEVICE_OBJECT pDeviceObj,
|
|
IN PPPDDM_CALLBACK_REQUEST *cbrp
|
|
)
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"SvPppCallbackRequest: Entered, hPort = %d\n",pDeviceObj->hPort);
|
|
|
|
//
|
|
// check the state
|
|
//
|
|
|
|
if (pDeviceObj->DeviceState != DEV_OBJ_AUTH_IS_ACTIVE)
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM, "Auth not started" );
|
|
|
|
return;
|
|
}
|
|
|
|
TimerQRemove( (HANDLE)pDeviceObj->hPort, SvAuthTimeout );
|
|
|
|
//
|
|
// copy relevant fields in our dcb
|
|
//
|
|
|
|
if (cbrp->fUseCallbackDelay)
|
|
{
|
|
pDeviceObj->dwCallbackDelay = cbrp->dwCallbackDelay;
|
|
}
|
|
else
|
|
{
|
|
pDeviceObj->dwCallbackDelay = gblDDMConfigInfo.dwCallbackTime;
|
|
}
|
|
|
|
MultiByteToWideChar( CP_ACP,
|
|
0,
|
|
cbrp->szCallbackNumber,
|
|
-1,
|
|
pDeviceObj->wchCallbackNumber,
|
|
MAX_PHONE_NUMBER_LEN + 1 );
|
|
|
|
//
|
|
// Disconnect the line and change the state
|
|
//
|
|
|
|
pDeviceObj->DeviceState = DEV_OBJ_CALLBACK_DISCONNECTING;
|
|
|
|
//
|
|
// Wait to enable the client to get the message
|
|
//
|
|
|
|
TimerQRemove( (HANDLE)pDeviceObj->hPort, SvDiscTimeout );
|
|
|
|
TimerQInsert( (HANDLE)pDeviceObj->hPort,
|
|
DISC_TIMEOUT_CALLBACK, SvDiscTimeout );
|
|
}
|
|
|
|
|
|
//***
|
|
//
|
|
// Function: SvPppDone
|
|
//
|
|
// Description: Activates all allocated bindings.
|
|
//
|
|
//***
|
|
VOID
|
|
SvPppDone(
|
|
IN PDEVICE_OBJECT pDeviceObj,
|
|
IN PPP_PROJECTION_RESULT *pProjectionResult
|
|
)
|
|
{
|
|
LPWSTR lpstrAudit[3];
|
|
DWORD dwRetCode;
|
|
DWORD dwNumActivatedProjections = 0;
|
|
ROUTER_INTERFACE_OBJECT * pIfObject;
|
|
CONNECTION_OBJECT * pConnObj;
|
|
WCHAR wchFullUserName[UNLEN+DNLEN+2];
|
|
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"SvPppDone: Entered, hPort=%d", pDeviceObj->hPort);
|
|
|
|
//
|
|
// If we are not authenicating and not been authenticated then we ignore
|
|
// this message.
|
|
//
|
|
|
|
if ( ( pDeviceObj->DeviceState != DEV_OBJ_AUTH_IS_ACTIVE ) &&
|
|
( pDeviceObj->DeviceState != DEV_OBJ_ACTIVE ) )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"We are not authenicating and not been authenticated" );
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Get pointer to connection object. If we cannot find it that means we
|
|
// have gotten a PPP message for a device who's connection does not exist.
|
|
// Simply ignore it.
|
|
//
|
|
|
|
if ( ( pConnObj = ConnObjGetPointer( pDeviceObj->hConnection ) ) == NULL )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM, "No ConnObj" );
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// If we are getting a projection info structure again, we just update it
|
|
// and return.
|
|
//
|
|
|
|
if ( pDeviceObj->DeviceState == DEV_OBJ_ACTIVE )
|
|
{
|
|
pConnObj->PppProjectionResult = *pProjectionResult;
|
|
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"Updated projection info structure" );
|
|
|
|
return;
|
|
}
|
|
|
|
if ( pConnObj->wchDomainName[0] != TEXT('\0') )
|
|
{
|
|
wcscpy( wchFullUserName, pConnObj->wchDomainName );
|
|
wcscat( wchFullUserName, TEXT("\\") );
|
|
wcscat( wchFullUserName, pConnObj->wchUserName );
|
|
}
|
|
else
|
|
{
|
|
wcscpy( wchFullUserName, pConnObj->wchUserName );
|
|
}
|
|
|
|
lpstrAudit[0] = wchFullUserName;
|
|
lpstrAudit[1] = pDeviceObj->wchPortName;
|
|
|
|
//
|
|
// If we have not yet been notifyied of projections for this connection.
|
|
//
|
|
|
|
if ( !(pConnObj->fFlags & CONN_OBJ_PROJECTIONS_NOTIFIED) )
|
|
{
|
|
if ( pProjectionResult->ip.dwError == NO_ERROR )
|
|
{
|
|
dwNumActivatedProjections++;
|
|
}
|
|
|
|
if ( pProjectionResult->ipx.dwError == NO_ERROR )
|
|
{
|
|
dwNumActivatedProjections++;
|
|
}
|
|
|
|
if ( pProjectionResult->at.dwError == NO_ERROR )
|
|
{
|
|
dwNumActivatedProjections++;
|
|
}
|
|
|
|
//
|
|
// We couldn't activate any projection due to some error error log
|
|
// and bring the link down
|
|
//
|
|
|
|
if ( dwNumActivatedProjections == 0 )
|
|
{
|
|
DDMLogError(ROUTERLOG_AUTH_NO_PROJECTIONS, 2, lpstrAudit, NO_ERROR);
|
|
|
|
PppDdmStop( pDeviceObj->hPort, NO_ERROR );
|
|
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Even though NBF was removed from the product, we can
|
|
// still get the computer namefrom the nbf projection result
|
|
// (PPP Engine dummied it in there).
|
|
//
|
|
// If the computer name ends with 0x03, that tells us
|
|
// the messenger service is running on the remote computer.
|
|
//
|
|
|
|
pConnObj->fFlags &= ~CONN_OBJ_MESSENGER_PRESENT;
|
|
|
|
pConnObj->bComputerName[0] = (CHAR)NULL;
|
|
|
|
if ( pProjectionResult->nbf.wszWksta[0] != (WCHAR)NULL )
|
|
{
|
|
WideCharToMultiByte(
|
|
CP_ACP,
|
|
0,
|
|
pProjectionResult->nbf.wszWksta,
|
|
-1,
|
|
pConnObj->bComputerName,
|
|
sizeof( pConnObj->bComputerName ),
|
|
NULL,
|
|
NULL );
|
|
|
|
if (pConnObj->bComputerName[NCBNAMSZ-1] == (WCHAR) 0x03)
|
|
{
|
|
pConnObj->fFlags |= CONN_OBJ_MESSENGER_PRESENT;
|
|
}
|
|
|
|
pConnObj->bComputerName[NCBNAMSZ-1] = (WCHAR)NULL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Projections Activated OK
|
|
//
|
|
|
|
pConnObj->PppProjectionResult = *pProjectionResult;
|
|
|
|
pConnObj->fFlags |= CONN_OBJ_PROJECTIONS_NOTIFIED;
|
|
|
|
//
|
|
// Set this interface to connected if it is not already connected
|
|
//
|
|
|
|
dwRetCode = IfObjectConnected(
|
|
pConnObj->hDIMInterface,
|
|
pConnObj->hConnection,
|
|
&(pConnObj->PppProjectionResult) );
|
|
|
|
//
|
|
// If the interface does not exist anymore bring down this connection
|
|
//
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"Interface does not exist anymore" );
|
|
|
|
PppDdmStop( pDeviceObj->hPort, NO_ERROR );
|
|
|
|
ConnObjDisconnect( pConnObj );
|
|
|
|
return;
|
|
}
|
|
|
|
GetSystemTimeAsFileTime( (FILETIME*)&(pConnObj->qwActiveTime) );
|
|
|
|
if ( !AcceptNewConnection( pDeviceObj, pConnObj ) )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"ERROR_ACCESS_DENIED" );
|
|
|
|
PppDdmStop( pDeviceObj->hPort, ERROR_ACCESS_DENIED );
|
|
|
|
ConnObjDisconnect( pConnObj );
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ( !AcceptNewLink( pDeviceObj, pConnObj ) )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"ERROR_ACCESS_DENIED" );
|
|
|
|
PppDdmStop( pDeviceObj->hPort, ERROR_ACCESS_DENIED );
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Reduce the media count for this device
|
|
//
|
|
|
|
if ( !(pDeviceObj->fFlags & DEV_OBJ_MARKED_AS_INUSE) )
|
|
{
|
|
if ( pDeviceObj->fFlags & DEV_OBJ_ALLOW_ROUTERS )
|
|
{
|
|
MediaObjRemoveFromTable( pDeviceObj->wchDeviceType );
|
|
}
|
|
|
|
pDeviceObj->fFlags |= DEV_OBJ_MARKED_AS_INUSE;
|
|
|
|
gblDeviceTable.NumDevicesInUse++;
|
|
|
|
//
|
|
// Possibly need to notify the router managers of unreachability
|
|
//
|
|
|
|
EnterCriticalSection( &(gblpInterfaceTable->CriticalSection) );
|
|
|
|
IfObjectNotifyAllOfReachabilityChange( FALSE,
|
|
INTERFACE_OUT_OF_RESOURCES );
|
|
|
|
LeaveCriticalSection( &(gblpInterfaceTable->CriticalSection) );
|
|
}
|
|
|
|
//
|
|
// log authentication success, 18 is MSPPC
|
|
//
|
|
|
|
if ( ( pConnObj->PppProjectionResult.ccp.dwSendProtocol == 18 ) &&
|
|
( pConnObj->PppProjectionResult.ccp.dwReceiveProtocol == 18 ) )
|
|
{
|
|
if ( ( pConnObj->PppProjectionResult.ccp.dwReceiveProtocolData &
|
|
( MSTYPE_ENCRYPTION_40 |
|
|
MSTYPE_ENCRYPTION_40F |
|
|
MSTYPE_ENCRYPTION_56 |
|
|
MSTYPE_ENCRYPTION_128 ) ) &&
|
|
( pConnObj->PppProjectionResult.ccp.dwSendProtocolData &
|
|
( MSTYPE_ENCRYPTION_40 |
|
|
MSTYPE_ENCRYPTION_40F |
|
|
MSTYPE_ENCRYPTION_56 |
|
|
MSTYPE_ENCRYPTION_128 ) ) )
|
|
{
|
|
if ( ( pConnObj->PppProjectionResult.ccp.dwSendProtocolData &
|
|
MSTYPE_ENCRYPTION_128 ) &&
|
|
( pConnObj->PppProjectionResult.ccp.dwReceiveProtocolData &
|
|
MSTYPE_ENCRYPTION_128 ) )
|
|
{
|
|
DDMLogInformation(ROUTERLOG_AUTH_SUCCESS_STRONG_ENCRYPTION,2,
|
|
lpstrAudit);
|
|
}
|
|
else
|
|
{
|
|
DDMLogInformation(ROUTERLOG_AUTH_SUCCESS_ENCRYPTION,2,
|
|
lpstrAudit);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DDMLogInformation( ROUTERLOG_AUTH_SUCCESS, 2, lpstrAudit );
|
|
}
|
|
|
|
if(pProjectionResult->ip.dwError == ERROR_SUCCESS)
|
|
{
|
|
WCHAR *pszIpAddress =
|
|
GetIpAddress(pProjectionResult->ip.dwRemoteAddress);
|
|
|
|
if(NULL != pszIpAddress)
|
|
{
|
|
lpstrAudit[2] = pszIpAddress;
|
|
DDMLogInformation(ROUTERLOG_IP_USER_CONNECTED, 3, lpstrAudit);
|
|
LocalFree(pszIpAddress);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DDMLogInformation( ROUTERLOG_AUTH_SUCCESS, 2, lpstrAudit );
|
|
|
|
if(pProjectionResult->ip.dwError == ERROR_SUCCESS)
|
|
{
|
|
WCHAR *pszIpAddress = GetIpAddress(
|
|
pProjectionResult->ip.dwRemoteAddress);
|
|
|
|
if(NULL != pszIpAddress)
|
|
{
|
|
lpstrAudit[2] = pszIpAddress;
|
|
DDMLogInformation(ROUTERLOG_IP_USER_CONNECTED, 3, lpstrAudit);
|
|
LocalFree(pszIpAddress);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// and finaly go to ACTIVE state
|
|
//
|
|
|
|
pDeviceObj->DeviceState = DEV_OBJ_ACTIVE;
|
|
|
|
pDeviceObj->dwTotalNumberOfCalls++;
|
|
|
|
pDeviceObj->fFlags |= DEV_OBJ_PPP_IS_ACTIVE;
|
|
|
|
//
|
|
// and initialize the active time
|
|
//
|
|
|
|
GetSystemTimeAsFileTime( (FILETIME*)&(pDeviceObj->qwActiveTime) );
|
|
|
|
//
|
|
// Was this a connection for a BAP callback?
|
|
//
|
|
|
|
if ( pDeviceObj->fFlags & DEV_OBJ_BAP_CALLBACK )
|
|
{
|
|
PppDdmBapCallbackResult( pDeviceObj->hBapConnection, NO_ERROR );
|
|
|
|
pDeviceObj->fFlags &= ~DEV_OBJ_BAP_CALLBACK;
|
|
}
|
|
|
|
|
|
return;
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: SvAddLinkToConnection
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description: Called to actually add a new link that BAP has brought up.
|
|
//
|
|
VOID
|
|
SvAddLinkToConnection(
|
|
IN PDEVICE_OBJECT pDeviceObj,
|
|
IN HRASCONN hRasConn
|
|
)
|
|
{
|
|
CONNECTION_OBJECT * pConnObj;
|
|
DWORD dwRetCode;
|
|
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"SvAddLinkToConnection: Entered, hPort=%d", pDeviceObj->hPort );
|
|
|
|
//
|
|
// Set this port to be notified by rasapi32 on disconnect.
|
|
//
|
|
|
|
dwRetCode = RasConnectionNotification(
|
|
hRasConn,
|
|
gblSupervisorEvents[NUM_DDM_EVENTS
|
|
+ (gblDeviceTable.NumDeviceBuckets*2)
|
|
+ DeviceObjHashPortToBucket(pDeviceObj->hPort)],
|
|
RASCN_Disconnection );
|
|
|
|
if ( dwRetCode != NO_ERROR )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"RasConnectionNotification failed: %d", dwRetCode );
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Get the HCONN bundle handle for this port
|
|
//
|
|
|
|
if ( RasPortGetBundle( NULL,
|
|
pDeviceObj->hPort,
|
|
&(pDeviceObj->hConnection) ) )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"RasPortGetBundle failed" );
|
|
|
|
return;
|
|
}
|
|
|
|
if ( ( pConnObj = ConnObjGetPointer( pDeviceObj->hConnection ) ) == NULL )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM, "No ConnObj" );
|
|
|
|
return;
|
|
}
|
|
|
|
if ( ( dwRetCode = ConnObjAddLink( pConnObj, pDeviceObj ) ) != NO_ERROR )
|
|
{
|
|
DDMLogError( ROUTERLOG_NOT_ENOUGH_MEMORY, 0, NULL, dwRetCode );
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Reduce the media count for this device
|
|
//
|
|
|
|
if ( !(pDeviceObj->fFlags & DEV_OBJ_MARKED_AS_INUSE) )
|
|
{
|
|
if ( pDeviceObj->fFlags & DEV_OBJ_ALLOW_ROUTERS )
|
|
{
|
|
MediaObjRemoveFromTable( pDeviceObj->wchDeviceType );
|
|
}
|
|
|
|
pDeviceObj->fFlags |= DEV_OBJ_MARKED_AS_INUSE;
|
|
|
|
gblDeviceTable.NumDevicesInUse++;
|
|
|
|
//
|
|
// Possibly need to notify the router managers of unreachability
|
|
//
|
|
|
|
IfObjectNotifyAllOfReachabilityChange(FALSE,INTERFACE_OUT_OF_RESOURCES);
|
|
}
|
|
|
|
pDeviceObj->fFlags |= DEV_OBJ_OPENED_FOR_DIALOUT;
|
|
pDeviceObj->hRasConn = hRasConn;
|
|
|
|
if ( pConnObj->InterfaceType == ROUTER_IF_TYPE_FULL_ROUTER )
|
|
{
|
|
RasSetRouterUsage( pDeviceObj->hPort, TRUE );
|
|
}
|
|
}
|
|
|
|
//**
|
|
//
|
|
// Call: SvDoBapCallbackRequest
|
|
//
|
|
// Returns: NO_ERROR - Success
|
|
// Non-zero returns - Failure
|
|
//
|
|
// Description: Called by BAP to initiate a callback to the remote peer
|
|
//
|
|
VOID
|
|
SvDoBapCallbackRequest(
|
|
IN PDEVICE_OBJECT pDevObj,
|
|
IN HCONN hConnection,
|
|
IN CHAR * szCallbackNumber
|
|
)
|
|
{
|
|
DWORD dwRetCode;
|
|
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"SvDoBapCallbackRequest: Entered, hPort=%d", pDevObj->hPort );
|
|
|
|
//
|
|
// Check to see if the device is available
|
|
//
|
|
|
|
if ( ( pDevObj->DeviceState != DEV_OBJ_LISTENING ) ||
|
|
( pDevObj->fFlags & DEV_OBJ_OPENED_FOR_DIALOUT ) )
|
|
{
|
|
DDM_PRINT( gblDDMConfigInfo.dwTraceId, TRACE_FSM,
|
|
"Device not available" );
|
|
|
|
PppDdmBapCallbackResult( hConnection, ERROR_PORT_NOT_AVAILABLE );
|
|
|
|
return;
|
|
}
|
|
|
|
pDevObj->fFlags |= DEV_OBJ_IS_PPP;
|
|
|
|
pDevObj->DeviceState = DEV_OBJ_CALLBACK_DISCONNECTING;
|
|
|
|
MultiByteToWideChar( CP_ACP,
|
|
0,
|
|
szCallbackNumber,
|
|
-1,
|
|
pDevObj->wchCallbackNumber,
|
|
MAX_PHONE_NUMBER_LEN + 1 );
|
|
|
|
pDevObj->dwCallbackDelay = 10;
|
|
|
|
pDevObj->hBapConnection = hConnection;
|
|
|
|
pDevObj->fFlags |= DEV_OBJ_BAP_CALLBACK;
|
|
|
|
RmDisconnect( pDevObj );
|
|
}
|
|
|
|
//***
|
|
//
|
|
// Function: PppEventHandler
|
|
//
|
|
// Description: receives the ppp messages and invokes the apropriate
|
|
// procedures in fsm.
|
|
//
|
|
//***
|
|
VOID
|
|
PppEventHandler(
|
|
VOID
|
|
)
|
|
{
|
|
PPP_MESSAGE PppMsg;
|
|
PDEVICE_OBJECT pDevObj;
|
|
PCONNECTION_OBJECT pConnObj;
|
|
|
|
//
|
|
// loop to get all messages
|
|
//
|
|
|
|
while( ServerReceiveMessage( MESSAGEQ_ID_PPP, (BYTE *)&PppMsg) )
|
|
{
|
|
EnterCriticalSection( &(gblDeviceTable.CriticalSection) );
|
|
|
|
if ( PppMsg.dwMsgId == PPPDDMMSG_PnPNotification )
|
|
{
|
|
//
|
|
// Port add/removal/change usage or protocol addition/removal
|
|
// notifications.
|
|
//
|
|
|
|
DWORD dwPnPEvent =
|
|
PppMsg.ExtraInfo.DdmPnPNotification.PnPNotification.dwEvent;
|
|
|
|
RASMAN_PORT * pRasmanPort =
|
|
&(PppMsg.ExtraInfo.DdmPnPNotification.PnPNotification.RasPort);
|
|
|
|
switch( dwPnPEvent )
|
|
{
|
|
case PNPNOTIFEVENT_CREATE:
|
|
if(pRasmanPort->P_ConfiguredUsage &
|
|
(CALL_IN | CALL_ROUTER | CALL_OUTBOUND_ROUTER))
|
|
{
|
|
DeviceObjAdd( pRasmanPort );
|
|
}
|
|
break;
|
|
|
|
case PNPNOTIFEVENT_REMOVE:
|
|
DeviceObjRemove( pRasmanPort );
|
|
break;
|
|
|
|
case PNPNOTIFEVENT_USAGE:
|
|
DeviceObjUsageChange( pRasmanPort );
|
|
break;
|
|
}
|
|
|
|
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
|
|
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Otherwise identify the port for which this event is received.
|
|
//
|
|
|
|
if ( ( pDevObj = DeviceObjGetPointer( PppMsg.hPort ) ) == NULL )
|
|
{
|
|
RTASSERT( pDevObj != NULL );
|
|
|
|
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
|
|
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// action on the message type
|
|
//
|
|
|
|
switch( PppMsg.dwMsgId )
|
|
{
|
|
case PPPDDMMSG_BapCallbackRequest:
|
|
|
|
SvDoBapCallbackRequest(
|
|
pDevObj,
|
|
PppMsg.ExtraInfo.BapCallbackRequest.hConnection,
|
|
PppMsg.ExtraInfo.BapCallbackRequest.szCallbackNumber );
|
|
|
|
break;
|
|
|
|
case PPPDDMMSG_PppDone:
|
|
|
|
pDevObj->fFlags &= (~DEV_OBJ_AUTH_ACTIVE);
|
|
|
|
SvPppDone(pDevObj, &PppMsg.ExtraInfo.ProjectionResult);
|
|
|
|
break;
|
|
|
|
case PPPDDMMSG_CallbackRequest:
|
|
|
|
SvPppCallbackRequest(pDevObj,&PppMsg.ExtraInfo.CallbackRequest);
|
|
|
|
break;
|
|
|
|
case PPPDDMMSG_Authenticated:
|
|
|
|
SvPppUserOK(pDevObj, &PppMsg.ExtraInfo.AuthResult);
|
|
|
|
break;
|
|
|
|
case PPPDDMMSG_NewLink:
|
|
|
|
SvPppNewLinkOrBundle( pDevObj, FALSE, NULL, NULL, NULL, FALSE );
|
|
|
|
break;
|
|
|
|
case PPPDDMMSG_NewBundle:
|
|
|
|
if(NULL != IfObjectGetPointerByName(
|
|
pDevObj->wchUserName, FALSE))
|
|
{
|
|
MprInfoDelete(PppMsg.ExtraInfo.DdmNewBundle.pClientInterface);
|
|
PppMsg.ExtraInfo.DdmNewBundle.pClientInterface = NULL;
|
|
MprInfoDelete(PppMsg.ExtraInfo.DdmNewBundle.pQuarantineIPFilter);
|
|
PppMsg.ExtraInfo.DdmNewBundle.pQuarantineIPFilter = NULL;
|
|
MprInfoDelete(PppMsg.ExtraInfo.DdmNewBundle.pFilter);
|
|
PppMsg.ExtraInfo.DdmNewBundle.pFilter = NULL;
|
|
PppMsg.ExtraInfo.DdmNewBundle.fQuarantinePresent = FALSE;
|
|
}
|
|
|
|
SvPppNewLinkOrBundle(
|
|
pDevObj,
|
|
TRUE,
|
|
PppMsg.ExtraInfo.DdmNewBundle.pClientInterface,
|
|
PppMsg.ExtraInfo.DdmNewBundle.pQuarantineIPFilter,
|
|
PppMsg.ExtraInfo.DdmNewBundle.pFilter,
|
|
PppMsg.ExtraInfo.DdmNewBundle.fQuarantinePresent);
|
|
|
|
if ( PppMsg.ExtraInfo.DdmNewBundle.pClientInterface != NULL )
|
|
{
|
|
MprInfoDelete( PppMsg.ExtraInfo.DdmNewBundle.pClientInterface );
|
|
}
|
|
|
|
break;
|
|
|
|
case PPPDDMMSG_PppFailure:
|
|
|
|
pDevObj->fFlags &= (~DEV_OBJ_AUTH_ACTIVE);
|
|
|
|
switch( PppMsg.ExtraInfo.DdmFailure.dwError )
|
|
{
|
|
case NO_ERROR:
|
|
case ERROR_IDLE_DISCONNECTED:
|
|
pDevObj->dwDisconnectReason = DDM_IDLE_DISCONNECT;
|
|
break;
|
|
case ERROR_PPP_SESSION_TIMEOUT:
|
|
pDevObj->dwDisconnectReason = DDM_SESSION_TIMEOUT;
|
|
break;
|
|
|
|
default:
|
|
pDevObj->dwDisconnectReason = 0;
|
|
SvPppFailure( pDevObj, &PppMsg.ExtraInfo.DdmFailure );
|
|
}
|
|
|
|
PppDdmStop( pDevObj->hPort, PppMsg.ExtraInfo.DdmFailure.dwError );
|
|
|
|
break;
|
|
|
|
case PPPDDMMSG_Stopped:
|
|
|
|
if ( ( pDevObj->DeviceState != DEV_OBJ_CLOSING ) &&
|
|
( pDevObj->DeviceState != DEV_OBJ_LISTENING ) )
|
|
{
|
|
DevStartClosing( pDevObj );
|
|
}
|
|
|
|
break;
|
|
|
|
case PPPDDMMSG_PortCleanedUp:
|
|
|
|
if ( pDevObj->DeviceState != DEV_OBJ_LISTENING )
|
|
{
|
|
pDevObj->fFlags &= (~DEV_OBJ_PPP_IS_ACTIVE);
|
|
|
|
if ( pDevObj->DeviceState != DEV_OBJ_CLOSING )
|
|
{
|
|
DevStartClosing( pDevObj );
|
|
}
|
|
else
|
|
{
|
|
DevCloseComplete( pDevObj );
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case PPPDDMMSG_NewBapLinkUp:
|
|
|
|
SvAddLinkToConnection( pDevObj,
|
|
PppMsg.ExtraInfo.BapNewLinkUp.hRasConn );
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
RTASSERT(FALSE);
|
|
break;
|
|
}
|
|
|
|
LeaveCriticalSection( &(gblDeviceTable.CriticalSection) );
|
|
}
|
|
}
|