windows-nt/Source/XPSP1/NT/net/rras/ras/ppp/engine/pppapi.c

679 lines
18 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/* Copyright (c) 1993, Microsoft Corporation, all rights reserved
**
** rasppp.c
** Remote Access PPP APIs
**
** 11/15/93 Steve Cobb
*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <lmcons.h>
#include <rasauth.h>
#include <rasman.h>
#include <rasppp.h>
#include <ddmif.h>
#include <rtutils.h>
#include <mprlog.h>
#include <raserror.h>
#include <pppcp.h>
#include <ppp.h>
#include <util.h>
#include <init.h>
#include <worker.h>
#include <bap.h>
#include <raseapif.h>
//**
//
// Call: StartPPP
//
// Returns: NO_ERROR - Success.
// Non zero return code - Failure
//
// Description:
//
DWORD APIENTRY
StartPPP(
DWORD NumPorts
)
{
DWORD dwRetCode;
//
// Read registry info, load CP DLLS, initialize globals etc.
//
PcbTable.NumPcbBuckets = ((DWORD)NumPorts > MAX_NUMBER_OF_PCB_BUCKETS)
? MAX_NUMBER_OF_PCB_BUCKETS
: (DWORD)NumPorts;
dwRetCode = InitializePPP();
if ( dwRetCode != NO_ERROR )
{
PPPCleanUp();
}
else
{
PppLog( 2, "PPP Initialized successfully." );
}
return( dwRetCode );
}
//**
//
// Call: StopPPP
//
// Returns: NO_ERROR - Success.
// Non zero return code - Failure
//
DWORD APIENTRY
StopPPP(
HANDLE hEventStopPPP
)
{
PCB_WORK_ITEM * pWorkItem;
PppLog( 2, "StopPPP called" );
//
// Insert shutdown event
//
pWorkItem = (PCB_WORK_ITEM*)LOCAL_ALLOC(LPTR,sizeof(PCB_WORK_ITEM));
if ( pWorkItem == (PCB_WORK_ITEM *)NULL )
{
return( GetLastError() );
}
pWorkItem->Process = ProcessStopPPP;
pWorkItem->hEvent = hEventStopPPP;
InsertWorkItemInQ( pWorkItem );
return( NO_ERROR );
}
//**
//
// Call: SendPPPMessageToEngine
//
// Returns: NO_ERROR - Success
// non-zero - FAILURE
//
// Description: Will create a PCB_WORK_ITEM from a PPPE_MESSAGE structure
// received from client or rassrv and Send it to the engine.
//
DWORD APIENTRY
SendPPPMessageToEngine(
IN PPPE_MESSAGE* pMessage
)
{
PCB_WORK_ITEM * pWorkItem = (PCB_WORK_ITEM *)LOCAL_ALLOC(
LPTR,
sizeof(PCB_WORK_ITEM));
if ( pWorkItem == (PCB_WORK_ITEM *)NULL )
{
LogPPPEvent( ROUTERLOG_NOT_ENOUGH_MEMORY, 0 );
return( GetLastError() );
}
//
// Set up PCB_WORK_ITEM structure from the PPPE_MESSAGE
//
pWorkItem->hPort = pMessage->hPort;
switch( pMessage->dwMsgId )
{
case PPPEMSG_Start:
pWorkItem->Process = ProcessLineUp;
pWorkItem->fServer = FALSE;
pWorkItem->PppMsg.Start = pMessage->ExtraInfo.Start;
//Create a seed for encoding the password
pMessage->ExtraInfo.Start.chSeed = pWorkItem->PppMsg.Start.chSeed = GEN_RAND_ENCODE_SEED;
PppLog( 2, "PPPEMSG_Start recvd, d=%s, hPort=%d,callback=%d,"
"mask=%x,IfType=%d",
pMessage->ExtraInfo.Start.szDomain,
pWorkItem->hPort,
pMessage->ExtraInfo.Start.fThisIsACallback,
pMessage->ExtraInfo.Start.ConfigInfo.dwConfigMask,
pMessage->ExtraInfo.Start.PppInterfaceInfo.IfType );
EncodePw( pWorkItem->PppMsg.Start.chSeed, pWorkItem->PppMsg.Start.szPassword );
EncodePw( pMessage->ExtraInfo.Start.chSeed, pMessage->ExtraInfo.Start.szPassword );
break;
case PPPEMSG_Stop:
PppLog( 2, "PPPEMSG_Stop recvd\r\n" );
pWorkItem->Process = ProcessClose;
pWorkItem->PppMsg.PppStop = pMessage->ExtraInfo.Stop;
break;
case PPPEMSG_Callback:
PppLog( 2, "PPPEMSG_Callback recvd, hPort=%d\r\n",
pWorkItem->hPort);
pWorkItem->Process = ProcessGetCallbackNumberFromUser;
pWorkItem->PppMsg.Callback = pMessage->ExtraInfo.Callback;
break;
case PPPEMSG_ChangePw:
PppLog( 2, "PPPEMSG_ChangePw recvd, hPort=%d\r\n",
pWorkItem->hPort);
pWorkItem->Process = ProcessChangePassword;
pWorkItem->PppMsg.ChangePw = pMessage->ExtraInfo.ChangePw;
pWorkItem->PppMsg.ChangePw.chSeed = pMessage->ExtraInfo.ChangePw.chSeed = GEN_RAND_ENCODE_SEED;
EncodePw( pWorkItem->PppMsg.ChangePw.chSeed, pWorkItem->PppMsg.ChangePw.szNewPassword );
EncodePw( pMessage->ExtraInfo.ChangePw.chSeed, pMessage->ExtraInfo.ChangePw.szNewPassword );
EncodePw( pWorkItem->PppMsg.ChangePw.chSeed, pWorkItem->PppMsg.ChangePw.szOldPassword );
EncodePw( pMessage->ExtraInfo.ChangePw.chSeed, pMessage->ExtraInfo.ChangePw.szOldPassword );
break;
case PPPEMSG_Retry:
PppLog( 2, "PPPEMSG_Retry recvd hPort=%d,u=%s",
pWorkItem->hPort,
pMessage->ExtraInfo.Start.szUserName );
pWorkItem->Process = ProcessRetryPassword;
pWorkItem->PppMsg.Retry = pMessage->ExtraInfo.Retry;
pWorkItem->PppMsg.Retry.chSeed = pMessage->ExtraInfo.Retry.chSeed = GEN_RAND_ENCODE_SEED;
EncodePw( pWorkItem->PppMsg.Retry.chSeed, pWorkItem->PppMsg.Retry.szPassword );
EncodePw( pMessage->ExtraInfo.Retry.chSeed, pMessage->ExtraInfo.Retry.szPassword );
break;
case PPPEMSG_Receive:
pWorkItem->Process = ProcessReceive;
pWorkItem->PacketLen = pMessage->ExtraInfo.Receive.dwNumBytes;
PppLog( 2, "Packet received (%d bytes) for hPort %d",
pWorkItem->PacketLen, pWorkItem->hPort );
pWorkItem->pPacketBuf = (PPP_PACKET *)LOCAL_ALLOC(LPTR,
pWorkItem->PacketLen);
if ( pWorkItem->pPacketBuf == (PPP_PACKET*)NULL )
{
LogPPPEvent( ROUTERLOG_NOT_ENOUGH_MEMORY, 0 );
LOCAL_FREE( pWorkItem );
return( GetLastError() );
}
CopyMemory( pWorkItem->pPacketBuf,
pMessage->ExtraInfo.Receive.pbBuffer,
pWorkItem->PacketLen );
break;
case PPPEMSG_LineDown:
PppLog( 2, "PPPEMSG_LineDown recvd, hPort=%d\r\n",
pWorkItem->hPort);
pWorkItem->Process = ProcessLineDown;
break;
case PPPEMSG_ListenResult:
pWorkItem->Process = ProcessRasPortListenEvent;
break;
case PPPEMSG_BapEvent:
BapTrace( "Threshold event on HCONN 0x%x. Type: %s, Threshold: %s",
pMessage->hConnection,
pMessage->ExtraInfo.BapEvent.fTransmit ? "transmit" : "receive",
pMessage->ExtraInfo.BapEvent.fAdd ? "upper" : "lower");
pWorkItem->Process = ProcessThresholdEvent;
pWorkItem->hConnection = pMessage->hConnection;
pWorkItem->PppMsg.BapEvent = pMessage->ExtraInfo.BapEvent;
break;
case PPPEMSG_DdmStart:
pWorkItem->Process = ProcessLineUp;
pWorkItem->fServer = TRUE;
pWorkItem->PppMsg.DdmStart = pMessage->ExtraInfo.DdmStart;
break;
case PPPEMSG_DdmCallbackDone:
PppLog( 2, "PPPEMSG_DdmCallbackDone recvd\r\n" );
pWorkItem->Process = ProcessCallbackDone;
pWorkItem->fServer = TRUE;
pWorkItem->PppMsg.CallbackDone = pMessage->ExtraInfo.CallbackDone;
break;
case PPPEMSG_DdmInterfaceInfo:
pWorkItem->Process = ProcessInterfaceInfo;
pWorkItem->fServer = TRUE;
pWorkItem->hConnection = pMessage->hConnection;
pWorkItem->PppMsg.InterfaceInfo = pMessage->ExtraInfo.InterfaceInfo;
PppLog(2,"PPPEMSG_DdmInterfaceInfo recvd,IPXif=%x,IPif=%x,Type=%x\r\n",
pWorkItem->PppMsg.InterfaceInfo.hIPXInterface,
pWorkItem->PppMsg.InterfaceInfo.hIPInterface,
pWorkItem->PppMsg.InterfaceInfo.IfType );
break;
case PPPEMSG_DdmBapCallbackResult:
pWorkItem->Process = ProcessCallResult;
pWorkItem->hConnection = pMessage->hConnection;
pWorkItem->PppMsg.BapCallResult.dwResult =
pMessage->ExtraInfo.BapCallbackResult.dwCallbackResultCode;
pWorkItem->PppMsg.BapCallResult.hRasConn = (HRASCONN) -1;
break;
case PPPEMSG_DhcpInform:
pWorkItem->Process = ProcessDhcpInform;
pWorkItem->hConnection = pMessage->hConnection;
pWorkItem->PppMsg.DhcpInform = pMessage->ExtraInfo.DhcpInform;
break;
case PPPEMSG_EapUIData:
pWorkItem->Process = ProcessEapUIData;
pWorkItem->PppMsg.EapUIData = pMessage->ExtraInfo.EapUIData;
break;
case PPPEMSG_ProtocolEvent:
pWorkItem->Process = ProcessProtocolEvent;
pWorkItem->PppMsg.ProtocolEvent = pMessage->ExtraInfo.ProtocolEvent;
break;
case PPPEMSG_DdmChangeNotification:
pWorkItem->Process = ProcessChangeNotification;
break;
case PPPEMSG_IpAddressLeaseExpired:
pWorkItem->Process = ProcessIpAddressLeaseExpired;
pWorkItem->PppMsg.IpAddressLeaseExpired =
pMessage->ExtraInfo.IpAddressLeaseExpired;
break;
case PPPEMSG_PostLineDown:
pWorkItem->Process = ProcessPostLineDown;
pWorkItem->PppMsg.PostLineDown =
pMessage->ExtraInfo.PostLineDown;
break;
default:
PppLog( 2,"Unknown IPC message %d received\r\n", pMessage->dwMsgId );
LOCAL_FREE( pWorkItem );
pWorkItem = (PCB_WORK_ITEM*)NULL;
}
if ( pWorkItem != NULL )
{
InsertWorkItemInQ( pWorkItem );
}
return( NO_ERROR );
}
//**
//
// Call: PppDdmInit
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will initialize the entry point into DDM that it will call to
// send DDM a PPP_MESSAGE
//
DWORD
PppDdmInit(
IN VOID (*SendPPPMessageToDdm)( PPP_MESSAGE * PppMsg ),
IN DWORD dwServerFlags,
IN DWORD dwLoggingLevel,
IN DWORD dwNASIpAddress,
IN BOOL fRadiusAuthentication,
IN LPVOID lpfnRasAuthProviderAuthenticateUser,
IN LPVOID lpfnRasAuthProviderFreeAttributes,
IN LPVOID lpfnRasAcctProviderStartAccounting,
IN LPVOID lpfnRasAcctProviderInterimAccounting,
IN LPVOID lpfnRasAcctProviderStopAccounting,
IN LPVOID lpfnRasAcctProviderFreeAttributes,
IN LPVOID lpfnGetNextAccountingSessionId
)
{
DWORD dwRetCode;
PppConfigInfo.SendPPPMessageToDdm = SendPPPMessageToDdm;
PppConfigInfo.ServerConfigInfo.dwConfigMask |= dwServerFlags;
PppConfigInfo.dwNASIpAddress = dwNASIpAddress;
PppConfigInfo.dwLoggingLevel = dwLoggingLevel;
if ( dwNASIpAddress == 0 )
{
DWORD dwComputerNameLen = MAX_COMPUTERNAME_LENGTH + 1;
//
// Failed to get the LOCAL IP address, used computer name instead.
//
PppConfigInfo.dwNASIpAddress = 0;
if ( !GetComputerNameA( PppConfigInfo.szNASIdentifier,
&dwComputerNameLen ) )
{
return( GetLastError() );
}
}
PppConfigInfo.fRadiusAuthenticationUsed = fRadiusAuthentication;
PppConfigInfo.RasAuthProviderFreeAttributes =
(DWORD(*)( RAS_AUTH_ATTRIBUTE *))
lpfnRasAuthProviderFreeAttributes;
PppConfigInfo.RasAuthProviderAuthenticateUser =
(DWORD(*)( RAS_AUTH_ATTRIBUTE * ,
PRAS_AUTH_ATTRIBUTE* ,
DWORD *))
lpfnRasAuthProviderAuthenticateUser;
PppConfigInfo.RasAcctProviderStartAccounting =
(DWORD(*)( RAS_AUTH_ATTRIBUTE *,
PRAS_AUTH_ATTRIBUTE*))
lpfnRasAcctProviderStartAccounting;
PppConfigInfo.RasAcctProviderInterimAccounting =
(DWORD(*)( RAS_AUTH_ATTRIBUTE * ,
PRAS_AUTH_ATTRIBUTE*))
lpfnRasAcctProviderInterimAccounting;
PppConfigInfo.RasAcctProviderStopAccounting =
(DWORD(*)( RAS_AUTH_ATTRIBUTE * ,
PRAS_AUTH_ATTRIBUTE*))
lpfnRasAcctProviderStopAccounting;
PppConfigInfo.RasAcctProviderFreeAttributes =
(DWORD(*)( RAS_AUTH_ATTRIBUTE *))
lpfnRasAcctProviderFreeAttributes;
PppConfigInfo.GetNextAccountingSessionId =
(DWORD(*)(VOID))
lpfnGetNextAccountingSessionId;
return( NO_ERROR );
}
//**
//
// Call: PppDdmDeInit
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description:
//
VOID
PppDdmDeInit(
VOID
)
{
return;
}
//**
//
// Call: PppDdmCallbackDone
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will create a PPPEMSG_DdmCallbackDone and send it to the
// worker thread of the PPP engine.
//
DWORD
PppDdmCallbackDone(
IN HPORT hPort,
IN WCHAR* pwszCallbackNumber
)
{
PPPE_MESSAGE PppMessage;
PppMessage.hPort = hPort;
PppMessage.dwMsgId = PPPEMSG_DdmCallbackDone;
wcstombs( PppMessage.ExtraInfo.CallbackDone.szCallbackNumber,
pwszCallbackNumber,
sizeof( PppMessage.ExtraInfo.CallbackDone.szCallbackNumber ) );
return( SendPPPMessageToEngine( &PppMessage ) );
}
//**
//
// Call: PppDdmStart
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will create a PPPEMSG_DdmStart and send it to the
// worker thread of the PPP engine.
//
DWORD
PppDdmStart(
IN HPORT hPort,
IN WCHAR * wszPortName,
IN CHAR* pchFirstFrame,
IN DWORD cbFirstFrame,
IN DWORD dwAuthRetries
)
{
PPPE_MESSAGE PppMessage;
PppMessage.hPort = hPort;
PppMessage.dwMsgId = PPPEMSG_DdmStart;
PppMessage.ExtraInfo.DdmStart.dwAuthRetries = dwAuthRetries;
wcstombs( PppMessage.ExtraInfo.DdmStart.szPortName,
wszPortName,
sizeof( PppMessage.ExtraInfo.DdmStart.szPortName ) );
CopyMemory( &(PppMessage.ExtraInfo.DdmStart.achFirstFrame),
pchFirstFrame,
sizeof( PppMessage.ExtraInfo.DdmStart.achFirstFrame ) );
PppMessage.ExtraInfo.DdmStart.cbFirstFrame = cbFirstFrame;
return( SendPPPMessageToEngine( &PppMessage ) );
}
//**
//
// Call: PppStop
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will create a PPPEMSG_Stop and send it to the
// worker thread of the PPP engine.
//
DWORD
PppStop(
IN HPORT hPort
)
{
PPPE_MESSAGE PppMessage;
PppLog( 2, "PppStop\r\n" );
PppMessage.hPort = hPort;
PppMessage.dwMsgId = PPPEMSG_Stop;
PppMessage.ExtraInfo.Stop.dwStopReason = NO_ERROR;
return( SendPPPMessageToEngine( &PppMessage ) );
}
//**
//
// Call: PppDdmStop
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will create a PPPEMSG_Stop and send it to the
// worker thread of the PPP engine.
//
DWORD
PppDdmStop(
IN HPORT hPort,
IN DWORD dwStopReason
)
{
PPPE_MESSAGE PppMessage;
PppLog( 2, "PppDdmStop\r\n" );
PppMessage.hPort = hPort;
PppMessage.dwMsgId = PPPEMSG_Stop;
PppMessage.ExtraInfo.Stop.dwStopReason = dwStopReason;
return( SendPPPMessageToEngine( &PppMessage ) );
}
//**
//
// Call: PppDdmSendInterfaceInfo
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will create a PPPEMSG_DdmInterfaceInfo and send it to the
// worker thread of the PPP engine.
//
DWORD
PppDdmSendInterfaceInfo(
IN HCONN hConnection,
IN PPP_INTERFACE_INFO * pInterfaceInfo
)
{
PPPE_MESSAGE PppMessage;
PppMessage.hConnection = hConnection;
PppMessage.dwMsgId = PPPEMSG_DdmInterfaceInfo;
PppMessage.ExtraInfo.InterfaceInfo = *pInterfaceInfo;
return( SendPPPMessageToEngine( &PppMessage ) );
}
//**
//
// Call: PppDdmBapCallbackResult
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will create a PPPEMSG_DdmBapCallbackResult and send it to the
// worker thread of the PPP engine.
//
DWORD
PppDdmBapCallbackResult(
IN HCONN hConnection,
IN DWORD dwBapCallbackResultCode
)
{
PPPE_MESSAGE PppMessage;
PppMessage.hConnection = hConnection;
PppMessage.dwMsgId = PPPEMSG_DdmBapCallbackResult;
PppMessage.ExtraInfo.BapCallbackResult.dwCallbackResultCode
= dwBapCallbackResultCode;
return( SendPPPMessageToEngine( &PppMessage ) );
}
//**
//
// Call: PppDdmChangeNotification
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description:
//
DWORD
PppDdmChangeNotification(
IN DWORD dwServerFlags,
IN DWORD dwLoggingLevel
)
{
PPPE_MESSAGE PppMessage;
PppLog( 2, "PppDdmChangeNotification. New flags: 0x%x", dwServerFlags );
PppMessage.dwMsgId = PPPEMSG_DdmChangeNotification;
PppConfigInfo.ServerConfigInfo.dwConfigMask = dwServerFlags;
PppConfigInfo.dwLoggingLevel = dwLoggingLevel;
return( SendPPPMessageToEngine( &PppMessage ) );
}