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.

2692 lines
75 KiB

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