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.

314 lines
8.2 KiB

  1. // AccessTok.cpp -- Access Token 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. #include "NoWarning.h"
  8. #include "ForceLib.h"
  9. #include <limits>
  10. #include <memory>
  11. #include <WinError.h>
  12. #include <scuOsExc.h>
  13. #include "Blob.h"
  14. #include "AccessTok.h"
  15. using namespace std;
  16. using namespace scu;
  17. /////////////////////////// LOCAL/HELPER /////////////////////////////////
  18. namespace
  19. {
  20. const char PinPad = '\xFF';
  21. void
  22. DoAuthenticate(HCardContext const &rhcardctx,
  23. SecureArray<BYTE> &rsPin)
  24. {
  25. rhcardctx->Card()->AuthenticateUser(rsPin);
  26. }
  27. }
  28. /////////////////////////// PUBLIC /////////////////////////////////
  29. // Types
  30. // C'tors/D'tors
  31. AccessToken::AccessToken(HCardContext const &rhcardctx,
  32. LoginIdentity const &rlid)
  33. : m_hcardctx(rhcardctx),
  34. m_lid(rlid),
  35. m_hpc(0),
  36. m_sPin()
  37. {
  38. // TO DO: Support Administrator and Manufacturing PINs
  39. switch (m_lid)
  40. {
  41. case User:
  42. break;
  43. case Administrator:
  44. // TO DO: Support authenticating admin (aut 0)
  45. throw scu::OsException(E_NOTIMPL);
  46. case Manufacturer:
  47. // TO DO: Support authenticating manufacturer (aut ?)
  48. throw scu::OsException(E_NOTIMPL);
  49. default:
  50. throw scu::OsException(ERROR_INVALID_PARAMETER);
  51. }
  52. //m_sPin.append(MaxPinLength, '\0');
  53. }
  54. AccessToken::AccessToken(AccessToken const &rhs)
  55. : m_hcardctx(rhs.m_hcardctx),
  56. m_lid(rhs.m_lid),
  57. m_hpc(0), // doesn't commute
  58. m_sPin(rhs.m_sPin)
  59. {}
  60. AccessToken::~AccessToken()
  61. {
  62. try
  63. {
  64. FlushPin();
  65. }
  66. catch (...)
  67. {
  68. }
  69. }
  70. // Operators
  71. // Operations
  72. void
  73. AccessToken::Authenticate()
  74. {
  75. // Only the user pin (CHV) is supported.
  76. DWORD dwError = ERROR_SUCCESS;
  77. SecureArray<BYTE> bPin(MaxPinLength);
  78. DWORD cbPin = bPin.size();
  79. if ((0 == m_hpc) || (0 != m_sPin.length_string()))
  80. {
  81. // The MS pin cache is either uninitialized (empty) or a new
  82. // pin supplied. Authenticate using requested pin, having the MS pin
  83. // cache library update the cache if authentication succeeds.
  84. if (m_sPin.length() > cbPin)
  85. throw scu::OsException(ERROR_BAD_LENGTH);
  86. bPin=m_sPin;
  87. cbPin=bPin.size();
  88. PINCACHE_PINS pcpins = {
  89. cbPin,
  90. bPin.data(),
  91. 0,
  92. 0
  93. };
  94. dwError = PinCacheAdd(&m_hpc, &pcpins, VerifyPin, this);
  95. if (ERROR_SUCCESS != dwError)
  96. {
  97. m_sPin = SecureArray<BYTE>(0);// clear this pin ?
  98. if (Exception())
  99. PropagateException();
  100. else
  101. throw scu::OsException(dwError);
  102. }
  103. }
  104. else
  105. {
  106. // The MS pin cache must already be initialized at this point.
  107. // Retrieve it and authenticate.
  108. dwError = PinCacheQuery(m_hpc, bPin.data(), &cbPin);
  109. if (ERROR_SUCCESS != dwError)
  110. throw scu::OsException(dwError);
  111. SecureArray<BYTE> blbPin(bPin.data(), cbPin);
  112. DoAuthenticate(m_hcardctx, blbPin);
  113. m_sPin = blbPin; // cache in case changing pin
  114. }
  115. }
  116. void
  117. AccessToken::ChangePin(AccessToken const &ratNew)
  118. {
  119. DWORD dwError = ERROR_SUCCESS;
  120. SecureArray<BYTE> bPin(MaxPinLength);
  121. DWORD cbPin = bPin.size();
  122. if (m_sPin.length() > cbPin)
  123. throw scu::OsException(ERROR_BAD_LENGTH);
  124. bPin = m_sPin;
  125. cbPin = bPin.size();
  126. SecureArray<BYTE> bNewPin(MaxPinLength);
  127. DWORD cbNewPin = bNewPin.size();
  128. if (ratNew.m_sPin.length() > cbPin)
  129. throw scu::OsException(ERROR_BAD_LENGTH);
  130. bNewPin = ratNew.m_sPin;
  131. cbNewPin = bNewPin.size();
  132. PINCACHE_PINS pcpins = {
  133. cbPin,
  134. bPin.data(),
  135. cbNewPin,
  136. bNewPin.data()
  137. };
  138. dwError = PinCacheAdd(&m_hpc, &pcpins, ChangeCardPin, this);
  139. if (ERROR_SUCCESS != dwError)
  140. {
  141. if (Exception())
  142. PropagateException();
  143. else
  144. throw scu::OsException(dwError);
  145. }
  146. m_sPin = ratNew.m_sPin; // cache the new pin
  147. }
  148. void
  149. AccessToken::ClearPin()
  150. {
  151. m_sPin = SecureArray<BYTE>(0);
  152. }
  153. void
  154. AccessToken::FlushPin()
  155. {
  156. PinCacheFlush(&m_hpc);
  157. ClearPin();
  158. }
  159. void
  160. AccessToken::Pin(char const *pczPin,
  161. bool fInHex)
  162. {
  163. if (!pczPin)
  164. throw scu::OsException(ERROR_INVALID_PARAMETER);
  165. if (fInHex)
  166. throw scu::OsException(ERROR_INVALID_PARAMETER);
  167. else
  168. m_sPin = SecureArray<BYTE>((BYTE*)pczPin, strlen(pczPin));
  169. if (m_sPin.length() > MaxPinLength)
  170. // clear the existing pin to replace it later with invalid chars
  171. m_sPin = SecureArray<BYTE>();
  172. if (m_sPin.length() < MaxPinLength) // always pad the pin
  173. m_sPin.append(MaxPinLength - m_sPin.length(), PinPad);
  174. }
  175. // Access
  176. HCardContext
  177. AccessToken::CardContext() const
  178. {
  179. return m_hcardctx;
  180. }
  181. LoginIdentity
  182. AccessToken::Identity() const
  183. {
  184. return m_lid;
  185. }
  186. SecureArray<BYTE>
  187. AccessToken::Pin() const
  188. {
  189. return m_sPin;
  190. }
  191. // Predicates
  192. bool
  193. AccessToken::PinIsCached() const
  194. {
  195. DWORD cbPin;
  196. DWORD dwError = PinCacheQuery(m_hpc, 0, &cbPin);
  197. bool fIsCached = (0 != cbPin);
  198. return fIsCached;
  199. }
  200. // Static Variables
  201. /////////////////////////// PROTECTED /////////////////////////////////
  202. // C'tors/D'tors
  203. // Operators
  204. // Operations
  205. // Access
  206. // Predicates
  207. // Static Variables
  208. /////////////////////////// PRIVATE /////////////////////////////////
  209. // C'tors/D'tors
  210. // Operators
  211. // Operations
  212. DWORD
  213. AccessToken::ChangeCardPin(PPINCACHE_PINS pPins,
  214. PVOID pvCallbackCtx)
  215. {
  216. AccessToken *pat = reinterpret_cast<AccessToken *>(pvCallbackCtx);
  217. DWORD dwError = ERROR_SUCCESS;
  218. EXCCTX_TRY
  219. {
  220. pat->ClearException();
  221. SecureArray<BYTE> blbPin(pPins->pbCurrentPin, pPins->cbCurrentPin);
  222. SecureArray<BYTE> blbNewPin(pPins->pbNewPin, pPins->cbNewPin);
  223. pat->m_hcardctx->Card()->ChangePIN(blbPin,
  224. blbNewPin);
  225. }
  226. EXCCTX_CATCH(pat, false);
  227. if (pat->Exception())
  228. dwError = E_FAIL;
  229. return dwError;
  230. }
  231. DWORD
  232. AccessToken::VerifyPin(PPINCACHE_PINS pPins,
  233. PVOID pvCallbackCtx)
  234. {
  235. AccessToken *pat = reinterpret_cast<AccessToken *>(pvCallbackCtx);
  236. DWORD dwError = ERROR_SUCCESS;
  237. EXCCTX_TRY
  238. {
  239. pat->ClearException();
  240. SecureArray<BYTE> blbPin(pPins->pbCurrentPin, pPins->cbCurrentPin);
  241. DoAuthenticate(pat->m_hcardctx, blbPin);
  242. }
  243. EXCCTX_CATCH(pat, false);
  244. if (pat->Exception())
  245. dwError = E_FAIL;
  246. return dwError;
  247. }
  248. // Access
  249. // Predicates
  250. // Static Variables