Leaked source code of windows server 2003
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.

523 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. if (hr == E_INVALIDARG)
  195. {
  196. pCPacketRadius->reportMalformed();
  197. hr = RADIUS_E_ERRORS_OCCURRED;
  198. }
  199. IASTracePrintf (
  200. "Unable to convert Radius VSAs to IAS attributes in "
  201. "request object before sending it to backend"
  202. );
  203. __leave;
  204. }
  205. //
  206. // now the packet is ready for sending out
  207. //
  208. hr = pIRequestHandler->OnRequest (pIRequest);
  209. if (FAILED (hr))
  210. {
  211. IASTracePrintf ("Unable to send request object to backend");
  212. __leave;
  213. }
  214. //
  215. // success
  216. //
  217. }
  218. __finally
  219. {
  220. if (pIRequestHandler) {pIRequestHandler->Release ();}
  221. if (pIAttributesRaw) {pIAttributesRaw->Release();}
  222. if (pIRequest) {pIRequest->Release();}
  223. }
  224. return (hr);
  225. } // end of CSendToPipe::Process method
  226. //+++-------------------------------------------------------------
  227. //
  228. // Function: Init
  229. //
  230. // Synopsis: This is the CSendToPipe class public method which
  231. // initializes the class object
  232. //
  233. // Arguments:
  234. // [in] IRequestSource*
  235. //
  236. // Returns: BOOL - status
  237. //
  238. // History: MKarki Created 11/22/97
  239. //
  240. //----------------------------------------------------------------
  241. BOOL CSendToPipe::Init (
  242. IRequestSource *pIRequestSource,
  243. VSAFilter *pCVSAFilter,
  244. CReportEvent *pCReportEvent
  245. )
  246. {
  247. BOOL bStatus = TRUE;
  248. HRESULT hr = S_OK;
  249. _ASSERT (pIRequestSource && pCReportEvent && pCVSAFilter);
  250. m_pCReportEvent = pCReportEvent;
  251. m_pCVSAFilter = pCVSAFilter;
  252. //
  253. // get the IClassFactory interface to be used to create
  254. // the Request COM object
  255. // TODO - replace CLSID with __uuidof
  256. //
  257. hr = ::CoGetClassObject (
  258. CLSID_Request,
  259. CLSCTX_INPROC_SERVER,
  260. NULL,
  261. IID_IClassFactory,
  262. reinterpret_cast <PVOID*> (&m_pIClassFactory)
  263. );
  264. if (FAILED (hr))
  265. {
  266. IASTracePrintf (
  267. "Unable to obtain Request object class factory"
  268. );
  269. bStatus = FALSE;
  270. }
  271. else
  272. {
  273. m_pIRequestSource = pIRequestSource;
  274. }
  275. return (bStatus);
  276. } // end of CSendToPipe::Init method
  277. //+++-------------------------------------------------------------
  278. //
  279. // Function: StartProcessing
  280. //
  281. // Synopsis: This is the CSendToPipe class public method which
  282. // gets object ready to send data to the PipeLine
  283. //
  284. // Arguments:
  285. // [in] IRequestHandler*
  286. //
  287. // Returns: BOOL - status
  288. //
  289. // History: MKarki Created 11/22/97
  290. //
  291. //----------------------------------------------------------------
  292. BOOL
  293. CSendToPipe::StartProcessing (
  294. IRequestHandler *pIRequestHandler
  295. )
  296. {
  297. _ASSERT (pIRequestHandler);
  298. //
  299. // set the value of the handler
  300. //
  301. m_pIRequestHandler = pIRequestHandler;
  302. return (TRUE);
  303. } // end of CSendToPipe::StartProcessing method
  304. //+++-------------------------------------------------------------
  305. //
  306. // Function: StopProcessing
  307. //
  308. // Synopsis: This is the CSendToPipe class public method which
  309. // gets object to stop sending data to the PipeLine
  310. //
  311. // Arguments: none
  312. //
  313. // Returns: BOOL - status
  314. //
  315. // History: MKarki Created 11/22/97
  316. //
  317. //----------------------------------------------------------------
  318. BOOL
  319. CSendToPipe::StopProcessing (
  320. VOID
  321. )
  322. {
  323. //
  324. // set the value of the handlers
  325. //
  326. m_pIRequestHandler = NULL;
  327. return (TRUE);
  328. } // end of CSendToPipe::StartProcessing method
  329. //+++-------------------------------------------------------------
  330. //
  331. // Function: SetRequestProperties
  332. //
  333. // Synopsis: This is the CSendToPipe class public method which
  334. // set the properties in the IRequestRaw object
  335. //
  336. // Arguments:
  337. // [in] IRequesetRaw*
  338. // [in] CPacketRadius*
  339. // [in] PACKETTYPE
  340. //
  341. // Returns: HRESULT - status
  342. //
  343. // History: MKarki Created 11/22/97
  344. //
  345. //----------------------------------------------------------------
  346. HRESULT
  347. CSendToPipe::SetRequestProperties (
  348. IRequest *pIRequest,
  349. CPacketRadius *pCPacketRadius,
  350. PACKETTYPE ePacketType
  351. )
  352. {
  353. IRequestState *pIRequestState = NULL;
  354. IASREQUEST eRequest;
  355. IASRESPONSE eResponse;
  356. HRESULT hr = S_OK;
  357. _ASSERT (pIRequest && pCPacketRadius);
  358. __try
  359. {
  360. //
  361. // decide the Request and Response Type
  362. //
  363. switch (ePacketType)
  364. {
  365. case ACCESS_REQUEST:
  366. eRequest = IAS_REQUEST_ACCESS_REQUEST;
  367. eResponse = IAS_RESPONSE_ACCESS_ACCEPT;
  368. break;
  369. case ACCOUNTING_REQUEST:
  370. eRequest = IAS_REQUEST_ACCOUNTING;
  371. eResponse = IAS_RESPONSE_ACCOUNTING;
  372. break;
  373. case ACCESS_ACCEPT:
  374. eRequest = IAS_REQUEST_PROXY_PACKET;
  375. eResponse = IAS_RESPONSE_ACCESS_ACCEPT;
  376. break;
  377. case ACCOUNTING_RESPONSE:
  378. eRequest = IAS_REQUEST_PROXY_PACKET;
  379. eResponse = IAS_RESPONSE_ACCOUNTING;
  380. break;
  381. case ACCESS_CHALLENGE:
  382. eRequest = IAS_REQUEST_PROXY_PACKET;
  383. eResponse = IAS_RESPONSE_ACCESS_CHALLENGE;
  384. break;
  385. default:
  386. //
  387. // should never reach here
  388. //
  389. _ASSERT (0);
  390. IASTracePrintf (
  391. "Packet of unsupported type:%d, before sending request to "
  392. "backend",
  393. static_cast <DWORD> (ePacketType)
  394. );
  395. hr = E_FAIL;
  396. __leave;
  397. break;
  398. }
  399. //
  400. // set the request type now
  401. //
  402. hr = pIRequest->put_Request (eRequest);
  403. if (FAILED (hr))
  404. {
  405. IASTracePrintf (
  406. "Unable to set request type in request before sending "
  407. "it to the backend"
  408. );
  409. __leave;
  410. }
  411. //
  412. // set the protocol now
  413. //
  414. hr = pIRequest->put_Protocol (IAS_PROTOCOL_RADIUS);
  415. if (FAILED (hr))
  416. {
  417. IASTracePrintf (
  418. "Unable to set protocol type in request before sending "
  419. "it to the backend"
  420. );
  421. __leave;
  422. }
  423. //
  424. // Set source callback
  425. //
  426. hr = pIRequest->put_Source (m_pIRequestSource);
  427. if (FAILED (hr))
  428. {
  429. IASTracePrintf (
  430. "Unable to set request source type in request before sending "
  431. "it to the backend"
  432. );
  433. __leave;
  434. }
  435. //
  436. // get the request state interface to put in our state now
  437. //
  438. //
  439. hr = pIRequest->QueryInterface (
  440. __uuidof (IRequestState),
  441. reinterpret_cast <PVOID*> (&pIRequestState)
  442. );
  443. if (FAILED (hr))
  444. {
  445. IASTracePrintf (
  446. "Unable to get RequestState interface from request object "
  447. "before sending it to the backend"
  448. );
  449. __leave;
  450. }
  451. //
  452. // put in the request state now
  453. //
  454. hr = pIRequestState->Push (
  455. reinterpret_cast <unsigned hyper> (pCPacketRadius)
  456. );
  457. if (FAILED (hr))
  458. {
  459. IASTracePrintf (
  460. "Unable to set information in request state "
  461. "before sending request to backend"
  462. );
  463. __leave;
  464. }
  465. //
  466. // success
  467. //
  468. }
  469. __finally
  470. {
  471. if (pIRequestState) { pIRequestState->Release (); }
  472. }
  473. return (hr);
  474. } // end of CSendToPipe::SetRequestProperties method