Source code of Windows XP (NT5)
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.

517 lines
14 KiB

  1. //#--------------------------------------------------------------
  2. //
  3. // File: sendtopipe.cpp
  4. //
  5. // Synopsis: Implementation of CSendToPipe class methods
  6. //
  7. //
  8. // History: 11/22/97 MKarki Created
  9. // 06/12/98 SBens Changed put_Response to SetResponse.
  10. //
  11. // Copyright (C) 1997-98 Microsoft Corporation
  12. // All rights reserved.
  13. //
  14. //----------------------------------------------------------------
  15. #include "radcommon.h"
  16. #include "sendtopipe.h"
  17. //+++-------------------------------------------------------------
  18. //
  19. // Function: CSendToPipe
  20. //
  21. // Synopsis: This is the constructor of the CSendToPipe
  22. // class method
  23. //
  24. // Arguments: NONE
  25. //
  26. // Returns: NONE
  27. //
  28. // History: MKarki Created 11/22/97
  29. //
  30. //----------------------------------------------------------------
  31. CSendToPipe::CSendToPipe()
  32. : m_pIRequestHandler (NULL),
  33. m_pIRequestSource (NULL),
  34. m_pIClassFactory (NULL),
  35. m_pCVSAFilter (NULL),
  36. m_pCReportEvent (NULL)
  37. {
  38. } // end of CSendToPipe constructor
  39. //++--------------------------------------------------------------
  40. //
  41. // Function: ~CSendToPipe
  42. //
  43. // Synopsis: This is the destructor of the CSendToPipe
  44. // class method
  45. //
  46. // Arguments: NONE
  47. //
  48. // Returns: NONE
  49. //
  50. // History: MKarki Created 11/22/97
  51. //
  52. //----------------------------------------------------------------
  53. CSendToPipe::~CSendToPipe()
  54. {
  55. if (m_pIClassFactory) { m_pIClassFactory->Release(); }
  56. } // end of CSendToPipe destructor
  57. //+++-------------------------------------------------------------
  58. //
  59. // Function: Process
  60. //
  61. // Synopsis: This is the public method of the CSendToPipe class
  62. // that gets hold of a IRequestRaw interface, puts the
  63. // data in it and sends it on its way.
  64. //
  65. // Arguments:
  66. // [in] CPacketRadius*
  67. //
  68. // Returns: HRESULT - status
  69. //
  70. // History: MKarki Created 11/22/97
  71. //
  72. //----------------------------------------------------------------
  73. HRESULT
  74. CSendToPipe::Process(
  75. CPacketRadius *pCPacketRadius
  76. )
  77. {
  78. BOOL bRetVal = FALSE;
  79. BOOL bStatus = FALSE;
  80. HRESULT hr = S_OK;
  81. IRequest *pIRequest = NULL;
  82. IAttributesRaw *pIAttributesRaw = NULL;
  83. PATTRIBUTEPOSITION pIasAttribPos = NULL;
  84. DWORD dwCount = 0;
  85. DWORD dwRetVal = 0;
  86. PACKETTYPE ePacketType;
  87. IRequestHandler *pIRequestHandler = m_pIRequestHandler;
  88. _ASSERT (pCPacketRadius);
  89. __try
  90. {
  91. //
  92. // check if the pipeline is present to process our
  93. // request
  94. //
  95. if (NULL != pIRequestHandler)
  96. {
  97. pIRequestHandler->AddRef ();
  98. }
  99. else
  100. {
  101. //
  102. // should never reach here
  103. //
  104. _ASSERT (0);
  105. IASTracePrintf (
  106. "Unable to send request to backend as request handler "
  107. "unavailable"
  108. );
  109. hr = E_FAIL;
  110. __leave;
  111. }
  112. //
  113. // create the Request COM object here
  114. //
  115. hr = m_pIClassFactory->CreateInstance (
  116. NULL,
  117. __uuidof (IRequest),
  118. reinterpret_cast <PVOID*> (&pIRequest)
  119. );
  120. if (FAILED (hr))
  121. {
  122. IASTracePrintf (
  123. "Unable to create a Request object from class factory "
  124. "before sending request to backend"
  125. );
  126. __leave;
  127. }
  128. //
  129. // get the packettype
  130. //
  131. ePacketType = pCPacketRadius->GetInCode ();
  132. //
  133. // get the attributes collection
  134. // get the total attributes in the collection
  135. // get as many IASATTRIBUTE structs
  136. // fill in the IAS attribute structs with the appropriate
  137. // values
  138. //
  139. dwCount = pCPacketRadius->GetInAttributeCount();
  140. if (dwCount > 0)
  141. {
  142. //
  143. // get the attributes collection now
  144. //
  145. pIasAttribPos = pCPacketRadius->GetInAttributes ();
  146. //
  147. // if the attribute count is greater than 0 there
  148. // should always be attributes around
  149. //
  150. _ASSERT (pIasAttribPos);
  151. //
  152. // get IAttributesRaw interface
  153. //
  154. hr = pIRequest->QueryInterface (
  155. __uuidof (IAttributesRaw),
  156. reinterpret_cast <PVOID*> (&pIAttributesRaw)
  157. );
  158. if (FAILED (hr))
  159. {
  160. IASTracePrintf (
  161. "Unable to obtain Attributes interface in request object "
  162. "before sending request to backend"
  163. );
  164. __leave;
  165. }
  166. //
  167. // put the attributes collection into the request
  168. //
  169. hr = pIAttributesRaw->AddAttributes (dwCount, pIasAttribPos);
  170. if (FAILED (hr))
  171. {
  172. IASTracePrintf (
  173. "Unable to add Attributes to request object "
  174. "before sending request to backend"
  175. );
  176. __leave;
  177. }
  178. }
  179. //
  180. // set IRequestRaw interface properties
  181. //
  182. hr = SetRequestProperties (
  183. pIRequest,
  184. pCPacketRadius,
  185. ePacketType
  186. );
  187. if (FAILED (hr)) { __leave; }
  188. //
  189. // convert the VSA attributes into IAS format
  190. //
  191. hr = m_pCVSAFilter->radiusToIAS (pIAttributesRaw);
  192. if (FAILED (hr))
  193. {
  194. IASTracePrintf (
  195. "Unable to convert Radius VSAs to IAS attributes in "
  196. "request object before sending it to backend"
  197. );
  198. __leave;
  199. }
  200. //
  201. // now the packet is ready for sending out
  202. //
  203. hr = pIRequestHandler->OnRequest (pIRequest);
  204. if (FAILED (hr))
  205. {
  206. IASTracePrintf ("Unable to send request object to backend");
  207. __leave;
  208. }
  209. //
  210. // success
  211. //
  212. }
  213. __finally
  214. {
  215. if (pIRequestHandler) {pIRequestHandler->Release ();}
  216. if (pIAttributesRaw) {pIAttributesRaw->Release();}
  217. if (pIRequest) {pIRequest->Release();}
  218. }
  219. return (hr);
  220. } // end of CSendToPipe::Process method
  221. //+++-------------------------------------------------------------
  222. //
  223. // Function: Init
  224. //
  225. // Synopsis: This is the CSendToPipe class public method which
  226. // initializes the class object
  227. //
  228. // Arguments:
  229. // [in] IRequestSource*
  230. //
  231. // Returns: BOOL - status
  232. //
  233. // History: MKarki Created 11/22/97
  234. //
  235. //----------------------------------------------------------------
  236. BOOL CSendToPipe::Init (
  237. IRequestSource *pIRequestSource,
  238. VSAFilter *pCVSAFilter,
  239. CReportEvent *pCReportEvent
  240. )
  241. {
  242. BOOL bStatus = TRUE;
  243. HRESULT hr = S_OK;
  244. _ASSERT (pIRequestSource && pCReportEvent && pCVSAFilter);
  245. m_pCReportEvent = pCReportEvent;
  246. m_pCVSAFilter = pCVSAFilter;
  247. //
  248. // get the IClassFactory interface to be used to create
  249. // the Request COM object
  250. // TODO - replace CLSID with __uuidof
  251. //
  252. hr = ::CoGetClassObject (
  253. CLSID_Request,
  254. CLSCTX_INPROC_SERVER,
  255. NULL,
  256. IID_IClassFactory,
  257. reinterpret_cast <PVOID*> (&m_pIClassFactory)
  258. );
  259. if (FAILED (hr))
  260. {
  261. IASTracePrintf (
  262. "Unable to obtain Request object class factory"
  263. );
  264. bStatus = FALSE;
  265. }
  266. else
  267. {
  268. m_pIRequestSource = pIRequestSource;
  269. }
  270. return (bStatus);
  271. } // end of CSendToPipe::Init method
  272. //+++-------------------------------------------------------------
  273. //
  274. // Function: StartProcessing
  275. //
  276. // Synopsis: This is the CSendToPipe class public method which
  277. // gets object ready to send data to the PipeLine
  278. //
  279. // Arguments:
  280. // [in] IRequestHandler*
  281. //
  282. // Returns: BOOL - status
  283. //
  284. // History: MKarki Created 11/22/97
  285. //
  286. //----------------------------------------------------------------
  287. BOOL
  288. CSendToPipe::StartProcessing (
  289. IRequestHandler *pIRequestHandler
  290. )
  291. {
  292. _ASSERT (pIRequestHandler);
  293. //
  294. // set the value of the handler
  295. //
  296. m_pIRequestHandler = pIRequestHandler;
  297. return (TRUE);
  298. } // end of CSendToPipe::StartProcessing method
  299. //+++-------------------------------------------------------------
  300. //
  301. // Function: StopProcessing
  302. //
  303. // Synopsis: This is the CSendToPipe class public method which
  304. // gets object to stop sending data to the PipeLine
  305. //
  306. // Arguments: none
  307. //
  308. // Returns: BOOL - status
  309. //
  310. // History: MKarki Created 11/22/97
  311. //
  312. //----------------------------------------------------------------
  313. BOOL
  314. CSendToPipe::StopProcessing (
  315. VOID
  316. )
  317. {
  318. //
  319. // set the value of the handlers
  320. //
  321. m_pIRequestHandler = NULL;
  322. return (TRUE);
  323. } // end of CSendToPipe::StartProcessing method
  324. //+++-------------------------------------------------------------
  325. //
  326. // Function: SetRequestProperties
  327. //
  328. // Synopsis: This is the CSendToPipe class public method which
  329. // set the properties in the IRequestRaw object
  330. //
  331. // Arguments:
  332. // [in] IRequesetRaw*
  333. // [in] CPacketRadius*
  334. // [in] PACKETTYPE
  335. //
  336. // Returns: HRESULT - status
  337. //
  338. // History: MKarki Created 11/22/97
  339. //
  340. //----------------------------------------------------------------
  341. HRESULT
  342. CSendToPipe::SetRequestProperties (
  343. IRequest *pIRequest,
  344. CPacketRadius *pCPacketRadius,
  345. PACKETTYPE ePacketType
  346. )
  347. {
  348. IRequestState *pIRequestState = NULL;
  349. IASREQUEST eRequest;
  350. IASRESPONSE eResponse;
  351. HRESULT hr = S_OK;
  352. _ASSERT (pIRequest && pCPacketRadius);
  353. __try
  354. {
  355. //
  356. // decide the Request and Response Type
  357. //
  358. switch (ePacketType)
  359. {
  360. case ACCESS_REQUEST:
  361. eRequest = IAS_REQUEST_ACCESS_REQUEST;
  362. eResponse = IAS_RESPONSE_ACCESS_ACCEPT;
  363. break;
  364. case ACCOUNTING_REQUEST:
  365. eRequest = IAS_REQUEST_ACCOUNTING;
  366. eResponse = IAS_RESPONSE_ACCOUNTING;
  367. break;
  368. case ACCESS_ACCEPT:
  369. eRequest = IAS_REQUEST_PROXY_PACKET;
  370. eResponse = IAS_RESPONSE_ACCESS_ACCEPT;
  371. break;
  372. case ACCOUNTING_RESPONSE:
  373. eRequest = IAS_REQUEST_PROXY_PACKET;
  374. eResponse = IAS_RESPONSE_ACCOUNTING;
  375. break;
  376. case ACCESS_CHALLENGE:
  377. eRequest = IAS_REQUEST_PROXY_PACKET;
  378. eResponse = IAS_RESPONSE_ACCESS_CHALLENGE;
  379. break;
  380. default:
  381. //
  382. // should never reach here
  383. //
  384. _ASSERT (0);
  385. IASTracePrintf (
  386. "Packet of unsupported type:%d, before sending request to "
  387. "backend",
  388. static_cast <DWORD> (ePacketType)
  389. );
  390. hr = E_FAIL;
  391. __leave;
  392. break;
  393. }
  394. //
  395. // set the request type now
  396. //
  397. hr = pIRequest->put_Request (eRequest);
  398. if (FAILED (hr))
  399. {
  400. IASTracePrintf (
  401. "Unable to set request type in request before sending "
  402. "it to the backend"
  403. );
  404. __leave;
  405. }
  406. //
  407. // set the protocol now
  408. //
  409. hr = pIRequest->put_Protocol (IAS_PROTOCOL_RADIUS);
  410. if (FAILED (hr))
  411. {
  412. IASTracePrintf (
  413. "Unable to set protocol type in request before sending "
  414. "it to the backend"
  415. );
  416. __leave;
  417. }
  418. //
  419. // Set source callback
  420. //
  421. hr = pIRequest->put_Source (m_pIRequestSource);
  422. if (FAILED (hr))
  423. {
  424. IASTracePrintf (
  425. "Unable to set request source type in request before sending "
  426. "it to the backend"
  427. );
  428. __leave;
  429. }
  430. //
  431. // get the request state interface to put in our state now
  432. //
  433. //
  434. hr = pIRequest->QueryInterface (
  435. __uuidof (IRequestState),
  436. reinterpret_cast <PVOID*> (&pIRequestState)
  437. );
  438. if (FAILED (hr))
  439. {
  440. IASTracePrintf (
  441. "Unable to get RequestState interface from request object "
  442. "before sending it to the backend"
  443. );
  444. __leave;
  445. }
  446. //
  447. // put in the request state now
  448. //
  449. hr = pIRequestState->Push (
  450. reinterpret_cast <unsigned hyper> (pCPacketRadius)
  451. );
  452. if (FAILED (hr))
  453. {
  454. IASTracePrintf (
  455. "Unable to set information in request state "
  456. "before sending request to backend"
  457. );
  458. __leave;
  459. }
  460. //
  461. // success
  462. //
  463. }
  464. __finally
  465. {
  466. if (pIRequestState) { pIRequestState->Release (); }
  467. }
  468. return (hr);
  469. } // end of CSendToPipe::SetRequestProperties method