1467 lines
34 KiB
C++
1467 lines
34 KiB
C++
//#--------------------------------------------------------------
|
|
//
|
|
// File: controller.cpp
|
|
//
|
|
// Synopsis: Implementation of CController class methods
|
|
//
|
|
//
|
|
// History: 10/02/97 MKarki Created
|
|
// 6/04/98 SBens Added the InfoBase class.
|
|
// 9/09/98 SBens Let the InfoBase know when we're reset.
|
|
// 1/25/00 SBens Clear the ports in InternalCleanup.
|
|
//
|
|
// Copyright (C) 1997-98 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
//----------------------------------------------------------------
|
|
#include "radcommon.h"
|
|
#include "controller.h"
|
|
#include <new>
|
|
|
|
LONG g_lPacketCount = 0;
|
|
LONG g_lThreadCount = 0;
|
|
const DWORD MAX_SLEEP_TIME = 50; //milliseconds
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: CController
|
|
//
|
|
// Synopsis: This is CController class constructor
|
|
//
|
|
// Arguments: NONE
|
|
//
|
|
// Returns: NONE
|
|
//
|
|
//
|
|
// History: MKarki Created 10/2/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
CController::CController (
|
|
VOID
|
|
)
|
|
:m_objCRequestSource (this),
|
|
m_pCSendToPipe (NULL),
|
|
m_pCProxyState (NULL),
|
|
m_pCDictionary (NULL),
|
|
m_pCPacketReceiver (NULL),
|
|
m_pCPreValidator (NULL),
|
|
m_pCPreProcessor (NULL),
|
|
m_pCClients (NULL),
|
|
m_pCHashMD5 (NULL),
|
|
m_pCHashHmacMD5 (NULL),
|
|
m_pCRecvFromPipe (NULL),
|
|
m_pCPacketSender (NULL),
|
|
m_pCReportEvent (NULL),
|
|
m_pCVSAFilter (NULL),
|
|
m_pInfoBase (NULL),
|
|
m_pCTunnelPassword (NULL),
|
|
m_wAuthPort (IAS_DEFAULT_AUTH_PORT),
|
|
m_wAcctPort (IAS_DEFAULT_ACCT_PORT),
|
|
m_dwAuthHandle (0),
|
|
m_dwAcctHandle (0),
|
|
m_pIRequestHandler (NULL),
|
|
m_eRadCompState (COMP_SHUTDOWN)
|
|
{
|
|
} // end of CController constructor
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: ~CController
|
|
//
|
|
// Synopsis: This is CController class destructor
|
|
//
|
|
// Arguments: NONE
|
|
//
|
|
// Returns: NONE
|
|
//
|
|
//
|
|
// History: MKarki Created 10/2/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
CController::~CController(
|
|
VOID
|
|
)
|
|
{
|
|
} // end of CController destructor
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: InitNew
|
|
//
|
|
// Synopsis: This is the InitNew method exposed through the
|
|
// IIasComponent COM Interface. It is used to
|
|
// initialize the RADIUS protocol component
|
|
//
|
|
// Arguments: NONE
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
//
|
|
// History: MKarki Created 10/2/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CController::InitNew (
|
|
VOID
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL bStatus = FALSE;
|
|
|
|
//
|
|
// InitNew can only be called from the shutdown state
|
|
//
|
|
if (COMP_SHUTDOWN != m_eRadCompState)
|
|
{
|
|
IASTracePrintf ("Incorrect state for calling InitNew");
|
|
hr = E_UNEXPECTED;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// create the CReportEvent class object
|
|
//
|
|
m_pCReportEvent = new (std::nothrow) CReportEvent ();
|
|
if (NULL == m_pCReportEvent)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to create ReportEvent object in Controller initialization"
|
|
);
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// create the CTunnelPassword class object
|
|
//
|
|
m_pCTunnelPassword = new (std::nothrow) CTunnelPassword;
|
|
if (NULL == m_pCTunnelPassword)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to create Tunnel-Password object in Controller initialization"
|
|
);
|
|
hr = E_FAIL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// create the VSAFilter class object
|
|
//
|
|
m_pCVSAFilter = new (std::nothrow) VSAFilter;
|
|
if (NULL == m_pCVSAFilter)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to create VSA-Filter object in Controller initialization"
|
|
);
|
|
hr = E_FAIL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// initialize the VSA filter class object
|
|
//
|
|
hr = m_pCVSAFilter->initialize ();
|
|
if (FAILED (hr))
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to initalize VSA-Filter object in Controller initialization"
|
|
);
|
|
delete m_pCVSAFilter;
|
|
m_pCVSAFilter = NULL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// create the CPacketSender class object
|
|
//
|
|
m_pCPacketSender = new (std::nothrow) CPacketSender ();
|
|
if (NULL == m_pCPacketSender)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to create Packet-Sender object in Controller initialization"
|
|
);
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// create the CProxyState class object
|
|
//
|
|
m_pCProxyState = new (std::nothrow) CProxyState ();
|
|
if (NULL == m_pCProxyState)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to create Proxy-State object in Controller initialization"
|
|
);
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// initialize the CProxyState class object
|
|
// TODO - initalize the IP address and the Table Size
|
|
//
|
|
bStatus = m_pCProxyState->Init (212, 1024);
|
|
if (FALSE == bStatus)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to initialize Proxy-State object in Controller initialization"
|
|
);
|
|
hr = E_FAIL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// create the CHashHmacMD5 class object
|
|
//
|
|
m_pCHashHmacMD5 = new (std::nothrow) CHashHmacMD5 ();
|
|
if (NULL == m_pCHashHmacMD5)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to create HMAC-MD5 object in Controller initialization"
|
|
);
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// create the CHashMD5 class object
|
|
//
|
|
m_pCHashMD5 = new (std::nothrow) CHashMD5 ();
|
|
if (NULL == m_pCHashMD5)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to create MD5 object in Controller initialization"
|
|
);
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
|
|
//
|
|
// create the CDictionary class object
|
|
//
|
|
m_pCDictionary = new (std::nothrow) CDictionary ();
|
|
if (NULL == m_pCDictionary)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to create Dictionary object in Controller initialization"
|
|
);
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// initialize the CDictionary class object
|
|
//
|
|
bStatus = m_pCDictionary->Init ();
|
|
if (FALSE == bStatus)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to initialize Dictionary object in Controller initialization"
|
|
);
|
|
hr = E_FAIL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// create the CClients class object
|
|
//
|
|
m_pCClients = new (std::nothrow) CClients ();
|
|
if (NULL == m_pCClients)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to create clients object in Controller initialization"
|
|
);
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// initialize the CClients call object now
|
|
//
|
|
hr = m_pCClients->Init ();
|
|
if (FAILED (hr))
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to initialize clients object in Controller initialization"
|
|
);
|
|
delete m_pCClients;
|
|
m_pCClients = NULL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// create the CSendToPipe class object
|
|
//
|
|
m_pCSendToPipe = new (std::nothrow) CSendToPipe();
|
|
if (NULL == m_pCSendToPipe)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to create Send-To-Pipe object in Controller initialization"
|
|
);
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// create the CPreProcessor class object
|
|
//
|
|
//
|
|
m_pCPreProcessor = new (std::nothrow) CPreProcessor();
|
|
if (NULL == m_pCPreProcessor)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to create Pre-Processor object in Controller initialization"
|
|
);
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// create the CPreValidator class object
|
|
//
|
|
//
|
|
m_pCPreValidator = new (std::nothrow) CPreValidator ();
|
|
if (NULL == m_pCPreValidator)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to create Pre-Validator object in Controller initialization"
|
|
);
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// initialize the CPreProcessor class object
|
|
//
|
|
bStatus = m_pCPreProcessor->Init (
|
|
m_pCPreValidator,
|
|
m_pCHashMD5,
|
|
m_pCProxyState,
|
|
m_pCSendToPipe,
|
|
m_pCPacketSender,
|
|
m_pCReportEvent
|
|
);
|
|
if (FALSE == bStatus)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to initialize Pre-Processor object in Controller initialization"
|
|
);
|
|
hr = E_FAIL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// initialize the CPreValidator class object
|
|
//
|
|
bStatus = m_pCPreValidator->Init (
|
|
m_pCDictionary,
|
|
m_pCPreProcessor,
|
|
m_pCClients,
|
|
m_pCHashMD5,
|
|
m_pCProxyState,
|
|
m_pCSendToPipe,
|
|
m_pCReportEvent
|
|
);
|
|
if (FALSE == bStatus)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to initialize Pre-Validator object in Controller initialization"
|
|
);
|
|
hr = E_FAIL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// create the CRecvFromPipe class object
|
|
//
|
|
m_pCRecvFromPipe = new (std::nothrow) CRecvFromPipe (
|
|
m_pCPreProcessor,
|
|
m_pCHashMD5,
|
|
m_pCHashHmacMD5,
|
|
m_pCClients,
|
|
m_pCVSAFilter,
|
|
m_pCTunnelPassword,
|
|
m_pCReportEvent
|
|
);
|
|
if (NULL == m_pCRecvFromPipe)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to create RecvFromPipe object in Controller initialization"
|
|
);
|
|
hr = E_FAIL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
// create the CPacketReceiver class object
|
|
//
|
|
m_pCPacketReceiver = new (std::nothrow) CPacketReceiver ();
|
|
if (NULL == m_pCPacketReceiver)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to create Packet-Receiver object in Controller initialization"
|
|
);
|
|
hr = E_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// initialize the CPacketReceiver class object
|
|
//
|
|
bStatus = m_pCPacketReceiver->Init (
|
|
m_pCDictionary,
|
|
m_pCPreValidator,
|
|
m_pCHashMD5,
|
|
m_pCHashHmacMD5,
|
|
m_pCClients,
|
|
m_pCReportEvent
|
|
);
|
|
if (FALSE == bStatus)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to initialize Packet-Receiver object "
|
|
"in Controller initialization"
|
|
);
|
|
hr = E_FAIL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
|
|
//
|
|
// initialize the CSendToPipe class object
|
|
//
|
|
bStatus = m_pCSendToPipe->Init (
|
|
reinterpret_cast <IRequestSource*>
|
|
(&m_objCRequestSource),
|
|
m_pCVSAFilter,
|
|
m_pCReportEvent
|
|
);
|
|
if (FALSE == bStatus)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to initialize Send-to-pipe object in Controller initialization"
|
|
);
|
|
hr = E_FAIL;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Create and InitNew the InfoBase object
|
|
//
|
|
CLSID clsid;
|
|
hr = CLSIDFromProgID(IAS_PROGID(InfoBase), &clsid);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = CoCreateInstance(clsid,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
__uuidof(IIasComponent),
|
|
(PVOID*)&m_pInfoBase);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = m_pInfoBase->InitNew();
|
|
}
|
|
}
|
|
if (FAILED(hr))
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to create InfoBase auditor in Controller initialization"
|
|
);
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// reset make the global counts as a precaution
|
|
//
|
|
g_lPacketCount = 0;
|
|
g_lThreadCount = 0;
|
|
|
|
//
|
|
// if we have reached here than InitNew succeeded and we
|
|
// are in Uninitialized state
|
|
//
|
|
m_eRadCompState = COMP_UNINITIALIZED;
|
|
|
|
Cleanup:
|
|
|
|
|
|
//
|
|
// if we failed its time to cleanup
|
|
//
|
|
if (FAILED (hr)) { InternalCleanup (); }
|
|
|
|
return (hr);
|
|
|
|
} // end of CController::OnInit method
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: Load
|
|
//
|
|
// Synopsis: This is the IPersistPropertyBag2 COM Interface
|
|
// method which is called in to indicate that its
|
|
// time to load configuration information from the
|
|
// property bag.
|
|
//
|
|
// Arguments:
|
|
// [in] IPropertyBag2
|
|
// [in] IErrorLog
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
//
|
|
// History: MKarki Created 10/2/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CController::Load (
|
|
IPropertyBag2 *pIPropertyBag,
|
|
IErrorLog *pIErrorLog
|
|
)
|
|
{
|
|
|
|
if ((NULL == pIPropertyBag) || (NULL == pIErrorLog)){return (E_POINTER);}
|
|
|
|
return (S_OK);
|
|
|
|
} // end of CController::Load method
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: Save
|
|
//
|
|
// Synopsis: This is the IPersistPropertyBag2 COM Interface
|
|
// method which is called in to indicate that its
|
|
// time to save configuration information from the
|
|
// property bag.
|
|
//
|
|
// Arguments:
|
|
// [in] IPropertyBag2
|
|
// [in] BOOL - Dirty Bit flag
|
|
// [in] BOOL - save all properties
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
//
|
|
// History: MKarki Created 10/2/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CController::Save (
|
|
IPropertyBag2 *pIPropertyBag,
|
|
BOOL bClearDirty,
|
|
BOOL bSaveAllProperties
|
|
)
|
|
{
|
|
if (NULL == pIPropertyBag) {return (E_POINTER);}
|
|
|
|
return (S_OK);
|
|
|
|
} // end of CController::Save method
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: IsDirty
|
|
//
|
|
// Synopsis: This is the IPersistPropertyBag2 COM Interface
|
|
// method which is called to check if any of the
|
|
// properties data have become dirty
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
//
|
|
// History: MKarki Created 10/2/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CController::IsDirty (
|
|
VOID
|
|
)
|
|
{
|
|
return (S_FALSE);
|
|
|
|
} // end of CController::Save method
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: Initialize
|
|
//
|
|
// Synopsis: This is the OnStart method exposed through the
|
|
// IIasComponent COM Interface. It is used to start
|
|
// processing data
|
|
//
|
|
// Arguments: NONE
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
//
|
|
// History: MKarki Created 10/2/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CController::Initialize (
|
|
VOID
|
|
)
|
|
{
|
|
IASTracePrintf ("Initializing Radius component....");
|
|
|
|
//
|
|
// Initialize call can only be made from Uninitialized state
|
|
//
|
|
if (COMP_INITIALIZED == m_eRadCompState)
|
|
{
|
|
return (S_OK);
|
|
}
|
|
else if (COMP_UNINITIALIZED != m_eRadCompState)
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to initialize Radius Component in this state"
|
|
);
|
|
return (E_UNEXPECTED);
|
|
}
|
|
|
|
//
|
|
// We forward all state transitions to the InfoBase auditor.
|
|
//
|
|
HRESULT hr = m_pInfoBase->Initialize();
|
|
if (FAILED (hr))
|
|
{
|
|
IASTracePrintf ( "InfoBase initialization failed" );
|
|
return (hr);
|
|
}
|
|
|
|
//
|
|
// call the internal initializer now
|
|
//
|
|
hr = InternalInit ();
|
|
if (FAILED (hr)) { return (hr); }
|
|
|
|
//
|
|
// we have finished initialization here
|
|
//
|
|
m_eRadCompState = COMP_INITIALIZED;
|
|
|
|
IASTracePrintf ("Radius component initialized.");
|
|
|
|
return (S_OK);
|
|
|
|
} // end of CController::Start method
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: Shutdown
|
|
//
|
|
// Synopsis: This is the OnShutDown method exposed through the
|
|
// IComponent COM Interface. It is used to stop
|
|
// processing data
|
|
//
|
|
// Arguments: NONE
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
//
|
|
// History: MKarki Created 10/2/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CController::Shutdown (
|
|
VOID
|
|
)
|
|
{
|
|
BOOL bStatus = FALSE;
|
|
HRESULT hr = S_OK;
|
|
|
|
IASTracePrintf ("Shutting down Radius Component...");
|
|
|
|
//
|
|
// shutdown can only be called from the suspend state
|
|
//
|
|
if (COMP_SHUTDOWN == m_eRadCompState)
|
|
{
|
|
return (S_OK);
|
|
}
|
|
else if (
|
|
(COMP_SUSPENDED != m_eRadCompState) &&
|
|
(COMP_UNINITIALIZED != m_eRadCompState)
|
|
)
|
|
{
|
|
IASTracePrintf (
|
|
"Radius component can not be shutdown in this state"
|
|
);
|
|
return (E_UNEXPECTED);
|
|
}
|
|
|
|
//
|
|
// We forward all state transitions to the InfoBase auditor.
|
|
//
|
|
hr = m_pInfoBase->Shutdown();
|
|
if (FAILED (hr))
|
|
{
|
|
IASTracePrintf ("InfoBase shutdown failed");
|
|
}
|
|
|
|
|
|
//
|
|
// do the internal cleanup now
|
|
//
|
|
InternalCleanup ();
|
|
|
|
//
|
|
// we have cleanly shutdown
|
|
//
|
|
m_eRadCompState = COMP_SHUTDOWN;
|
|
|
|
|
|
IASTracePrintf ("Radius component shutdown completed");
|
|
|
|
return (hr);
|
|
|
|
} // end of CController::Shutdown method
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: Suspend
|
|
//
|
|
// Synopsis: This is the Suspend method exposed through the
|
|
// IComponent COM Interface. It is used to suspend
|
|
// packet processing operations
|
|
//
|
|
// Arguments: NONE
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
//
|
|
// History: MKarki Created 10/2/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CController::Suspend (
|
|
VOID
|
|
)
|
|
{
|
|
BOOL bStatus = FALSE;
|
|
HRESULT hr = S_OK;
|
|
|
|
IASTracePrintf ("Suspending Radius component...");
|
|
|
|
//
|
|
// suspend can only be called from the initialized state
|
|
//
|
|
if (COMP_SUSPENDED == m_eRadCompState)
|
|
{
|
|
return (S_OK);
|
|
}
|
|
else if (COMP_INITIALIZED != m_eRadCompState)
|
|
{
|
|
IASTracePrintf (
|
|
"Radius component can not be suspended in current state"
|
|
);
|
|
return (E_UNEXPECTED);
|
|
}
|
|
|
|
//
|
|
// We forward all state transitions to the InfoBase auditor.
|
|
//
|
|
hr = m_pInfoBase->Suspend();
|
|
if (FAILED (hr))
|
|
{
|
|
IASTracePrintf ("Infobase suspend failed");
|
|
}
|
|
|
|
//
|
|
// stop receiving packets now
|
|
//
|
|
bStatus = m_pCPacketReceiver->StopProcessing ();
|
|
if (FALSE == bStatus) { hr = E_FAIL; }
|
|
|
|
//
|
|
// now wait till all requests are completed
|
|
//
|
|
while ( g_lPacketCount )
|
|
{
|
|
IASTracePrintf (
|
|
"Packet Left to process:%d",
|
|
g_lPacketCount
|
|
);
|
|
Sleep (MAX_SLEEP_TIME);
|
|
}
|
|
|
|
//
|
|
// stop sending out packets
|
|
//
|
|
bStatus = m_pCPacketSender->StopProcessing ();
|
|
if (FALSE == bStatus) { hr = E_FAIL; }
|
|
|
|
//
|
|
// stop sending packets to the pipeline
|
|
//
|
|
bStatus = m_pCSendToPipe->StopProcessing ();
|
|
if (FALSE == bStatus) { hr = E_FAIL; }
|
|
|
|
//
|
|
// now wait till allour earlier threads are back
|
|
// and requests are completed
|
|
//
|
|
while ( g_lThreadCount )
|
|
{
|
|
IASTracePrintf (
|
|
"Worker thread active:%d",
|
|
g_lThreadCount
|
|
);
|
|
Sleep (MAX_SLEEP_TIME);
|
|
}
|
|
|
|
//
|
|
// we have successfully suspended RADIUS component's packet
|
|
// processing operations
|
|
//
|
|
m_eRadCompState = COMP_SUSPENDED;
|
|
|
|
IASTracePrintf ("Radius component suspended.");
|
|
|
|
return (hr);
|
|
|
|
} // end of CController::Suspend method
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: Resume
|
|
//
|
|
// Synopsis: This is the Resume method exposed through the
|
|
// IComponent COM Interface. It is used to resume
|
|
// packet processing operations which had been
|
|
// stopped by a previous call to Suspend API
|
|
//
|
|
//
|
|
// Arguments: NONE
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
//
|
|
// History: MKarki Created 10/2/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CController::Resume (
|
|
VOID
|
|
)
|
|
{
|
|
IASTracePrintf ("Resuming Radius component...");
|
|
|
|
if (COMP_SUSPENDED != m_eRadCompState)
|
|
{
|
|
IASTracePrintf ("Can not resume Radius component in current state");
|
|
return (E_UNEXPECTED);
|
|
}
|
|
|
|
//
|
|
// We forward all state transitions to the InfoBase auditor.
|
|
//
|
|
HRESULT hr = m_pInfoBase->Resume();
|
|
if (FAILED (hr))
|
|
{
|
|
IASTracePrintf ("Unable to resume Infobase");
|
|
return (hr);
|
|
}
|
|
|
|
//
|
|
// now call the internal initializer to start up the component
|
|
//
|
|
hr = InternalInit ();
|
|
if (FAILED (hr)) { return (hr); }
|
|
|
|
//
|
|
// we have successfully resumed operations in the RADIUS component
|
|
//
|
|
m_eRadCompState = COMP_INITIALIZED;
|
|
|
|
IASTracePrintf ("Radius componend resumed.");
|
|
|
|
return (S_OK);
|
|
|
|
} // end of CController::Resume method
|
|
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: GetProperty
|
|
//
|
|
// Synopsis: This is the IIasComponent Interface method used
|
|
// to get property information from the RADIUS protocol
|
|
// component
|
|
//
|
|
// Arguments:
|
|
// [in] LONG - id
|
|
// [out] VARIANT - *pValue
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
//
|
|
// History: MKarki Created 10/2/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CController::GetProperty (
|
|
LONG id,
|
|
VARIANT *pValue
|
|
)
|
|
{
|
|
return (S_OK);
|
|
|
|
} // end of CController::GetProperty method
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: PutProperty
|
|
//
|
|
// Synopsis: This is the IIasComponent Interface method used
|
|
// to put property information int the RADIUS protocol
|
|
// component
|
|
//
|
|
// Arguments:
|
|
// [in] LONG - id
|
|
// [out] VARIANT - *pValue
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
//
|
|
// History: MKarki Created 10/2/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CController::PutProperty (
|
|
LONG id,
|
|
VARIANT *pValue
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// PutProperty method can only be called from
|
|
// Uninitialized, Initialized or Suspended state
|
|
//
|
|
if (
|
|
(COMP_UNINITIALIZED != m_eRadCompState) &&
|
|
(COMP_INITIALIZED != m_eRadCompState) &&
|
|
(COMP_SUSPENDED != m_eRadCompState)
|
|
)
|
|
{
|
|
IASTracePrintf ("Unable to PutProperty in current state");
|
|
return (E_UNEXPECTED);
|
|
}
|
|
|
|
//
|
|
// check if valid arguments where passed in
|
|
//
|
|
if (NULL == pValue) { return (E_POINTER); }
|
|
|
|
//
|
|
// carry out the property intialization now
|
|
//
|
|
switch (id)
|
|
{
|
|
|
|
case PROPERTY_RADIUS_ACCOUNTING_PORT:
|
|
|
|
if (VT_BSTR != V_VT (pValue))
|
|
{
|
|
hr = DISP_E_TYPEMISMATCH;
|
|
}
|
|
else if (COMP_INITIALIZED != m_eRadCompState)
|
|
{
|
|
//
|
|
// initialize Accounting Port
|
|
//
|
|
m_objAcctPort.Resolve (pValue);
|
|
}
|
|
break;
|
|
|
|
case PROPERTY_RADIUS_AUTHENTICATION_PORT:
|
|
|
|
if (VT_BSTR != V_VT (pValue))
|
|
{
|
|
hr = DISP_E_TYPEMISMATCH;
|
|
}
|
|
else if (COMP_INITIALIZED != m_eRadCompState)
|
|
{
|
|
//
|
|
// initialize Authentication Port
|
|
//
|
|
m_objAuthPort.Resolve (pValue);
|
|
}
|
|
break;
|
|
|
|
case PROPERTY_RADIUS_CLIENTS_COLLECTION:
|
|
|
|
hr = m_pCClients->SetClients (pValue);
|
|
break;
|
|
|
|
case PROPERTY_PROTOCOL_REQUEST_HANDLER:
|
|
|
|
if (VT_DISPATCH != pValue->vt)
|
|
{
|
|
hr = DISP_E_TYPEMISMATCH;
|
|
}
|
|
else if (NULL == pValue->punkVal)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// initialize the provider
|
|
//
|
|
m_pIRequestHandler = reinterpret_cast <IRequestHandler*>
|
|
(pValue->punkVal);
|
|
m_pIRequestHandler->AddRef ();
|
|
|
|
//
|
|
// now that we have the request handler set,
|
|
// we are ready to start processing requests
|
|
//
|
|
if (COMP_INITIALIZED == m_eRadCompState)
|
|
{
|
|
hr = InternalInit ();
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
hr = DISP_E_MEMBERNOTFOUND;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Tickle the InfoBase to let it know we've been reset.
|
|
//
|
|
m_pInfoBase->PutProperty(0, NULL);
|
|
|
|
return (hr);
|
|
|
|
} // end of CController::PutProperty method
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: InternalInit
|
|
//
|
|
// Synopsis: This is the InternalInit private method
|
|
// of the CController class object which is used
|
|
// to the initialization when the Initialize or
|
|
// Resume methods of the IIasComponent interface
|
|
// are called
|
|
//
|
|
// Arguments: NONE
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
// History: MKarki Created 4/28/98
|
|
//
|
|
//----------------------------------------------------------------
|
|
HRESULT
|
|
CController::InternalInit (
|
|
VOID
|
|
)
|
|
{
|
|
BOOL bStatus = FALSE;
|
|
HRESULT hr = S_OK;
|
|
|
|
__try
|
|
{
|
|
//
|
|
//
|
|
// check if we have the RequestHandler in place
|
|
//
|
|
if (NULL == m_pIRequestHandler) { __leave; }
|
|
|
|
//
|
|
// get the authentication socket set
|
|
//
|
|
fd_set AuthSet;
|
|
hr = m_objAuthPort.GetSocketSet (&AuthSet);
|
|
if (FAILED (hr))
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to obtain Authentication Socket set during "
|
|
"internal initialization of Radius Component"
|
|
);
|
|
__leave;
|
|
}
|
|
|
|
//
|
|
// get the accounting socket set
|
|
//
|
|
fd_set AcctSet;
|
|
hr = m_objAcctPort.GetSocketSet (&AcctSet);
|
|
if (FAILED (hr))
|
|
{
|
|
IASTracePrintf (
|
|
"Unable to obtain Accounting Socket set during "
|
|
"internal initialization of Radius Component"
|
|
);
|
|
__leave;
|
|
}
|
|
|
|
//
|
|
// start sending data to pipe
|
|
//
|
|
bStatus = m_pCSendToPipe->StartProcessing (m_pIRequestHandler);
|
|
if (FALSE == bStatus)
|
|
{
|
|
hr = E_FAIL;
|
|
__leave;
|
|
}
|
|
|
|
//
|
|
// start sending out packets
|
|
//
|
|
bStatus = m_pCPacketSender->StartProcessing ();
|
|
if (FALSE == bStatus)
|
|
{
|
|
hr = E_FAIL;
|
|
__leave;
|
|
}
|
|
|
|
//
|
|
// start receiving packets now
|
|
//
|
|
bStatus = m_pCPacketReceiver->StartProcessing (AuthSet, AcctSet);
|
|
if (FALSE == bStatus)
|
|
{
|
|
hr = E_FAIL;
|
|
__leave;
|
|
}
|
|
|
|
//
|
|
// we have finished internal initialization here
|
|
//
|
|
}
|
|
__finally
|
|
{
|
|
if (FAILED (hr))
|
|
{
|
|
//
|
|
// if failed, disconnect from backend
|
|
//
|
|
m_pCPacketReceiver->StopProcessing ();
|
|
m_pCPacketSender->StopProcessing ();
|
|
m_pCSendToPipe->StopProcessing ();
|
|
}
|
|
}
|
|
|
|
return (hr);
|
|
|
|
} // end of CController::InternalInit method
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: InternalCleanup
|
|
//
|
|
// Synopsis: This is the InternalInit private method
|
|
// of the CController class object which is used
|
|
// to shutdown the internal resources when then
|
|
// InitNew call failed or Shutdown is called
|
|
//
|
|
// Arguments: NONE
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
// History: MKarki Created 4/28/98
|
|
//
|
|
//----------------------------------------------------------------
|
|
VOID
|
|
CController::InternalCleanup (
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// release the IRequestHandler interfaces
|
|
//
|
|
if (m_pIRequestHandler)
|
|
{
|
|
m_pIRequestHandler->Release ();
|
|
m_pIRequestHandler = NULL;
|
|
}
|
|
|
|
//
|
|
// shutdown the VSA filter object
|
|
//
|
|
if (m_pCVSAFilter) { m_pCVSAFilter->shutdown (); }
|
|
|
|
//
|
|
// stop the CClients object from resolving DNS names
|
|
//
|
|
if (m_pCClients) { m_pCClients->Shutdown (); }
|
|
|
|
// Close all the ports.
|
|
m_objAuthPort.Clear();
|
|
m_objAcctPort.Clear();
|
|
|
|
//
|
|
// delete all the internal objects
|
|
//
|
|
if (m_pInfoBase)
|
|
{
|
|
m_pInfoBase->Release();
|
|
m_pInfoBase = NULL;
|
|
}
|
|
|
|
if (m_pCTunnelPassword)
|
|
{
|
|
delete m_pCTunnelPassword;
|
|
m_pCTunnelPassword = NULL;
|
|
}
|
|
|
|
if (m_pCVSAFilter)
|
|
{
|
|
delete m_pCVSAFilter;
|
|
m_pCVSAFilter = NULL;
|
|
}
|
|
|
|
if (m_pCPacketSender)
|
|
{
|
|
delete m_pCPacketSender;
|
|
m_pCPacketSender = NULL;
|
|
}
|
|
|
|
if (m_pCSendToPipe)
|
|
{
|
|
delete m_pCSendToPipe;
|
|
m_pCSendToPipe = NULL;
|
|
}
|
|
|
|
if (m_pCProxyState)
|
|
{
|
|
delete m_pCProxyState;
|
|
m_pCProxyState = NULL;
|
|
}
|
|
|
|
if (m_pCRecvFromPipe)
|
|
{
|
|
delete m_pCRecvFromPipe;
|
|
m_pCRecvFromPipe = NULL;
|
|
}
|
|
|
|
if (m_pCPacketReceiver)
|
|
{
|
|
delete m_pCPacketReceiver;
|
|
m_pCPacketReceiver = NULL;
|
|
}
|
|
|
|
if (m_pCPreProcessor)
|
|
{
|
|
delete m_pCPreProcessor;
|
|
m_pCPreProcessor = NULL;
|
|
}
|
|
|
|
if (m_pCPreValidator)
|
|
{
|
|
delete m_pCPreValidator;
|
|
m_pCPreValidator = NULL;
|
|
}
|
|
|
|
if (m_pCDictionary)
|
|
{
|
|
delete m_pCDictionary;
|
|
m_pCDictionary = NULL;
|
|
}
|
|
|
|
if (m_pCClients)
|
|
{
|
|
delete m_pCClients;
|
|
m_pCClients = NULL;
|
|
}
|
|
|
|
if (m_pCHashMD5)
|
|
{
|
|
delete m_pCHashMD5;
|
|
m_pCHashMD5 = NULL;
|
|
}
|
|
|
|
if (m_pCHashHmacMD5)
|
|
{
|
|
delete m_pCHashHmacMD5;
|
|
m_pCHashHmacMD5 = NULL;
|
|
}
|
|
|
|
if (m_pCReportEvent)
|
|
{
|
|
delete m_pCReportEvent;
|
|
m_pCReportEvent = NULL;
|
|
}
|
|
|
|
return;
|
|
|
|
} // end of CController::InternalCleanup method
|
|
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: OnPropertyChange
|
|
//
|
|
// Synopsis: This is the OnPropertyChange method exposed through the
|
|
// IComponentNotify COM Interface. It is called to notify
|
|
// the component of any change in its properties
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
//
|
|
// History: MKarki Created 12/3/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CController::OnPropertyChange (
|
|
ULONG ulProperties,
|
|
ULONG *pulProperties,
|
|
IPropertyBag2 *pIPropertyBag
|
|
)
|
|
{
|
|
|
|
if ((NULL == pulProperties) || (NULL == pIPropertyBag))
|
|
return (E_POINTER);
|
|
|
|
return (S_OK);
|
|
|
|
} // end of CController::OnPropertyChange method
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: QueryInterfaceReqSrc
|
|
//
|
|
// Synopsis: This is the function called when this Component
|
|
// is called and queried for its IRequestSource
|
|
// interface
|
|
//
|
|
// Arguments: NONE
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
//
|
|
// History: MKarki Created 11/21/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
HRESULT WINAPI
|
|
CController::QueryInterfaceReqSrc (
|
|
PVOID pThis,
|
|
REFIID riid,
|
|
LPVOID *ppv,
|
|
ULONG_PTR ulpValue
|
|
)
|
|
{
|
|
*ppv = &(static_cast<CController*>(pThis))->m_objCRequestSource;
|
|
|
|
//
|
|
// increment count
|
|
//
|
|
((LPUNKNOWN)*ppv)->AddRef();
|
|
|
|
return (S_OK);
|
|
|
|
} // end of CController::QueryInterfaceReqSrc method
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: CRequestSource
|
|
//
|
|
// Synopsis: This is the constructor of the CRequestSource
|
|
// nested class
|
|
//
|
|
// Arguments:
|
|
// CController*
|
|
//
|
|
// Returns:
|
|
//
|
|
//
|
|
// History: MKarki Created 11/21/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
CController::CRequestSource::CRequestSource (
|
|
CController *pCController
|
|
)
|
|
:m_pCController (pCController)
|
|
{
|
|
_ASSERT (pCController);
|
|
|
|
} // end of CRequestSource constructor
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: ~CRequestSource
|
|
//
|
|
// Synopsis: This is the destructor of the CRequestSource
|
|
// nested class
|
|
//
|
|
// Arguments:
|
|
//
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
//
|
|
// History: MKarki Created 11/21/97
|
|
//
|
|
//----------------------------------------------------------------
|
|
CController::CRequestSource::~CRequestSource()
|
|
{
|
|
} // end of CRequestSource destructor
|
|
|
|
//++--------------------------------------------------------------
|
|
//
|
|
// Function: OnRequestComplete
|
|
//
|
|
// Synopsis: This is the function called when a request is
|
|
// is being pushed back after backend processing
|
|
//
|
|
// Arguments:
|
|
// [in] IRequest*
|
|
// [in] IASREQUESTSTATUS
|
|
//
|
|
// Returns: HRESULT - status
|
|
//
|
|
//
|
|
// History: MKarki Created 1/20/98
|
|
//
|
|
//----------------------------------------------------------------
|
|
STDMETHODIMP CController::CRequestSource::OnRequestComplete (
|
|
IRequest *pIRequest,
|
|
IASREQUESTSTATUS eStatus
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL bStatus = FALSE;
|
|
|
|
__try
|
|
{
|
|
if (NULL == pIRequest)
|
|
{
|
|
IASTracePrintf (
|
|
"Invalid argument passed to OnRequestComplete method"
|
|
);
|
|
hr = E_POINTER;
|
|
__leave;
|
|
}
|
|
|
|
//
|
|
// start using this interface in processing outbound
|
|
// requests now
|
|
//
|
|
hr = m_pCController->m_pCRecvFromPipe->Process (pIRequest);
|
|
if (FAILED (hr)) { __leave; }
|
|
|
|
//
|
|
// success
|
|
//
|
|
|
|
}
|
|
__finally
|
|
{
|
|
}
|
|
|
|
return (hr);
|
|
|
|
} // end of CController::CRequestSource::OnRequestComplete method
|