|
|
//#--------------------------------------------------------------
//
// File: crascom.cpp
//
// Synopsis: Implementation of CRasCom class methods
//
//
// History: 2/10/98 MKarki Created
// 5/15/98 SBens Do not consolidate VSAs.
// 9/16/98 SBens Signature of VSAFilter::radiusFromIAS changed.
// 11/17/99 TPerraut Split code for MS-Filter Attribute added
// 428843
//
//
// Copyright (C) Microsoft Corporation
// All rights reserved.
//
//----------------------------------------------------------------
#include "rascominclude.h"
#include "crascom.h"
#include <iastlutl.h>
const DWORD MAX_SLEEP_TIME = 50; //milli-seconds
//
// const and defines below added for the split functions. 428843
//
const CHAR NUL = '\0'; //
// these are the largest values that the attribute type
// packet type have
//
#define MAX_ATTRIBUTE_TYPE 255
//
// these are the related constants
//
#define MAX_ATTRIBUTE_LENGTH 253
#define MAX_VSA_ATTRIBUTE_LENGTH 247
//++--------------------------------------------------------------
//
// Function: SplitAndAdd
//
// Synopsis: This method is used to remove the original attribute
// and add new ones
// Arguments:
// [in] IAttributesRaw*
// [in] PIASATTRIBUTE
// [in] IASTYPE
// [in] DWORD - attribute length
// [in] DWORD - max attribute length
//
// Returns: HRESULT - status
//
// History: MKarki Created 1/19/99
// TPerraut Copied from CRecvFromPipe::SplitAndAdd 11/17/99
//
// Called By: SplitAttributes
//
//----------------------------------------------------------------
HRESULT SplitAndAdd ( /*[in]*/ IAttributesRaw *pIAttributesRaw, /*[in]*/ PIASATTRIBUTE pIasAttribute, /*[in]*/ IASTYPE iasType, /*[in]*/ DWORD dwAttributeLength, /*[in]*/ DWORD dwMaxLength ) { HRESULT hr = S_OK; DWORD dwPacketsNeeded = 0; DWORD dwFailed = 0; PIASATTRIBUTE *ppAttribArray = NULL; PATTRIBUTEPOSITION pAttribPos = NULL;
_ASSERT (pIAttributesRaw && pIasAttribute);
__try { dwPacketsNeeded = dwAttributeLength / dwMaxLength; if (dwAttributeLength % dwMaxLength) {++dwPacketsNeeded;}
//
// allocate memory for the ATTRIBUTEPOSITION array
//
pAttribPos = reinterpret_cast <PATTRIBUTEPOSITION> ( ::CoTaskMemAlloc ( sizeof (ATTRIBUTEPOSITION)*dwPacketsNeeded)); if (NULL == pAttribPos) { IASTracePrintf ( "Unable to allocate memory for attribute position array " "while split and add of attributese in out-bound packet" ); hr = E_OUTOFMEMORY; __leave; }
//
// allocate array to store the attributes in
//
ppAttribArray = reinterpret_cast <PIASATTRIBUTE*> ( ::CoTaskMemAlloc (sizeof (PIASATTRIBUTE)*dwPacketsNeeded)); if (NULL == ppAttribArray) { IASTracePrintf ( "Unable to allocate memory" "while split and add of out-bound attribues" ); hr = E_OUTOFMEMORY; __leave; }
DWORD dwFailed = ::IASAttributeAlloc (dwPacketsNeeded, ppAttribArray); if (0 != dwFailed) { IASTracePrintf ( "Unable to allocate attributes while splitting out-bound" "attributes" ); hr = HRESULT_FROM_WIN32 (dwFailed); __leave; }
if (IASTYPE_STRING == iasType) { PCHAR pStart = (pIasAttribute->Value).String.pszAnsi; DWORD dwCopySize = dwMaxLength;
//
// set value in each of the new attributes
//
for (DWORD dwCount1 = 0; dwCount1 < dwPacketsNeeded; dwCount1++) { (ppAttribArray[dwCount1])->Value.String.pszAnsi = reinterpret_cast <PCHAR> (::CoTaskMemAlloc ((dwCopySize + 1)*sizeof (CHAR))); if (NULL == (ppAttribArray[dwCount1])->Value.String.pszAnsi) { IASTracePrintf ( "Unable to allocate memory for new attribute values" "while split and add of out-bound attribues" ); hr = E_OUTOFMEMORY; __leave; }
//
// set the value now
//
::CopyMemory ( (ppAttribArray[dwCount1])->Value.String.pszAnsi, pStart, dwCopySize ); //
// nul terminate the values
//
((ppAttribArray[dwCount1])->Value.String.pszAnsi)[dwCopySize]=NUL; (ppAttribArray[dwCount1])->Value.itType = iasType; (ppAttribArray[dwCount1])->dwId = pIasAttribute->dwId; (ppAttribArray[dwCount1])->dwFlags = pIasAttribute->dwFlags;
//
// calculate for next attribute
//
pStart = pStart + dwCopySize; dwAttributeLength -= dwCopySize; dwCopySize = (dwAttributeLength > dwMaxLength) ? dwMaxLength : dwAttributeLength;
//
// add attribute to position array
//
pAttribPos[dwCount1].pAttribute = ppAttribArray[dwCount1]; } } else { PBYTE pStart = (pIasAttribute->Value).OctetString.lpValue; DWORD dwCopySize = dwMaxLength;
//
// fill the new attributes now
//
for (DWORD dwCount1 = 0; dwCount1 < dwPacketsNeeded; dwCount1++) { (ppAttribArray[dwCount1])->Value.OctetString.lpValue = reinterpret_cast <PBYTE> (::CoTaskMemAlloc (dwCopySize)); if (NULL ==(ppAttribArray[dwCount1])->Value.OctetString.lpValue) { IASTracePrintf ( "Unable to allocate memory for new attribute values" "while split and add of out-bound attribues" ); hr = E_OUTOFMEMORY; __leave; }
//
// set the value now
//
::CopyMemory ( (ppAttribArray[dwCount1])->Value.OctetString.lpValue, pStart, dwCopySize );
(ppAttribArray[dwCount1])->Value.OctetString.dwLength = dwCopySize; (ppAttribArray[dwCount1])->Value.itType = iasType; (ppAttribArray[dwCount1])->dwId = pIasAttribute->dwId; (ppAttribArray[dwCount1])->dwFlags = pIasAttribute->dwFlags;
//
// calculate for next attribute
//
pStart = pStart + dwCopySize; dwAttributeLength -= dwCopySize; dwCopySize = (dwAttributeLength > dwMaxLength) ? dwMaxLength : dwAttributeLength;
//
// add attribute to position array
//
pAttribPos[dwCount1].pAttribute = ppAttribArray[dwCount1]; } }
//
// add the attribute to the collection
//
hr = pIAttributesRaw->AddAttributes (dwPacketsNeeded, pAttribPos); if (FAILED (hr)) { IASTracePrintf ( "Failed to add attributes to the collection" "on split and add out-bound attributes" ); __leave; } } __finally { if ((FAILED (hr)) && (ppAttribArray) && (0 == dwFailed)) { for (DWORD dwCount = 0; dwCount < dwPacketsNeeded; dwCount++) { ::IASAttributeRelease (ppAttribArray[dwCount]); } }
if (ppAttribArray) {::CoTaskMemFree (ppAttribArray);}
if (pAttribPos) {::CoTaskMemFree (pAttribPos);} }
return (hr);
} // end of SplitAndAdd method
//++--------------------------------------------------------------
//
// Function: SplitAttributes
//
// Synopsis: This method is used to split up the following
// out-bound attributes:
// 1) Reply-Message attribute
// 2) MS-Filter-VSA attribute
// 3) MS QuarantineIpFilter attribute (VSA)
//
// Arguments:
// [in] IAttributesRaw*
//
// Returns: HRESULT - status
//
// History: MKarki Created 1/19/99
// TPerraut Copied from CRecvFromPipe::SplitAttributes
// 11/17/99
//
// Called By: CRasCom::Process method
//
//----------------------------------------------------------------
HRESULT SplitAttributes ( /*[in]*/ IAttributesRaw *pIAttributesRaw ) { const DWORD SPLIT_ATTRIBUTE_COUNT = 3; static DWORD AttribIds [] = { RADIUS_ATTRIBUTE_REPLY_MESSAGE, MS_ATTRIBUTE_FILTER, MS_ATTRIBUTE_QUARANTINE_IPFILTER };
HRESULT hr = S_OK; DWORD dwAttributesFound = 0; PATTRIBUTEPOSITION pAttribPos = NULL;
_ASSERT (pIAttributesRaw);
__try { //
// get the count of the total attributes in the collection
//
DWORD dwAttributeCount = 0; hr = pIAttributesRaw->GetAttributeCount (&dwAttributeCount); if (FAILED (hr)) { IASTracePrintf ( "Unable to obtain attribute count in request while " "splitting attributes in out-bound packet " ); __leave; } else if (0 == dwAttributeCount) { __leave; }
//
// allocate memory for the ATTRIBUTEPOSITION array
//
pAttribPos = reinterpret_cast <PATTRIBUTEPOSITION> ( ::CoTaskMemAlloc ( sizeof (ATTRIBUTEPOSITION)*dwAttributeCount) ); if (NULL == pAttribPos) { IASTracePrintf ( "Unable to allocate memory for attribute position array " "while splitting attributes in out-bound packet" ); hr = E_OUTOFMEMORY; __leave; }
//
// get the attributes we are interested in from the interface
//
hr = pIAttributesRaw->GetAttributes ( &dwAttributeCount, pAttribPos, SPLIT_ATTRIBUTE_COUNT, static_cast <PDWORD> (AttribIds) ); if (FAILED (hr)) { IASTracePrintf ( "Unable to obtain information about attributes" "while splitting attributes in out-bound RADIUS packet" ); __leave; } else if (0 == dwAttributeCount) { __leave; }
//
// save the count of attributes returned
//
dwAttributesFound = dwAttributeCount;
DWORD dwAttribLength = 0; DWORD dwMaxPossibleLength = 0; IASTYPE iasType = IASTYPE_INVALID; //
// evaluate each attribute now
//
for (DWORD dwCount = 0; dwCount < dwAttributeCount; dwCount++) { if ((pAttribPos[dwCount].pAttribute)->dwFlags & IAS_INCLUDE_IN_RESPONSE) { //
// get attribute type and length
//
if ( (iasType = (pAttribPos[dwCount].pAttribute)->Value.itType) == IASTYPE_STRING ) { DWORD dwErr = ::IASAttributeAnsiAlloc(pAttribPos[dwCount].pAttribute); if (dwErr != NO_ERROR) { hr = (HRESULT_FROM_WIN32(dwErr)); __leave; }
dwAttribLength = strlen ( (pAttribPos[dwCount].pAttribute)->Value.String.pszAnsi);
} else if ( (iasType = (pAttribPos[dwCount].pAttribute)->Value.itType) == IASTYPE_OCTET_STRING ) { dwAttribLength = (pAttribPos[dwCount].pAttribute)->Value.OctetString.dwLength; } else { //
// only string values need to be split
//
continue; }
//
// get max possible attribute length
//
if ((pAttribPos[dwCount].pAttribute)->dwId > MAX_ATTRIBUTE_TYPE) { dwMaxPossibleLength = MAX_VSA_ATTRIBUTE_LENGTH; } else { dwMaxPossibleLength = MAX_ATTRIBUTE_LENGTH; }
//
// check if we need to split this attribute
//
if (dwAttribLength <= dwMaxPossibleLength) {continue;}
//
// split the attribute now
//
hr = SplitAndAdd ( pIAttributesRaw, pAttribPos[dwCount].pAttribute, iasType, dwAttribLength, dwMaxPossibleLength ); if (SUCCEEDED (hr)) { //
// remove this attribute from the collection now
//
hr = pIAttributesRaw->RemoveAttributes ( 1, &(pAttribPos[dwCount]) ); if (FAILED (hr)) { IASTracePrintf ( "Unable to remove attribute from collection" "while splitting out-bound attributes" ); } } } } } __finally { if (pAttribPos) { for (DWORD dwCount = 0; dwCount < dwAttributesFound; dwCount++) { ::IASAttributeRelease (pAttribPos[dwCount].pAttribute); }
::CoTaskMemFree (pAttribPos); } }
return (hr);
} // end of SplitAttributes method
//++--------------------------------------------------------------
//
// Function: CRasCom
//
// Synopsis: This is CRasCom Class constructor
//
// Arguments: NONE
//
// Returns: NONE
//
// History: MKarki Created 2/10/98
//
//----------------------------------------------------------------
CRasCom::CRasCom ( VOID ) :m_objCRequestSource (this), m_pIRequestHandler(NULL), m_pIClassFactory (NULL), m_bVSAFilterInitialized (FALSE), m_lRequestCount (0), m_eCompState (COMP_SHUTDOWN) { } // end of CRasCom class constructor
//++--------------------------------------------------------------
//
// Function: ~CRasCom
//
// Synopsis: This is CRasCom class destructor
//
// Arguments: NONE
//
// Returns: NONE
//
//
// History: MKarki Created 2/10/98
//
//----------------------------------------------------------------
CRasCom::~CRasCom( VOID ) { } // end of CRasCom class destructor
//++--------------------------------------------------------------
//
// Function: InitNew
//
// Synopsis: This is the InitNew method exposed through the
// IIasComponent COM Interface.
// For the RasCom Component it is implemented for
// completeness
//
//
// Arguments: none
//
// Returns: HRESULT - status
//
// History: MKarki Created 2/10/98
//
// Called By: by the Component intializer through the IIasComponent
// interface
//
//----------------------------------------------------------------
STDMETHODIMP CRasCom::InitNew ( VOID ) { //
// InitNew call can only be made from SHUTDOWN state
//
if (COMP_SHUTDOWN != m_eCompState) { IASTracePrintf ("The Surrogate can not be called in this state"); return (E_UNEXPECTED); }
//
// reset the total pending request count
//
m_lRequestCount = 0;
//
// now we are initialized
m_eCompState = COMP_UNINITIALIZED;
return (S_OK);
} // end of CRasCom::InitNew method
//++--------------------------------------------------------------
//
// Function: Initialize
//
// Synopsis: This is the Initialize method exposed through the
// IIasComponent COM Interface. It initializes the
// Request object ClassFactory
//
// Arguments: none
//
// Returns: HRESULT - status
//
// History: MKarki Created 2/10/98
//
// Called By: by the Component intializer through the IIasComponent
// interface
//
//----------------------------------------------------------------
STDMETHODIMP CRasCom::Initialize ( VOID ) { HRESULT hr = S_OK;
//
// Initialize call can only be made from Uninitialized state
//
if (COMP_INITIALIZED == m_eCompState) { return (S_OK); } else if (COMP_UNINITIALIZED != m_eCompState) { IASTracePrintf ("The Surrogate can not be initialized in this state"); return (E_UNEXPECTED); }
//
// get the IClassFactory interface to be used to create
// the Request COM object
//
hr = ::CoGetClassObject ( __uuidof (Request), CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, reinterpret_cast <PVOID*> (&m_pIClassFactory) ); if (FAILED (hr)) { IASTracePrintf ("The Surrogate was unable to obtain request factory"); return (hr); }
//
// initialize the VSAFilter class object
//
hr = m_objVSAFilter.initialize (); if (FAILED (hr)) { IASTracePrintf ("The Surrogate was unable to initializa VSA filtering"); m_pIClassFactory->Release (); m_pIClassFactory = NULL; return (hr); } else { m_bVSAFilterInitialized = TRUE; }
//
// correctly initialized the surrogate
//
m_eCompState = COMP_INITIALIZED;
return (S_OK);
} // end of CRasCom::Initialize method
//++--------------------------------------------------------------
//
// Function: Shutdown
//
// Synopsis: This is the ShutDown method exposed through the
// IIasComponent COM Interface. It is used to stop
// processing data
//
// Arguments: NONE
//
// Returns: HRESULT - status
//
// History: MKarki Created 2/10/98
//
// Called By: by the Component shutdown through the IIasComponent
// interface
//
//----------------------------------------------------------------
STDMETHODIMP CRasCom::Shutdown ( VOID ) { BOOL bStatus = FALSE;
//
// shutdown can only be called from the suspend state
//
if (COMP_SHUTDOWN == m_eCompState) { return (S_OK); } else if ( (COMP_SUSPENDED != m_eCompState) && (COMP_UNINITIALIZED != m_eCompState) ) { IASTracePrintf ("The Surrogate can not be shutdown in current state"); return (E_UNEXPECTED); }
//
// release the interfaces
//
if (NULL != m_pIRequestHandler) { m_pIRequestHandler->Release (); m_pIRequestHandler = NULL; }
if (NULL != m_pIClassFactory) { m_pIClassFactory->Release (); m_pIClassFactory = NULL; }
//
// shutdown the VSAFilter
//
if (TRUE == m_bVSAFilterInitialized) { m_objVSAFilter.shutdown (); m_bVSAFilterInitialized = FALSE; }
//
// cleanly shutting down
//
m_eCompState = COMP_SHUTDOWN;
return (S_OK);
} // end of CRasCom::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 CRasCom::Suspend ( VOID ) { BOOL bStatus = FALSE; HRESULT hr = S_OK;
//
// suspend can only be called from the initialized state
//
if (COMP_SUSPENDED == m_eCompState) { return (S_OK); } else if (COMP_INITIALIZED != m_eCompState) { IASTracePrintf ("The Surrogate can not be suspended in current state"); return (E_UNEXPECTED); }
//
// change state
//
m_eCompState = COMP_SUSPENDED;
while (0 != m_lRequestCount) { Sleep (MAX_SLEEP_TIME); }
//
// we have successfully suspended RADIUS component's packet
// processing operations
//
return (hr);
} // end of CRasCom::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 CRasCom::Resume ( VOID ) { if (COMP_SUSPENDED != m_eCompState) { IASTracePrintf ("The Surrogate can not resume in current state"); return (E_UNEXPECTED); }
//
// we have successfully resumed operations in the RADIUS component
//
m_eCompState = COMP_INITIALIZED;
return (S_OK);
} // end of CRasCom::Resume method
//++--------------------------------------------------------------
//
// Function: GetProperty
//
// Synopsis: This is the IIasComponent Interface method.
// Only Implemented for the sake of completeness
//
// Arguments:
// [in] LONG - id
// [out] VARIANT - *pValue
//
// Returns: HRESULT - status
//
//
// History: MKarki Created 2/10/98
//
//----------------------------------------------------------------
STDMETHODIMP CRasCom::GetProperty ( LONG id, VARIANT *pValue ) { return (S_OK);
} // end of CRasCom::GetProperty method
//++--------------------------------------------------------------
//
// Function: PutProperty
//
// Synopsis: This is the IIasComponent Interface method.
// Only Implemented for the sake of completeness
// Arguments:
// [in] LONG - id
// [out] VARIANT - *pValue
//
// Returns: HRESULT - status
//
// History: MKarki Created 2/10/98
//
//----------------------------------------------------------------
STDMETHODIMP CRasCom::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_eCompState) && (COMP_INITIALIZED != m_eCompState) && (COMP_SUSPENDED == m_eCompState) ) { IASTracePrintf ("Surrogate can not put property 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_PROTOCOL_REQUEST_HANDLER:
if (NULL != m_pIRequestHandler) { //
// clients can not be updated in INITIALIZED or
// SUSPENDED state
//
hr = HRESULT_FROM_WIN32 (ERROR_ALREADY_INITIALIZED); } else if (VT_DISPATCH != pValue->vt) { hr = DISP_E_TYPEMISMATCH; } else if (NULL == pValue->punkVal) { hr = E_INVALIDARG; } else { //
// initialize the providers
//
m_pIRequestHandler = reinterpret_cast <IRequestHandler*> (pValue->punkVal); m_pIRequestHandler->AddRef (); } break;
default:
hr = DISP_E_MEMBERNOTFOUND; break; }
return (hr);
} // end of CRasCom::PutProperty method
//++--------------------------------------------------------------
//
// Function: QueryInterfaceReqSrc
//
// Synopsis: This is the function called when this Component
// is called and queried for its IRequestSource
// interface
//
// Arguments:
// [in] PVOID - this object refrence
// [in] REFIID - IID of interface requested
// [out] LPVOID - return appropriate interface
// [in] DWORD
//
//
// Returns: HRESULT - status
//
// History: MKarki Created 2/10/98
//
//----------------------------------------------------------------
HRESULT WINAPI CRasCom::QueryInterfaceReqSrc ( PVOID pThis, REFIID riid, LPVOID *ppv, DWORD_PTR dwValue ) { if ((NULL == pThis) || (NULL == ppv)) return (E_FAIL);
//
// get a reference to the nested CRequestSource object
//
*ppv = &(static_cast<CRasCom*>(pThis))->m_objCRequestSource;
//
// increment count
//
((LPUNKNOWN)*ppv)->AddRef();
return (S_OK);
} // end of CRasCom::QueryInterfaceReqSrc method
//++--------------------------------------------------------------
//
// Function: CRequestSource
//
// Synopsis: This is the constructor of the CRequestSource
// nested class
//
// Arguments:
// [in] CRasCom*
//
// Returns: none
//
// History: MKarki Created 2/10/98
//
//----------------------------------------------------------------
CRasCom::CRequestSource::CRequestSource( CRasCom *pCRasCom ) :m_pCRasCom (pCRasCom) { _ASSERT (NULL != pCRasCom);
} // end of CRequestSource class constructor
//++--------------------------------------------------------------
//
// Function: ~CRequestSource
//
// Synopsis: This is the destructor of the CRequestSource
// nested class
//
// Arguments:
//
// Returns: HRESULT - status
//
//
// History: MKarki Created 11/21/97
//
//----------------------------------------------------------------
CRasCom::CRequestSource::~CRequestSource() { } // end of CRequestSource destructor
//++--------------------------------------------------------------
//
// Function: OnRequestComplete
//
// Synopsis: This is a method of IRequestHandler COM interface
// This is the function called when a request is
// is being pushed back after backend processing
// we just return here as we are only be doing
// synchronous processing
//
// Arguments:
// [in] IRequest*
// [in] IASREQUESTSTATUS
//
// Returns: HRESULT - status
//
// History: MKarki Created 2/10/98
//
// Called By: Pipeline through the IRequestHandler interface
//
//----------------------------------------------------------------
STDMETHODIMP CRasCom::CRequestSource::OnRequestComplete ( IRequest *pIRequest, IASREQUESTSTATUS eStatus ) { BOOL bStatus = FALSE; HANDLE hEvent = NULL; HRESULT hr = S_OK; unsigned hyper uhyState = 0; CComPtr <IRequestState> pIRequestState;
if (NULL == pIRequest) { IASTracePrintf ( "Surrogate passed invalid argumen in OnRequestComplete method" ); return (E_POINTER); }
//
// get the IRequestState interface now
//
hr = pIRequest->QueryInterface ( __uuidof(IRequestState), reinterpret_cast <PVOID*> (&pIRequestState) ); if (FAILED (hr)) { IASTracePrintf ( "Surrogate unable to obtain IRequestState interface in" " OnRequestComplete method" ); return (hr); }
//
// get the CPacketRadius class object
//
hr = pIRequestState->Pop ( reinterpret_cast <unsigned hyper*> (&uhyState) ); if (FAILED (hr)) { IASTracePrintf ( "Surrogate unable to obtain information from Request State" " in OnRequestComplete method" ); return (hr); }
//
// get the hEvent;
//
hEvent = reinterpret_cast <HANDLE> (uhyState);
//
// set the event now
//
bStatus = ::SetEvent (hEvent); if (FALSE == bStatus) { IASTracePrintf ( "Surrogate unable to send notification that request is" " processed in OnRequestComplete method" ); return (E_FAIL); }
return (S_OK);
} // end of CRasCom::CRequestSource::OnRequestComplete method
//++--------------------------------------------------------------
//
// Function: Process
//
// Synopsis: This is the method of the IRecvRequest COM interface
// It is called to generate and send request to the
// pipeline
//
// Arguments:
// [in] DWORD - number of in attributes
// [in] PIASATTRIBUTE* - array of pointer to attribs
// [out] PDWORD - number of out attributes
// [out] PIASATTRIBUTE** - pointer
// [in] LONG
// [in/out]LONG*
// [in] IASPROTCOL
//
// Returns: HRESULT - status
//
// History: MKarki Created 2/10/98
//
// Called By: Called by DoRequest C style API
//
//----------------------------------------------------------------
STDMETHODIMP CRasCom::Process ( /*[in]*/ DWORD dwInAttributeCount, /*[in]*/ PIASATTRIBUTE *ppInIasAttribute, /*[out]*/ PDWORD pdwOutAttributeCount, /*[out]*/ PIASATTRIBUTE **pppOutIasAttribute, /*[in]*/ LONG IasRequest, /*[in/out]*/ LONG *pIasResponse, /*[in]*/ IASPROTOCOL IasProtocol, /*[out]*/ PLONG plReason, /*[in]*/ BOOL bProcessVSA ) {
DWORD dwCount = 0; HRESULT hr = S_OK; HANDLE hEvent = NULL; DWORD dwRetVal = 0; IRequest *pIRequest = NULL; IAttributesRaw *pIAttributesRaw = NULL; IRequestState *pIRequestState = NULL; PATTRIBUTEPOSITION pIasAttribPos = NULL; static DWORD dwRequestCount = 0;
//
// check if processing is enabled
//
if ((COMP_INITIALIZED != m_eCompState) || (NULL == m_pIRequestHandler)) { IASTracePrintf ( "Surrogate passed invalid argument for request processing" ); return (E_FAIL); }
__try { //
// increment the request count
//
InterlockedIncrement (&m_lRequestCount);
// check if we are processing requests at this time
//
if ((COMP_INITIALIZED != m_eCompState) || (NULL == m_pIRequestHandler)) { IASTracePrintf ( "Surrogate unable to process request in the current state" ); hr = E_FAIL; __leave; }
if ( (0 == dwInAttributeCount) || (NULL == ppInIasAttribute) || (NULL == pdwOutAttributeCount) || (NULL == pppOutIasAttribute) || (NULL == pIasResponse) || (NULL == plReason) ) { IASTracePrintf ( "Surrogate passed invalid argument for processing request" ); hr = E_INVALIDARG; __leave; }
_ASSERT (NULL != m_pIClassFactory);
//
// create the request object
//
HRESULT hr = m_pIClassFactory->CreateInstance ( NULL, __uuidof (IRequest), reinterpret_cast <PVOID*> (&pIRequest) ); if (FAILED (hr)) { IASTracePrintf ( "Surrogate failed in creation of a new request object" ); __leave; }
//
// get IAttributesRaw interface
//
hr = pIRequest->QueryInterface ( __uuidof (IAttributesRaw), reinterpret_cast <PVOID*> (&pIAttributesRaw) ); if (FAILED (hr)) { IASTracePrintf ( "Surrogate unable to obtain Attribute interface while" " processing request" ); __leave; }
//
// allocate memory for the ATTRIBUTEPOSITION array
//
pIasAttribPos = reinterpret_cast <PATTRIBUTEPOSITION>( ::CoTaskMemAlloc ( sizeof (ATTRIBUTEPOSITION)*dwInAttributeCount) ); if (NULL == pIasAttribPos) { IASTracePrintf ( "Surrogate unable to allocate memory while processing request" );
hr = E_OUTOFMEMORY; __leave; }
//
// put the attributes in the ATTRIBUTEPOSITION structs
//
for (dwCount = 0; dwCount < dwInAttributeCount; dwCount++) { //
// mark the attribute as having been received from client
//
ppInIasAttribute[dwCount]->dwFlags |= IAS_RECVD_FROM_CLIENT;
pIasAttribPos[dwCount].pAttribute = ppInIasAttribute[dwCount]; }
//
// put the attributes collection that we are holding into the
// Request object through the IAttributesRaw interface
//
hr = pIAttributesRaw->AddAttributes ( dwInAttributeCount, pIasAttribPos ); if (FAILED (hr)) { IASTracePrintf ( "Surrogate failed to add attributes to request being processed" ); __leave; }
//
// set the request type now
//
hr = pIRequest->put_Request (IasRequest); if (FAILED (hr)) { IASTracePrintf ( "Surrogate unable to set the request type for processing" ); __leave; }
//
// set the protocol now
//
hr = pIRequest->put_Protocol (IasProtocol); if (FAILED (hr)) { IASTracePrintf ( "Surrogate unable to set protocol type in request for processing" ); __leave; }
//
// put your IRequestSource interface in now
//
hr = pIRequest->put_Source (&m_objCRequestSource); if (FAILED (hr)) { IASTracePrintf ( "Surrogate unable to set source in request for processing" ); __leave; }
//
// convert the VSA attributes to IAS format if requested
//
if (TRUE == bProcessVSA) { hr = m_objVSAFilter.radiusToIAS (pIAttributesRaw); if (FAILED (hr)) { IASTracePrintf ( "Surrogate unable to convert VSAs to IAS format" ); __leave; } }
//
// create an event which will be used to wake this thread
// when the pipeline does multithreaded processing
//
hEvent = CreateEvent (NULL, TRUE, FALSE, NULL); if (NULL == hEvent) { IASTracePrintf ( "Surrogate unable to create event while processing request" ); __leave; }
//
// get the request state interface to put in our state now
//
//
hr = pIRequest->QueryInterface ( __uuidof (IRequestState), reinterpret_cast <PVOID*> (&pIRequestState) ); if (FAILED (hr)) { IASTracePrintf ( "Surrogate unable to extract request state interface" ); __leave; }
//
// put in the request state - which is our event handle in
//
hr = pIRequestState->Push ( reinterpret_cast <unsigned hyper> (hEvent) ); if (FAILED (hr)) { IASTracePrintf ( "Surrogate unable to set event in request state" ); __leave; }
_ASSERT (NULL != m_pIRequestHandler);
//
// send the request to the pipeline now
//
hr = m_pIRequestHandler->OnRequest (pIRequest); if (FAILED (hr)) { IASTracePrintf ( "Surrogate request failed backend processing..." ); __leave; }
//
// now wait for the event now
//
dwRetVal = ::WaitForSingleObjectEx (hEvent, INFINITE, TRUE); if (0XFFFFFFFF == dwRetVal) { IASTracePrintf ( "Surrogate failed on waiting for process completion" ); hr = E_FAIL; __leave; }
//
// convert the IAS attributes to VSA format if requested
//
if (TRUE == bProcessVSA) { //
// TPERRAUT ADDED Bug 428843
// Always called from RAS with bProcessVSA = true
//
// split the attributes which can not fit in a radius packet
//
hr = SplitAttributes (pIAttributesRaw); if (FAILED (hr)) { IASTracePrintf ( "TPERRAUT: Unable to split IAS attribute received from backend" ); __leave; } // TPERRAUT ADDED: END
hr = m_objVSAFilter.radiusFromIAS (pIAttributesRaw); if (FAILED (hr)) { IASTracePrintf ( "Surrogate failed on extracting VSAs from IAS format" ); __leave; } }
//
// now its time to dismantle the request sent to find out
// what we got back
//
hr = pIRequest->get_Response (pIasResponse); if (FAILED (hr)) { IASTracePrintf ( "Surrogate unable to obtain response from processed request" ); __leave; }
hr = pIRequest->get_Reason (plReason); if (FAILED (hr)) { IASTracePrintf ( "Surrogate unable to obtain reason from processed request" ); __leave; }
//
// remove all the attributes from the request object now
//
hr = RemoveAttributesFromRequest ( *pIasResponse, pIAttributesRaw, pdwOutAttributeCount, pppOutIasAttribute ); if (FAILED (hr)) { IASTracePrintf ( "Surrogate unable to remove attributes from processed request" ); __leave; } }
__finally { //
// do the cleanup now
//
if (NULL != hEvent) { CloseHandle (hEvent); }
if (NULL != pIasAttribPos) { ::CoTaskMemFree (pIasAttribPos); }
if (NULL != pIRequestState) { pIRequestState->Release (); }
if (NULL != pIAttributesRaw) { pIAttributesRaw->Release (); }
if (NULL != pIRequest) { pIRequest->Release (); }
//
// increment the requestreceived
//
dwRequestCount = (0xFFFFFFFF == dwRequestCount) ? 1 : dwRequestCount+ 1;
//
// decrement the request count
//
InterlockedDecrement (&m_lRequestCount); }
return (hr);
} // end of CRasCom::Process method
//++--------------------------------------------------------------
//
// Function: RemoveAttributesFromRequest
//
// Synopsis: This is the CRasCom class private method
// that is used to remove the attributes
// from the Request object through the
// IAttributesRaw interface
//
// Arguments:
// [in] LONG - response received from pipe
// [in] IAttributesRaw*
// [out] PIASATTRIBUTE**
// [out] PDWORD - out attribute count
//
// Returns: HRESULT - status
//
// History: MKarki Created 2/10/98
//
// Called By: CRasCom::Process method
//
//----------------------------------------------------------------
STDMETHODIMP CRasCom::RemoveAttributesFromRequest ( LONG lResponse, IAttributesRaw *pIasAttributesRaw, PDWORD pdwOutAttributeCount, PIASATTRIBUTE **pppIasAttribute ) { HRESULT hr = S_OK; PATTRIBUTEPOSITION pIasOutAttributePos = NULL; DWORD dwCount = 0; DWORD dwAttribCount = 0; DWORD dwOutCount = 0; BOOL bGotAttributes = FALSE; PIASATTRIBUTE pIasAttribute = NULL;
_ASSERT ( (NULL != pIasAttributesRaw) && (NULL != pppIasAttribute) && (NULL != pdwOutAttributeCount) );
__try {
//
// get the count of the attributes remaining in the collection
// these will be the OUT attributes
//
hr = pIasAttributesRaw->GetAttributeCount (&dwAttribCount); if (FAILED (hr)) { IASTracePrintf ( "Surrogate unable to obtain attribute count from request in" "while removing attributes from request" ); __leave; }
//
// allocate memory for the ATTRIBUTEPOSITION array
//
pIasOutAttributePos = reinterpret_cast <PATTRIBUTEPOSITION> ( ::CoTaskMemAlloc ( sizeof (ATTRIBUTEPOSITION)*(dwAttribCount)) ); if (NULL == pIasOutAttributePos) { IASTracePrintf ( "Surrogate unable to allocate memory" "while removing attributes from request" ); hr = E_OUTOFMEMORY; __leave; }
//
// get all the attributes from the collection
//
hr = pIasAttributesRaw->GetAttributes ( &dwAttribCount, pIasOutAttributePos, 0, NULL ); if (FAILED (hr)) { IASTracePrintf ( "Surrogate unable get attributes from request interface" "while removing attributes" ); __leave; }
//
// we have obtained the attributes
//
bGotAttributes = TRUE;
//
// remove the attributes from the collection now
//
hr = pIasAttributesRaw->RemoveAttributes ( dwAttribCount, pIasOutAttributePos ); if (FAILED (hr)) { IASTracePrintf ( "Surrogate unable remove attributes from request" ); __leave; }
//
// calculate the number of attributes not added by the client
//
*pdwOutAttributeCount = 0; for (dwCount = 0; dwCount < dwAttribCount; dwCount++) { pIasAttribute = pIasOutAttributePos[dwCount].pAttribute;
//
// verify that this attributes has to be sent to client
//
if ( ((pIasAttribute->dwFlags & IAS_INCLUDE_IN_ACCEPT) && (IAS_RESPONSE_ACCESS_ACCEPT == lResponse)) || ((pIasAttribute->dwFlags & IAS_INCLUDE_IN_REJECT) && (IAS_RESPONSE_ACCESS_REJECT == lResponse)) || ((pIasAttribute->dwFlags & IAS_INCLUDE_IN_CHALLENGE) && (IAS_RESPONSE_ACCESS_CHALLENGE == lResponse)) ) { (*pdwOutAttributeCount)++; }
}
//
// allocate memory for PIASATTRIBUTE array
//
*pppIasAttribute = reinterpret_cast <PIASATTRIBUTE*> ( ::CoTaskMemAlloc (sizeof(PIASATTRIBUTE)*(*pdwOutAttributeCount)) ); if (NULL == *pppIasAttribute) { IASTracePrintf ( "Surrogate unable to allocate memory for attrib pointer array" "while removing attribute from request" ); hr = E_OUTOFMEMORY; __leave; }
//
// put the attributes in the PIASATTRIBUTE array
//
for (dwCount = 0, dwOutCount = 0; dwCount < dwAttribCount; dwCount++) { pIasAttribute = pIasOutAttributePos[dwCount].pAttribute;
if ( (((pIasAttribute->dwFlags & IAS_INCLUDE_IN_ACCEPT) && (IAS_RESPONSE_ACCESS_ACCEPT == lResponse)) || ((pIasAttribute->dwFlags & IAS_INCLUDE_IN_REJECT) && (IAS_RESPONSE_ACCESS_REJECT == lResponse)) || ((pIasAttribute->dwFlags & IAS_INCLUDE_IN_CHALLENGE) && (IAS_RESPONSE_ACCESS_CHALLENGE == lResponse))) && (dwOutCount < *pdwOutAttributeCount) ) {
//
// put the out attribute in the output array
//
(*pppIasAttribute)[dwOutCount] = pIasAttribute;
dwOutCount++; } else { //
// decrement the reference count for the
// attributes we created or the ones we are
// not sending as out to client
//
::IASAttributeRelease (pIasAttribute); } }
//
// now put in the number of out attribute we are actually
// giving the client
//
*pdwOutAttributeCount = dwOutCount;
} __finally {
//
// cleanup on failure
//
if (FAILED (hr)) { if (NULL != *pppIasAttribute) { ::CoTaskMemFree (*pppIasAttribute); pppIasAttribute = NULL; }
//
// correct the out attribute count
//
*pdwOutAttributeCount = 0;
//
// free up all the attributes also
//
if ((TRUE == bGotAttributes) && (NULL != pIasOutAttributePos)) { for (dwCount = 0; dwCount < dwAttribCount; dwCount++) { ::IASAttributeRelease ( pIasOutAttributePos[dwCount].pAttribute ); } } }
//
// delete the dynamically allocated memory
//
if (NULL != pIasOutAttributePos) { ::CoTaskMemFree (pIasOutAttributePos); } }
return (hr);
} // end of CRasCom::RemoveAttributesFromRequest method
|