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.

2763 lines
73 KiB

  1. //#--------------------------------------------------------------
  2. //
  3. // File: packetradius.cpp
  4. //
  5. // Synopsis: Implementation of CPacketRadius class methods
  6. //
  7. //
  8. // History: 9/23/97 MKarki Created
  9. //
  10. // Copyright (C) 1997-2001 Microsoft Corporation
  11. // All rights reserved.
  12. //
  13. //----------------------------------------------------------------
  14. #include "radcommon.h"
  15. #include "iasutil.h"
  16. #include "packetradius.h"
  17. const CHAR NUL = '\0';
  18. const DWORD DEFAULT_ATTRIB_ARRAY_SIZE = 64;
  19. memory_pool<MAX_PACKET_SIZE, task_allocator> CPacketRadius::m_OutBufferPool;
  20. namespace
  21. {
  22. const DWORDLONG UNIX_EPOCH = 116444736000000000ui64;
  23. }
  24. void CPacketRadius::reportMalformed() const throw ()
  25. {
  26. PCWSTR strings[] = { GetClientName() };
  27. IASReportEvent(
  28. RADIUS_E_MALFORMED_PACKET,
  29. 1,
  30. GetInLength(),
  31. strings,
  32. GetInPacket()
  33. );
  34. }
  35. //++--------------------------------------------------------------
  36. //
  37. // Function: CPacketRadius
  38. //
  39. // Synopsis: This is the constructor of the CPacketRadius class
  40. //
  41. // Arguments: NONE
  42. //
  43. // Returns: NONE
  44. //
  45. //
  46. // History: MKarki Created 9/23/97
  47. //
  48. //----------------------------------------------------------------
  49. CPacketRadius::CPacketRadius(
  50. CHashMD5 *pCHashMD5,
  51. CHashHmacMD5 *pCHashHmacMD5,
  52. IIasClient *pIIasClient,
  53. CReportEvent *pCReportEvent,
  54. PBYTE pInBuffer,
  55. DWORD dwInLength,
  56. DWORD dwIPAddress,
  57. WORD wInPort,
  58. SOCKET sock,
  59. PORTTYPE portType
  60. )
  61. : m_wInPort (wInPort),
  62. m_dwInIPaddress (dwIPAddress),
  63. m_socket (sock),
  64. m_porttype (portType),
  65. m_pCProxyInfo (NULL),
  66. m_pCHashMD5 (pCHashMD5),
  67. m_pCHashHmacMD5 (pCHashHmacMD5),
  68. m_pIIasClient (pIIasClient),
  69. m_pCReportEvent (pCReportEvent),
  70. m_pIasAttribPos (NULL),
  71. m_pInPacket (pInBuffer),
  72. m_dwInLength(dwInLength),
  73. m_pOutPacket (NULL),
  74. m_pInSignature (NULL),
  75. m_pOutSignature(NULL),
  76. m_pUserName (NULL),
  77. m_pPasswordAttrib (NULL)
  78. {
  79. _ASSERT (
  80. (NULL != pInBuffer) &&
  81. (NULL != pCHashMD5) &&
  82. (NULL != pCHashHmacMD5) &&
  83. (NULL != pIIasClient)
  84. );
  85. m_pIIasClient->AddRef ();
  86. } // end of CPacketRadius constructor
  87. //++--------------------------------------------------------------
  88. //
  89. // Function: ~CPacketRadius
  90. //
  91. // Synopsis: This is the destructor of the CPacketRadius class
  92. //
  93. // Arguments: NONE
  94. //
  95. // Returns: NONE
  96. //
  97. // History: MKarki Created 9/23/97
  98. //
  99. //----------------------------------------------------------------
  100. CPacketRadius::~CPacketRadius()
  101. {
  102. if (NULL != m_pIasAttribPos)
  103. {
  104. //
  105. // release the attribute
  106. //
  107. for (
  108. DWORD dwCount = 0;
  109. dwCount < (m_dwInAttributeCount + COMPONENT_SPECIFIC_ATTRIBUTE_COUNT);
  110. dwCount++
  111. )
  112. {
  113. ::IASAttributeRelease (m_pIasAttribPos[dwCount].pAttribute);
  114. }
  115. //
  116. // delete the attribute position array now
  117. //
  118. ::CoTaskMemFree (m_pIasAttribPos);
  119. }
  120. //
  121. // release the reference to Client object
  122. //
  123. if (m_pIIasClient) { m_pIIasClient->Release ();}
  124. //
  125. // delete the out-packet buffer
  126. //
  127. if (m_pOutPacket) { m_OutBufferPool.deallocate (m_pOutPacket); }
  128. //
  129. // delete the in packet buffer
  130. //
  131. if (m_pInPacket) { ::CoTaskMemFree (m_pInPacket); }
  132. } // end of CPacketRadius destructor
  133. //+++-------------------------------------------------------------
  134. //
  135. // Function: PrelimVerification
  136. //
  137. // Synopsis: The method starts the verification of the
  138. // buffer passed in this is done only when
  139. // the class objec is created for an inbound
  140. // packet
  141. //
  142. // Arguments:
  143. // [in] CDictionary*
  144. // [in] DWORD - size of the buffer provided
  145. //
  146. // Returns: HRESULT - status
  147. //
  148. // Called By: CPacketReceiver::ReceivePacket class method
  149. //
  150. // History: MKarki Created 9/23/97
  151. //
  152. //----------------------------------------------------------------
  153. HRESULT
  154. CPacketRadius::PrelimVerification (
  155. CDictionary *pCDictionary,
  156. DWORD dwBufferSize
  157. )
  158. {
  159. PRADIUSPACKET pPacket = NULL;
  160. DWORD dwAttribCount = 0;
  161. TCHAR szErrorString [IAS_ERROR_STRING_LENGTH];
  162. HRESULT hr = S_OK;
  163. __try
  164. {
  165. //
  166. // check that the buffer received is atleast big enough to
  167. // accomdate out RADIUSPACKET struct
  168. //
  169. if (dwBufferSize < MIN_PACKET_SIZE)
  170. {
  171. IASTracePrintf (
  172. "Packet received is smaller than minimum Radius packet"
  173. );
  174. reportMalformed();
  175. m_pCReportEvent->Process (
  176. RADIUS_MALFORMED_PACKET,
  177. (AUTH_PORTTYPE == GetPortType ())?
  178. ACCESS_REQUEST:ACCOUNTING_REQUEST,
  179. dwBufferSize,
  180. m_dwInIPaddress,
  181. NULL,
  182. static_cast <LPVOID> (m_pInPacket)
  183. );
  184. hr = RADIUS_E_ERRORS_OCCURRED;
  185. __leave;
  186. }
  187. pPacket = reinterpret_cast <PRADIUSPACKET> (m_pInPacket);
  188. //
  189. // now save values in host byte order
  190. //
  191. m_wInPacketLength = ntohs (pPacket->wLength);
  192. //
  193. // validate the fields of the packet, except the attributes
  194. //
  195. hr = ValidatePacketFields (dwBufferSize);
  196. if (FAILED (hr)) { __leave; }
  197. //
  198. // verify that the attributes are completely formed
  199. //
  200. hr = VerifyAttributes (pCDictionary);
  201. if (FAILED (hr)) { __leave; }
  202. //
  203. // now we have to create the attributes collection
  204. //
  205. hr = CreateAttribCollection (pCDictionary);
  206. if (FAILED (hr)) { __leave; }
  207. //
  208. // success
  209. //
  210. }
  211. __finally
  212. {
  213. }
  214. return (hr);
  215. } // end of CPacketRadius::PrelimVerification method
  216. //+++-------------------------------------------------------------
  217. //
  218. // Function: VerifyAttributes
  219. //
  220. // Synopsis: This is a CPacketRadius class private method used
  221. // verify that the attributes received are well formed
  222. //
  223. // Arguments: none
  224. //
  225. // Returns: HRESULT - status
  226. //
  227. // History: MKarki Created 10/3/97
  228. //
  229. // Called By: CPacketRadius::PrelimVerification method
  230. //
  231. //----------------------------------------------------------------
  232. HRESULT
  233. CPacketRadius::VerifyAttributes (
  234. CDictionary *pCDictionary
  235. )
  236. { PRADIUSPACKET pPacketEnd = NULL;
  237. PRADIUSPACKET pPacketStart = NULL;
  238. PATTRIBUTE pAttrib = NULL;
  239. DWORD dwAttribCount = 0;
  240. TCHAR szErrorString [IAS_ERROR_STRING_LENGTH];
  241. HRESULT hr = S_OK;
  242. BOOL bStatus = FALSE;
  243. _ASSERT (pCDictionary);
  244. __try
  245. {
  246. pPacketStart = reinterpret_cast <PRADIUSPACKET> (m_pInPacket);
  247. //
  248. // get a pointer to the packet end
  249. //
  250. pPacketEnd = reinterpret_cast <PRADIUSPACKET> (
  251. reinterpret_cast <PBYTE> (pPacketStart)
  252. + m_wInPacketLength
  253. );
  254. //
  255. // go through the attributes once, to verify they are of correct
  256. // length
  257. //
  258. pAttrib = reinterpret_cast <PATTRIBUTE> (pPacketStart->AttributeStart);
  259. const DWORD dwMinAttribOffset = sizeof (ATTRIBUTE) - sizeof (BYTE);
  260. while (static_cast <PVOID> (
  261. reinterpret_cast <PBYTE> (pAttrib) +
  262. dwMinAttribOffset
  263. ) <=
  264. static_cast <PVOID> (pPacketEnd)
  265. )
  266. {
  267. //
  268. // verify that the attributes is of correct length
  269. // and in any case not of length 0
  270. // MKarki Fix #147284
  271. // Fix summary - forgot the "__leave"
  272. //
  273. if (pAttrib->byLength < ATTRIBUTE_HEADER_SIZE)
  274. {
  275. reportMalformed();
  276. m_pCReportEvent->Process (
  277. RADIUS_MALFORMED_PACKET,
  278. GetInCode (),
  279. m_wInPacketLength,
  280. m_dwInIPaddress,
  281. NULL,
  282. static_cast <LPVOID> (m_pInPacket)
  283. );
  284. hr = RADIUS_E_ERRORS_OCCURRED;
  285. __leave;
  286. }
  287. //
  288. // move to the next attribute
  289. //
  290. pAttrib = reinterpret_cast <PATTRIBUTE> (
  291. reinterpret_cast <PBYTE> (pAttrib) +
  292. pAttrib->byLength
  293. );
  294. //
  295. // count the attributes
  296. //
  297. dwAttribCount++;
  298. }
  299. //
  300. // if the attributes don't addup to end of packet
  301. //
  302. if (static_cast <PVOID> (pAttrib) != static_cast <PVOID> (pPacketEnd))
  303. {
  304. IASTracePrintf (
  305. "Attributes do not add up to end of Radius packet"
  306. );
  307. reportMalformed();
  308. m_pCReportEvent->Process (
  309. RADIUS_MALFORMED_PACKET,
  310. GetInCode (),
  311. m_wInPacketLength,
  312. m_dwInIPaddress,
  313. NULL,
  314. static_cast <LPVOID> (m_pInPacket)
  315. );
  316. hr = RADIUS_E_ERRORS_OCCURRED;
  317. __leave;
  318. }
  319. //
  320. // verified
  321. //
  322. m_dwInAttributeCount = dwAttribCount;
  323. }
  324. __finally
  325. {
  326. }
  327. return (hr);
  328. } // end of CPacketRadius::VerifyAttributes method
  329. //+++-------------------------------------------------------------
  330. //
  331. // Function: CreateAttribCollection
  332. //
  333. // Synopsis: This is a CPacketRadius class private method used
  334. // to put the RADIUS attributes into the CAttributes
  335. // collection
  336. //
  337. // Arguments: none
  338. //
  339. // Returns: HRESULT - status
  340. //
  341. // History: MKarki Created 9/23/97
  342. //
  343. // Called By: CPacketRadius::Init method
  344. //
  345. //----------------------------------------------------------------
  346. HRESULT
  347. CPacketRadius::CreateAttribCollection(
  348. CDictionary *pCDictionary
  349. )
  350. {
  351. HRESULT hr = S_OK;
  352. PATTRIBUTE pAttrib = NULL;
  353. DWORD dwAttribType = 0;
  354. DWORD dwCount = 0;
  355. DWORD dwRetVal = ERROR_NOT_ENOUGH_MEMORY;
  356. PIASATTRIBUTE AttributePtrArray[DEFAULT_ATTRIB_ARRAY_SIZE];
  357. PIASATTRIBUTE *ppAttribArray = NULL;
  358. PRADIUSPACKET pPacketStart = reinterpret_cast <PRADIUSPACKET>
  359. (m_pInPacket);
  360. const DWORD dwTotalAttribCount = m_dwInAttributeCount +
  361. COMPONENT_SPECIFIC_ATTRIBUTE_COUNT;
  362. _ASSERT (pCDictionary);
  363. //
  364. // allocate an ATTRIBUTEPOSITION array to carry the attribute
  365. // around
  366. //
  367. m_pIasAttribPos = reinterpret_cast <PATTRIBUTEPOSITION> (
  368. ::CoTaskMemAlloc (
  369. sizeof (ATTRIBUTEPOSITION)*dwTotalAttribCount
  370. ));
  371. if (NULL == m_pIasAttribPos)
  372. {
  373. IASTracePrintf (
  374. "Unable to allocate memory for Attribute position array "
  375. "while creating attribute collection"
  376. );
  377. hr = E_OUTOFMEMORY;
  378. goto Cleanup;
  379. }
  380. if (dwTotalAttribCount > DEFAULT_ATTRIB_ARRAY_SIZE)
  381. {
  382. //
  383. // allocate array to store the attributes in
  384. //
  385. ppAttribArray = reinterpret_cast <PIASATTRIBUTE*> (
  386. ::CoTaskMemAlloc (
  387. sizeof (PIASATTRIBUTE)*dwTotalAttribCount
  388. ));
  389. if (NULL == ppAttribArray)
  390. {
  391. IASTracePrintf (
  392. "Unable to allocate memory for Attribute array "
  393. "while creating attribute collection"
  394. );
  395. hr = E_OUTOFMEMORY;
  396. goto Cleanup;
  397. }
  398. }
  399. else
  400. {
  401. //
  402. // the default array is big enough
  403. //
  404. ppAttribArray = AttributePtrArray;
  405. }
  406. //
  407. // create a bunch of new blank attributes to fill up the positions
  408. //
  409. dwRetVal = ::IASAttributeAlloc (dwTotalAttribCount, ppAttribArray);
  410. if (0 != dwRetVal)
  411. {
  412. IASTracePrintf (
  413. "Unable to allocate IAS attribute while creating attribute "
  414. "collection"
  415. );
  416. hr = HRESULT_FROM_WIN32 (dwRetVal);
  417. goto Cleanup;
  418. }
  419. //
  420. // go through the attributes storing them in the collection
  421. //
  422. pAttrib = reinterpret_cast <PATTRIBUTE> (pPacketStart->AttributeStart);
  423. //
  424. // now initialize the IASATTRIBUTE value structs with the values
  425. // in the packet
  426. //
  427. for (dwCount = 0; dwCount < m_dwInAttributeCount; dwCount++)
  428. {
  429. hr = FillInAttributeInfo (
  430. pCDictionary,
  431. static_cast <PACKETTYPE> (pPacketStart->byCode),
  432. ppAttribArray[dwCount],
  433. pAttrib
  434. );
  435. if (FAILED (hr)) { goto Cleanup; }
  436. //
  437. // now put this in the attribute position structure
  438. //
  439. m_pIasAttribPos[dwCount].pAttribute = ppAttribArray[dwCount];
  440. //
  441. // now store a reference to the attribute here if its
  442. // a User-Password attribute, because we know we will
  443. // access it later and don't want to have to search for
  444. // it
  445. // TODO - do the same kind of stuff for ProxyState
  446. // as we would need the proxystate too.
  447. //
  448. if (USER_PASSWORD_ATTRIB == pAttrib->byType)
  449. {
  450. m_pPasswordAttrib = ppAttribArray[dwCount];
  451. }
  452. else if (SIGNATURE_ATTRIB == pAttrib->byType)
  453. {
  454. //
  455. // for Signature we want its position in the
  456. // raw input buffer
  457. //
  458. m_pInSignature = pAttrib;
  459. }
  460. else if (USER_NAME_ATTRIB == pAttrib->byType)
  461. {
  462. //
  463. // for UserName we want its position in the
  464. // raw input buffer
  465. //
  466. m_pUserName = pAttrib;
  467. }
  468. //
  469. // move to the next attribute now
  470. //
  471. pAttrib = reinterpret_cast <PATTRIBUTE> (
  472. reinterpret_cast <PBYTE> (pAttrib) +
  473. pAttrib->byLength
  474. );
  475. } // end of for loop
  476. //
  477. // put in Client IP address in an attribute
  478. //
  479. hr = FillClientIPInfo (ppAttribArray[m_dwInAttributeCount]);
  480. if (FAILED (hr)) { goto Cleanup; }
  481. m_pIasAttribPos[m_dwInAttributeCount].pAttribute =
  482. ppAttribArray[m_dwInAttributeCount];
  483. //
  484. // put in Client Port number in the attribute
  485. //
  486. hr = FillClientPortInfo (ppAttribArray[m_dwInAttributeCount +1]);
  487. if (FAILED (hr)) { goto Cleanup; }
  488. m_pIasAttribPos[m_dwInAttributeCount +1].pAttribute =
  489. ppAttribArray[m_dwInAttributeCount +1];
  490. //
  491. // put in the packet header information
  492. //
  493. hr = FillPacketHeaderInfo (ppAttribArray[m_dwInAttributeCount +2]);
  494. if (FAILED (hr)) { goto Cleanup; }
  495. m_pIasAttribPos[m_dwInAttributeCount +2].pAttribute =
  496. ppAttribArray[m_dwInAttributeCount +2];
  497. //
  498. // put in the Shared Secret
  499. //
  500. hr = FillSharedSecretInfo (ppAttribArray[m_dwInAttributeCount +3]);
  501. if (FAILED (hr)) { goto Cleanup; }
  502. m_pIasAttribPos[m_dwInAttributeCount +3].pAttribute =
  503. ppAttribArray[m_dwInAttributeCount +3];
  504. //
  505. // put in the Client Vendor Type
  506. //
  507. hr = FillClientVendorType (ppAttribArray[m_dwInAttributeCount +4]);
  508. if (FAILED (hr)) { goto Cleanup; }
  509. m_pIasAttribPos[m_dwInAttributeCount +4].pAttribute =
  510. ppAttribArray[m_dwInAttributeCount +4];
  511. //
  512. // put in the Client Name
  513. //
  514. hr = FillClientName (ppAttribArray[m_dwInAttributeCount +5]);
  515. if (FAILED (hr)) { goto Cleanup; }
  516. m_pIasAttribPos[m_dwInAttributeCount +5].pAttribute =
  517. ppAttribArray[m_dwInAttributeCount +5];
  518. //
  519. // successfully collected attributes
  520. //
  521. Cleanup:
  522. if (FAILED (hr))
  523. {
  524. if (0 == dwRetVal)
  525. {
  526. //
  527. // release the attribute
  528. //
  529. for (dwCount = 0; dwCount < m_dwInAttributeCount; dwCount++)
  530. {
  531. ::IASAttributeRelease (ppAttribArray[dwCount]);
  532. }
  533. }
  534. if (NULL != m_pIasAttribPos)
  535. {
  536. ::CoTaskMemFree (m_pIasAttribPos);
  537. m_pIasAttribPos = NULL;
  538. }
  539. }
  540. //
  541. // the attribute array is always freed
  542. //
  543. if (
  544. (NULL != ppAttribArray) &&
  545. (dwTotalAttribCount > DEFAULT_ATTRIB_ARRAY_SIZE)
  546. )
  547. {
  548. ::CoTaskMemFree (ppAttribArray);
  549. }
  550. return (hr);
  551. } // end of CPacketRadius::CreateAttribCollection method
  552. //+++-------------------------------------------------------------
  553. //
  554. // Function: ValidatePacketFields
  555. //
  556. // Synopsis: This is a CPacketRadius class private method used
  557. // to validate the fields of the RADIUS packet, execpt
  558. // the attributes
  559. //
  560. // Arguments: [in] DWORD - buffer size
  561. //
  562. //
  563. // Returns: HRESULT - status
  564. //
  565. //
  566. // History: MKarki Created 9/23/97
  567. //
  568. // Called By: CPacketRadius::PrelimVerification method
  569. //
  570. //----------------------------------------------------------------
  571. HRESULT
  572. CPacketRadius::ValidatePacketFields(
  573. DWORD dwBufferSize
  574. )
  575. {
  576. HRESULT hr = S_OK;
  577. TCHAR szErrorString [IAS_ERROR_STRING_LENGTH];
  578. PRADIUSPACKET pPacket =
  579. reinterpret_cast <PRADIUSPACKET> (m_pInPacket);
  580. __try
  581. {
  582. //
  583. // check that we have received the complete packet
  584. //
  585. if (m_wInPacketLength > dwBufferSize)
  586. {
  587. //
  588. // log error and generate audit event
  589. //
  590. IASTracePrintf (
  591. "Packet length:%d is greater than received buffer:%d",
  592. m_wInPacketLength,
  593. dwBufferSize
  594. );
  595. reportMalformed();
  596. m_pCReportEvent->Process (
  597. RADIUS_MALFORMED_PACKET,
  598. (AUTH_PORTTYPE== GetPortType ())?
  599. ACCESS_REQUEST:ACCOUNTING_REQUEST,
  600. dwBufferSize,
  601. m_dwInIPaddress,
  602. NULL,
  603. static_cast <LPVOID> (m_pInPacket)
  604. );
  605. hr = RADIUS_E_ERRORS_OCCURRED;
  606. __leave;
  607. }
  608. //
  609. // verify that the packet is of correct lenth;
  610. // i.e between 20 to 4096 octets
  611. //
  612. if (
  613. (m_wInPacketLength < MIN_PACKET_SIZE) ||
  614. (m_wInPacketLength > MAX_PACKET_SIZE)
  615. )
  616. {
  617. //
  618. // Log Error and Audit Event
  619. //
  620. IASTracePrintf (
  621. "Incorrect received packet size:%d",
  622. m_wInPacketLength
  623. );
  624. reportMalformed();
  625. m_pCReportEvent->Process (
  626. RADIUS_MALFORMED_PACKET,
  627. (AUTH_PORTTYPE == GetPortType ())?
  628. ACCESS_REQUEST:ACCOUNTING_REQUEST,
  629. dwBufferSize,
  630. m_dwInIPaddress,
  631. NULL,
  632. static_cast <LPVOID> (m_pInPacket)
  633. );
  634. hr = RADIUS_E_ERRORS_OCCURRED;
  635. __leave;
  636. }
  637. //
  638. // verify that the PACKET code is correct
  639. //
  640. if (
  641. ((ACCESS_REQUEST == static_cast <PACKETTYPE> (pPacket->byCode)) &&
  642. (AUTH_PORTTYPE != GetPortType ()))
  643. ||
  644. ((ACCOUNTING_REQUEST == static_cast<PACKETTYPE>(pPacket->byCode)) &&
  645. (ACCT_PORTTYPE != GetPortType ()))
  646. ||
  647. (((ACCESS_REQUEST != static_cast<PACKETTYPE>(pPacket->byCode))) &&
  648. ((ACCOUNTING_REQUEST != static_cast<PACKETTYPE>(pPacket->byCode))))
  649. )
  650. {
  651. //
  652. // log error and generate audit event
  653. //
  654. IASTracePrintf (
  655. "UnSupported Packet type:%d on this port",
  656. static_cast <INT> (pPacket->byCode)
  657. );
  658. WCHAR packetCode[11];
  659. _ultow(pPacket->byCode, packetCode, 10);
  660. sockaddr_in sin;
  661. int namelen = sizeof(sin);
  662. getsockname(GetSocket(), (sockaddr*)&sin, &namelen);
  663. WCHAR dstPort[11];
  664. _ultow(ntohs(sin.sin_port), dstPort, 10);
  665. PCWSTR strings[] = { packetCode, dstPort, GetClientName() };
  666. IASReportEvent(
  667. RADIUS_E_INVALID_PACKET_TYPE,
  668. 3,
  669. 0,
  670. strings,
  671. NULL
  672. );
  673. m_pCReportEvent->Process (
  674. RADIUS_UNKNOWN_TYPE,
  675. (AUTH_PORTTYPE == GetPortType ())?
  676. ACCESS_REQUEST:ACCOUNTING_REQUEST,
  677. dwBufferSize,
  678. m_dwInIPaddress,
  679. NULL,
  680. static_cast <LPVOID> (m_pInPacket)
  681. );
  682. hr = RADIUS_E_ERRORS_OCCURRED;
  683. __leave;
  684. }
  685. }
  686. __finally
  687. {
  688. }
  689. return (hr);
  690. } // end of CPacketRadius::ValidatePacketFields method
  691. //+++-------------------------------------------------------------
  692. //
  693. // Function: SetPassword
  694. //
  695. // Synopsis: Thie is a CPacketRadius class public method used to
  696. // store the user password.
  697. //
  698. // Arguments: [in] PBYTE - buffer to return password
  699. // [in] PDWORD - holds the buffer size
  700. //
  701. //
  702. // Returns: HRESULT - status
  703. //
  704. // History: MKarki Created 9/23/97
  705. //
  706. //----------------------------------------------------------------
  707. HRESULT
  708. CPacketRadius::SetPassword (
  709. PBYTE pPassword,
  710. DWORD dwSize
  711. )
  712. {
  713. if (dwSize > MAX_ATTRIBUTE_LENGTH)
  714. {
  715. IASTracePrintf (
  716. "Password length is greater than max attribute value size"
  717. );
  718. return (E_INVALIDARG);
  719. }
  720. //
  721. // delete the dynamically allocated memory if its not big enough
  722. //
  723. if (dwSize > m_pPasswordAttrib->Value.OctetString.dwLength)
  724. {
  725. if (NULL != m_pPasswordAttrib->Value.OctetString.lpValue)
  726. {
  727. ::CoTaskMemFree (m_pPasswordAttrib->Value.OctetString.lpValue);
  728. }
  729. //
  730. // allocate memory for OctetString
  731. //
  732. m_pPasswordAttrib->Value.OctetString.lpValue =
  733. reinterpret_cast <PBYTE> (::CoTaskMemAlloc (dwSize));
  734. if (NULL == m_pPasswordAttrib->Value.OctetString.lpValue)
  735. {
  736. IASTracePrintf (
  737. "Unable to allocate memory for password attribute "
  738. "during packet processing"
  739. );
  740. return (E_OUTOFMEMORY);
  741. }
  742. }
  743. //
  744. // copy the value now
  745. //
  746. CopyMemory (
  747. m_pPasswordAttrib->Value.OctetString.lpValue,
  748. pPassword,
  749. dwSize
  750. );
  751. m_pPasswordAttrib->Value.OctetString.dwLength = dwSize;
  752. return (S_OK);
  753. } // end of CPacketRadius::SetPassword method
  754. //+++-------------------------------------------------------------
  755. //
  756. // Function: GetPassword
  757. //
  758. // Synopsis: Thie is a CPacketRadius class public method used to
  759. // return the RADIUS password.
  760. //
  761. // Arguments: [in] PBYTE - buffer to return the password in
  762. // [in/out] PDWORD - holds the buffer size
  763. //
  764. // Returns: HRESULT - status
  765. //
  766. // History: MKarki Created 9/23/97
  767. //
  768. //----------------------------------------------------------------
  769. HRESULT
  770. CPacketRadius :: GetPassword (
  771. PBYTE pbyPassword,
  772. PDWORD pdwBufferSize
  773. )
  774. {
  775. HRESULT hr = S_OK;
  776. _ASSERT ((pbyPassword) && (pdwBufferSize));
  777. if (*pdwBufferSize < m_pPasswordAttrib->Value.OctetString.dwLength)
  778. {
  779. IASTracePrintf (
  780. "Password BufferSize is less than length of password"
  781. );
  782. hr = E_INVALIDARG;
  783. }
  784. else
  785. {
  786. //
  787. // copy the password into the out buffer
  788. //
  789. CopyMemory (
  790. pbyPassword,
  791. m_pPasswordAttrib->Value.OctetString.lpValue,
  792. m_pPasswordAttrib->Value.OctetString.dwLength
  793. );
  794. }
  795. *pdwBufferSize = m_pPasswordAttrib->Value.OctetString.dwLength;
  796. return (hr);
  797. } // end of CPacketRadius::GetPassword method
  798. //++--------------------------------------------------------------
  799. //
  800. // Function: GetUserName
  801. //
  802. // Synopsis: Thie is a CPacketRadius class public method used to
  803. // return the RADIUS UserName
  804. //
  805. // Arguments: [in] PBYTE - buffer to return the password in
  806. // [in/out] PDWORD - holds the buffer size
  807. //
  808. // Returns: BOOL - status
  809. //
  810. // History: MKarki Created 9/23/97
  811. //
  812. //----------------------------------------------------------------
  813. BOOL
  814. CPacketRadius :: GetUserName (
  815. PBYTE pbyUserName,
  816. PDWORD pdwBufferSize
  817. )
  818. {
  819. _ASSERT ((pbyUserName) && (pdwBufferSize));
  820. if (NULL == m_pUserName)
  821. {
  822. IASTracePrintf (
  823. "No User-Name attribute found during packet processing"
  824. );
  825. return (FALSE);
  826. }
  827. DWORD dwNameLength = m_pUserName->byLength - ATTRIBUTE_HEADER_SIZE;
  828. if (*pdwBufferSize < dwNameLength)
  829. {
  830. IASTracePrintf (
  831. "User-Name Buffer Size is less than length of attribute value"
  832. );
  833. return (FALSE);
  834. }
  835. //
  836. // copy the password into the out buffer
  837. //
  838. CopyMemory (pbyUserName, m_pUserName->ValueStart, dwNameLength);
  839. *pdwBufferSize = dwNameLength;
  840. return (TRUE);
  841. } // end of CPacketRadius::GetPassword method
  842. //++--------------------------------------------------------------
  843. //
  844. // Function: IsProxyStatePresent
  845. //
  846. // Synopsis: Thie is a CPacketRadius class public method used to
  847. // check if the RADIUS packet has a proxy state present.
  848. //
  849. //
  850. // Arguments: none
  851. //
  852. //
  853. // Returns: BOOL - status
  854. //
  855. //
  856. // History: MKarki Created 9/23/97
  857. //
  858. //----------------------------------------------------------------
  859. BOOL
  860. CPacketRadius::IsProxyStatePresent (
  861. VOID
  862. )
  863. {
  864. return (NULL != m_pCProxyInfo);
  865. } // end of CPacketRadius::IsProxyStatePresent method
  866. //++--------------------------------------------------------------
  867. //
  868. // Function: GetInAuthenticator
  869. //
  870. // Synopsis: Thie is a CPacketRadius class public method used
  871. // to get the inbound RADIUS packet authenticator
  872. // field.
  873. //
  874. //
  875. // Arguments: [out] PBYTE - buffer to hold authenticator
  876. //
  877. //
  878. // Returns: BOOL - status
  879. //
  880. // History: MKarki Created 9/23/97
  881. //
  882. //----------------------------------------------------------------
  883. HRESULT
  884. CPacketRadius::GetInAuthenticator (
  885. PBYTE pbyAuthenticator,
  886. PDWORD pdwBufSize
  887. )
  888. {
  889. HRESULT hr = S_OK;
  890. PRADIUSPACKET pPacket = reinterpret_cast <PRADIUSPACKET>(m_pInPacket);
  891. _ASSERT ((pbyAuthenticator) && (pdwBufSize) && (pPacket));
  892. if (*pdwBufSize < AUTHENTICATOR_SIZE)
  893. {
  894. hr = E_INVALIDARG;
  895. }
  896. else
  897. {
  898. CopyMemory (
  899. pbyAuthenticator,
  900. pPacket->Authenticator,
  901. AUTHENTICATOR_SIZE
  902. );
  903. }
  904. *pdwBufSize = AUTHENTICATOR_SIZE;
  905. return hr;
  906. } // end of CPacketRadius::GetInAuthenticator method
  907. //++--------------------------------------------------------------
  908. //
  909. // Function: SetOutAuthenticator
  910. //
  911. // Synopsis: Thie is a CPacketRadius class public method used
  912. // to set the RADIUS authenticator field in the outbound
  913. // packet
  914. //
  915. //
  916. // Arguments: [in] PBYTE - buffer hold authenticator
  917. //
  918. //
  919. // Returns: BOOL - status
  920. //
  921. //
  922. // History: MKarki Created 11/11/97
  923. //
  924. //----------------------------------------------------------------
  925. BOOL
  926. CPacketRadius::SetOutAuthenticator (
  927. PBYTE pbyAuthenticator
  928. )
  929. {
  930. PRADIUSPACKET pPacket = reinterpret_cast <PRADIUSPACKET> (m_pOutPacket);
  931. _ASSERT ((pbyAuthenticator) && (pPacket));
  932. CopyMemory (
  933. pPacket->Authenticator,
  934. pbyAuthenticator,
  935. AUTHENTICATOR_SIZE
  936. );
  937. return (TRUE);
  938. } // end of CPacketRadius::SetOutAuthenticator method
  939. //++--------------------------------------------------------------
  940. //
  941. // Function: SetOutSignature
  942. //
  943. // Synopsis: Thie is a CPacketRadius class public method used
  944. // to set the RADIUS Signature attribute value in the
  945. // outbound packet
  946. //
  947. //
  948. // Arguments: [in] PBYTE - buffer holds signature
  949. //
  950. //
  951. // Returns: BOOL - status
  952. //
  953. //
  954. // History: MKarki Created 11/18/98
  955. //
  956. //----------------------------------------------------------------
  957. HRESULT
  958. CPacketRadius::SetOutSignature (
  959. PBYTE pbySignature
  960. )
  961. {
  962. _ASSERT (pbySignature && m_pOutPacket && m_pOutSignature);
  963. CopyMemory (
  964. m_pOutSignature->ValueStart,
  965. pbySignature,
  966. SIGNATURE_SIZE
  967. );
  968. return (S_OK);
  969. } // end of CPacketRadius::SetOutSignature method
  970. //+++-------------------------------------------------------------
  971. //
  972. // Function: GetInCode
  973. //
  974. // Synopsis: Thie is a CPacketRadius class public method used
  975. // to get the inbound RADIUS packet code field.
  976. //
  977. //
  978. // Arguments: none
  979. //
  980. //
  981. // Returns: PACKETTYPE
  982. //
  983. //
  984. // History: MKarki Created 9/23/97
  985. //
  986. //----------------------------------------------------------------
  987. PACKETTYPE
  988. CPacketRadius::GetInCode (
  989. VOID
  990. )
  991. {
  992. PRADIUSPACKET pPacket = reinterpret_cast <PRADIUSPACKET>
  993. (m_pInPacket);
  994. return (static_cast <PACKETTYPE> (pPacket->byCode));
  995. } // end of CPacketRadius::GetInCode method
  996. //++--------------------------------------------------------------
  997. //
  998. // Function: GetOutCode
  999. //
  1000. // Synopsis: Thie is a CPacketRadius class public method used
  1001. // to get the outbound RADIUS packet code field.
  1002. //
  1003. //
  1004. // Arguments: NONE
  1005. //
  1006. //
  1007. // Returns: PACKETTYPE
  1008. //
  1009. //
  1010. // History: MKarki Created 9/23/97
  1011. //
  1012. //----------------------------------------------------------------
  1013. PACKETTYPE
  1014. CPacketRadius::GetOutCode (
  1015. VOID
  1016. )
  1017. {
  1018. PRADIUSPACKET pPacket = reinterpret_cast <PRADIUSPACKET> (m_pOutPacket);
  1019. return (static_cast <PACKETTYPE> (pPacket->byCode));
  1020. } // end of CPacketRadius::GetOutCode method
  1021. //++--------------------------------------------------------------
  1022. //
  1023. // Function: GetOutLength
  1024. //
  1025. // Synopsis: Thie is a CPacketRadius class public method used
  1026. // to get the outbound RADIUS packet length.
  1027. //
  1028. //
  1029. // Arguments: none
  1030. //
  1031. //
  1032. // Returns: WORD - RADIUS in packet length
  1033. //
  1034. //
  1035. // History: MKarki Created 9/23/97
  1036. //
  1037. //----------------------------------------------------------------
  1038. WORD
  1039. CPacketRadius::GetOutLength (
  1040. VOID
  1041. )
  1042. {
  1043. PRADIUSPACKET pPacket = reinterpret_cast <PRADIUSPACKET>
  1044. (m_pOutPacket);
  1045. return (ntohs (pPacket->wLength));
  1046. } // end of CPacketRadius::GetOutLength method
  1047. //++--------------------------------------------------------------
  1048. //
  1049. // Function: SetProxyState
  1050. //
  1051. // Synopsis: Thie is a CPacketRadius class public method used
  1052. // to set the proxy state to TRUE
  1053. //
  1054. // Arguments: none
  1055. //
  1056. // Returns: BOOL - status
  1057. //
  1058. // History: MKarki Created 10/2/97
  1059. //
  1060. //----------------------------------------------------------------
  1061. VOID
  1062. CPacketRadius::SetProxyState (
  1063. VOID
  1064. )
  1065. {
  1066. return;
  1067. } // end of CPacketRadius::SetProxyState method
  1068. //++--------------------------------------------------------------
  1069. //
  1070. // Function: SetProxyInfo
  1071. //
  1072. // Synopsis: Thie is a CPacketRadius class public method used
  1073. // to set the proxy state information for the packet
  1074. //
  1075. // Arguments: [in] CProxyInfo*
  1076. //
  1077. // Returns: BOOL - status
  1078. //
  1079. // History: MKarki Created 10/2/97
  1080. //
  1081. //----------------------------------------------------------------
  1082. BOOL
  1083. CPacketRadius::SetProxyInfo (
  1084. CProxyInfo *pCProxyInfo
  1085. )
  1086. {
  1087. BOOL bRetVal = FALSE;
  1088. _ASSERT (pCProxyInfo);
  1089. m_pCProxyInfo = pCProxyInfo;
  1090. return (TRUE);
  1091. } // end of CPacketRadius::SetProxyInfo method
  1092. //++--------------------------------------------------------------
  1093. //
  1094. // Function: BuildOutPacket
  1095. //
  1096. // Synopsis: This is a CPacketRadius class public method used
  1097. // to build the outbound packet
  1098. //
  1099. // Arguments:
  1100. // [in] PACKETTYPE - out packet type
  1101. // [in] PATTRIBUTEPOSITION - out attributes array
  1102. // [in] DWORD - Attributes Count
  1103. //
  1104. // Returns: HRESULT - status
  1105. //
  1106. // History: MKarki Created 10/22/97
  1107. //
  1108. //----------------------------------------------------------------
  1109. HRESULT
  1110. CPacketRadius::BuildOutPacket (
  1111. PACKETTYPE ePacketType,
  1112. PATTRIBUTEPOSITION pAttribPos,
  1113. DWORD dwTotalAttributes
  1114. )
  1115. {
  1116. BOOL bRetVal = FALSE;
  1117. PRADIUSPACKET pOutPacket = NULL;
  1118. PRADIUSPACKET pInPacket = reinterpret_cast <PRADIUSPACKET> (m_pInPacket);
  1119. PATTRIBUTE pCurrent = NULL;
  1120. PATTRIBUTE pAttribStart = NULL;
  1121. PBYTE pPacketEnd = NULL;
  1122. WORD wAttributeLength = 0;
  1123. DWORD dwPacketLength = 0;
  1124. DWORD dwMaxPossibleAttribLength = 0;
  1125. HRESULT hr = S_OK;
  1126. __try
  1127. {
  1128. dwPacketLength =
  1129. PACKET_HEADER_SIZE +
  1130. dwTotalAttributes*(MAX_ATTRIBUTE_LENGTH + ATTRIBUTE_HEADER_SIZE);
  1131. //
  1132. // limit the packet size to max UDP packet size
  1133. //
  1134. dwPacketLength = (dwPacketLength > MAX_PACKET_SIZE)
  1135. ? MAX_PACKET_SIZE
  1136. : dwPacketLength;
  1137. m_pOutPacket = reinterpret_cast <PBYTE> (m_OutBufferPool.allocate ());
  1138. if (NULL == m_pOutPacket)
  1139. {
  1140. IASTracePrintf (
  1141. "Unable to allocate memory for pool for out-bound packet"
  1142. );
  1143. hr = E_OUTOFMEMORY;
  1144. __leave;
  1145. }
  1146. pOutPacket = reinterpret_cast <PRADIUSPACKET> (m_pOutPacket);
  1147. //
  1148. // put the packet type
  1149. //
  1150. pOutPacket->byCode = ePacketType;
  1151. //
  1152. // put the packet ID
  1153. //
  1154. pOutPacket->byIdentifier = pInPacket->byIdentifier;
  1155. //
  1156. // now fill in the current packet length
  1157. //
  1158. pOutPacket->wLength = htons (PACKET_HEADER_SIZE);
  1159. //
  1160. // get the end of buffer
  1161. //
  1162. pPacketEnd = (reinterpret_cast <PBYTE> (pOutPacket)) + dwPacketLength;
  1163. //
  1164. // goto start of attributes
  1165. //
  1166. pAttribStart = reinterpret_cast <PATTRIBUTE>
  1167. (pOutPacket->AttributeStart);
  1168. //
  1169. // Fix for Bug #190523 - 06/26/98 - MKarki
  1170. // we shouldn't be taking diff of PUNINTs
  1171. //
  1172. dwMaxPossibleAttribLength = static_cast <DWORD> (
  1173. reinterpret_cast<PBYTE> (pPacketEnd) -
  1174. reinterpret_cast<PBYTE> (pAttribStart)
  1175. );
  1176. //
  1177. // filled the attributes now
  1178. //
  1179. for (
  1180. DWORD dwAttribCount = 0;
  1181. dwAttribCount < dwTotalAttributes;
  1182. dwAttribCount++
  1183. )
  1184. {
  1185. if (IsOutBoundAttribute (
  1186. ePacketType,
  1187. pAttribPos[dwAttribCount].pAttribute
  1188. ))
  1189. {
  1190. //
  1191. // fill the attribute in the packet buffer
  1192. //
  1193. hr = FillOutAttributeInfo (
  1194. pAttribStart,
  1195. pAttribPos[dwAttribCount].pAttribute,
  1196. &wAttributeLength,
  1197. dwMaxPossibleAttribLength
  1198. );
  1199. if (FAILED (hr)) { __leave; }
  1200. dwMaxPossibleAttribLength -= wAttributeLength;
  1201. //
  1202. // go to the next attribute start
  1203. //
  1204. PBYTE pTemp = reinterpret_cast <PBYTE> (pAttribStart) +
  1205. wAttributeLength;
  1206. pAttribStart = reinterpret_cast <PATTRIBUTE> (pTemp);
  1207. if ((reinterpret_cast <PBYTE> (pAttribStart)) > pPacketEnd)
  1208. {
  1209. //
  1210. // log error
  1211. //
  1212. IASTracePrintf (
  1213. "Attributes can not fit in out-bound packet"
  1214. );
  1215. hr = RADIUS_E_PACKET_OVERFLOW;
  1216. __leave;
  1217. }
  1218. } // end of if
  1219. } // end of for loop
  1220. m_wOutPort = m_wInPort;
  1221. m_dwOutIPaddress = m_dwInIPaddress;
  1222. //
  1223. // now update the length of the packet
  1224. //
  1225. pOutPacket->wLength = htons (
  1226. (reinterpret_cast <PBYTE> (pAttribStart)) -
  1227. (reinterpret_cast <PBYTE> (pOutPacket))
  1228. );
  1229. //
  1230. // success
  1231. //
  1232. }
  1233. __finally
  1234. {
  1235. }
  1236. if (hr == RADIUS_E_PACKET_OVERFLOW)
  1237. {
  1238. IASReportEvent(
  1239. RADIUS_E_PACKET_OVERFLOW,
  1240. 0,
  1241. 0,
  1242. NULL,
  1243. NULL
  1244. );
  1245. hr = RADIUS_E_ERRORS_OCCURRED;
  1246. }
  1247. return (hr);
  1248. } // end of CPacketRadius::BuildOutPacket method
  1249. //++--------------------------------------------------------------
  1250. //
  1251. // Function: GetInSignature
  1252. //
  1253. // Synopsis: This is CPacketARadius class public method
  1254. // that returns the Signature attribute present
  1255. // in the in bound request
  1256. //
  1257. // Arguments:
  1258. // [out] PBYTE - signature
  1259. //
  1260. // Returns: BOOL - status
  1261. //
  1262. // History: MKarki Created 1/6/98
  1263. //
  1264. //----------------------------------------------------------------
  1265. BOOL
  1266. CPacketRadius::GetInSignature (
  1267. PBYTE pSignatureValue
  1268. )
  1269. {
  1270. BOOL bRetVal = TRUE;
  1271. _ASSERT (pSignatureValue);
  1272. //
  1273. // assuming that the caller provides a buffer of 16 bytes
  1274. // as this the signature size ALWAYS
  1275. //
  1276. if (NULL == m_pInSignature)
  1277. {
  1278. //
  1279. // no signature attribute received
  1280. //
  1281. bRetVal = FALSE;
  1282. }
  1283. else
  1284. {
  1285. CopyMemory (
  1286. pSignatureValue,
  1287. m_pInSignature->ValueStart,
  1288. SIGNATURE_SIZE
  1289. );
  1290. }
  1291. return (bRetVal);
  1292. } // end of CPacketRadius::GetInSignature method
  1293. //++--------------------------------------------------------------
  1294. //
  1295. // Function: GenerateInAuthenticator
  1296. //
  1297. // Synopsis: This is CPacketARadius class public method
  1298. // that generates the authenticator from the
  1299. // input packet
  1300. //
  1301. // Arguments:
  1302. // [in] PBYTE - Inbound Authenticator
  1303. // [out] PBYTE - Outbound Authenticator
  1304. //
  1305. // Returns: BOOL - status
  1306. //
  1307. // History: MKarki Created 12/8/97
  1308. //
  1309. //
  1310. //----------------------------------------------------------------
  1311. BOOL
  1312. CPacketRadius::GenerateInAuthenticator (
  1313. PBYTE pInAuthenticator,
  1314. PBYTE pOutAuthenticator
  1315. )
  1316. {
  1317. PRADIUSPACKET pPacket = reinterpret_cast <PRADIUSPACKET> (m_pInPacket);
  1318. _ASSERT ((pOutAuthenticator) && (pInAuthenticator) && (pPacket));
  1319. return (InternalGenerator (
  1320. pInAuthenticator,
  1321. pOutAuthenticator,
  1322. pPacket
  1323. ));
  1324. } // end of CPacketRadius::GenerateInAuthenticator
  1325. //++--------------------------------------------------------------
  1326. //
  1327. // Function: GenerateOutAuthenticator
  1328. //
  1329. // Synopsis: This is CPacketARadius class public method
  1330. // that generates the authenticator from the
  1331. // outbound packet
  1332. //
  1333. // Arguments:
  1334. // [in] PBYTE - Inbound authenticator
  1335. // [out] PBYTE - Outbound authenticator
  1336. //
  1337. // Returns: BOOL - status
  1338. //
  1339. // History: MKarki Created 12/8/97
  1340. //
  1341. //
  1342. //----------------------------------------------------------------
  1343. BOOL
  1344. CPacketRadius::GenerateOutAuthenticator()
  1345. {
  1346. PRADIUSPACKET pPacket = reinterpret_cast <PRADIUSPACKET> (m_pOutPacket);
  1347. _ASSERT ((pOutAuthenticator) && (pInAuthenticator) && (pPacket));
  1348. return (InternalGenerator (
  1349. m_pInPacket + 4,
  1350. pPacket->Authenticator,
  1351. pPacket
  1352. ));
  1353. } // end of CPacketRadius::GenerateOutAuthenticator method
  1354. //++--------------------------------------------------------------
  1355. //
  1356. // Function: InternalGenerator
  1357. //
  1358. // Synopsis: This is CPacketARadius class private method
  1359. // that generates the response authenticator for the
  1360. // packet provided
  1361. //
  1362. // Arguments:
  1363. // [in] PBYTE - InAuthenticator
  1364. // [out] PBYTE - OutAuthenticator
  1365. // [in] PPACKETRADIUS
  1366. //
  1367. // Returns: BOOL - status
  1368. //
  1369. // History: MKarki Created 12/8/97
  1370. //
  1371. //
  1372. //----------------------------------------------------------------
  1373. BOOL
  1374. CPacketRadius::InternalGenerator(
  1375. PBYTE pInAuthenticator,
  1376. PBYTE pOutAuthenticator,
  1377. PRADIUSPACKET pPacket
  1378. )
  1379. {
  1380. BOOL bStatus = TRUE;
  1381. DWORD dwPacketHeaderSize = 0;
  1382. DWORD dwAttributesLength = 0;
  1383. BYTE bySecret[MAX_SECRET_SIZE];
  1384. DWORD dwSecretSize = MAX_SECRET_SIZE;
  1385. _ASSERT ((pInAuthenticator) && (pOutAuthenticator) && (pPacket));
  1386. __try
  1387. {
  1388. //
  1389. // get the size of the packet without the attributes and
  1390. // request authenticator
  1391. //
  1392. dwPacketHeaderSize = sizeof (RADIUSPACKET)
  1393. - sizeof (BYTE)
  1394. - AUTHENTICATOR_SIZE;
  1395. //
  1396. // get the total attributes length now
  1397. //
  1398. dwAttributesLength = ntohs (pPacket->wLength)
  1399. - (dwPacketHeaderSize + AUTHENTICATOR_SIZE);
  1400. //
  1401. // get the shared secret
  1402. //
  1403. HRESULT hr = m_pIIasClient->GetSecret (bySecret, &dwSecretSize);
  1404. if (FAILED (hr))
  1405. {
  1406. bStatus = FALSE;
  1407. __leave;
  1408. }
  1409. //
  1410. // do the hashing here
  1411. //
  1412. m_pCHashMD5->HashIt (
  1413. pOutAuthenticator,
  1414. NULL,
  1415. 0,
  1416. reinterpret_cast <PBYTE> (pPacket),
  1417. dwPacketHeaderSize,
  1418. pInAuthenticator,
  1419. AUTHENTICATOR_SIZE,
  1420. pPacket->AttributeStart,
  1421. dwAttributesLength,
  1422. reinterpret_cast <PBYTE> (bySecret),
  1423. dwSecretSize,
  1424. 0,
  1425. 0
  1426. );
  1427. //
  1428. // we have successfully got the outbound authenticator
  1429. //
  1430. }
  1431. __finally
  1432. {
  1433. }
  1434. return (bStatus);
  1435. } // end of CPacketRadius::InternalGenerator method
  1436. //++--------------------------------------------------------------
  1437. //
  1438. // Function: FillInAttributeInfo
  1439. //
  1440. // Synopsis: This is CPacketARadius class private method
  1441. // that fills up the attribute information into
  1442. // the IASATTRIBUTE struct from the raw RADIUS
  1443. // packet
  1444. //
  1445. // Arguments:
  1446. // [in] PACKETTYPE
  1447. // [in] PIASATTRIBUTE
  1448. // [in] PATTRIBUTE
  1449. //
  1450. // Returns: HRESULT - status
  1451. //
  1452. // History: MKarki Created 12/31/97
  1453. //
  1454. //---------------------------------------------------------------
  1455. HRESULT
  1456. CPacketRadius::FillInAttributeInfo (
  1457. CDictionary *pCDictionary,
  1458. PACKETTYPE ePacketType,
  1459. PIASATTRIBUTE pIasAttrib,
  1460. PATTRIBUTE pRadiusAttrib
  1461. )
  1462. {
  1463. HRESULT hr = S_OK;
  1464. _ASSERT ((pCDictionary) && (pIasAttrib) && (pRadiusAttrib));
  1465. __try
  1466. {
  1467. // IAS IDs always match the RADIUS ID.
  1468. pIasAttrib->dwId = pRadiusAttrib->byType;
  1469. // Get the IAS syntax from the dictionary.
  1470. pIasAttrib->Value.itType =
  1471. pCDictionary->getAttributeType(pRadiusAttrib->byType);
  1472. //
  1473. // get the length of the value
  1474. //
  1475. DWORD dwValueLength = static_cast <DWORD>
  1476. (pRadiusAttrib->byLength - ATTRIBUTE_HEADER_SIZE);
  1477. //
  1478. // Set Value now
  1479. //
  1480. switch (pIasAttrib->Value.itType)
  1481. {
  1482. case IASTYPE_BOOLEAN:
  1483. if (sizeof (DWORD) != dwValueLength)
  1484. {
  1485. hr = RADIUS_E_MALFORMED_PACKET;
  1486. __leave;
  1487. }
  1488. pIasAttrib->Value.Boolean = IASExtractDWORD(
  1489. pRadiusAttrib->ValueStart
  1490. );
  1491. break;
  1492. case IASTYPE_INTEGER:
  1493. if (sizeof (DWORD) != dwValueLength)
  1494. {
  1495. hr = RADIUS_E_MALFORMED_PACKET;
  1496. __leave;
  1497. }
  1498. pIasAttrib->Value.Integer = IASExtractDWORD(
  1499. pRadiusAttrib->ValueStart
  1500. );
  1501. break;
  1502. case IASTYPE_ENUM:
  1503. if (sizeof (DWORD) != dwValueLength)
  1504. {
  1505. hr = RADIUS_E_MALFORMED_PACKET;
  1506. __leave;
  1507. }
  1508. pIasAttrib->Value.Enumerator = IASExtractDWORD(
  1509. pRadiusAttrib->ValueStart
  1510. );
  1511. break;
  1512. case IASTYPE_INET_ADDR:
  1513. if (sizeof (DWORD) != dwValueLength)
  1514. {
  1515. hr = RADIUS_E_MALFORMED_PACKET;
  1516. __leave;
  1517. }
  1518. pIasAttrib->Value.InetAddr = IASExtractDWORD(
  1519. pRadiusAttrib->ValueStart
  1520. );
  1521. break;
  1522. case IASTYPE_STRING:
  1523. //
  1524. // allocate memory for string + ending NUL
  1525. //
  1526. if(0 == dwValueLength)
  1527. {
  1528. pIasAttrib->Value.String.pszAnsi = NULL;
  1529. }
  1530. else
  1531. {
  1532. pIasAttrib->Value.String.pszAnsi =
  1533. reinterpret_cast <PCHAR>
  1534. (::CoTaskMemAlloc (dwValueLength + 1));
  1535. if (NULL == pIasAttrib->Value.String.pszAnsi)
  1536. {
  1537. hr = E_OUTOFMEMORY;
  1538. __leave;
  1539. }
  1540. CopyMemory (
  1541. pIasAttrib->Value.String.pszAnsi,
  1542. pRadiusAttrib->ValueStart,
  1543. dwValueLength
  1544. );
  1545. pIasAttrib->Value.String.pszAnsi[dwValueLength] = NUL;
  1546. }
  1547. pIasAttrib->Value.String.pszWide = NUL;
  1548. break;
  1549. case IASTYPE_OCTET_STRING:
  1550. pIasAttrib->Value.OctetString.dwLength = dwValueLength;
  1551. //
  1552. // here dwValueLength == 0
  1553. //
  1554. if(0 == dwValueLength)
  1555. {
  1556. pIasAttrib->Value.OctetString.lpValue = NULL;
  1557. }
  1558. else
  1559. {
  1560. pIasAttrib->Value.OctetString.lpValue =
  1561. reinterpret_cast <PBYTE> (::CoTaskMemAlloc (dwValueLength));
  1562. if (NULL == pIasAttrib->Value.OctetString.lpValue)
  1563. {
  1564. hr = E_OUTOFMEMORY;
  1565. __leave;
  1566. }
  1567. CopyMemory (
  1568. pIasAttrib->Value.OctetString.lpValue,
  1569. pRadiusAttrib->ValueStart,
  1570. dwValueLength
  1571. );
  1572. }
  1573. break;
  1574. case IASTYPE_UTC_TIME:
  1575. {
  1576. if (dwValueLength != 4)
  1577. {
  1578. hr = RADIUS_E_MALFORMED_PACKET;
  1579. __leave;
  1580. }
  1581. DWORDLONG val;
  1582. // Extract the UNIX time.
  1583. val = IASExtractDWORD(pRadiusAttrib->ValueStart);
  1584. // Convert from seconds to 100 nsec intervals.
  1585. val *= 10000000;
  1586. // Shift to the NT epoch.
  1587. val += UNIX_EPOCH;
  1588. // Split into the high and low DWORDs.
  1589. pIasAttrib->Value.UTCTime.dwLowDateTime = (DWORD)val;
  1590. pIasAttrib->Value.UTCTime.dwHighDateTime = (DWORD)(val >> 32);
  1591. }
  1592. break;
  1593. case IASTYPE_INVALID:
  1594. case IASTYPE_PROV_SPECIFIC:
  1595. default:
  1596. hr = E_FAIL;
  1597. __leave;
  1598. }
  1599. //
  1600. // sign the attribute that the Protocol component created it
  1601. //
  1602. pIasAttrib->dwFlags |= (IAS_RECVD_FROM_CLIENT | IAS_RECVD_FROM_PROTOCOL);
  1603. //
  1604. // also if this is a proxy state attribute also send
  1605. // it out on the wire
  1606. //
  1607. if (PROXY_STATE_ATTRIB == pIasAttrib->dwId)
  1608. {
  1609. pIasAttrib->dwFlags |= IAS_INCLUDE_IN_RESPONSE;
  1610. }
  1611. //
  1612. // success
  1613. //
  1614. }
  1615. __finally
  1616. {
  1617. if (hr == RADIUS_E_MALFORMED_PACKET)
  1618. {
  1619. IASTracePrintf (
  1620. "Incorrect attribute:%d in packet",
  1621. static_cast <DWORD> (pRadiusAttrib->byType)
  1622. );
  1623. reportMalformed();
  1624. m_pCReportEvent->Process (
  1625. RADIUS_MALFORMED_PACKET,
  1626. GetInCode (),
  1627. m_wInPacketLength,
  1628. m_dwInIPaddress,
  1629. NULL,
  1630. static_cast <LPVOID> (m_pInPacket)
  1631. );
  1632. hr = RADIUS_E_ERRORS_OCCURRED;
  1633. }
  1634. }
  1635. return (hr);
  1636. } // end of CPacketRadius::FillInAttributeInfo method
  1637. //++--------------------------------------------------------------
  1638. //
  1639. // Function: FillOutAttributeInfo
  1640. //
  1641. // Synopsis: This is CPacketARadius class private method
  1642. // that fills up the attribute information into
  1643. // the outbound RADIUS packet from the IASATTRIBUTE
  1644. // struct
  1645. //
  1646. // Arguments:
  1647. // [in] PATTRIBUTE
  1648. // [in] PIASATTRIBUTE
  1649. // [out] PWORD - return attribute length
  1650. // [in] DWORD - Max possible attribute length
  1651. //
  1652. // Returns: HRESULT - status
  1653. //
  1654. // History: MKarki Created 1/3/97
  1655. //
  1656. //----------------------------------------------------------------
  1657. HRESULT
  1658. CPacketRadius::FillOutAttributeInfo (
  1659. PATTRIBUTE pRadiusAttrib,
  1660. PIASATTRIBUTE pIasAttrib,
  1661. PWORD pwAttributeLength,
  1662. DWORD dwMaxPossibleAttribSize
  1663. )
  1664. {
  1665. DWORD dwAttributeLength = 0;
  1666. IAS_BOOLEAN iasBoolean = 0;
  1667. IAS_INTEGER iasInteger = 0;
  1668. IAS_ENUM iasEnum = 0;
  1669. IAS_INET_ADDR iasAddr = 0;
  1670. HRESULT hr = S_OK;
  1671. _ASSERT ((pRadiusAttrib) && (pIasAttrib) && (pwAttributeLength));
  1672. __try
  1673. {
  1674. //
  1675. // now put the value into the buffer
  1676. //
  1677. switch (pIasAttrib->Value.itType)
  1678. {
  1679. case IASTYPE_BOOLEAN:
  1680. iasBoolean = htonl (pIasAttrib->Value.Boolean);
  1681. dwAttributeLength =
  1682. ATTRIBUTE_HEADER_SIZE + sizeof (IAS_BOOLEAN);
  1683. if (dwMaxPossibleAttribSize >= dwAttributeLength)
  1684. {
  1685. CopyMemory (
  1686. pRadiusAttrib->ValueStart,
  1687. &iasBoolean,
  1688. sizeof (IAS_BOOLEAN)
  1689. );
  1690. }
  1691. else
  1692. {
  1693. hr = RADIUS_E_PACKET_OVERFLOW;
  1694. __leave;
  1695. }
  1696. break;
  1697. case IASTYPE_INTEGER:
  1698. iasInteger = htonl (pIasAttrib->Value.Integer);
  1699. dwAttributeLength =
  1700. ATTRIBUTE_HEADER_SIZE + sizeof (IAS_INTEGER);
  1701. if (dwMaxPossibleAttribSize >= dwAttributeLength)
  1702. {
  1703. CopyMemory (
  1704. pRadiusAttrib->ValueStart,
  1705. &iasInteger,
  1706. sizeof (IAS_INTEGER)
  1707. );
  1708. }
  1709. else
  1710. {
  1711. hr = RADIUS_E_PACKET_OVERFLOW;
  1712. __leave;
  1713. }
  1714. break;
  1715. case IASTYPE_ENUM:
  1716. iasEnum = htonl (pIasAttrib->Value.Enumerator);
  1717. dwAttributeLength =
  1718. ATTRIBUTE_HEADER_SIZE + sizeof (IAS_ENUM);
  1719. if (dwMaxPossibleAttribSize >= dwAttributeLength)
  1720. {
  1721. CopyMemory (
  1722. pRadiusAttrib->ValueStart,
  1723. &iasEnum,
  1724. sizeof (IAS_ENUM)
  1725. );
  1726. }
  1727. else
  1728. {
  1729. hr = RADIUS_E_PACKET_OVERFLOW;
  1730. __leave;
  1731. }
  1732. break;
  1733. case IASTYPE_INET_ADDR:
  1734. iasAddr = htonl (pIasAttrib->Value.InetAddr);
  1735. dwAttributeLength = ATTRIBUTE_HEADER_SIZE +
  1736. sizeof (IAS_INET_ADDR);
  1737. if (dwMaxPossibleAttribSize >= dwAttributeLength)
  1738. {
  1739. CopyMemory (
  1740. pRadiusAttrib->ValueStart,
  1741. &iasAddr,
  1742. sizeof (IAS_INET_ADDR)
  1743. );
  1744. }
  1745. else
  1746. {
  1747. hr = RADIUS_E_PACKET_OVERFLOW;
  1748. __leave;
  1749. }
  1750. break;
  1751. case IASTYPE_STRING:
  1752. //
  1753. // for RADIUS protocol always ANSI
  1754. //
  1755. IASAttributeAnsiAlloc (pIasAttrib);
  1756. dwAttributeLength = ATTRIBUTE_HEADER_SIZE +
  1757. strlen (pIasAttrib->Value.String.pszAnsi);
  1758. if (dwMaxPossibleAttribSize >= dwAttributeLength)
  1759. {
  1760. CopyMemory (
  1761. pRadiusAttrib->ValueStart,
  1762. reinterpret_cast <PBYTE>
  1763. (pIasAttrib->Value.String.pszAnsi),
  1764. strlen (pIasAttrib->Value.String.pszAnsi)
  1765. );
  1766. }
  1767. else
  1768. {
  1769. hr = RADIUS_E_PACKET_OVERFLOW;
  1770. __leave;
  1771. }
  1772. break;
  1773. case IASTYPE_OCTET_STRING:
  1774. dwAttributeLength =
  1775. ATTRIBUTE_HEADER_SIZE +
  1776. pIasAttrib->Value.OctetString.dwLength;
  1777. if (dwMaxPossibleAttribSize >= dwAttributeLength)
  1778. {
  1779. CopyMemory (
  1780. pRadiusAttrib->ValueStart,
  1781. static_cast <PBYTE>
  1782. (pIasAttrib->Value.OctetString.lpValue),
  1783. pIasAttrib->Value.OctetString.dwLength
  1784. );
  1785. }
  1786. else
  1787. {
  1788. hr = RADIUS_E_PACKET_OVERFLOW;
  1789. __leave;
  1790. }
  1791. break;
  1792. case IASTYPE_UTC_TIME:
  1793. {
  1794. dwAttributeLength = ATTRIBUTE_HEADER_SIZE + 4;
  1795. if (dwAttributeLength <= dwMaxPossibleAttribSize)
  1796. {
  1797. DWORDLONG val;
  1798. // Move in the high DWORD.
  1799. val = pIasAttrib->Value.UTCTime.dwHighDateTime;
  1800. val <<= 32;
  1801. // Move in the low DWORD.
  1802. val |= pIasAttrib->Value.UTCTime.dwLowDateTime;
  1803. // Convert to the UNIX epoch.
  1804. val -= UNIX_EPOCH;
  1805. // Convert to seconds.
  1806. val /= 10000000;
  1807. IASInsertDWORD(pRadiusAttrib->ValueStart, (DWORD)val);
  1808. }
  1809. else
  1810. {
  1811. hr = RADIUS_E_PACKET_OVERFLOW;
  1812. __leave;
  1813. }
  1814. }
  1815. break;
  1816. case IASTYPE_PROV_SPECIFIC:
  1817. case IASTYPE_INVALID:
  1818. default:
  1819. _ASSERT (0);
  1820. //
  1821. // should never reach here
  1822. //
  1823. IASTracePrintf (
  1824. "Unknown IAS Value type :%d encountered "
  1825. "while building out-bound packet",
  1826. static_cast <DWORD> (pIasAttrib->Value.itType)
  1827. );
  1828. __leave;
  1829. hr = E_FAIL;
  1830. break;
  1831. } // end of switch
  1832. //
  1833. // check the size against spec
  1834. //
  1835. if (dwAttributeLength >
  1836. (MAX_ATTRIBUTE_LENGTH + ATTRIBUTE_HEADER_SIZE)
  1837. )
  1838. {
  1839. IASTracePrintf (
  1840. "Attribute Value for:%d is too large to fit "
  1841. "in a Radius attribute",
  1842. pIasAttrib->dwId
  1843. );
  1844. IASReportEvent(
  1845. RADIUS_E_ATTRIBUTE_OVERFLOW,
  1846. 0,
  1847. sizeof(pIasAttrib->dwId),
  1848. NULL,
  1849. &(pIasAttrib->dwId)
  1850. );
  1851. hr = RADIUS_E_ERRORS_OCCURRED;
  1852. __leave;
  1853. }
  1854. //
  1855. // IAS attribute type matches RADIUS attribute type
  1856. //
  1857. pRadiusAttrib->byType = static_cast <BYTE> (pIasAttrib->dwId);
  1858. //
  1859. // hold a reference to the signature attribute for future use
  1860. //
  1861. if (RADIUS_ATTRIBUTE_SIGNATURE == pIasAttrib->dwId)
  1862. {
  1863. m_pOutSignature = pRadiusAttrib;
  1864. }
  1865. //
  1866. // set the length in the packet
  1867. //
  1868. *pwAttributeLength = pRadiusAttrib->byLength = dwAttributeLength;
  1869. //
  1870. // success
  1871. //
  1872. }
  1873. __finally
  1874. {
  1875. }
  1876. return (hr);
  1877. } // end of CPacketRadius::FillOutAttributeInfo method
  1878. //++--------------------------------------------------------------
  1879. //
  1880. // Function: FillClientIPInfo
  1881. //
  1882. // Synopsis: This is CPacketARadius class private method
  1883. // that fills the attribute information for Client
  1884. // IP address
  1885. //
  1886. // Arguments:
  1887. // [in] PIASATTRIBUTE
  1888. //
  1889. // Returns: HRESULT - status
  1890. //
  1891. // History: MKarki Created 1/6/98
  1892. //
  1893. // Called By: CPacketRadius::CreateAttribCollection private method
  1894. //
  1895. //----------------------------------------------------------------
  1896. HRESULT
  1897. CPacketRadius::FillClientIPInfo (
  1898. PIASATTRIBUTE pIasAttrib
  1899. )
  1900. {
  1901. _ASSERT (pIasAttrib);
  1902. //
  1903. // put in the values now
  1904. //
  1905. pIasAttrib->dwId = IAS_ATTRIBUTE_CLIENT_IP_ADDRESS;
  1906. pIasAttrib->Value.itType = IASTYPE_INET_ADDR;
  1907. pIasAttrib->Value.InetAddr = m_dwInIPaddress;
  1908. pIasAttrib->dwFlags = IAS_RECVD_FROM_PROTOCOL;
  1909. return (S_OK);
  1910. } // end of CPacketRadius::FillClientIPInfo method
  1911. //++--------------------------------------------------------------
  1912. //
  1913. // Function: FillClientPortInfo
  1914. //
  1915. // Synopsis: This is CPacketARadius class private method
  1916. // that fills the attribute information for Client
  1917. // UDP port
  1918. //
  1919. // Arguments:
  1920. // [in] PIASATTRIBUTE
  1921. //
  1922. // Returns: HRESULT - status
  1923. //
  1924. // History: MKarki Created 1/6/98
  1925. //
  1926. // Called By: CPacketRadius::CreateAttribCollection private method
  1927. //
  1928. //----------------------------------------------------------------
  1929. HRESULT
  1930. CPacketRadius::FillClientPortInfo (
  1931. PIASATTRIBUTE pIasAttrib
  1932. )
  1933. {
  1934. _ASSERT (pIasAttrib);
  1935. //
  1936. // put in the values now
  1937. //
  1938. pIasAttrib->dwId = IAS_ATTRIBUTE_CLIENT_UDP_PORT;
  1939. pIasAttrib->Value.itType = IASTYPE_INTEGER;
  1940. pIasAttrib->Value.Integer = m_wInPort;
  1941. pIasAttrib->dwFlags = IAS_RECVD_FROM_PROTOCOL;
  1942. return (S_OK);
  1943. } // end of CPacketRadius::FillClientPortInfo method
  1944. //++--------------------------------------------------------------
  1945. //
  1946. // Function: FillPacketHeaderInfo
  1947. //
  1948. // Synopsis: This is CPacketARadius class private method
  1949. // that fills the attribute information for
  1950. // RADIUS packet header
  1951. //
  1952. // Arguments:
  1953. // [in] PIASATTRIBUTE
  1954. //
  1955. // Returns: HRESULT - status
  1956. //
  1957. // History: MKarki Created 1/6/98
  1958. //
  1959. // Called By: CPacketRadius::CreateAttribCollection private method
  1960. //
  1961. //----------------------------------------------------------------
  1962. HRESULT
  1963. CPacketRadius::FillPacketHeaderInfo (
  1964. PIASATTRIBUTE pIasAttrib
  1965. )
  1966. {
  1967. HRESULT hr = S_OK;
  1968. _ASSERT (pIasAttrib);
  1969. //
  1970. // allocate dynamic memory for the packet header
  1971. //
  1972. pIasAttrib->Value.OctetString.lpValue =
  1973. reinterpret_cast <PBYTE> (::CoTaskMemAlloc (PACKET_HEADER_SIZE));
  1974. if (NULL == pIasAttrib->Value.OctetString.lpValue)
  1975. {
  1976. IASTracePrintf (
  1977. "Unable to allocate dynamic memory for packet header info "
  1978. "during in-packet processing"
  1979. );
  1980. hr = E_OUTOFMEMORY;
  1981. }
  1982. else
  1983. {
  1984. //
  1985. // put in the values now
  1986. //
  1987. pIasAttrib->dwId = IAS_ATTRIBUTE_CLIENT_PACKET_HEADER;
  1988. pIasAttrib->Value.itType = IASTYPE_OCTET_STRING;
  1989. CopyMemory (
  1990. pIasAttrib->Value.OctetString.lpValue,
  1991. m_pInPacket,
  1992. PACKET_HEADER_SIZE
  1993. );
  1994. pIasAttrib->Value.OctetString.dwLength = PACKET_HEADER_SIZE;
  1995. pIasAttrib->dwFlags = IAS_RECVD_FROM_PROTOCOL;
  1996. }
  1997. return (hr);
  1998. } // end of CPacketRadius::FillPacketHeaderInfo method
  1999. //++--------------------------------------------------------------
  2000. //
  2001. // Function: FillSharedSecretInfo
  2002. //
  2003. // Synopsis: This is CPacketARadius class private method
  2004. // that fills the shared secret that the server
  2005. // shares with the client from which this request
  2006. // has been received
  2007. //
  2008. // Arguments:
  2009. // [in] PIASATTRIBUTE
  2010. //
  2011. // Returns: HRESULT - status
  2012. //
  2013. // History: MKarki Created 1/6/98
  2014. //
  2015. // Called By: CPacketRadius::CreateAttribCollection private method
  2016. //
  2017. //----------------------------------------------------------------
  2018. HRESULT
  2019. CPacketRadius::FillSharedSecretInfo (
  2020. PIASATTRIBUTE pIasAttrib
  2021. )
  2022. {
  2023. BOOL bStatus = FALSE;
  2024. BYTE SharedSecret[MAX_SECRET_SIZE];
  2025. DWORD dwSecretSize = MAX_SECRET_SIZE;
  2026. HRESULT hr = S_OK;
  2027. _ASSERT ((pIasAttrib) && (m_pIIasClient));
  2028. __try
  2029. {
  2030. //
  2031. // get the client secret
  2032. //
  2033. hr = m_pIIasClient->GetSecret (SharedSecret, &dwSecretSize);
  2034. if (FAILED (hr)) { __leave; }
  2035. //
  2036. // allocate dynamic memory for the client secret
  2037. //
  2038. pIasAttrib->Value.OctetString.lpValue =
  2039. reinterpret_cast <PBYTE> (::CoTaskMemAlloc (dwSecretSize));
  2040. if (NULL == pIasAttrib->Value.OctetString.lpValue)
  2041. {
  2042. IASTracePrintf (
  2043. "Unable to allocate memory for client secret "
  2044. "during in-packet processing"
  2045. );
  2046. hr = E_OUTOFMEMORY;
  2047. __leave;
  2048. }
  2049. //
  2050. // put in the values now
  2051. //
  2052. pIasAttrib->dwId = IAS_ATTRIBUTE_SHARED_SECRET;
  2053. pIasAttrib->Value.itType = IASTYPE_OCTET_STRING;
  2054. CopyMemory (
  2055. pIasAttrib->Value.OctetString.lpValue,
  2056. SharedSecret,
  2057. dwSecretSize
  2058. );
  2059. pIasAttrib->Value.OctetString.dwLength = dwSecretSize;
  2060. pIasAttrib->dwFlags = IAS_RECVD_FROM_PROTOCOL;
  2061. //
  2062. // success
  2063. //
  2064. }
  2065. __finally
  2066. {
  2067. }
  2068. return (hr);
  2069. } // end of CPacketRadius::FillSharedSecretInfo method
  2070. //++--------------------------------------------------------------
  2071. //
  2072. // Function: FillClientVendorType
  2073. //
  2074. // Synopsis: This is CPacketARadius class private method
  2075. // that fills the Client-Vendor-Type information
  2076. //
  2077. // Arguments:
  2078. // [in] PIASATTRIBUTE
  2079. //
  2080. // Returns: HRESULT - status
  2081. //
  2082. // History: MKarki Created 3/16/98
  2083. //
  2084. // Called By: CPacketRadius::CreateAttribCollection private method
  2085. //
  2086. //----------------------------------------------------------------
  2087. HRESULT
  2088. CPacketRadius::FillClientVendorType (
  2089. PIASATTRIBUTE pIasAttrib
  2090. )
  2091. {
  2092. LONG lVendorType = 0;
  2093. _ASSERT ((pIasAttrib) && (m_pIIasClient));
  2094. //
  2095. // put in the values now
  2096. //
  2097. pIasAttrib->dwId = IAS_ATTRIBUTE_CLIENT_VENDOR_TYPE;
  2098. pIasAttrib->Value.itType = IASTYPE_INTEGER;
  2099. pIasAttrib->dwFlags = IAS_RECVD_FROM_PROTOCOL;
  2100. //
  2101. // get the client vendor type
  2102. //
  2103. HRESULT hr = m_pIIasClient->GetVendorType (&lVendorType);
  2104. _ASSERT (SUCCEEDED (hr));
  2105. pIasAttrib->Value.Integer = static_cast <IAS_INTEGER> (lVendorType);
  2106. return (S_OK);
  2107. } // end of CPacketRadius::ClientVendorType method
  2108. //++--------------------------------------------------------------
  2109. //
  2110. // Function: FillClientName
  2111. //
  2112. // Synopsis: This is CPacketARadius class private method
  2113. // that fills the Client-Name information
  2114. //
  2115. // Arguments:
  2116. // [in] PIASATTRIBUTE
  2117. //
  2118. // Returns: HRESULT - status
  2119. //
  2120. // History: MKarki Created 3/30/98
  2121. //
  2122. // Called By: CPacketRadius::CreateAttribCollection private method
  2123. //
  2124. //----------------------------------------------------------------
  2125. HRESULT
  2126. CPacketRadius::FillClientName (
  2127. PIASATTRIBUTE pIasAttrib
  2128. )
  2129. {
  2130. _ASSERT ((pIasAttrib) && (m_pIIasClient));
  2131. // Fill in the attribute fields.
  2132. pIasAttrib->dwId = IAS_ATTRIBUTE_CLIENT_NAME;
  2133. pIasAttrib->Value.itType = IASTYPE_STRING;
  2134. pIasAttrib->dwFlags = IAS_RECVD_FROM_PROTOCOL;
  2135. pIasAttrib->Value.String.pszAnsi = NULL;
  2136. // Get the client name and length.
  2137. PCWSTR name = m_pIIasClient->GetClientNameW();
  2138. SIZE_T nbyte = (wcslen(name) + 1) * sizeof(WCHAR);
  2139. // Make a copy.
  2140. pIasAttrib->Value.String.pszWide = (PWSTR)CoTaskMemAlloc(nbyte);
  2141. if (!pIasAttrib->Value.String.pszWide) { return E_OUTOFMEMORY; }
  2142. memcpy(pIasAttrib->Value.String.pszWide, name, nbyte);
  2143. return S_OK;
  2144. }
  2145. //+++-------------------------------------------------------------
  2146. //
  2147. // Function: GenerateInSignature
  2148. //
  2149. // Synopsis: This is CPacketARadius class public method
  2150. // that carries out generation of Signature
  2151. // over the in-bound RADIUS packet
  2152. //
  2153. // Arguments:
  2154. // [out] PBYTE - signature
  2155. // [in/out] PDWORD - signature size
  2156. //
  2157. // Returns: BOOL - status
  2158. //
  2159. // History: MKarki Created 1/6/98
  2160. //
  2161. //----------------------------------------------------------------
  2162. HRESULT
  2163. CPacketRadius::GenerateInSignature (
  2164. PBYTE pSignatureValue,
  2165. PDWORD pdwSigSize
  2166. )
  2167. {
  2168. HRESULT hr = S_OK;
  2169. PRADIUSPACKET pPacket = reinterpret_cast <PRADIUSPACKET> (m_pInPacket);
  2170. PATTRIBUTE pSignature = m_pInSignature;
  2171. _ASSERT (pSignatureValue && pdwSigSize && pSignature);
  2172. if (*pdwSigSize >= SIGNATURE_SIZE)
  2173. {
  2174. //
  2175. // generate the signature now
  2176. //
  2177. hr = InternalSignatureGenerator (
  2178. pSignatureValue,
  2179. pdwSigSize,
  2180. pPacket,
  2181. pSignature
  2182. );
  2183. }
  2184. else
  2185. {
  2186. IASTracePrintf (
  2187. "Buffer not large enough to hold generated Signature"
  2188. );
  2189. *pdwSigSize = SIGNATURE_SIZE;
  2190. hr = E_INVALIDARG;
  2191. }
  2192. return (hr);
  2193. } // end of CPacketRadius::GenerateInSignature method
  2194. //+++-------------------------------------------------------------
  2195. //
  2196. // Function: GenerateOutSignature
  2197. //
  2198. // Synopsis: This is CPacketARadius class public method
  2199. // that carries out generation of Signature
  2200. // for the outbound RADIUS packet
  2201. //
  2202. // Arguments:
  2203. // [out] PBYTE - signature
  2204. // [in/out] PDWORD - signature size
  2205. //
  2206. // Returns: BOOL - status
  2207. //
  2208. // History: MKarki Created 11/18/98
  2209. //
  2210. //----------------------------------------------------------------
  2211. HRESULT
  2212. CPacketRadius::GenerateOutSignature (
  2213. PBYTE pSignatureValue,
  2214. PDWORD pdwSigSize
  2215. )
  2216. {
  2217. HRESULT hr = S_OK;
  2218. PRADIUSPACKET pPacket = reinterpret_cast <PRADIUSPACKET> (m_pOutPacket);
  2219. PATTRIBUTE pSignature = m_pOutSignature;
  2220. _ASSERT (pSignatureValue && pdwSigSize && pSignature);
  2221. if (*pdwSigSize >= SIGNATURE_SIZE)
  2222. {
  2223. //
  2224. // generate the signature now
  2225. //
  2226. hr = InternalSignatureGenerator (
  2227. pSignatureValue,
  2228. pdwSigSize,
  2229. pPacket,
  2230. pSignature
  2231. );
  2232. }
  2233. else
  2234. {
  2235. IASTracePrintf (
  2236. "Buffer not large enough to hold generated Signature"
  2237. );
  2238. *pdwSigSize = SIGNATURE_SIZE;
  2239. hr = E_INVALIDARG;
  2240. }
  2241. return (hr);
  2242. } // end of CPacketRadius::GenerateOutSignature method
  2243. //+++-------------------------------------------------------------
  2244. //
  2245. // Function: InternalSignatureGenerator
  2246. //
  2247. // Synopsis: This is CPacketARadius class public method
  2248. // that carries out the HMAC-MD5 hash to give the
  2249. // signature value
  2250. //
  2251. // Arguments:
  2252. // [out] PBYTE - signature
  2253. // [in/out] PDWORD - signature size
  2254. // [in] PRADIUSPACKET
  2255. //
  2256. // Returns: BOOL - status
  2257. //
  2258. // History: MKarki Created 1/6/98
  2259. //
  2260. //----------------------------------------------------------------
  2261. HRESULT
  2262. CPacketRadius::InternalSignatureGenerator (
  2263. PBYTE pSignatureValue,
  2264. PDWORD pdwSigSize,
  2265. PRADIUSPACKET pPacket,
  2266. PATTRIBUTE pSignatureAttr
  2267. )
  2268. {
  2269. BYTE bySecret[MAX_SECRET_SIZE];
  2270. BYTE byAuthenticator[AUTHENTICATOR_SIZE];
  2271. DWORD dwSecretSize = MAX_SECRET_SIZE;
  2272. DWORD dwAuthenticatorSize = AUTHENTICATOR_SIZE;
  2273. HRESULT hr = S_OK;
  2274. _ASSERT (
  2275. (NULL != pSignatureValue) &&
  2276. (NULL != pdwSigSize) &&
  2277. (NULL != pPacket) &&
  2278. (NULL != pSignatureAttr) &&
  2279. (NULL != m_pIIasClient)
  2280. );
  2281. //
  2282. // get the In authenticator
  2283. //
  2284. hr = GetInAuthenticator (byAuthenticator, &dwAuthenticatorSize);
  2285. if (FAILED (hr)) { return (hr); }
  2286. //
  2287. // get the shared secret
  2288. //
  2289. hr = m_pIIasClient->GetSecret (bySecret, &dwSecretSize);
  2290. if (FAILED (hr)) { return (hr); }
  2291. //
  2292. // we will have all zero's in packet for signature generation
  2293. //
  2294. ZeroMemory (pSignatureValue, SIGNATURE_SIZE);
  2295. //
  2296. // Fixing bug #181029 - MKarki
  2297. // Don't prepend secret in case of HMAC-MD5 hash
  2298. //
  2299. //
  2300. // carry out the HmacMD5 hashing now
  2301. //
  2302. m_pCHashHmacMD5->HashIt (
  2303. pSignatureValue,
  2304. bySecret,
  2305. dwSecretSize,
  2306. reinterpret_cast <PBYTE> (pPacket),
  2307. PACKET_HEADER_SIZE - AUTHENTICATOR_SIZE,
  2308. byAuthenticator,
  2309. AUTHENTICATOR_SIZE,
  2310. reinterpret_cast <PBYTE> (pPacket) + PACKET_HEADER_SIZE,
  2311. (reinterpret_cast <PBYTE> (pSignatureAttr) + ATTRIBUTE_HEADER_SIZE) -
  2312. (reinterpret_cast <PBYTE> (pPacket) + PACKET_HEADER_SIZE),
  2313. pSignatureValue,
  2314. SIGNATURE_SIZE,
  2315. reinterpret_cast <PBYTE> (pSignatureAttr) + pSignatureAttr->byLength,
  2316. reinterpret_cast <PBYTE> (reinterpret_cast <PBYTE> (pPacket) +
  2317. ntohs (pPacket->wLength)) -
  2318. reinterpret_cast <PBYTE> (reinterpret_cast <PBYTE>(pSignatureAttr) +
  2319. pSignatureAttr->byLength)
  2320. );
  2321. *pdwSigSize = SIGNATURE_SIZE;
  2322. return (hr);
  2323. } // end of CPacketRadius::GenerateInSignature method
  2324. //++--------------------------------------------------------------
  2325. //
  2326. // Function: IsOutBoundAttribute
  2327. //
  2328. // Synopsis: This is CPacketARadius class private method
  2329. // that checks if this attribute has to be put
  2330. // in the outbound RADIUS packet
  2331. //
  2332. // Arguments:
  2333. // [in] PACKETTYPE
  2334. // [in] PIASATTRIBUTE
  2335. //
  2336. // Returns: BOOL - status
  2337. //
  2338. // History: MKarki Created 1/6/98
  2339. //
  2340. // Called By: CPacketRadius::BuildOutPacket private method
  2341. //
  2342. //----------------------------------------------------------------
  2343. BOOL
  2344. CPacketRadius::IsOutBoundAttribute (
  2345. PACKETTYPE ePacketType,
  2346. PIASATTRIBUTE pIasAttribute
  2347. )
  2348. {
  2349. _ASSERT (pIasAttribute);
  2350. // Ensure this is a RADIUS attribute ...
  2351. if (pIasAttribute->dwId < 1 || pIasAttribute->dwId > 255) { return FALSE; }
  2352. // ... and it's flagged to be sent over the wire.
  2353. switch (ePacketType)
  2354. {
  2355. case ACCESS_ACCEPT:
  2356. return pIasAttribute->dwFlags & IAS_INCLUDE_IN_ACCEPT;
  2357. case ACCESS_REJECT:
  2358. return pIasAttribute->dwFlags & IAS_INCLUDE_IN_REJECT;
  2359. case ACCESS_CHALLENGE:
  2360. return pIasAttribute->dwFlags & IAS_INCLUDE_IN_CHALLENGE;
  2361. }
  2362. // Always return the Proxy-State.
  2363. return pIasAttribute->dwId == PROXY_STATE_ATTRIB;
  2364. }
  2365. HRESULT CPacketRadius::cryptBuffer(
  2366. BOOL encrypt,
  2367. BOOL salted,
  2368. PBYTE buf,
  2369. ULONG buflen
  2370. ) const throw ()
  2371. {
  2372. // Get the shared secret.
  2373. BYTE secret[MAX_SECRET_SIZE];
  2374. ULONG secretLen = sizeof(secret);
  2375. HRESULT hr = m_pIIasClient->GetSecret(secret, &secretLen);
  2376. if (SUCCEEDED(hr))
  2377. {
  2378. // Crypt the buffer.
  2379. IASRadiusCrypt(
  2380. encrypt,
  2381. salted,
  2382. secret,
  2383. secretLen,
  2384. m_pInPacket + 4,
  2385. buf,
  2386. buflen
  2387. );
  2388. }
  2389. return hr;
  2390. }
  2391. //++--------------------------------------------------------------
  2392. //
  2393. // Function: GetClient
  2394. //
  2395. // Synopsis: This is CPacketARadius class public method
  2396. // that returns the the Client object
  2397. //
  2398. //
  2399. // Arguments:
  2400. // [out] IIASClient**
  2401. //
  2402. // Returns: HRESULT - status
  2403. //
  2404. // History: MKarki Created 3/30/98
  2405. //
  2406. // Called By:
  2407. //
  2408. //----------------------------------------------------------------
  2409. HRESULT
  2410. CPacketRadius::GetClient (
  2411. /*[out]*/ IIasClient **ppIasClient
  2412. )
  2413. {
  2414. _ASSERT (ppIasClient);
  2415. m_pIIasClient->AddRef ();
  2416. *ppIasClient = m_pIIasClient;
  2417. return (S_OK);
  2418. } // end of CPacketRadius::GetClient method