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.

545 lines
14 KiB

  1. #include "precomp.h"
  2. #include "fsdiag.h"
  3. DEBUG_FILEZONE(ZONE_T120_UTILITY);
  4. /*
  5. * sesskey.cpp
  6. *
  7. * Copyright (c) 1995 by DataBeam Corporation, Lexington, KY
  8. *
  9. * Abstract:
  10. * This is the implementation file for the class CSessKeyContainer. This class
  11. * manages the data associated with a Session Key. Session Key's are used
  12. * to uniquely identify an Application Protocol Session. The Application
  13. * Protocol is identified by an Object Key and the particular session
  14. * identified by an optional session ID. The CSessKeyContainer class uses an
  15. * CObjectKeyContainer container to maintain the object key data internally. An
  16. * unsigned short integer is used to hold the optional session ID.
  17. *
  18. * Protected Instance Variables:
  19. * m_InternalSessKey
  20. * Structure used to hold the object key data internally.
  21. * m_SessionKeyPDU
  22. * Storage for the "PDU" form of the session key.
  23. * m_fValidSessionKeyPDU
  24. * Flag indicating that memory has been allocated to hold the internal
  25. * "PDU" session key.
  26. * m_cbDataSize
  27. * Variable holding the size of the memory which will be required to
  28. * hold any data referenced by the "API" GCCSessionKey structure.
  29. *
  30. * Caveats:
  31. * None.
  32. *
  33. * Author:
  34. * jbo
  35. */
  36. #include "sesskey.h"
  37. /*
  38. * CSessKeyContainer()
  39. *
  40. * Public Function Description:
  41. * This constructor is used to create a CSessKeyContainer object from
  42. * an "API" GCCSessionKey.
  43. */
  44. CSessKeyContainer::
  45. CSessKeyContainer(PGCCSessionKey session_key, PGCCError pRetCode)
  46. :
  47. CRefCount(MAKE_STAMP_ID('S','e','s','K')),
  48. m_fValidSessionKeyPDU(FALSE),
  49. m_cbDataSize(0)
  50. {
  51. GCCError rc;
  52. /*
  53. * Save the Object Key portion of the Session Key in the internal structure
  54. * by creating a new CObjectKeyContainer object. Check to make sure the object
  55. * is successfully created.
  56. */
  57. DBG_SAVE_FILE_LINE
  58. m_InternalSessKey.application_protocol_key = new CObjectKeyContainer(
  59. &session_key->application_protocol_key,
  60. &rc);
  61. if (NULL != m_InternalSessKey.application_protocol_key && GCC_NO_ERROR == rc)
  62. {
  63. /*
  64. * Save the session ID if the CObjectKeyContainer was saved correctly. A zero
  65. * value of the GCC session ID will indicate that one is not actually
  66. * present.
  67. */
  68. m_InternalSessKey.session_id = session_key->session_id;
  69. }
  70. else if (GCC_BAD_OBJECT_KEY == rc)
  71. {
  72. ERROR_OUT(("CSessKeyContainer::SessionKeyData1: bad session key"));
  73. rc = GCC_BAD_SESSION_KEY;
  74. }
  75. else
  76. {
  77. ERROR_OUT(("CSessKeyContainer::SessionKeyData1: Error creating new CObjectKeyContainer"));
  78. rc = GCC_ALLOCATION_FAILURE;
  79. }
  80. *pRetCode = rc;
  81. }
  82. /*
  83. * CSessKeyContainer()
  84. *
  85. * Public Function Description:
  86. * This constructor is used to create a CSessKeyContainer object from
  87. * a "PDU" SessionKey.
  88. */
  89. CSessKeyContainer::
  90. CSessKeyContainer(PSessionKey session_key, PGCCError pRetCode)
  91. :
  92. CRefCount(MAKE_STAMP_ID('S','e','s','K')),
  93. m_fValidSessionKeyPDU(FALSE),
  94. m_cbDataSize(0)
  95. {
  96. GCCError rc;
  97. /*
  98. * Save the Object Key portion of the Session Key in the internal structure
  99. * by creating a new CObjectKeyContainer object. Check to make sure the object
  100. * is successfully created.
  101. */
  102. DBG_SAVE_FILE_LINE
  103. m_InternalSessKey.application_protocol_key = new CObjectKeyContainer(
  104. &session_key->application_protocol_key,
  105. &rc);
  106. if (NULL != m_InternalSessKey.application_protocol_key && GCC_NO_ERROR == rc)
  107. {
  108. /*
  109. * Save the session ID if one is present and the CObjectKeyContainer was saved
  110. * correctly. If a session ID is not present, set the internal session ID
  111. * to zero to indicate this.
  112. */
  113. if (session_key->bit_mask & SESSION_ID_PRESENT)
  114. {
  115. m_InternalSessKey.session_id = session_key->session_id;
  116. }
  117. else
  118. {
  119. m_InternalSessKey.session_id = 0;
  120. }
  121. }
  122. else if (GCC_BAD_OBJECT_KEY == rc)
  123. {
  124. ERROR_OUT(("CSessKeyContainer::SessionKeyData2: bad session key"));
  125. rc = GCC_BAD_SESSION_KEY;
  126. }
  127. else
  128. {
  129. ERROR_OUT(("CSessKeyContainer::SessionKeyData2: Error creating new CObjectKeyContainer"));
  130. rc = GCC_ALLOCATION_FAILURE;
  131. }
  132. *pRetCode = rc;
  133. }
  134. /*
  135. * CSessKeyContainer()
  136. *
  137. * Public Function Description:
  138. * This copy constructor is used to create a new CSessKeyContainer object from
  139. * another CSessKeyContainer object.
  140. */
  141. CSessKeyContainer::
  142. CSessKeyContainer(CSessKeyContainer *session_key, PGCCError pRetCode)
  143. :
  144. CRefCount(MAKE_STAMP_ID('S','e','s','K')),
  145. m_fValidSessionKeyPDU(FALSE),
  146. m_cbDataSize(0)
  147. {
  148. GCCError rc;
  149. /*
  150. * Copy the Object Key portion of the Session Key using the copy constructor
  151. * of the CObjectKeyContainer class. Check to make sure the CObjectKeyContainer object
  152. * is successfully created.
  153. */
  154. DBG_SAVE_FILE_LINE
  155. m_InternalSessKey.application_protocol_key = new CObjectKeyContainer(
  156. session_key->m_InternalSessKey.application_protocol_key,
  157. &rc);
  158. if (NULL != m_InternalSessKey.application_protocol_key && GCC_NO_ERROR == rc)
  159. {
  160. /*
  161. * Save the session ID if the CObjectKeyContainer was saved correctly. A zero
  162. * value of the GCC session ID will indicate that one is not actually
  163. * present.
  164. */
  165. m_InternalSessKey.session_id = session_key->m_InternalSessKey.session_id;
  166. }
  167. else if (GCC_BAD_OBJECT_KEY == rc)
  168. {
  169. ERROR_OUT(("CSessKeyContainer::SessionKeyData3: bad session key"));
  170. rc = GCC_BAD_SESSION_KEY;
  171. }
  172. else
  173. {
  174. ERROR_OUT(("CSessKeyContainer::SessionKeyData3: Error creating new CObjectKeyContainer"));
  175. rc = GCC_ALLOCATION_FAILURE;
  176. }
  177. *pRetCode = rc;
  178. }
  179. /*
  180. * ~CSessKeyContainer()
  181. *
  182. * Public Function Description
  183. * The CSessKeyContainer destructor is responsible for freeing any memory
  184. * allocated to hold the session key data.
  185. *
  186. */
  187. CSessKeyContainer::
  188. ~CSessKeyContainer(void)
  189. {
  190. /*
  191. * If "PDU" data has been allocated for this object, free it now.
  192. */
  193. if (m_fValidSessionKeyPDU)
  194. {
  195. FreeSessionKeyDataPDU();
  196. }
  197. /*
  198. * Delete any object key data held internally.
  199. */
  200. if (NULL != m_InternalSessKey.application_protocol_key)
  201. {
  202. m_InternalSessKey.application_protocol_key->Release();
  203. }
  204. }
  205. /*
  206. * LockSessionKeyData ()
  207. *
  208. * Public Function Description:
  209. * This routine locks the session key data and determines the amount of
  210. * memory referenced by the "API" session key data structure.
  211. */
  212. UINT CSessKeyContainer::
  213. LockSessionKeyData(void)
  214. {
  215. /*
  216. * If this is the first time this routine is called, determine the size of
  217. * the memory required to hold the data referenced by the session key
  218. * structure. Otherwise, just increment the lock count.
  219. */
  220. if (Lock() == 1)
  221. {
  222. /*
  223. * Lock the data for the object key held within the session key. The
  224. * pointer to the CObjectKeyContainer object is validated in the constructor.
  225. */
  226. m_cbDataSize = m_InternalSessKey.application_protocol_key->LockObjectKeyData();
  227. }
  228. return m_cbDataSize;
  229. }
  230. /*
  231. * GetGCCSessionKeyData ()
  232. *
  233. * Public Function Description:
  234. * This routine retrieves session key data in the "API" form of a
  235. * GCCSessionKey. This routine is called after "locking" the session
  236. * key data.
  237. */
  238. UINT CSessKeyContainer::
  239. GetGCCSessionKeyData(PGCCSessionKey session_key, LPBYTE memory)
  240. {
  241. UINT cbDataSizeToRet = 0;
  242. /*
  243. * If the session key data has been locked, fill in the output structure and
  244. * the data referenced by the structure. Call the "Get" routine for the
  245. * ObjectKey to fill in the object key data.
  246. */
  247. if (GetLockCount() > 0)
  248. {
  249. /*
  250. * Fill in the output length parameter which indicates how much data
  251. * referenced outside the structure will be written.
  252. */
  253. cbDataSizeToRet = m_cbDataSize;
  254. ::ZeroMemory(memory, m_cbDataSize);
  255. session_key->session_id = m_InternalSessKey.session_id;
  256. m_InternalSessKey.application_protocol_key->GetGCCObjectKeyData(
  257. &session_key->application_protocol_key,
  258. memory);
  259. }
  260. else
  261. {
  262. ERROR_OUT(("CSessKeyContainer::GetGCCSessionKeyData: Error: data not locked"));
  263. }
  264. return cbDataSizeToRet;
  265. }
  266. /*
  267. * UnlockSessionKeyData ()
  268. *
  269. * Public Function Description:
  270. * This routine decrements the lock count and frees the memory associated
  271. * with the "API" session key once the lock count reaches zero.
  272. */
  273. void CSessKeyContainer::
  274. UnLockSessionKeyData(void)
  275. {
  276. if (Unlock(FALSE) == 0)
  277. {
  278. /*
  279. * Unlock the data associated with the internal CObjectKeyContainer and
  280. * delete this object if the "free flag" is set.
  281. */
  282. if (m_InternalSessKey.application_protocol_key != NULL)
  283. {
  284. m_InternalSessKey.application_protocol_key->UnLockObjectKeyData();
  285. }
  286. }
  287. // we have to call Release() because we used Unlock(FALSE)
  288. Release();
  289. }
  290. /*
  291. * GetSessionKeyDataPDU ()
  292. *
  293. * Public Function Description:
  294. * This routine converts the session key from it's internal form of a
  295. * SESSION_KEY structure into the "PDU" form which can be passed in
  296. * to the ASN.1 encoder. A pointer to a "PDU" "SessionKey" structure is
  297. * returned.
  298. */
  299. GCCError CSessKeyContainer::
  300. GetSessionKeyDataPDU(PSessionKey session_key)
  301. {
  302. GCCError rc = GCC_NO_ERROR;
  303. /*
  304. * If this is the first time that PDU data has been requested then we must
  305. * fill in the internal PDU structure and copy it into the structure pointed
  306. * to by the output parameter. On subsequent calls to "GetPDU" we can just
  307. * copy the internal PDU structure into the structure pointed to by the
  308. * output parameter.
  309. */
  310. if (m_fValidSessionKeyPDU == FALSE)
  311. {
  312. m_fValidSessionKeyPDU = TRUE;
  313. /*
  314. * Initialize the "PDU" session key's bit mask to zero.
  315. */
  316. m_SessionKeyPDU.bit_mask = 0;
  317. /*
  318. * Fill in the "PDU" session key from the internal structure.
  319. */
  320. if (m_InternalSessKey.application_protocol_key != NULL)
  321. {
  322. /*
  323. * Fill in the object key portion of the session key by using the
  324. * "GetPDU" routine of the internal CObjectKeyContainer object.
  325. */
  326. rc = m_InternalSessKey.application_protocol_key->
  327. GetObjectKeyDataPDU(&m_SessionKeyPDU.application_protocol_key);
  328. }
  329. else
  330. {
  331. rc = GCC_ALLOCATION_FAILURE;
  332. }
  333. /*
  334. * Fill in the "PDU" session ID if one exists. A value of zero for the
  335. * internal session ID indicates that one really does not exist.
  336. */
  337. if (m_InternalSessKey.session_id != 0)
  338. {
  339. m_SessionKeyPDU.bit_mask |= SESSION_ID_PRESENT;
  340. m_SessionKeyPDU.session_id = m_InternalSessKey.session_id;
  341. }
  342. }
  343. /*
  344. * Copy the internal PDU structure into the structure pointed to by the
  345. * output parameter.
  346. */
  347. *session_key = m_SessionKeyPDU;
  348. return rc;
  349. }
  350. /*
  351. * FreeSessionKeyDataPDU ()
  352. *
  353. * Public Function Description:
  354. * This routine is used to free the session key data held internally in
  355. * the "PDU" form of a "SessionKey".
  356. */
  357. void CSessKeyContainer::
  358. FreeSessionKeyDataPDU(void)
  359. {
  360. if (m_fValidSessionKeyPDU)
  361. {
  362. /*
  363. * Set the flag indicating that PDU session key data is no longer
  364. * allocated.
  365. */
  366. m_fValidSessionKeyPDU = FALSE;
  367. if (m_InternalSessKey.application_protocol_key != NULL)
  368. {
  369. m_InternalSessKey.application_protocol_key->FreeObjectKeyDataPDU ();
  370. }
  371. else
  372. {
  373. ERROR_OUT(("CSessKeyContainer::FreeSessionKeyDataPDU: Bad internal pointer"));
  374. }
  375. }
  376. }
  377. /*
  378. * IsThisYourApplicationKey()
  379. *
  380. * Public Function Description:
  381. * This routine is used to determine whether the specified application
  382. * key is held within this session key.
  383. */
  384. BOOL CSessKeyContainer::
  385. IsThisYourApplicationKey(PGCCObjectKey application_key)
  386. {
  387. BOOL fRet = FALSE;
  388. CObjectKeyContainer *object_key_data;
  389. GCCError rc2;
  390. DBG_SAVE_FILE_LINE
  391. object_key_data = new CObjectKeyContainer(application_key, &rc2);
  392. if ((object_key_data != NULL) && (rc2 == GCC_NO_ERROR))
  393. {
  394. if (*object_key_data == *m_InternalSessKey.application_protocol_key)
  395. {
  396. fRet = TRUE;
  397. }
  398. }
  399. else
  400. {
  401. ERROR_OUT(("CSessKeyContainer::IsThisYourApplicationKey: Error creating new CObjectKeyContainer"));
  402. }
  403. if (NULL != object_key_data)
  404. {
  405. object_key_data->Release();
  406. }
  407. return fRet;
  408. }
  409. /*
  410. * IsThisYourApplicationKeyPDU()
  411. *
  412. * Public Function Description:
  413. * This routine is used to determine whether the specified application
  414. * key is held within this session key.
  415. */
  416. BOOL CSessKeyContainer::
  417. IsThisYourApplicationKeyPDU(PKey application_key)
  418. {
  419. BOOL fRet = FALSE;
  420. CObjectKeyContainer *object_key_data;
  421. GCCError rc2;
  422. DBG_SAVE_FILE_LINE
  423. object_key_data = new CObjectKeyContainer(application_key, &rc2);
  424. if ((object_key_data != NULL) && (rc2 == GCC_NO_ERROR))
  425. {
  426. if (*object_key_data == *m_InternalSessKey.application_protocol_key)
  427. {
  428. fRet = TRUE;
  429. }
  430. }
  431. else
  432. {
  433. ERROR_OUT(("CSessKeyContainer::IsThisYourApplicationKeyPDU: Error creating new CObjectKeyContainer"));
  434. }
  435. if (NULL != object_key_data)
  436. {
  437. object_key_data->Release();
  438. }
  439. return fRet;
  440. }
  441. /*
  442. * IsThisYourSessionKeyPDU ()
  443. *
  444. * Public Function Description:
  445. * This routine is used to determine whether the specified session key
  446. * is equal in value to this session key.
  447. */
  448. BOOL CSessKeyContainer::
  449. IsThisYourSessionKeyPDU(PSessionKey session_key)
  450. {
  451. BOOL fRet = FALSE;
  452. CSessKeyContainer *session_key_data;
  453. GCCError rc2;
  454. DBG_SAVE_FILE_LINE
  455. session_key_data = new CSessKeyContainer(session_key, &rc2);
  456. if ((session_key_data != NULL) && (rc2 == GCC_NO_ERROR))
  457. {
  458. if (*session_key_data == *this)
  459. {
  460. fRet = TRUE;
  461. }
  462. }
  463. else
  464. {
  465. ERROR_OUT(("CSessKeyContainer::IsThisYourSessionKeyPDU: Error creating new CSessKeyContainer"));
  466. }
  467. if (NULL != session_key_data)
  468. {
  469. session_key_data->Release();
  470. }
  471. return fRet;
  472. }
  473. /*
  474. * operator== ()
  475. *
  476. * Public Function Description:
  477. * This routine is used to determine whether or not two session keys are
  478. * equal in value.
  479. */
  480. BOOL operator==(const CSessKeyContainer& session_key_1, const CSessKeyContainer& session_key_2)
  481. {
  482. BOOL fRet = FALSE;
  483. if ((session_key_1.m_InternalSessKey.application_protocol_key != NULL) &&
  484. (session_key_2.m_InternalSessKey.application_protocol_key != NULL))
  485. {
  486. if (*session_key_1.m_InternalSessKey.application_protocol_key ==
  487. *session_key_2.m_InternalSessKey.application_protocol_key)
  488. {
  489. if (session_key_1.m_InternalSessKey.session_id ==
  490. session_key_2.m_InternalSessKey.session_id)
  491. {
  492. fRet = TRUE;
  493. }
  494. }
  495. }
  496. return fRet;
  497. }