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.

374 lines
8.5 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: userctxt.c
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 10-10-96 RichardW Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "sslp.h"
  18. #define SCHANNEL_USERLIST_COUNT (16) // count of lists
  19. #define SCHANNEL_USERLIST_LOCK_COUNT (2) // count of locks
  20. RTL_RESOURCE SslContextLock[ SCHANNEL_USERLIST_LOCK_COUNT ];
  21. LIST_ENTRY SslContextList[ SCHANNEL_USERLIST_COUNT ] ;
  22. ULONG
  23. HandleToListIndex(
  24. ULONG_PTR ContextHandle
  25. );
  26. ULONG
  27. __inline
  28. ListIndexToLockIndex(
  29. ULONG ListIndex
  30. );
  31. //+---------------------------------------------------------------------------
  32. //
  33. // Function: SslInitContextManager
  34. //
  35. // Synopsis: Initializes the context manager controls
  36. //
  37. // History: 10-10-96 RichardW Created
  38. //
  39. // Notes:
  40. //
  41. //----------------------------------------------------------------------------
  42. BOOL
  43. SslInitContextManager(
  44. VOID
  45. )
  46. {
  47. ULONG Index;
  48. NTSTATUS Status = STATUS_SUCCESS;
  49. for( Index=0 ; Index < SCHANNEL_USERLIST_LOCK_COUNT ; Index++ )
  50. {
  51. __try {
  52. RtlInitializeResource (&SslContextLock[Index]);
  53. } __except(EXCEPTION_EXECUTE_HANDLER)
  54. {
  55. Status = STATUS_INSUFFICIENT_RESOURCES;
  56. break;
  57. }
  58. }
  59. if( !NT_SUCCESS(Status) )
  60. {
  61. DebugLog(( DEB_ERROR, "SslInitContextManager failed!\n" ));
  62. return FALSE;
  63. }
  64. for( Index = 0 ; Index < SCHANNEL_USERLIST_COUNT ; Index++ )
  65. {
  66. InitializeListHead( &SslContextList[Index] );
  67. }
  68. return( TRUE );
  69. }
  70. #if 0
  71. VOID
  72. SslFreeUserContextElements(PSPContext pContext)
  73. {
  74. if(pContext->hReadKey)
  75. {
  76. if(!CryptDestroyKey(pContext->hReadKey))
  77. {
  78. SP_LOG_RESULT(GetLastError());
  79. }
  80. }
  81. pContext->hReadKey = 0;
  82. if(pContext->hReadMAC)
  83. {
  84. if(!CryptDestroyKey(pContext->hReadMAC))
  85. {
  86. SP_LOG_RESULT(GetLastError());
  87. }
  88. }
  89. pContext->hReadMAC = 0;
  90. if(pContext->hWriteKey)
  91. {
  92. if(!CryptDestroyKey(pContext->hWriteKey))
  93. {
  94. SP_LOG_RESULT(GetLastError());
  95. }
  96. }
  97. pContext->hWriteKey = 0;
  98. if(pContext->hWriteMAC)
  99. {
  100. if(!CryptDestroyKey(pContext->hWriteMAC))
  101. {
  102. SP_LOG_RESULT(GetLastError());
  103. }
  104. }
  105. pContext->hWriteMAC = 0;
  106. }
  107. #endif
  108. SECURITY_STATUS
  109. SslAddUserContext(
  110. IN LSA_SEC_HANDLE LsaHandle,
  111. IN HANDLE Token, // optional
  112. IN PSecBuffer ContextData,
  113. IN BOOL fImportedContext)
  114. {
  115. PSSL_USER_CONTEXT Context ;
  116. SP_STATUS Status ;
  117. ULONG ListIndex;
  118. ULONG LockIndex;
  119. DebugLog(( DEB_TRACE, "SslAddUserContext: 0x%p\n", LsaHandle ));
  120. if ( ContextData->cbBuffer < sizeof( SPPackedContext ) )
  121. {
  122. return( SEC_E_INVALID_TOKEN );
  123. }
  124. if(!fImportedContext)
  125. {
  126. Context = SslFindUserContext( LsaHandle );
  127. if ( Context )
  128. {
  129. DebugLog(( DEB_TRACE, "Replacing existing context!\n" ));
  130. // Destroy elements of existing context.
  131. LsaContextDelete(Context->pContext);
  132. SPExternalFree(Context->pContext);
  133. Context->pContext = NULL;
  134. Status = SPContextDeserialize( ContextData->pvBuffer,
  135. &Context->pContext);
  136. if(Status != PCT_ERR_OK)
  137. {
  138. return SP_LOG_RESULT(SEC_E_DECRYPT_FAILURE);
  139. }
  140. return( SEC_E_OK );
  141. }
  142. }
  143. Context = LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT,
  144. sizeof( SSL_USER_CONTEXT ));
  145. if ( !Context )
  146. {
  147. return( SEC_E_INSUFFICIENT_MEMORY );
  148. }
  149. Status = SPContextDeserialize( ContextData->pvBuffer,
  150. &Context->pContext);
  151. if(Status != PCT_ERR_OK)
  152. {
  153. LocalFree(Context);
  154. return SP_LOG_RESULT(SEC_E_DECRYPT_FAILURE);
  155. }
  156. if(ARGUMENT_PRESENT(Token))
  157. {
  158. Context->pContext->RipeZombie->hLocator = (HLOCATOR)Token;
  159. }
  160. Context->LsaHandle = LsaHandle ;
  161. Context->Align = ContextData->cbBuffer ;
  162. ListIndex = HandleToListIndex( LsaHandle );
  163. LockIndex = ListIndexToLockIndex( ListIndex );
  164. RtlAcquireResourceExclusive( &SslContextLock[LockIndex], TRUE );
  165. InsertTailList( &SslContextList[ListIndex], &Context->List );
  166. RtlReleaseResource( &SslContextLock[LockIndex] );
  167. return( SEC_E_OK );
  168. }
  169. PSSL_USER_CONTEXT
  170. SslReferenceUserContext(
  171. IN LSA_SEC_HANDLE LsaHandle,
  172. IN BOOLEAN Delete
  173. )
  174. {
  175. PLIST_ENTRY List ;
  176. PSSL_USER_CONTEXT Context = NULL ;
  177. ULONG ListIndex;
  178. ULONG LockIndex;
  179. ListIndex = HandleToListIndex( LsaHandle );
  180. LockIndex = ListIndexToLockIndex( ListIndex );
  181. if( !Delete )
  182. {
  183. RtlAcquireResourceShared( &SslContextLock[LockIndex], TRUE );
  184. } else {
  185. RtlAcquireResourceExclusive( &SslContextLock[LockIndex], TRUE );
  186. }
  187. List = SslContextList[ListIndex].Flink ;
  188. while ( List != &SslContextList[ListIndex] )
  189. {
  190. Context = CONTAINING_RECORD( List, SSL_USER_CONTEXT, List.Flink );
  191. if ( Context->LsaHandle == LsaHandle )
  192. {
  193. if( Delete )
  194. {
  195. RemoveEntryList( &Context->List );
  196. }
  197. break;
  198. }
  199. Context = NULL ;
  200. List = List->Flink ;
  201. }
  202. RtlReleaseResource( &SslContextLock[LockIndex] );
  203. return( Context );
  204. }
  205. PSSL_USER_CONTEXT
  206. SslFindUserContext(
  207. IN LSA_SEC_HANDLE LsaHandle
  208. )
  209. {
  210. return SslReferenceUserContext( LsaHandle, FALSE );
  211. }
  212. PSSL_USER_CONTEXT
  213. SslFindUserContextEx(
  214. IN PCRED_THUMBPRINT pThumbprint
  215. )
  216. {
  217. PLIST_ENTRY List ;
  218. PSSL_USER_CONTEXT Context = NULL ;
  219. ULONG ListIndex;
  220. ULONG LockIndex;
  221. DebugLog(( DEB_TRACE, "SslFindUserContextEx: \n"));
  222. for (ListIndex = 0 ; ListIndex < SCHANNEL_USERLIST_COUNT ; ListIndex++)
  223. {
  224. LockIndex = ListIndexToLockIndex( ListIndex );
  225. RtlAcquireResourceShared( &SslContextLock[LockIndex], TRUE );
  226. List = SslContextList[ListIndex].Flink ;
  227. while ( List != &SslContextList[ListIndex] )
  228. {
  229. Context = CONTAINING_RECORD( List, SSL_USER_CONTEXT, List.Flink );
  230. if(Context->pContext != NULL &&
  231. IsSameThumbprint(pThumbprint, &Context->pContext->ContextThumbprint))
  232. {
  233. RtlReleaseResource( &SslContextLock[LockIndex] );
  234. goto done;
  235. }
  236. List = List->Flink ;
  237. }
  238. RtlReleaseResource( &SslContextLock[LockIndex] );
  239. }
  240. Context = NULL ;
  241. done:
  242. return( Context );
  243. }
  244. VOID
  245. SslDeleteUserContext(
  246. IN LSA_SEC_HANDLE LsaHandle
  247. )
  248. {
  249. PSSL_USER_CONTEXT Context ;
  250. Context = SslReferenceUserContext( LsaHandle, TRUE );
  251. if ( Context )
  252. {
  253. DebugLog(( DEB_TRACE, "Deleting user mode context %x, handle = %x\n",
  254. Context, LsaHandle ));
  255. LsaContextDelete(Context->pContext);
  256. SPExternalFree(Context->pContext);
  257. LocalFree( Context );
  258. }
  259. else
  260. {
  261. DebugLog(( DEB_TRACE, "No context found for handle %x\n", LsaHandle ));
  262. }
  263. }
  264. ULONG
  265. HandleToListIndex(
  266. ULONG_PTR ContextHandle
  267. )
  268. {
  269. ULONG Number ;
  270. ULONG Hash;
  271. ULONG HashFinal;
  272. ASSERT( (SCHANNEL_USERLIST_COUNT != 0) );
  273. ASSERT( (SCHANNEL_USERLIST_COUNT & 1) == 0 );
  274. Number = (ULONG)ContextHandle;
  275. Hash = Number;
  276. Hash += Number >> 8;
  277. Hash += Number >> 16;
  278. Hash += Number >> 24;
  279. HashFinal = Hash;
  280. HashFinal += Hash >> 4;
  281. //
  282. // insure power of two if not one.
  283. //
  284. return ( HashFinal & (SCHANNEL_USERLIST_COUNT-1) ) ;
  285. }
  286. ULONG
  287. __inline
  288. ListIndexToLockIndex(
  289. ULONG ListIndex
  290. )
  291. {
  292. ASSERT( (SCHANNEL_USERLIST_LOCK_COUNT) != 0 );
  293. ASSERT( (SCHANNEL_USERLIST_LOCK_COUNT & 1) == 0 );
  294. //
  295. // insure power of two if not one.
  296. //
  297. return ( ListIndex & (SCHANNEL_USERLIST_LOCK_COUNT-1) );
  298. }