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.

387 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows NT Security
  4. // Copyright (C) Microsoft Corporation, 1997 - 1999
  5. //
  6. // File: catcache.cpp
  7. //
  8. // Contents: Implementation of Catalog Cache (see catcache.h for details)
  9. //
  10. // History: 26-May-98 kirtd Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <global.hxx>
  14. //+---------------------------------------------------------------------------
  15. //
  16. // Member: CCatalogCache::Initialize, public
  17. //
  18. // Synopsis: initialize the cache
  19. //
  20. //----------------------------------------------------------------------------
  21. BOOL
  22. CCatalogCache::Initialize ()
  23. {
  24. LRU_CACHE_CONFIG Config;
  25. BOOL f;
  26. __try
  27. {
  28. InitializeCriticalSection( &m_Lock );
  29. }
  30. __except(EXCEPTION_EXECUTE_HANDLER)
  31. {
  32. return ( FALSE );
  33. }
  34. memset( &Config, 0, sizeof( Config ) );
  35. m_hCache = NULL;
  36. Config.dwFlags = LRU_CACHE_NO_SERIALIZE;
  37. Config.pfnFree = CatalogCacheFreeEntryData;
  38. Config.pfnHash = CatalogCacheHashIdentifier;
  39. Config.cBuckets = DEFAULT_CATALOG_CACHE_BUCKETS;
  40. Config.MaxEntries = DEFAULT_CATALOG_CACHE_MAX_ENTRIES;
  41. f = I_CryptCreateLruCache( &Config, &m_hCache );
  42. if ( !f )
  43. {
  44. DeleteCriticalSection( &m_Lock );
  45. }
  46. return( f );
  47. }
  48. //+---------------------------------------------------------------------------
  49. //
  50. // Member: CCatalogCache::Uninitialize, public
  51. //
  52. // Synopsis: uninitialize the cache
  53. //
  54. //----------------------------------------------------------------------------
  55. VOID
  56. CCatalogCache::Uninitialize ()
  57. {
  58. if ( m_hCache != NULL )
  59. {
  60. I_CryptFreeLruCache( m_hCache, 0, NULL );
  61. }
  62. DeleteCriticalSection( &m_Lock );
  63. }
  64. //+---------------------------------------------------------------------------
  65. //
  66. // Member: CCatalogCache::IsCacheableWintrustCall, public
  67. //
  68. // Synopsis: is this a cacheable call
  69. //
  70. //----------------------------------------------------------------------------
  71. BOOL
  72. CCatalogCache::IsCacheableWintrustCall (WINTRUST_DATA* pWintrustData)
  73. {
  74. if ( pWintrustData->dwUnionChoice != WTD_CHOICE_CATALOG )
  75. {
  76. return( FALSE );
  77. }
  78. if ( _ISINSTRUCT( WINTRUST_DATA, pWintrustData->cbStruct, hWVTStateData ) )
  79. {
  80. if ( ( pWintrustData->dwStateAction == WTD_STATEACTION_AUTO_CACHE ) ||
  81. ( pWintrustData->dwStateAction == WTD_STATEACTION_AUTO_CACHE_FLUSH ) )
  82. {
  83. return( TRUE );
  84. }
  85. }
  86. return( FALSE );
  87. }
  88. //+---------------------------------------------------------------------------
  89. //
  90. // Member: CCatalogCache::AdjustWintrustDataToCachedState, public
  91. //
  92. // Synopsis: adjust the wintrust data structure
  93. //
  94. //----------------------------------------------------------------------------
  95. VOID
  96. CCatalogCache::AdjustWintrustDataToCachedState (
  97. WINTRUST_DATA* pWintrustData,
  98. PCATALOG_CACHED_STATE pCachedState,
  99. BOOL fUndoAdjustment
  100. )
  101. {
  102. PCRYPT_PROVIDER_DATA pProvData;
  103. if ( fUndoAdjustment == FALSE )
  104. {
  105. pWintrustData->dwStateAction = WTD_STATEACTION_VERIFY;
  106. if ( pCachedState != NULL )
  107. {
  108. pWintrustData->hWVTStateData = pCachedState->hStateData;
  109. pProvData = WTHelperProvDataFromStateData( pCachedState->hStateData );
  110. pProvData->pWintrustData = pWintrustData;
  111. }
  112. else
  113. {
  114. pWintrustData->hWVTStateData = NULL;
  115. }
  116. }
  117. else
  118. {
  119. if ( pCachedState != NULL )
  120. {
  121. pProvData = WTHelperProvDataFromStateData( pCachedState->hStateData );
  122. pProvData->pWintrustData = NULL;
  123. }
  124. pWintrustData->dwStateAction = WTD_STATEACTION_AUTO_CACHE;
  125. pWintrustData->hWVTStateData = NULL;
  126. }
  127. }
  128. //+---------------------------------------------------------------------------
  129. //
  130. // Member: CCatalogCache::CreateCachedStateFromWintrustData, public
  131. //
  132. // Synopsis: create cached state
  133. //
  134. //----------------------------------------------------------------------------
  135. BOOL
  136. CCatalogCache::CreateCachedStateFromWintrustData (
  137. WINTRUST_DATA* pWintrustData,
  138. PCATALOG_CACHED_STATE* ppCachedState
  139. )
  140. {
  141. BOOL fResult;
  142. PCATALOG_CACHED_STATE pCachedState;
  143. CRYPT_DATA_BLOB Identifier;
  144. PCRYPT_PROVIDER_DATA pProvData;
  145. if ( pWintrustData->hWVTStateData == NULL )
  146. {
  147. return( FALSE );
  148. }
  149. pProvData = WTHelperProvDataFromStateData( pWintrustData->hWVTStateData );
  150. if ( ( pProvData->padwTrustStepErrors[ TRUSTERROR_STEP_FINAL_INITPROV ] != ERROR_SUCCESS ) ||
  151. ( ( pProvData->padwTrustStepErrors[ TRUSTERROR_STEP_FINAL_OBJPROV ] != ERROR_SUCCESS ) &&
  152. ( pProvData->padwTrustStepErrors[ TRUSTERROR_STEP_FINAL_OBJPROV ] != TRUST_E_BAD_DIGEST ) ) ||
  153. ( pProvData->padwTrustStepErrors[ TRUSTERROR_STEP_FINAL_SIGPROV ] != ERROR_SUCCESS ) ||
  154. ( pProvData->hMsg == NULL ) )
  155. {
  156. return( FALSE );
  157. }
  158. assert( pProvData->hMsg != NULL );
  159. pCachedState = new CATALOG_CACHED_STATE;
  160. if ( pCachedState != NULL )
  161. {
  162. pCachedState->hStateData = pWintrustData->hWVTStateData;
  163. pCachedState->hEntry = NULL;
  164. Identifier.cbData = wcslen(
  165. pWintrustData->pCatalog->pcwszCatalogFilePath
  166. );
  167. Identifier.cbData *= sizeof( WCHAR );
  168. Identifier.pbData = (LPBYTE)pWintrustData->pCatalog->pcwszCatalogFilePath;
  169. fResult = I_CryptCreateLruEntry(
  170. m_hCache,
  171. &Identifier,
  172. pCachedState,
  173. &pCachedState->hEntry
  174. );
  175. }
  176. else
  177. {
  178. SetLastError( E_OUTOFMEMORY );
  179. fResult = FALSE;
  180. }
  181. if ( fResult == TRUE )
  182. {
  183. *ppCachedState = pCachedState;
  184. }
  185. else
  186. {
  187. delete pCachedState;
  188. }
  189. return( fResult );
  190. }
  191. //+---------------------------------------------------------------------------
  192. //
  193. // Member: CCatalogCache::ReleaseCachedState, public
  194. //
  195. // Synopsis: release the cached state
  196. //
  197. //----------------------------------------------------------------------------
  198. VOID
  199. CCatalogCache::ReleaseCachedState (PCATALOG_CACHED_STATE pCachedState)
  200. {
  201. if ( pCachedState == NULL )
  202. {
  203. return;
  204. }
  205. I_CryptReleaseLruEntry( pCachedState->hEntry );
  206. }
  207. //+---------------------------------------------------------------------------
  208. //
  209. // Member: CCatalogCache::AddCachedState, public
  210. //
  211. // Synopsis: add cached state
  212. //
  213. //----------------------------------------------------------------------------
  214. VOID
  215. CCatalogCache::AddCachedState (PCATALOG_CACHED_STATE pCachedState)
  216. {
  217. I_CryptInsertLruEntry( pCachedState->hEntry, NULL );
  218. }
  219. //+---------------------------------------------------------------------------
  220. //
  221. // Member: CCatalogCache::RemoveCachedState, public
  222. //
  223. // Synopsis: remove cached state
  224. //
  225. //----------------------------------------------------------------------------
  226. VOID
  227. CCatalogCache::RemoveCachedState (PCATALOG_CACHED_STATE pCachedState)
  228. {
  229. I_CryptRemoveLruEntry( pCachedState->hEntry, 0, NULL );
  230. }
  231. //+---------------------------------------------------------------------------
  232. //
  233. // Member: CCatalogCache::RemoveCachedState, public
  234. //
  235. // Synopsis: remove cached state
  236. //
  237. //----------------------------------------------------------------------------
  238. VOID
  239. CCatalogCache::RemoveCachedState (WINTRUST_DATA* pWintrustData)
  240. {
  241. PCATALOG_CACHED_STATE pCachedState;
  242. pCachedState = FindCachedState( pWintrustData );
  243. if ( pCachedState != NULL )
  244. {
  245. RemoveCachedState( pCachedState );
  246. ReleaseCachedState( pCachedState );
  247. }
  248. }
  249. //+---------------------------------------------------------------------------
  250. //
  251. // Member: CCatalogCache::FindCachedState, public
  252. //
  253. // Synopsis: find cached state, the state is addref'd via the entry
  254. //
  255. //----------------------------------------------------------------------------
  256. PCATALOG_CACHED_STATE
  257. CCatalogCache::FindCachedState (WINTRUST_DATA* pWintrustData)
  258. {
  259. PCATALOG_CACHED_STATE pCachedState;
  260. CRYPT_DATA_BLOB Identifier;
  261. HLRUENTRY hEntry;
  262. Identifier.cbData = wcslen(
  263. pWintrustData->pCatalog->pcwszCatalogFilePath
  264. );
  265. Identifier.cbData *= sizeof( WCHAR );
  266. Identifier.pbData = (LPBYTE)pWintrustData->pCatalog->pcwszCatalogFilePath;
  267. pCachedState = (PCATALOG_CACHED_STATE)I_CryptFindLruEntryData(
  268. m_hCache,
  269. &Identifier,
  270. &hEntry
  271. );
  272. return( pCachedState );
  273. }
  274. //+---------------------------------------------------------------------------
  275. //
  276. // Member: CCatalogCache::FlushCache, public
  277. //
  278. // Synopsis: flush the cache
  279. //
  280. //----------------------------------------------------------------------------
  281. VOID
  282. CCatalogCache::FlushCache ()
  283. {
  284. I_CryptFlushLruCache( m_hCache, 0, NULL );
  285. }
  286. //+---------------------------------------------------------------------------
  287. //
  288. // Function: CatalogCacheFreeEntryData
  289. //
  290. // Synopsis: free entry data
  291. //
  292. //----------------------------------------------------------------------------
  293. VOID WINAPI
  294. CatalogCacheFreeEntryData (LPVOID pvData)
  295. {
  296. PCATALOG_CACHED_STATE pCachedState = (PCATALOG_CACHED_STATE)pvData;
  297. WINTRUST_DATA WintrustData;
  298. GUID ActionGuid;
  299. memset( &ActionGuid, 0, sizeof( ActionGuid ) );
  300. memset( &WintrustData, 0, sizeof( WintrustData ) );
  301. WintrustData.cbStruct = sizeof( WintrustData );
  302. WintrustData.dwStateAction = WTD_STATEACTION_CLOSE;
  303. WintrustData.hWVTStateData = pCachedState->hStateData;
  304. WinVerifyTrust( NULL, &ActionGuid, &WintrustData );
  305. delete pCachedState;
  306. }
  307. //+---------------------------------------------------------------------------
  308. //
  309. // Function: CatalogCacheHashIdentifier
  310. //
  311. // Synopsis: hash the name
  312. //
  313. //----------------------------------------------------------------------------
  314. DWORD WINAPI
  315. CatalogCacheHashIdentifier (PCRYPT_DATA_BLOB pIdentifier)
  316. {
  317. DWORD dwHash = 0;
  318. DWORD cb = pIdentifier->cbData;
  319. LPBYTE pb = pIdentifier->pbData;
  320. while ( cb-- )
  321. {
  322. if ( dwHash & 0x80000000 )
  323. {
  324. dwHash = ( dwHash << 1 ) | 1;
  325. }
  326. else
  327. {
  328. dwHash = dwHash << 1;
  329. }
  330. dwHash += *pb++;
  331. }
  332. return( dwHash );
  333. }