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.

505 lines
14 KiB

  1. /*++
  2. Copyright (c) 1996, 1997 Microsoft Corporation
  3. Module Name:
  4. misc.cpp
  5. Abstract:
  6. Functionality in this module:
  7. Globals management
  8. Author:
  9. Pete Skelly (petesk) 23-Mar-00
  10. --*/
  11. #include <pch.cpp>
  12. #pragma hdrstop
  13. //
  14. // Registry Setable Globals, and handlign goo
  15. //
  16. // Must access key via api's
  17. static HKEY g_hProtectedStorageKey = NULL;
  18. static HANDLE g_hProtectedStorageChangeEvent = NULL;
  19. static RTL_CRITICAL_SECTION g_csGlobals;
  20. static BOOL g_fcsGlobalsInitialized = FALSE;
  21. // key management globals
  22. static DWORD g_IterationCount = DEFAULT_MASTERKEY_ITERATION_COUNT;
  23. static BOOL g_LegacyMode = FALSE;
  24. static BOOL g_LegacyModeNt4Domain = FALSE;
  25. static BOOL g_DistributeDomainBackupKey = FALSE;
  26. static DWORD g_dwMasterKeyDefaultPolicy = 0;
  27. // define softcoded constants we use
  28. static DWORD g_dwDefaultCryptProvType = PROV_RSA_FULL;
  29. static DWORD g_dwAlgID_Encr_Alg = CALG_3DES;
  30. static DWORD g_dwAlgID_Encr_Alg_KeySize = -1; // any size
  31. static DWORD g_dwAlgID_MAC_Alg = CALG_SHA1;
  32. static DWORD g_dwAlgID_MAC_Alg_KeySize = -1; // any size
  33. typedef struct _ALG_TO_STRING
  34. {
  35. DWORD AlgId;
  36. LPCWSTR wszString;
  37. } ALG_TO_STRING;
  38. ALG_TO_STRING g_AlgToString[] =
  39. {
  40. { CALG_MD2, L"MD2-%d " },
  41. { CALG_MD4, L"MD4-%d " },
  42. { CALG_MD5, L"MD5-%d " },
  43. { CALG_SHA1, L"SHA1-%d " },
  44. { CALG_DES, L"DES-%d " },
  45. { CALG_3DES_112, L"3DES-%d " },
  46. { CALG_3DES, L"3DES-%d " },
  47. { CALG_DESX, L"DESX-%d " },
  48. { CALG_RC2, L"RC2-%d " },
  49. { CALG_RC4, L"RC4-%d " },
  50. { CALG_SEAL, L"SEAL-%d " },
  51. { CALG_RSA_SIGN, L"RSA Signature-%d " },
  52. { CALG_RSA_KEYX, L"RSA Exchange-%d " },
  53. { CALG_DSS_SIGN, L"DSS-%d " },
  54. { CALG_DH_SF, L"DH-%d " },
  55. { CALG_DH_EPHEM, L"DH Ephemeral-%d " },
  56. { CALG_KEA_KEYX, L"KEA Exchange-%d " },
  57. { CALG_SKIPJACK, L"SKIPJACK-%d " },
  58. { CALG_TEK, L"TEK-%d " },
  59. { CALG_RC5, L"RC5-%d " },
  60. { CALG_HMAC, L"HMAC-%d " }
  61. };
  62. DWORD g_cAlgToString = sizeof(g_AlgToString)/sizeof(g_AlgToString[0]);
  63. // supply a new, delete operator
  64. void * __cdecl operator new(size_t cb)
  65. {
  66. return SSAlloc( cb );
  67. }
  68. void __cdecl operator delete(void * pv)
  69. {
  70. SSFree( pv );
  71. }
  72. DWORD AlgIDToString(LPWSTR wszString, DWORD dwAlgID, DWORD dwStrength)
  73. {
  74. DWORD i;
  75. for(i=0; i < g_cAlgToString; i++)
  76. {
  77. if(dwAlgID == g_AlgToString[i].AlgId)
  78. {
  79. return wsprintf(wszString, g_AlgToString[i].wszString, dwStrength);
  80. }
  81. }
  82. return wsprintf(wszString, L"Unknown 0x%lx - %d", dwAlgID, dwStrength);
  83. }
  84. DWORD UpdateGlobals(BOOL fForce)
  85. {
  86. DWORD lRet = ERROR_SUCCESS;
  87. DWORD dwDisposition;
  88. if(NULL == g_fcsGlobalsInitialized ||
  89. NULL == g_hProtectedStorageKey ||
  90. NULL == g_hProtectedStorageChangeEvent)
  91. {
  92. return ERROR_SUCCESS;
  93. }
  94. if(WAIT_OBJECT_0 == WaitForSingleObject(g_hProtectedStorageChangeEvent, 0))
  95. {
  96. // Update the globals, as they have changed
  97. DWORD dwParameterValue;
  98. DWORD cbParameter = sizeof(dwParameterValue);
  99. DWORD dwValueType;
  100. RtlEnterCriticalSection(&g_csGlobals);
  101. lRet = RegQueryValueExU(
  102. g_hProtectedStorageKey,
  103. REGVAL_MK_DEFAULT_ITERATION_COUNT,
  104. NULL,
  105. &dwValueType,
  106. (LPBYTE)&dwParameterValue,
  107. &cbParameter
  108. );
  109. if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD )
  110. {
  111. //
  112. // Only allow policy to increase the iteration
  113. // count, never decrease it.
  114. //
  115. if( dwParameterValue > g_IterationCount)
  116. {
  117. g_IterationCount = dwParameterValue;
  118. }
  119. }
  120. lRet = RegQueryValueExU(
  121. g_hProtectedStorageKey,
  122. REGVAL_MK_LEGACY_COMPLIANCE,
  123. NULL,
  124. &dwValueType,
  125. (LPBYTE)&dwParameterValue,
  126. &cbParameter
  127. );
  128. if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD )
  129. {
  130. if( dwParameterValue != 0)
  131. {
  132. g_LegacyMode = TRUE;
  133. }
  134. }
  135. lRet = RegQueryValueExU(
  136. g_hProtectedStorageKey,
  137. REGVAL_MK_LEGACY_NT4_DOMAIN,
  138. NULL,
  139. &dwValueType,
  140. (LPBYTE)&dwParameterValue,
  141. &cbParameter
  142. );
  143. if((lRet == ERROR_SUCCESS) &&
  144. (dwValueType == REG_DWORD) &&
  145. (dwParameterValue != 0))
  146. {
  147. g_LegacyModeNt4Domain = TRUE;
  148. }
  149. else
  150. {
  151. g_LegacyModeNt4Domain = FALSE;
  152. }
  153. lRet = RegQueryValueExU(
  154. g_hProtectedStorageKey,
  155. REGVAL_DISTRIBUTE_BACKUP_KEY,
  156. NULL,
  157. &dwValueType,
  158. (LPBYTE)&dwParameterValue,
  159. &cbParameter
  160. );
  161. if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD )
  162. {
  163. // User specified registry value, so do what it says.
  164. g_DistributeDomainBackupKey = (dwParameterValue != 0);
  165. D_DebugLog((DEB_TRACE, "Registry: distribute whistler domain backup key: %s\n",
  166. g_DistributeDomainBackupKey ? "TRUE" : "FALSE"));
  167. }
  168. else
  169. {
  170. // Registry entry does not exist, so check to see if
  171. // the domain is in "Whistler native mode" and if so
  172. // then distribute the whistler domain backup key.
  173. g_DistributeDomainBackupKey = LsaINoMoreWin2KDomain();
  174. D_DebugLog((DEB_TRACE, "Policy: distribute whistler domain backup key: %s\n",
  175. g_DistributeDomainBackupKey ? "TRUE" : "FALSE"));
  176. }
  177. lRet = RegQueryValueExU(
  178. g_hProtectedStorageKey,
  179. REGVAL_POLICY_MK,
  180. NULL,
  181. &dwValueType,
  182. (LPBYTE)&dwParameterValue,
  183. &cbParameter
  184. );
  185. if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD )
  186. {
  187. if( dwParameterValue == 1 )
  188. {
  189. g_dwMasterKeyDefaultPolicy = POLICY_LOCAL_BACKUP;
  190. }
  191. }
  192. cbParameter = sizeof(DWORD);
  193. lRet = RegQueryValueExU(
  194. g_hProtectedStorageKey,
  195. CRYPTPROTECT_DEFAULT_PROVIDER_ENCR_ALG,
  196. NULL,
  197. &dwValueType,
  198. (PBYTE)&dwParameterValue,
  199. &cbParameter
  200. );
  201. if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD ) {
  202. // if successful, commit
  203. g_dwAlgID_Encr_Alg = dwParameterValue;
  204. }
  205. cbParameter = sizeof(DWORD);
  206. lRet = RegQueryValueExU(
  207. g_hProtectedStorageKey,
  208. CRYPTPROTECT_DEFAULT_PROVIDER_ENCR_ALG_KEYSIZE,
  209. NULL,
  210. &dwValueType,
  211. (PBYTE)&dwParameterValue,
  212. &cbParameter
  213. );
  214. if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD ) {
  215. // if successful, commit
  216. g_dwAlgID_Encr_Alg_KeySize = dwParameterValue;
  217. }
  218. cbParameter = sizeof(DWORD);
  219. lRet = RegQueryValueExU(
  220. g_hProtectedStorageKey,
  221. CRYPTPROTECT_DEFAULT_PROVIDER_MAC_ALG,
  222. NULL,
  223. &dwValueType,
  224. (PBYTE)&dwParameterValue,
  225. &cbParameter
  226. );
  227. if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD ) {
  228. // if successful, commit
  229. g_dwAlgID_MAC_Alg = dwParameterValue;
  230. }
  231. cbParameter = sizeof(DWORD);
  232. lRet = RegQueryValueExU(
  233. g_hProtectedStorageKey,
  234. CRYPTPROTECT_DEFAULT_PROVIDER_MAC_ALG_KEYSIZE,
  235. NULL,
  236. &dwValueType,
  237. (PBYTE)&dwParameterValue,
  238. &cbParameter
  239. );
  240. if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD ) {
  241. // if successful, commit
  242. g_dwAlgID_MAC_Alg_KeySize = dwParameterValue;
  243. }
  244. cbParameter = sizeof(DWORD);
  245. lRet = RegQueryValueExU(
  246. g_hProtectedStorageKey,
  247. CRYPTPROTECT_DEFAULT_PROVIDER_CRYPT_PROV_TYPE,
  248. NULL,
  249. &dwValueType,
  250. (PBYTE)&dwParameterValue,
  251. &cbParameter
  252. );
  253. if( lRet == ERROR_SUCCESS && dwValueType == REG_DWORD ) {
  254. // if successful, commit
  255. g_dwDefaultCryptProvType = dwParameterValue;
  256. }
  257. // Register to be notified of future registry changes.
  258. lRet = RegNotifyChangeKeyValue(g_hProtectedStorageKey,
  259. TRUE, // bWatchSubtree
  260. REG_NOTIFY_CHANGE_LAST_SET |
  261. REG_NOTIFY_CHANGE_NAME,
  262. g_hProtectedStorageChangeEvent,
  263. TRUE);
  264. if(ERROR_SUCCESS != lRet)
  265. {
  266. //
  267. // If notify failed, we no longer notify, so we don't need to handle anymore
  268. CloseHandle(g_hProtectedStorageChangeEvent);
  269. g_hProtectedStorageChangeEvent = NULL;
  270. }
  271. RtlLeaveCriticalSection(&g_csGlobals);
  272. }
  273. return lRet;
  274. }
  275. DWORD IntializeGlobals()
  276. {
  277. DWORD lRet = ERROR_SUCCESS;
  278. DWORD dwDisposition;
  279. static const WCHAR szProviderKeyName[] = REG_CRYPTPROTECT_LOC L"\\" REG_CRYPTPROTECT_PROVIDERS_SUBKEYLOC L"\\" CRYPTPROTECT_DEFAULT_PROVIDER_GUIDSZ ;
  280. lRet = RtlInitializeCriticalSection(&g_csGlobals);
  281. if(!NT_SUCCESS(lRet))
  282. {
  283. return lRet;
  284. }
  285. g_fcsGlobalsInitialized = TRUE;
  286. lRet = RegCreateKeyExU(
  287. HKEY_LOCAL_MACHINE,
  288. szProviderKeyName,
  289. 0,
  290. NULL,
  291. 0,
  292. KEY_QUERY_VALUE | KEY_NOTIFY,
  293. NULL,
  294. &g_hProtectedStorageKey,
  295. &dwDisposition
  296. );
  297. if(lRet != ERROR_SUCCESS)
  298. {
  299. goto error;
  300. }
  301. g_hProtectedStorageChangeEvent = CreateEvent(NULL,
  302. FALSE,
  303. TRUE,
  304. NULL);
  305. lRet = UpdateGlobals(TRUE);
  306. error:
  307. return lRet;
  308. }
  309. DWORD ShutdownGlobals()
  310. {
  311. DWORD lRet = ERROR_SUCCESS;
  312. DWORD dwDisposition;
  313. if(g_hProtectedStorageKey)
  314. {
  315. RegCloseKey(g_hProtectedStorageKey);
  316. g_hProtectedStorageKey = NULL;
  317. }
  318. if(g_hProtectedStorageChangeEvent)
  319. {
  320. CloseHandle(g_hProtectedStorageChangeEvent);
  321. g_hProtectedStorageChangeEvent = NULL;
  322. }
  323. if(g_fcsGlobalsInitialized)
  324. {
  325. RtlDeleteCriticalSection(&g_csGlobals);
  326. }
  327. return lRet;
  328. }
  329. DWORD GetIterationCount()
  330. {
  331. UpdateGlobals(FALSE);
  332. return g_IterationCount;
  333. }
  334. BOOL FIsLegacyCompliant()
  335. {
  336. UpdateGlobals(FALSE);
  337. return g_LegacyMode;
  338. }
  339. BOOL FIsLegacyNt4Domain()
  340. {
  341. UpdateGlobals(FALSE);
  342. return g_LegacyModeNt4Domain;
  343. }
  344. BOOL FDistributeDomainBackupKey()
  345. {
  346. UpdateGlobals(FALSE);
  347. return g_DistributeDomainBackupKey;
  348. }
  349. DWORD GetMasterKeyDefaultPolicy()
  350. {
  351. UpdateGlobals(FALSE);
  352. return g_dwMasterKeyDefaultPolicy;
  353. }
  354. DWORD GetDefaultAlgInfo(DWORD *pdwProvType,
  355. DWORD *pdwEncryptionAlg,
  356. DWORD *pdwEncryptionAlgSize,
  357. DWORD *pdwMACAlg,
  358. DWORD *pdwMACAlgSize)
  359. {
  360. BOOL fCritSec = FALSE;
  361. UpdateGlobals(FALSE);
  362. if(g_fcsGlobalsInitialized)
  363. {
  364. RtlEnterCriticalSection(&g_csGlobals);
  365. fCritSec = TRUE;
  366. }
  367. if(pdwProvType)
  368. {
  369. *pdwProvType = g_dwDefaultCryptProvType;
  370. }
  371. if(pdwEncryptionAlg)
  372. {
  373. *pdwEncryptionAlg = g_dwAlgID_Encr_Alg;
  374. }
  375. if(pdwEncryptionAlgSize)
  376. {
  377. *pdwEncryptionAlgSize = g_dwAlgID_Encr_Alg_KeySize;
  378. }
  379. if(pdwMACAlg)
  380. {
  381. *pdwMACAlg = g_dwAlgID_MAC_Alg;
  382. }
  383. if(pdwMACAlgSize)
  384. {
  385. *pdwMACAlgSize = g_dwAlgID_MAC_Alg_KeySize;
  386. }
  387. if(fCritSec)
  388. {
  389. RtlLeaveCriticalSection(&g_csGlobals);
  390. }
  391. return ERROR_SUCCESS;
  392. }
  393. void
  394. InitLsaString(
  395. PLSA_UNICODE_STRING LsaString,
  396. LPWSTR String
  397. )
  398. {
  399. DWORD StringLength;
  400. if(String == NULL) {
  401. LsaString->Buffer = NULL;
  402. LsaString->Length = 0;
  403. LsaString->MaximumLength = 0;
  404. return;
  405. }
  406. StringLength = lstrlenW(String);
  407. LsaString->Buffer = String;
  408. LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
  409. LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR);
  410. }