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.

426 lines
9.0 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. secinit.cxx
  5. Abstract:
  6. Contains load function for security.dll on NT and secur32.dll on win95
  7. Also handles WinTrust.dll function loading.
  8. Author:
  9. Sophia Chung (sophiac) 6-Feb-1996
  10. Environment:
  11. User Mode - Win32
  12. Revision History:
  13. --*/
  14. #include <wininetp.h>
  15. //
  16. // InitializationLock - protects against multiple threads loading security.dll
  17. // (secur32.dll) and entry points
  18. //
  19. CCritSec InitializationSecLock;
  20. HCRYPTPROV GlobalFortezzaCryptProv;
  21. //
  22. // GlobalSecFuncTable - Pointer to Global Structure of Pointers that are used
  23. // for storing the entry points into the SCHANNEL.dll
  24. //
  25. PSecurityFunctionTable GlobalSecFuncTable = NULL;
  26. //
  27. // pWinVerifyTrust - Pointer to Entry Point in WINTRUST.DLL
  28. //
  29. WIN_VERIFY_TRUST_FN pWinVerifyTrust;
  30. WT_HELPER_PROV_DATA_FROM_STATE_DATA_FN pWTHelperProvDataFromStateData;
  31. //
  32. // hSecurity - NULL when security.dll/secur32.dll is not loaded
  33. //
  34. HINSTANCE hSecurity = NULL;
  35. //
  36. // hWinTrust - NULL when WinTrust DLL is not loaded.
  37. //
  38. HINSTANCE hWinTrust = NULL;
  39. HCERTSTORE g_hMyCertStore = NULL;
  40. BOOL g_bFortezzaInstalled = FALSE;
  41. BOOL g_bCheckedForFortezza = FALSE;
  42. CRYPT_INSTALL_DEFAULT_CONTEXT_FN g_CryptInstallDefaultContext = NULL;
  43. CRYPT_UNINSTALL_DEFAULT_CONTEXT_FN g_CryptUninstallDefaultContext = NULL;
  44. CERT_FIND_CHAIN_IN_STORE_FN g_CertFindChainInStore = NULL;
  45. CERT_FREE_CERTIFICATE_CHAIN_FN g_CertFreeCertificateChain = NULL;
  46. DWORD
  47. LoadWinTrust(
  48. VOID
  49. )
  50. /*++
  51. Routine Description:
  52. This function loads the WinTrust.DLL and binds a pointer to a function
  53. that is needed in the WinTrust DLL.
  54. Arguments:
  55. NONE.
  56. Return Value:
  57. WINDOWS Error Code.
  58. --*/
  59. {
  60. DWORD error = ERROR_SUCCESS;
  61. if (!LOCK_SECURITY())
  62. {
  63. return ERROR_NOT_ENOUGH_MEMORY;
  64. }
  65. if( hWinTrust == NULL )
  66. {
  67. LPSTR lpszDllFileName = WINTRUST_DLLNAME;
  68. pWinVerifyTrust = NULL;
  69. //
  70. // Load the DLL
  71. //
  72. hWinTrust = LoadLibrary(lpszDllFileName);
  73. if ( hWinTrust )
  74. {
  75. pWinVerifyTrust = (WIN_VERIFY_TRUST_FN)
  76. GetProcAddress(hWinTrust, WIN_VERIFY_TRUST_NAME);
  77. pWTHelperProvDataFromStateData = (WT_HELPER_PROV_DATA_FROM_STATE_DATA_FN)
  78. GetProcAddress(hWinTrust, WT_HELPER_PROV_DATA_FROM_STATE_DATA_NAME);
  79. }
  80. if ( !hWinTrust || !pWinVerifyTrust )
  81. {
  82. error = GetLastError();
  83. if ( error == ERROR_SUCCESS )
  84. {
  85. error = ERROR_WINHTTP_INTERNAL_ERROR;
  86. }
  87. }
  88. }
  89. INET_ASSERT(pWinVerifyTrust);
  90. if ( error != ERROR_SUCCESS )
  91. {
  92. if (hWinTrust)
  93. {
  94. FreeLibrary(hWinTrust);
  95. hWinTrust = NULL;
  96. }
  97. }
  98. UNLOCK_SECURITY();
  99. return error;
  100. }
  101. BOOL
  102. SecurityInitialize(
  103. VOID
  104. )
  105. /*++
  106. Routine Description:
  107. This function initializes the global lock required for the security
  108. pkgs.
  109. Arguments:
  110. NONE.
  111. Return Value:
  112. WINDOWS Error Code.
  113. --*/
  114. {
  115. return InitializationSecLock.Init();
  116. }
  117. VOID
  118. SecurityTerminate(
  119. VOID
  120. )
  121. /*++
  122. Routine Description:
  123. This function Deletes the global lock required for the security
  124. pkgs.
  125. Arguments:
  126. NONE.
  127. Return Value:
  128. WINDOWS Error Code.
  129. --*/
  130. {
  131. InitializationSecLock.FreeLock();
  132. }
  133. VOID
  134. UnloadSecurity(
  135. VOID
  136. )
  137. /*++
  138. Routine Description:
  139. This function terminates the global data required for the security
  140. pkgs and dynamically unloads security APIs from security.dll (NT)
  141. or secur32.dll (WIN95).
  142. Arguments:
  143. NONE.
  144. Return Value:
  145. WINDOWS Error Code.
  146. --*/
  147. {
  148. DWORD i;
  149. if (!LOCK_SECURITY())
  150. {
  151. INET_ASSERT(FALSE);
  152. return;
  153. }
  154. //
  155. // free all security pkg credential handles
  156. //
  157. for (i = 0; SecProviders[i].pszName != NULL; i++) {
  158. if (SecProviders[i].fEnabled) {
  159. if (SecProviders[i].pCertCtxt == NULL && !IsCredClear(SecProviders[i].hCreds)) {
  160. // Beta1 Hack. Because of some circular dependency between dlls
  161. // both crypt32 and schannel's PROCESS_DETACH gets called before wininet.
  162. // This is catastrophic if we have a cert context attached to the credentials
  163. // handle. In this case we will just leak the handle since the process is dying
  164. // anyway. We really need to fix this.
  165. WRAP_REVERT_USER_VOID(g_FreeCredentialsHandle,
  166. (&SecProviders[i].hCreds));
  167. }
  168. }
  169. #if 0 // See comments above.
  170. if (SecProviders[i].pCertCtxt != NULL) {
  171. CertFreeCertificateContext(SecProviders[i].pCertCtxt);
  172. SecProviders[i].pCertCtxt = NULL;
  173. }
  174. #endif
  175. }
  176. //
  177. // close cert store. Protect against fault if DLL already unloaded
  178. //
  179. if (g_hMyCertStore != NULL)
  180. {
  181. SAFE_WRAP_REVERT_USER_VOID(CertCloseStore,
  182. (g_hMyCertStore, CERT_CLOSE_STORE_FORCE_FLAG));
  183. g_hMyCertStore = NULL;
  184. }
  185. // IMPORTANT : Don't free GlobalFortezzaCryptProv. When we free the cert context
  186. // from the SecProviders[] array above it gets freed automatically.
  187. if (GlobalFortezzaCryptProv != NULL)
  188. {
  189. GlobalFortezzaCryptProv = NULL;
  190. }
  191. //
  192. // unload dll
  193. //
  194. if (hSecurity != NULL) {
  195. FreeLibrary(hSecurity);
  196. hSecurity = NULL;
  197. }
  198. UNLOCK_SECURITY();
  199. }
  200. DWORD
  201. LoadSecurity(
  202. VOID
  203. )
  204. /*++
  205. Routine Description:
  206. This function dynamically loads security APIs from security.dll (NT)
  207. or secur32.dll (WIN95).
  208. Arguments:
  209. NONE.
  210. Return Value:
  211. WINDOWS Error Code.
  212. --*/
  213. {
  214. DWORD Error = ERROR_SUCCESS;
  215. INITSECURITYINTERFACE pfInitSecurityInterface = NULL;
  216. if (!LOCK_SECURITY())
  217. return ERROR_NOT_ENOUGH_MEMORY;
  218. if (g_hMyCertStore == NULL)
  219. {
  220. //
  221. // CRYPT32.DLL is delayloaded. Need SEH in case it fails.
  222. //
  223. // Don't worry about an error, because not supporting
  224. // client auth shouldn't stop us from scenarios
  225. // which do not require it as part of the SSL handshake.
  226. //
  227. SAFE_WRAP_REVERT_USER(CertOpenSystemStore, (0, "MY"), g_hMyCertStore);
  228. }
  229. if (Error == ERROR_SUCCESS)
  230. {
  231. Error = LoadWinTrust();
  232. }
  233. if ( Error != ERROR_SUCCESS )
  234. {
  235. goto quit;
  236. }
  237. if( hSecurity != NULL )
  238. {
  239. goto quit;
  240. }
  241. //
  242. // load dll.
  243. //
  244. //
  245. // This is better for performance. Rather than call through
  246. // SSPI, we go right to the DLL doing the work.
  247. //
  248. hSecurity = LoadLibrary( "schannel" );
  249. if ( hSecurity == NULL ) {
  250. Error = GetLastError();
  251. goto quit;
  252. }
  253. //
  254. // get function addresses.
  255. //
  256. #ifdef UNICODE
  257. pfInitSecurityInterface =
  258. (INITSECURITYINTERFACE) GetProcAddress( hSecurity,
  259. "InitSecurityInterfaceW" );
  260. #else
  261. pfInitSecurityInterface =
  262. (INITSECURITYINTERFACE) GetProcAddress( hSecurity,
  263. "InitSecurityInterfaceA" );
  264. #endif
  265. if ( pfInitSecurityInterface == NULL )
  266. {
  267. Error = GetLastError();
  268. goto quit;
  269. }
  270. GlobalSecFuncTable = (SecurityFunctionTable*) ((*pfInitSecurityInterface) ());
  271. if ( GlobalSecFuncTable == NULL ) {
  272. Error = GetLastError(); // BUGBUG does this work?
  273. goto quit;
  274. }
  275. HMODULE hCrypt32;
  276. hCrypt32 = GetModuleHandle("crypt32");
  277. INET_ASSERT(hCrypt32 != NULL);
  278. // We don't error out here because not finding these entry points
  279. // just affects Fortezza. The rest will still work fine.
  280. if (hCrypt32)
  281. {
  282. g_CryptInstallDefaultContext = (CRYPT_INSTALL_DEFAULT_CONTEXT_FN)
  283. GetProcAddress(hCrypt32, CRYPT_INSTALL_DEFAULT_CONTEXT_NAME);
  284. g_CryptUninstallDefaultContext = (CRYPT_UNINSTALL_DEFAULT_CONTEXT_FN)
  285. GetProcAddress(hCrypt32, CRYPT_UNINSTALL_DEFAULT_CONTEXT_NAME);
  286. g_CertFindChainInStore = (CERT_FIND_CHAIN_IN_STORE_FN)
  287. GetProcAddress(hCrypt32, CERT_FIND_CHAIN_IN_STORE_NAME);
  288. g_CertFreeCertificateChain = (CERT_FREE_CERTIFICATE_CHAIN_FN)
  289. GetProcAddress(hCrypt32, CERT_FREE_CERTIFICATE_CHAIN_NAME);
  290. }
  291. quit:
  292. if ( Error != ERROR_SUCCESS )
  293. {
  294. FreeLibrary( hSecurity );
  295. hSecurity = NULL;
  296. }
  297. UNLOCK_SECURITY();
  298. return( Error );
  299. }