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.

369 lines
12 KiB

  1. // CardCtx.cpp -- Card ConTeXt class definition
  2. // (c) Copyright Schlumberger Technology Corp., unpublished work, created
  3. // 1999. This computer program includes Confidential, Proprietary
  4. // Information and is a Trade Secret of Schlumberger Technology Corp. All
  5. // use, disclosure, and/or reproduction is prohibited unless authorized
  6. // in writing. All Rights Reserved.
  7. // Don't allow the min & max macros in WINDEF.H to be defined so the
  8. // min/max methods declared in limits are accessible.
  9. #define NOMINMAX
  10. #include "NoWarning.h"
  11. #include "ForceLib.h"
  12. #include <limits>
  13. #include <algorithm>
  14. #include <numeric>
  15. #include <scuOsExc.h>
  16. #include <scuCast.h>
  17. #include "HCardCtx.h"
  18. #include "LoginCtx.h"
  19. #include "Procedural.h"
  20. #include "HAdptvCntr.h"
  21. #include "Guarded.h"
  22. #include <scarderr.h> // always last for now
  23. using namespace std;
  24. using namespace cci;
  25. /////////////////////////// LOCAL/HELPER /////////////////////////////////
  26. namespace
  27. {
  28. class StaleContainerKeyAccumulator
  29. : public binary_function<vector<AdaptiveContainerRegistrar::EnrolleeType>,
  30. AdaptiveContainerRegistrar::RegistryType::CollectionType::value_type,
  31. vector<AdaptiveContainerRegistrar::EnrolleeType> >
  32. {
  33. public:
  34. explicit
  35. StaleContainerKeyAccumulator(HCardContext const &rhcardctx)
  36. : m_rhcardctx(rhcardctx)
  37. {}
  38. result_type
  39. operator()(first_argument_type &rvStaleCntrs,
  40. second_argument_type const &rvt) const
  41. {
  42. if (rvt.second->CardContext(false) == m_rhcardctx)
  43. rvStaleCntrs.push_back(rvt.second);
  44. return rvStaleCntrs;
  45. }
  46. private:
  47. HCardContext const &m_rhcardctx;
  48. };
  49. void
  50. ClearAdaptiveContainerCache(AdaptiveContainerRegistrar::EnrolleeType enrollee,
  51. HCardContext hcardctx)
  52. {
  53. if (enrollee->CardContext(false) == hcardctx)
  54. {
  55. enrollee->ClearCache();
  56. }
  57. }
  58. void
  59. DeleteAdaptiveContainerCache(AdaptiveContainerRegistrar::EnrolleeType enrollee,
  60. HCardContext hcardctx)
  61. {
  62. if (enrollee->CardContext(false) == hcardctx)
  63. enrollee->DeleteCache();
  64. }
  65. void
  66. DeactivateLoginContext(auto_ptr<LoginContext> const &raplc)
  67. {
  68. raplc->Deactivate();
  69. }
  70. }
  71. /////////////////////////// PUBLIC /////////////////////////////////
  72. // Types
  73. // C'tors/D'tors
  74. CardContext::CardContext(std::string const &rsReaderName)
  75. : RCObject(),
  76. Lockable(),
  77. Securable(),
  78. CachingObject(),
  79. CardContextRegistrar(rsReaderName),
  80. m_stkapGuards(),
  81. m_aptwCard(),
  82. m_cSecurers(0),
  83. m_card(CCard(rsReaderName)),
  84. m_mloginctx(),
  85. m_nMrkLastWrite()
  86. {}
  87. CardContext::~CardContext() throw()
  88. {}
  89. // Operators
  90. // Operations
  91. void
  92. CardContext::ClearLogin(LoginIdentity const &rlid)
  93. {
  94. Guarded<CardContext *> guard(this);
  95. auto_ptr<LoginContext> &raplc = m_mloginctx[rlid];
  96. if (raplc.get())
  97. raplc = auto_ptr<LoginContext>(0);
  98. }
  99. void
  100. CardContext::Login(LoginIdentity const &rlid,
  101. LoginTask &rlt,
  102. bool fForceLogin)
  103. {
  104. Guarded<CardContext *> guard(this);
  105. auto_ptr<LoginContext> &raplc = m_mloginctx[rlid];
  106. if (!raplc.get())
  107. raplc = auto_ptr<LoginContext>(new LoginContext(HCardContext(this),
  108. rlid));
  109. if (fForceLogin || !raplc->IsActive())
  110. raplc->Activate(rlt);
  111. }
  112. void
  113. CardContext::Logout()
  114. {
  115. ForEachMappedValue(m_mloginctx.begin(), m_mloginctx.end(),
  116. DeactivateLoginContext);
  117. }
  118. // Access
  119. CCard
  120. CardContext::Card()
  121. {
  122. return m_card;
  123. }
  124. // Predicates
  125. // Static Variables
  126. /////////////////////////// PROTECTED /////////////////////////////////
  127. // C'tors/D'tors
  128. // Operators
  129. // Operations
  130. void
  131. CardContext::DiscardHook()
  132. {
  133. DeleteCache();
  134. RemoveReference();
  135. }
  136. CardContext *
  137. CardContext::DoInstantiation(std::string const &rsReaderName)
  138. {
  139. return new CardContext(rsReaderName);
  140. }
  141. void
  142. CardContext::EnrollHook()
  143. {
  144. AddReference();
  145. }
  146. // Access
  147. // Predicates
  148. bool
  149. CardContext::KeepEnrolled()
  150. {
  151. return (m_card && m_card->IsAvailable())
  152. ? true
  153. : false;
  154. }
  155. // Static Variables
  156. /////////////////////////// PRIVATE /////////////////////////////////
  157. // C'tors/D'tors
  158. // Operators
  159. // Operations
  160. void
  161. CardContext::Abandon()
  162. {
  163. // Simplifying assumptions: (1) Abandon is only called by the
  164. // Secured destructor, (2) once the object is constructed, Secure
  165. // and Abandon are the only routines that access the count, and
  166. // (3) Abandon is called by a thread within the scope of a Retain
  167. // (e.g. using Retained) which the Secured class enforces.
  168. // Because of (1) and (2), an underflow check on the count is not
  169. // necessary since Secure will have already been called. Because
  170. // of (3), protection against race conditions accessing count
  171. // isn't necessary since Retain acts as a lock.
  172. --m_cSecurers;
  173. if (0 == m_cSecurers)
  174. {
  175. // Security: markers are moved to the card. Updating them
  176. // requires authentication by the user pin.
  177. // Notify any changes to this card during this transaction
  178. // before letting someone else have access and before loggin
  179. // out.
  180. try
  181. {
  182. UpdateMarkers();
  183. }
  184. catch(...)
  185. {
  186. // do not leave the card in authenticated state
  187. Logout();
  188. throw;
  189. }
  190. Logout();
  191. }
  192. }
  193. // Optionally clear the cached info
  194. void
  195. CardContext::ClearCache()
  196. {
  197. // Security: markers reside on the card. We trade off performance for
  198. // security because any update of the marker requires
  199. // authentication by the user pin. On the other hand, reading
  200. // markers from the card is considerably slower than reading from
  201. // memory.
  202. if(!Card()->IsMarkerOnCard() || m_nMrkLastWrite != Card()->MarkerOnCard())
  203. {
  204. ForEachEnrollee(AdaptiveContainerRegistrar::Registry(),
  205. ProcedureBind2nd(PointerProcedure(ClearAdaptiveContainerCache),
  206. HCardContext(this)));
  207. Card()->InvalidateCache();
  208. }
  209. }
  210. // Delete any cached info, never to be refreshed
  211. void
  212. CardContext::DeleteCache()
  213. {
  214. m_mloginctx.clear();
  215. Guarded<Lockable *> guard(&AdaptiveContainerRegistrar::Registry()); // serialize registry access
  216. AdaptiveContainerRegistrar::ConstRegistryType &rRegistry =
  217. AdaptiveContainerRegistrar::Registry();
  218. AdaptiveContainerRegistrar::ConstRegistryType::CollectionType
  219. &rcollection = rRegistry();
  220. HCardContext hcardctx(this);
  221. // Any containers associated with this card should be marked stale
  222. // now because on Whistler (W2K Upgrade) trying to access them
  223. // later when another context has a begin transaction on the same
  224. // reader will cause a wait. On earlier platforms, the RM would
  225. // return an error (e.g. card removed) when attempting to access
  226. // the container.
  227. vector<AdaptiveContainerRegistrar::EnrolleeType>
  228. vStaleCntrs(accumulate(rcollection.begin(), rcollection.end(),
  229. vector<AdaptiveContainerRegistrar::EnrolleeType>(),
  230. StaleContainerKeyAccumulator(hcardctx)));
  231. for (vector<AdaptiveContainerRegistrar::EnrolleeType>::iterator iCurrent(vStaleCntrs.begin());
  232. iCurrent != vStaleCntrs.end(); ++iCurrent)
  233. {
  234. (*iCurrent)->NullifyCard();
  235. }
  236. }
  237. void
  238. CardContext::Relinquish()
  239. {
  240. // Simplifying assumptions: (1) Relinquish is only called by the
  241. // Retained destructor and (2) once the object is constructed,
  242. // Retain and Relinquish are the only routines that access the
  243. // m_stkapGuards and m_aptwCard. Because of (1) and (2), an
  244. // underflow check on m_stkRetainedCardContexts is not necessary
  245. // since Retain will have already been called.
  246. // Protect against exceptions by fist assigning the newly acquired
  247. // "locks" to temporary variables until all the actions necessary
  248. // are successfully completed before assigning transfering
  249. // ownership of the locks to the associated member variables.
  250. auto_ptr<Guarded<CardContext *> > apgcardctx(m_stkapGuards.front());
  251. m_stkapGuards.pop_front();
  252. if (m_stkapGuards.empty())
  253. {
  254. try
  255. {
  256. m_aptwCard = auto_ptr<CTransactionWrap>(0);
  257. }
  258. catch (...)
  259. {
  260. }
  261. }
  262. }
  263. void
  264. CardContext::Retain()
  265. {
  266. // Simplifying assumptions: (1) Retain is only called by the
  267. // Retained constructor and (2) once the object is constructed,
  268. // Retain and Relinquish are the only routines that access the
  269. // m_stkapGuards and m_aptwCard. Because of (1) and (2), an
  270. // underflow check on m_stkRetainedCardContexts is not necessary
  271. // since Retain will have already been called.
  272. // Protect against exceptions by fist assigning the newly acquired
  273. // "locks" to temporary variables until all the actions necessary
  274. // are successfully completed before assigning transfering
  275. // ownership of the locks to the associated member variables.
  276. auto_ptr<Guarded<CardContext *> > apgcardctx(new Guarded<CardContext *>(this));
  277. auto_ptr<CTransactionWrap> aptwCard;
  278. if (m_stkapGuards.empty())
  279. {
  280. aptwCard = auto_ptr<CTransactionWrap>(new CTransactionWrap(m_card));
  281. ClearCache();
  282. }
  283. m_stkapGuards.push_front(apgcardctx);
  284. if (aptwCard.get())
  285. m_aptwCard = aptwCard;
  286. }
  287. void
  288. CardContext::UpdateMarkers()
  289. {
  290. // Security: there is only one marker and it resides on the
  291. // card. The marker indicates if any data on the card changed.
  292. m_nMrkLastWrite = Card()->MarkerOnCard();
  293. }
  294. void
  295. CardContext::Secure()
  296. {
  297. // Simplifying assumptions: (1) Secure is always called by a thread
  298. // within the scope of a Retain (e.g. using Retained). The
  299. // Secured template enforces this allowing Retain to act as a lock
  300. // to prevent race conditions updating m_cSecurers. (2) Once the
  301. // object is constructed, Secure and Abandon are the only routines
  302. // that access m_cSecurers.
  303. if (0 >= (m_cSecurers + 1))
  304. throw scu::OsException(ERROR_INVALID_HANDLE_STATE);
  305. ++m_cSecurers;
  306. }
  307. // Access
  308. // Predicates
  309. // Static Variables