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.

573 lines
14 KiB

  1. //#--------------------------------------------------------------
  2. //
  3. // File: client.cpp
  4. //
  5. // Synopsis: Implementation of CClient class methods
  6. //
  7. //
  8. // History: 9/23/97 MKarki Created
  9. //
  10. // Copyright (C) 1997-98 Microsoft Corporation
  11. // All rights reserved.
  12. //
  13. //----------------------------------------------------------------
  14. #include "radcommon.h"
  15. #include "client.h"
  16. #include "iasevent.h"
  17. #include <iasutil.h>
  18. #include <memory>
  19. #include "strsafe.h"
  20. inline BOOL IsDottedDecimal(PCWSTR sz) throw ()
  21. {
  22. return wcsspn(sz, L"0123456789./") == wcslen(sz);
  23. }
  24. STDMETHODIMP_(DWORD) CClient::GetAddress()
  25. {
  26. return m_adwAddrList[0].ipAddress;
  27. }
  28. STDMETHODIMP_(BOOL) CClient::NeedSignatureCheck()
  29. {
  30. return m_bSignatureCheck;
  31. }
  32. STDMETHODIMP_(LONG) CClient::GetVendorType()
  33. {
  34. return m_lVendorType;
  35. }
  36. STDMETHODIMP_(LPCWSTR) CClient::GetClientNameW()
  37. {
  38. return m_wszClientName;
  39. }
  40. STDMETHODIMP_(LPCWSTR) CClient::GetClientAddressW()
  41. {
  42. return m_wszClientAddress;
  43. }
  44. STDMETHODIMP_(const BYTE*) CClient::GetSecret(DWORD* pdwSecretSize)
  45. {
  46. if (pdwSecretSize != 0)
  47. {
  48. *pdwSecretSize = m_dwSecretSize;
  49. }
  50. return reinterpret_cast<const BYTE*>(m_szSecret);
  51. }
  52. //++--------------------------------------------------------------
  53. //
  54. // Function: CClient
  55. //
  56. // Synopsis: This is the constructor of the Client class
  57. //
  58. // Arguments: NONE
  59. //
  60. // Returns: NONE
  61. //
  62. // History: MKarki Created 9/26/97
  63. //
  64. //----------------------------------------------------------------
  65. CClient::CClient (
  66. VOID
  67. )
  68. : m_adwAddrList (m_adwAddressBuffer),
  69. m_lVendorType (0),
  70. m_bSignatureCheck (FALSE)
  71. {
  72. m_adwAddressBuffer[0].ipAddress = INADDR_NONE;
  73. ZeroMemory (m_szSecret, MAX_SECRET_SIZE + 1);
  74. } // end of CClient constructor
  75. //++--------------------------------------------------------------
  76. //
  77. // Function: ~CClient
  78. //
  79. // Synopsis: This is the destructor of the Client class
  80. //
  81. // Arguments: NONE
  82. //
  83. // Returns: NONE
  84. //
  85. // History: MKarki Created 9/26/97
  86. //
  87. //----------------------------------------------------------------
  88. CClient::~CClient(
  89. VOID
  90. )
  91. {
  92. ClearAddress();
  93. } // end of CClient constructor
  94. //++--------------------------------------------------------------
  95. //
  96. // Function: Init
  97. //
  98. // Synopsis: This is the CClient public method used
  99. // to initialize the object with the
  100. // ISdo interface
  101. //
  102. // Arguments:
  103. // [in] ISdo*
  104. //
  105. // Returns: NONE
  106. //
  107. // History: MKarki Created 9/26/97
  108. //
  109. // Called By: CClients::SetClients public method
  110. //
  111. //----------------------------------------------------------------
  112. STDMETHODIMP
  113. CClient::Init (
  114. ISdo *pISdo
  115. )
  116. {
  117. BOOL bStatus = FALSE;
  118. HRESULT hr = S_OK;
  119. CComVariant varClient;
  120. _ASSERT (pISdo);
  121. //
  122. // get the client address first
  123. //
  124. hr = pISdo->GetProperty (PROPERTY_CLIENT_ADDRESS, &varClient);
  125. if (FAILED (hr))
  126. {
  127. IASTracePrintf (
  128. "Unable to obtain Client Address Property "
  129. "during Client object initialization"
  130. );
  131. hr = E_FAIL;
  132. return (hr);
  133. }
  134. //
  135. // store the address
  136. //
  137. hr = SetAddress (varClient);
  138. if (FAILED(hr))
  139. {
  140. return hr;
  141. }
  142. varClient.Clear ();
  143. //
  144. // get the client address first
  145. //
  146. hr = pISdo->GetProperty (PROPERTY_CLIENT_SHARED_SECRET, &varClient);
  147. if (FAILED (hr))
  148. {
  149. IASTracePrintf (
  150. "Unable to obtain Client shared secret Property "
  151. "during Client object initialization"
  152. );
  153. return (hr);
  154. }
  155. //
  156. // now store away the shared secret
  157. //
  158. bStatus = SetSecret (varClient);
  159. if (FALSE == bStatus)
  160. {
  161. hr = E_FAIL;
  162. return (hr);
  163. }
  164. varClient.Clear ();
  165. //
  166. // get signature information
  167. //
  168. hr = pISdo->GetProperty (PROPERTY_CLIENT_REQUIRE_SIGNATURE, &varClient);
  169. if (FAILED (hr))
  170. {
  171. IASTracePrintf (
  172. "Unable to obtain Client Signature Property "
  173. "during Client object initialization"
  174. );
  175. return (hr);
  176. }
  177. //
  178. // store away the signature information
  179. //
  180. bStatus = SetSignatureFlag (varClient);
  181. if (FALSE == bStatus)
  182. {
  183. hr = E_FAIL;
  184. return (hr);
  185. }
  186. varClient.Clear ();
  187. //
  188. // get the client NAS Manufacturer information
  189. //
  190. hr = pISdo->GetProperty (PROPERTY_CLIENT_NAS_MANUFACTURER, &varClient);
  191. if (FAILED (hr))
  192. {
  193. IASTracePrintf (
  194. "Unable to obtain Client NAS Manufacturer Property "
  195. "during Client object initialization"
  196. );
  197. return (hr);
  198. }
  199. //
  200. // store away the Nas Manufacturer information
  201. //
  202. bStatus = SetVendorType (varClient);
  203. if (FALSE == bStatus)
  204. {
  205. hr = E_FAIL;
  206. return (hr);
  207. }
  208. varClient.Clear ();
  209. //
  210. // get the client name
  211. //
  212. hr = pISdo->GetProperty (PROPERTY_SDO_NAME, &varClient);
  213. if (FAILED (hr))
  214. {
  215. IASTracePrintf (
  216. "Unable to obtain SDO Name Property "
  217. "during Client object initialization"
  218. );
  219. return (hr);
  220. }
  221. //
  222. // store away the client name information
  223. //
  224. hr = SetClientName (varClient);
  225. if (FAILED(hr))
  226. {
  227. return hr;
  228. }
  229. varClient.Clear ();
  230. return (hr);
  231. } // end of CClient::Init method
  232. void CClient::ClearAddress() throw ()
  233. {
  234. if (m_adwAddrList != m_adwAddressBuffer)
  235. {
  236. delete[] m_adwAddrList;
  237. }
  238. m_adwAddressBuffer[0].ipAddress = INADDR_NONE;
  239. m_adwAddrList = m_adwAddressBuffer;
  240. }
  241. HRESULT CClient::SetAddress(const VARIANT& varAddress) throw ()
  242. {
  243. if (V_VT(&varAddress) != VT_BSTR)
  244. {
  245. return E_INVALIDARG;
  246. }
  247. return StringCchCopyW(
  248. m_wszClientAddress,
  249. RTL_NUMBER_OF(m_wszClientAddress),
  250. V_BSTR(&varAddress)
  251. );
  252. }
  253. //++--------------------------------------------------------------
  254. //
  255. // Function: ResolveAddress
  256. //
  257. // Synopsis: This is the CClient public method used
  258. // to resolve the Client IP address obtained previously
  259. // which could be a DNS name or dotted octed
  260. //
  261. // Arguments: VOID
  262. //
  263. // Returns: HRESULT
  264. //
  265. // History: MKarki Created 2/3/98
  266. //
  267. // Called By: CClient::Init method
  268. //
  269. //----------------------------------------------------------------
  270. STDMETHODIMP
  271. CClient::ResolveAddress (
  272. VOID
  273. )
  274. {
  275. INT iRetVal = 0;
  276. PHOSTENT pHostent = NULL;
  277. BOOL bDNSName = FALSE;
  278. BOOL bRetVal = TRUE;
  279. CHAR szClient[MAX_CLIENT_SIZE +1];
  280. HRESULT hr = S_OK;
  281. // Clear any existing addresses.
  282. ClearAddress();
  283. __try
  284. {
  285. //
  286. // check if this address is dotted octet or DNS name
  287. //
  288. if (!IsDottedDecimal(m_wszClientAddress))
  289. {
  290. //
  291. // we probably have a DNS name so
  292. // get the address information
  293. //
  294. pHostent = IASGetHostByName (m_wszClientAddress);
  295. if (NULL == pHostent)
  296. {
  297. IASTracePrintf (
  298. "Unable to get client IP Address through IASGetHostByName () "
  299. "during client address resolution"
  300. );
  301. //
  302. // log an event here
  303. //
  304. PCWSTR strings[] = { m_wszClientAddress, m_wszClientName };
  305. int data = WSAGetLastError();
  306. IASReportEvent(
  307. RADIUS_E_CANT_RESOLVE_CLIENT_NAME,
  308. 2,
  309. sizeof(data),
  310. strings,
  311. &data
  312. );
  313. hr = E_FAIL;
  314. __leave;
  315. }
  316. //
  317. // store addresses in host byte order
  318. //
  319. size_t count;
  320. for (count = 0; pHostent->h_addr_list[count]; ++count) { }
  321. if (count > 1)
  322. {
  323. m_adwAddrList = new (std::nothrow) Address[count + 1];
  324. if (!m_adwAddrList)
  325. {
  326. m_adwAddrList = m_adwAddressBuffer;
  327. hr = E_OUTOFMEMORY;
  328. __leave;
  329. }
  330. }
  331. for (count = 0; pHostent->h_addr_list[count]; ++count)
  332. {
  333. m_adwAddrList[count].ipAddress =
  334. ntohl(*(PDWORD)pHostent->h_addr_list[count]);
  335. m_adwAddrList[count].width = 32;
  336. }
  337. m_adwAddrList[count].ipAddress = INADDR_NONE;
  338. }
  339. else
  340. {
  341. //
  342. // this could be a dotted-octet address
  343. //
  344. ULONG width;
  345. m_adwAddressBuffer[0].ipAddress = IASStringToSubNetW(
  346. m_wszClientAddress,
  347. &m_adwAddressBuffer[0].width
  348. );
  349. if (INADDR_NONE == m_adwAddressBuffer[0].ipAddress)
  350. {
  351. IASTracePrintf (
  352. "Unable to get client IP Address through inet_addr () "
  353. "during client address resolution"
  354. );
  355. //
  356. // log an event here
  357. //
  358. PCWSTR strings[] = { m_wszClientAddress, m_wszClientName };
  359. IASReportEvent(
  360. RADIUS_E_INVALID_CLIENT_ADDRESS,
  361. 2,
  362. 0,
  363. strings,
  364. NULL
  365. );
  366. hr = E_FAIL;
  367. __leave;
  368. }
  369. // Terminate the array.
  370. m_adwAddressBuffer[1].ipAddress = INADDR_NONE;
  371. }
  372. }
  373. __finally
  374. {
  375. if (bRetVal)
  376. {
  377. IASTracePrintf (
  378. "Resolved Client:%S, to IP address:%ul", m_wszClientAddress, m_adwAddrList[0].ipAddress
  379. );
  380. }
  381. if (pHostent) { LocalFree(pHostent); }
  382. }
  383. return (hr);
  384. } // end of CClient::ResolveAddress method
  385. //++--------------------------------------------------------------
  386. //
  387. // Function: SetSecret
  388. //
  389. // Synopsis: This is the CClient private method used
  390. // to set the shared secret
  391. //
  392. // Arguments: VARIANT - holds the secret as a BSTR
  393. //
  394. // Returns: status
  395. //
  396. // History: MKarki Created 2/3/98
  397. //
  398. // Called By: CClient::Init method
  399. //
  400. //----------------------------------------------------------------
  401. BOOL
  402. CClient::SetSecret (
  403. VARIANT varSecret
  404. )
  405. {
  406. INT iRetVal = 0;
  407. _ASSERT (VT_BSTR == varSecret.vt);
  408. iRetVal = ::WideCharToMultiByte (
  409. CP_ACP,
  410. 0,
  411. reinterpret_cast <LPCWSTR> (varSecret.pbstrVal),
  412. -1,
  413. m_szSecret,
  414. MAX_SECRET_SIZE,
  415. NULL,
  416. NULL
  417. );
  418. if (0 == iRetVal)
  419. {
  420. IASTracePrintf (
  421. "Unable to convert client shared secret to multi-byte string "
  422. "during Client processing"
  423. );
  424. return (FALSE);
  425. }
  426. //
  427. // set secret size
  428. //
  429. m_dwSecretSize = strlen (m_szSecret);
  430. return (TRUE);
  431. } // end of CClient::SetSecret method
  432. HRESULT CClient::SetClientName(const VARIANT& varClientName) throw ()
  433. {
  434. if (V_VT(&varClientName) != VT_BSTR)
  435. {
  436. return E_INVALIDARG;
  437. }
  438. return StringCchCopyW(
  439. m_wszClientName,
  440. RTL_NUMBER_OF(m_wszClientName),
  441. V_BSTR(&varClientName)
  442. );
  443. }
  444. //++--------------------------------------------------------------
  445. //
  446. // Function: SetSignatureFlag
  447. //
  448. // Synopsis: This is the CClient private method used
  449. // to set the Client Signature flag
  450. //
  451. // Arguments: VARIANT - holds the signature as a boolean
  452. //
  453. // Returns: status
  454. //
  455. // History: MKarki Created 2/3/98
  456. //
  457. // Called By: CClient::Init method
  458. //
  459. //----------------------------------------------------------------
  460. BOOL
  461. CClient::SetSignatureFlag (
  462. VARIANT varSigFlag
  463. )
  464. {
  465. _ASSERT (VT_BOOL == varSigFlag.vt);
  466. if (0 == varSigFlag.boolVal)
  467. {
  468. m_bSignatureCheck = FALSE;
  469. }
  470. else
  471. {
  472. m_bSignatureCheck = TRUE;
  473. }
  474. return (TRUE);
  475. } // end of CClient::SetSignatureFlag method
  476. //++--------------------------------------------------------------
  477. //
  478. // Function: SetVendorType
  479. //
  480. // Synopsis: This is the CClient private method used
  481. // to set the Client Vendor Type
  482. //
  483. // Arguments: VARIANT - holds the Vendor Type
  484. //
  485. // Returns: status
  486. //
  487. // History: MKarki Created 3/16/98
  488. //
  489. // Called By: CClient::Init method
  490. //
  491. //----------------------------------------------------------------
  492. BOOL
  493. CClient::SetVendorType (
  494. VARIANT varVendorType
  495. )
  496. {
  497. _ASSERT (VT_I4 == varVendorType.vt);
  498. m_lVendorType = varVendorType.lVal;
  499. return (TRUE);
  500. } // end of CClient::SetVendorType method