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.

1801 lines
66 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997-2002.
  5. //
  6. // File: CertMgr.cpp
  7. //
  8. // Contents: Implementation of DLL Exports
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include <initguid.h>
  13. #include <gpedit.h>
  14. #include "CertMgr_i.c"
  15. #include "about.h" // CCertMgrAbout
  16. #include "compdata.h" // CCertMgrSnapin, CCertMgrExtension
  17. #pragma warning(push, 3)
  18. #include <compuuid.h> // UUIDs for Computer Management
  19. #include "uuids.h"
  20. #include <efsstruc.h>
  21. #include <sceattch.h> // For Security Configuratino Editor snapin
  22. #include <ntverp.h> // VER_PRODUCTVERSION_STR, VERS_COMPANYNAME_STR
  23. #include <typeinfo.h>
  24. #pragma warning(pop)
  25. #include <dsadminp.h>
  26. #include <ntdsapi.h>
  27. #ifdef _DEBUG
  28. #ifndef ALPHA
  29. #define new DEBUG_NEW
  30. #endif
  31. #undef THIS_FILE
  32. static char THIS_FILE[] = __FILE__;
  33. #endif
  34. bool g_bSchemaIsW2K = false;
  35. USE_HANDLE_MACROS ("CERTMGR (CertMgr.cpp)")
  36. LPCWSTR CM_HELP_TOPIC = L"sag_CMtopNode.htm";
  37. LPCWSTR CM_HELP_FILE = L"certmgr.chm";
  38. LPCWSTR CM_LINKED_HELP_FILE = L"CMconcepts.chm";
  39. LPCWSTR PKP_LINKED_HELP_FILE = L"SecSetConcepts.chm";
  40. LPCWSTR PKP_HELP_FILE = L"secsettings.chm";
  41. LPCWSTR PKP_HELP_TOPIC = L"sag_secsettopnode.htm";
  42. LPCWSTR SAFER_WINDOWS_HELP_FILE = L"SAFER.chm";
  43. LPCWSTR SAFER_WINDOWS_LINKED_HELP_FILE = L"SAFERconcepts.chm";
  44. LPCWSTR SAFER_HELP_TOPIC = L"SAFER_topnode.htm";
  45. LPCWSTR CM_CONTEXT_HELP = L"\\help\\certmgr.hlp";
  46. LPCWSTR WINDOWS_HELP = L"windows.hlp";
  47. LPCWSTR EFS_LINKED_HELP_FILE = L"encrypt.chm";
  48. LPCWSTR EFS_HELP_TOPIC = L"sag_SEProcsOndisk.htm";
  49. //
  50. // This is used by the nodetype utility routines in stdutils.cpp
  51. //
  52. const struct NODETYPE_GUID_ARRAYSTRUCT g_NodetypeGuids[CERTMGR_NUMTYPES] =
  53. {
  54. { // CERTMGR_SNAPIN
  55. structuuidNodetypeSnapin,
  56. lstruuidNodetypeSnapin },
  57. { // CERTMGR_CERTIFICATE
  58. structuuidNodetypeCertificate,
  59. lstruuidNodetypeCertificate },
  60. { // CERTMGR_LOG_STORE
  61. structuuidNodetypeLogStore,
  62. lstruuidNodetypeLogStore },
  63. { // CERTMGR_PHYS_STORE
  64. structuuidNodetypePhysStore,
  65. lstruuidNodetypePhysStore },
  66. { // CERTMGR_USAGE
  67. structuuidNodetypeUsage,
  68. lstruuidNodetypeUsage },
  69. { // CERTMGR_CRL_CONTAINER
  70. structuuidNodetypeCRLContainer,
  71. lstruuidNodetypeCRLContainer },
  72. { // CERTMGR_CTL_CONTAINER
  73. structuuidNodetypeCTLContainer,
  74. lstruuidNodetypeCTLContainer },
  75. { // CERTMGR_CERT_CONTAINER
  76. structuuidNodetypeCertContainer,
  77. lstruuidNodetypeCertContainer },
  78. { // CERTMGR_CRL
  79. structuuidNodetypeCRL,
  80. lstruuidNodetypeCRL },
  81. { // CERTMGR_CTL
  82. structuuidNodetypeCTL,
  83. lstruuidNodetypeCTL },
  84. { // CERTMGR_AUTO_CERT_REQUEST
  85. structuuidNodetypeAutoCertRequest,
  86. lstruuidNodetypeAutoCertRequest },
  87. { // CERTMGR_CERT_POLICIES_USER,
  88. structuuidNodetypeCertPoliciesUser,
  89. lstruiidNodetypeCertPoliciesUser },
  90. { // CERTMGR_CERT_POLICIES_COMPUTER,
  91. structuuidNodetypeCertPoliciesComputer,
  92. lstruiidNodetypeCertPoliciesComputer },
  93. { // CERTMGR_LOG_STORE_GPE
  94. structuuidNodetypeLogStore,
  95. lstruuidNodetypeLogStore },
  96. { // CERTMGR_LOG_STORE_RSOP
  97. structuuidNodetypeLogStore,
  98. lstruuidNodetypeLogStore },
  99. { // CERTMGR_PKP_AUTOENROLLMENT_COMPUTER_SETTINGS
  100. structuuidNodetypePKPAutoenrollmentSettings,
  101. lstruiidNodetypePKPAutoenrollmentSettings },
  102. { // CERTMGR_PKP_AUTOENROLLMENT_USER_SETTINGS
  103. 0,
  104. 0 },
  105. { // CERTMGR_SAFER_COMPUTER_ROOT
  106. structuuidNodetypeSaferComputerRoot,
  107. lstruiidNodetypeSaferComputerRoot },
  108. { // CERTMGR_SAFER_COMPUTER_LEVELS
  109. structuuidNodetypeSaferComputerLevels,
  110. lstruiidNodetypeSaferComputerLevels },
  111. { // CERTMGR_SAFER_COMPUTER_ENTRIES
  112. structuuidNodetypeSaferComputerEntries,
  113. lstruiidNodetypeSaferComputerEntries },
  114. { // CERTMGR_SAFER_USER_ROOT
  115. structuuidNodetypeSaferUserRoot,
  116. lstruiidNodetypeSaferUserRoot },
  117. { // CERTMGR_SAFER_USER_ENTRIES
  118. structuuidNodetypeSaferUserEntries,
  119. lstruiidNodetypeSaferUserEntries },
  120. { // CERTMGR_SAFER_USER_LEVELS
  121. structuuidNodetypeSaferUserLevels,
  122. lstruiidNodetypeSaferUserLevels },
  123. { // CERTMGR_SAFER_COMPUTER_LEVEL
  124. structuuidNodetypeSaferComputerLevel,
  125. lstruiidNodetypeSaferComputerLevel },
  126. { // CERTMGR_SAFER_USER_LEVEL
  127. structuuidNodetypeSaferUserLevel,
  128. lstruiidNodetypeSaferUserLevel },
  129. { // CERTMGR_SAFER_COMPUTER_ENTRY
  130. structuuidNodetypeSaferComputerEntry,
  131. lstruiidNodetypeSaferComputerEntry },
  132. { // CERTMGR_SAFER_USER_ENTRY
  133. structuuidNodetypeSaferUserEntry,
  134. lstruiidNodetypeSaferUserEntry },
  135. { // CERTMGR_SAFER_COMPUTER_TRUSTED_PUBLISHERS
  136. structuuidNodetypeSaferTrustedPublishers,
  137. lstruiidNodetypeSaferTrustedPublisher },
  138. { // CERTMGR_SAFER_USER_TRUSTED_PUBLISHERS
  139. 0,
  140. 0 },
  141. { // CERTMGR_SAFER_COMPUTER_DEFINED_FILE_TYPES
  142. structuuidNodetypeSaferDefinedFileTypes,
  143. lstruiidNodetypeSaferDefinedFileTypes },
  144. { // CERTMGR_SAFER_USER_DEFINED_FILE_TYPES
  145. 0,
  146. 0 },
  147. { // CERTMGR_SAFER_USER_ENFORCEMENT
  148. structuuidNodetypeSaferEnforcement,
  149. lstruiidNodetypeSaferEnforcement },
  150. { // CERTMGR_SAFER_COMPUTER_ENFORCEMENT
  151. 0,
  152. 0 }
  153. };
  154. const struct NODETYPE_GUID_ARRAYSTRUCT* g_aNodetypeGuids = g_NodetypeGuids;
  155. const int g_cNumNodetypeGuids = CERTMGR_NUMTYPES;
  156. HINSTANCE g_hInstance = 0;
  157. CString g_szFileName;
  158. CComModule _Module;
  159. BEGIN_OBJECT_MAP (ObjectMap)
  160. OBJECT_ENTRY (CLSID_CertificateManager, CCertMgrSnapin)
  161. OBJECT_ENTRY (CLSID_CertificateManagerPKPOLExt, CCertMgrPKPolExtension)
  162. OBJECT_ENTRY (CLSID_CertificateManagerAbout, CCertMgrAbout)
  163. OBJECT_ENTRY (CLSID_PublicKeyPoliciesAbout, CPublicKeyPoliciesAbout)
  164. OBJECT_ENTRY (CLSID_SaferWindowsExtension, CSaferWindowsExtension)
  165. OBJECT_ENTRY (CLSID_SaferWindowsAbout, CSaferWindowsAbout)
  166. END_OBJECT_MAP ()
  167. class CCertMgrApp : public CWinApp
  168. {
  169. public:
  170. CCertMgrApp ();
  171. virtual BOOL InitInstance ();
  172. virtual int ExitInstance ();
  173. private:
  174. };
  175. CCertMgrApp theApp;
  176. CCertMgrApp::CCertMgrApp ()
  177. {
  178. // security review 2/26/2002 BryanWal ok
  179. LPWSTR pszCommandLine = _wcsupr (::GetCommandLine ());
  180. LPWSTR pszParam = L"/CERTMGR:FILENAME=";
  181. // security review 2/26/2002 BryanWal ok
  182. size_t len = wcslen (pszParam);
  183. // security review 2/26/2002 BryanWal ok
  184. // NOTICE: handles very long strings - the Windows commandline parser will
  185. // return an error if the commandline is too long
  186. LPWSTR pszArg = wcsstr (pszCommandLine, pszParam);
  187. if ( !pszArg )
  188. {
  189. pszParam = L"-CERTMGR:FILENAME=";
  190. // security review 2/26/2002 BryanWal ok
  191. pszArg = wcsstr (pszCommandLine, pszParam);
  192. }
  193. if ( pszArg )
  194. {
  195. LPWSTR pszDelimiters = 0;
  196. // jump past the name of the arg to get the value
  197. pszArg += len;
  198. // Is the file name delimited by double quotes? This could indicate
  199. // the presence of spaces in the name. If so, skip the quote
  200. // and look for the closing quote. Otherwise, look for the next
  201. // space, tab or NULL terminator.
  202. if ( L'\"' == pszArg[0] )
  203. {
  204. pszDelimiters = L"\"";
  205. pszArg++;
  206. }
  207. else
  208. pszDelimiters = L" \t\0";
  209. // security review 2/26/2002 BryanWal ok
  210. len = wcscspn (pszArg, pszDelimiters);
  211. * (pszArg + len) = 0;
  212. g_szFileName = pszArg;
  213. }
  214. }
  215. BOOL CCertMgrApp::InitInstance ()
  216. {
  217. #ifdef _MERGE_PROXYSTUB
  218. hProxyDll = m_hInstance;
  219. #endif
  220. g_hInstance = m_hInstance;
  221. AfxSetResourceHandle (m_hInstance);
  222. _Module.Init (ObjectMap, m_hInstance);
  223. #if DBG == 1
  224. CheckDebugOutputLevel ();
  225. #endif
  226. SHFusionInitializeFromModuleID (m_hInstance, 2);
  227. return CWinApp::InitInstance ();
  228. }
  229. int CCertMgrApp::ExitInstance ()
  230. {
  231. SHFusionUninitialize();
  232. SetRegistryScope (0, false);
  233. _Module.Term ();
  234. return CWinApp::ExitInstance ();
  235. }
  236. /////////////////////////////////////////////////////////////////////////////
  237. // Used to determine whether the DLL can be unloaded by OLE
  238. STDAPI DllCanUnloadNow (void)
  239. {
  240. AFX_MANAGE_STATE (AfxGetStaticModuleState ());
  241. return (AfxDllCanUnloadNow ()==S_OK && _Module.GetLockCount ()==0) ? S_OK : S_FALSE;
  242. }
  243. /////////////////////////////////////////////////////////////////////////////
  244. // Returns a class factory to create an object of the requested type
  245. STDAPI DllGetClassObject (REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  246. {
  247. return _Module.GetClassObject (rclsid, riid, ppv);
  248. }
  249. /////////////////////////////////////////////////////////////////////////////
  250. // DllRegisterServer - Adds entries to the system registry
  251. //const WCHAR g_szNameString[] = TEXT ("NameString");
  252. //const WCHAR g_szNodeType[] = TEXT ("NodeType");
  253. STDAPI DllRegisterServer (void)
  254. {
  255. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  256. // NTRAID# 88502 intlext: mui: me common: crypto: certificate 's
  257. // intended purpose string unlocalized
  258. // Unregister szOID_EFS_RECOVERY
  259. CRYPT_OID_INFO oid;
  260. // security review 2/26/2002 BryanWal ok
  261. ::ZeroMemory (&oid, sizeof (oid));
  262. oid.cbSize = sizeof (CRYPT_OID_INFO);
  263. oid.pszOID = szOID_EFS_RECOVERY;
  264. oid.dwGroupId = CRYPT_ENHKEY_USAGE_OID_GROUP_ID;
  265. CryptUnregisterOIDInfo (&oid);
  266. // registers object, typelib and all interfaces in typelib
  267. HRESULT hr = _Module.RegisterServer (TRUE);
  268. ASSERT (SUCCEEDED (hr));
  269. if ( E_ACCESSDENIED == hr )
  270. {
  271. CString caption;
  272. CString text;
  273. CThemeContextActivator activator;
  274. VERIFY (caption.LoadString (IDS_REGISTER_CERTMGR));
  275. VERIFY (text.LoadString (IDS_INSUFFICIENT_RIGHTS_TO_REGISTER_CERTMGR));
  276. MessageBox (NULL, text, caption, MB_OK);
  277. return hr;
  278. }
  279. try
  280. {
  281. CString strGUID;
  282. CString snapinName;
  283. CString verProviderStr, verVersionStr;
  284. AMC::CRegKey rkSnapins;
  285. BOOL fFound = rkSnapins.OpenKeyEx (HKEY_LOCAL_MACHINE, SNAPINS_KEY);
  286. ASSERT (fFound);
  287. if ( fFound )
  288. {
  289. {
  290. AMC::CRegKey rkCertMgrSnapin;
  291. hr = GuidToCString (&strGUID, CLSID_CertificateManager);
  292. if ( FAILED (hr) )
  293. {
  294. ASSERT (FALSE);
  295. return SELFREG_E_CLASS;
  296. }
  297. rkCertMgrSnapin.CreateKeyEx (rkSnapins, strGUID);
  298. ASSERT (rkCertMgrSnapin.GetLastError () == ERROR_SUCCESS);
  299. rkCertMgrSnapin.SetString (g_szNodeType, g_aNodetypeGuids[CERTMGR_SNAPIN].bstr);
  300. VERIFY (snapinName.LoadString (IDS_CERTIFICATE_MANAGER_REGISTRY));
  301. rkCertMgrSnapin.SetString (g_szNameString, (LPCWSTR) snapinName);
  302. hr = GuidToCString (&strGUID, CLSID_CertificateManagerAbout);
  303. if ( FAILED (hr) )
  304. {
  305. ASSERT (FALSE);
  306. return SELFREG_E_CLASS;
  307. }
  308. rkCertMgrSnapin.SetString (L"About", strGUID);
  309. // security review 2/26/2002 BryanWal ok
  310. size_t len = strlen (VER_COMPANYNAME_STR);
  311. // last arg includes null-terminator. If the last arg doesn't
  312. // include the null terminator, the '/0' will not get converted.
  313. len = mbstowcs (verProviderStr.GetBufferSetLength ((int) len),
  314. VER_COMPANYNAME_STR, len+1);
  315. rkCertMgrSnapin.SetString (L"Provider", verProviderStr);
  316. // security review 2/26/2002 BryanWal ok
  317. len = strlen (VER_PRODUCTVERSION_STR);
  318. // security review 2/26/2002 BryanWal ok
  319. len = mbstowcs (verVersionStr.GetBufferSetLength ((int)len),
  320. VER_PRODUCTVERSION_STR, len+1); // last arg includes null-terminator
  321. rkCertMgrSnapin.SetString (L"Version", verVersionStr);
  322. AMC::CRegKey rkCertMgrStandalone;
  323. rkCertMgrStandalone.CreateKeyEx (rkCertMgrSnapin, g_szStandAlone);
  324. ASSERT (rkCertMgrStandalone.GetLastError () == ERROR_SUCCESS);
  325. AMC::CRegKey rkMyNodeTypes;
  326. rkMyNodeTypes.CreateKeyEx (rkCertMgrSnapin, g_szNodeTypes);
  327. ASSERT (rkMyNodeTypes.GetLastError () == ERROR_SUCCESS);
  328. AMC::CRegKey rkMyNodeType;
  329. for (int i = CERTMGR_SNAPIN; i < CERTMGR_NUMTYPES; i++)
  330. {
  331. switch (i)
  332. {
  333. case CERTMGR_LOG_STORE_GPE:
  334. case CERTMGR_LOG_STORE_RSOP:
  335. case CERTMGR_AUTO_CERT_REQUEST:
  336. case CERTMGR_CERT_POLICIES_USER:
  337. case CERTMGR_CERT_POLICIES_COMPUTER:
  338. case CERTMGR_PKP_AUTOENROLLMENT_USER_SETTINGS: // not necessary - just another kind of the same node
  339. break;
  340. // TODO: What to do with these?
  341. case CERTMGR_SAFER_COMPUTER_ROOT:
  342. case CERTMGR_SAFER_USER_ROOT:
  343. case CERTMGR_SAFER_COMPUTER_LEVELS:
  344. case CERTMGR_SAFER_USER_LEVELS:
  345. case CERTMGR_SAFER_COMPUTER_ENTRIES:
  346. case CERTMGR_SAFER_USER_ENTRIES:
  347. case CERTMGR_SAFER_COMPUTER_LEVEL:
  348. case CERTMGR_SAFER_USER_LEVEL:
  349. case CERTMGR_SAFER_COMPUTER_ENTRY:
  350. case CERTMGR_SAFER_USER_ENTRY:
  351. case CERTMGR_SAFER_COMPUTER_TRUSTED_PUBLISHERS:
  352. case CERTMGR_SAFER_USER_TRUSTED_PUBLISHERS:
  353. case CERTMGR_SAFER_COMPUTER_DEFINED_FILE_TYPES:
  354. case CERTMGR_SAFER_USER_DEFINED_FILE_TYPES:
  355. case CERTMGR_SAFER_USER_ENFORCEMENT:
  356. case CERTMGR_SAFER_COMPUTER_ENFORCEMENT:
  357. break;
  358. case CERTMGR_PKP_AUTOENROLLMENT_COMPUTER_SETTINGS:
  359. default:
  360. // security review 2/26/2002 BryanWal ok
  361. if ( wcslen (g_aNodetypeGuids[i].bstr) )
  362. {
  363. rkMyNodeType.CreateKeyEx (rkMyNodeTypes, g_aNodetypeGuids[i].bstr);
  364. ASSERT (rkMyNodeType.GetLastError () == ERROR_SUCCESS);
  365. rkMyNodeType.CloseKey ();
  366. }
  367. break;
  368. }
  369. }
  370. //
  371. // BryanWal 5/18/00
  372. // 94793: MUI: MMC: Certificates snap-in stores its display
  373. // information in the registry
  374. //
  375. // MMC now supports NameStringIndirect
  376. //
  377. WCHAR achModuleFileName[MAX_PATH+20];
  378. if (0 < ::GetModuleFileName(
  379. AfxGetInstanceHandle(),
  380. achModuleFileName,
  381. sizeof(achModuleFileName)/sizeof(WCHAR) )) // size of buffer in TCHARS
  382. {
  383. CString strNameIndirect;
  384. strNameIndirect.Format(L"@%s,-%d",
  385. achModuleFileName,
  386. IDS_CERTIFICATE_MANAGER_REGISTRY );
  387. rkCertMgrSnapin.SetString(L"NameStringIndirect",
  388. strNameIndirect );
  389. }
  390. rkCertMgrSnapin.CloseKey ();
  391. }
  392. AMC::CRegKey rkNodeTypes;
  393. fFound = rkNodeTypes.OpenKeyEx (HKEY_LOCAL_MACHINE, NODE_TYPES_KEY);
  394. ASSERT (fFound);
  395. if ( fFound )
  396. {
  397. AMC::CRegKey rkNodeType;
  398. for (int i = CERTMGR_SNAPIN; i < CERTMGR_NUMTYPES; i++)
  399. {
  400. switch (i)
  401. {
  402. // these types are not used in the primary snapin
  403. case CERTMGR_LOG_STORE_GPE:
  404. case CERTMGR_LOG_STORE_RSOP:
  405. case CERTMGR_AUTO_CERT_REQUEST:
  406. case CERTMGR_CERT_POLICIES_USER:
  407. case CERTMGR_CERT_POLICIES_COMPUTER:
  408. case CERTMGR_PKP_AUTOENROLLMENT_COMPUTER_SETTINGS:
  409. case CERTMGR_PKP_AUTOENROLLMENT_USER_SETTINGS:
  410. case CERTMGR_SAFER_COMPUTER_ROOT:
  411. case CERTMGR_SAFER_USER_ROOT:
  412. case CERTMGR_SAFER_COMPUTER_LEVELS:
  413. case CERTMGR_SAFER_USER_LEVELS:
  414. case CERTMGR_SAFER_COMPUTER_ENTRIES:
  415. case CERTMGR_SAFER_USER_ENTRIES:
  416. case CERTMGR_SAFER_COMPUTER_LEVEL:
  417. case CERTMGR_SAFER_USER_LEVEL:
  418. case CERTMGR_SAFER_COMPUTER_ENTRY:
  419. case CERTMGR_SAFER_USER_ENTRY:
  420. case CERTMGR_SAFER_COMPUTER_TRUSTED_PUBLISHERS:
  421. case CERTMGR_SAFER_USER_TRUSTED_PUBLISHERS:
  422. case CERTMGR_SAFER_COMPUTER_DEFINED_FILE_TYPES:
  423. case CERTMGR_SAFER_USER_DEFINED_FILE_TYPES:
  424. case CERTMGR_SAFER_USER_ENFORCEMENT:
  425. case CERTMGR_SAFER_COMPUTER_ENFORCEMENT:
  426. break;
  427. default:
  428. // security review 2/26/2002 BryanWal ok
  429. if ( wcslen (g_aNodetypeGuids[i].bstr) )
  430. {
  431. rkNodeType.CreateKeyEx (rkNodeTypes, g_aNodetypeGuids[i].bstr);
  432. ASSERT (rkNodeType.GetLastError () == ERROR_SUCCESS);
  433. rkNodeType.CloseKey ();
  434. }
  435. break;
  436. }
  437. }
  438. if ( IsWindowsNT () )
  439. {
  440. {
  441. // Public Key PoliciesSnap-in under Security Configuration Editor (SCE)
  442. // Certificate Manager extends "Computer Settings" and
  443. // "User Settings" node
  444. CString strCertMgrExtPKPolGUID;
  445. hr = GuidToCString (&strCertMgrExtPKPolGUID,
  446. CLSID_CertificateManagerPKPOLExt);
  447. if ( FAILED (hr) )
  448. {
  449. ASSERT (FALSE);
  450. return SELFREG_E_CLASS;
  451. }
  452. VERIFY (snapinName.LoadString (IDS_CERT_MGR_SCE_EXTENSION_REGISTRY));
  453. {
  454. AMC::CRegKey rkCertMgrExtension;
  455. rkCertMgrExtension.CreateKeyEx (rkSnapins, strCertMgrExtPKPolGUID);
  456. ASSERT (rkCertMgrExtension.GetLastError () == ERROR_SUCCESS);
  457. rkCertMgrExtension.SetString (g_szNameString, (LPCWSTR) snapinName);
  458. hr = GuidToCString (&strGUID, CLSID_PublicKeyPoliciesAbout);
  459. if ( FAILED (hr) )
  460. {
  461. ASSERT (FALSE);
  462. return SELFREG_E_CLASS;
  463. }
  464. rkCertMgrExtension.SetString (L"About", strGUID);
  465. rkCertMgrExtension.SetString (L"Provider", verProviderStr);
  466. rkCertMgrExtension.SetString (L"Version", verVersionStr);
  467. // Register the node types of the extension
  468. AMC::CRegKey rkMyNodeTypes;
  469. rkMyNodeTypes.CreateKeyEx (rkCertMgrExtension, g_szNodeTypes);
  470. ASSERT (rkMyNodeTypes.GetLastError () == ERROR_SUCCESS);
  471. AMC::CRegKey rkMyNodeType;
  472. for (int i = CERTMGR_SNAPIN; i < CERTMGR_NUMTYPES; i++)
  473. {
  474. switch (i)
  475. {
  476. // None of these are used in the Public Key Policy extension
  477. case CERTMGR_USAGE:
  478. case CERTMGR_PHYS_STORE:
  479. case CERTMGR_LOG_STORE:
  480. case CERTMGR_CRL_CONTAINER:
  481. case CERTMGR_CTL_CONTAINER:
  482. case CERTMGR_CERT_CONTAINER:
  483. case CERTMGR_CRL:
  484. case CERTMGR_SAFER_COMPUTER_ROOT:
  485. case CERTMGR_SAFER_USER_ROOT:
  486. case CERTMGR_SAFER_COMPUTER_LEVELS:
  487. case CERTMGR_SAFER_USER_LEVELS:
  488. case CERTMGR_SAFER_COMPUTER_ENTRIES:
  489. case CERTMGR_SAFER_USER_ENTRIES:
  490. case CERTMGR_SAFER_COMPUTER_LEVEL:
  491. case CERTMGR_SAFER_USER_LEVEL:
  492. case CERTMGR_SAFER_COMPUTER_ENTRY:
  493. case CERTMGR_SAFER_USER_ENTRY:
  494. case CERTMGR_SAFER_COMPUTER_TRUSTED_PUBLISHERS:
  495. case CERTMGR_SAFER_USER_TRUSTED_PUBLISHERS:
  496. case CERTMGR_SAFER_COMPUTER_DEFINED_FILE_TYPES:
  497. case CERTMGR_SAFER_USER_DEFINED_FILE_TYPES:
  498. case CERTMGR_SAFER_USER_ENFORCEMENT:
  499. case CERTMGR_SAFER_COMPUTER_ENFORCEMENT:
  500. // not necessary - just another kind of the same node
  501. case CERTMGR_PKP_AUTOENROLLMENT_USER_SETTINGS:
  502. break;
  503. default:
  504. // security review 2/26/2002 BryanWal ok
  505. if ( wcslen (g_aNodetypeGuids[i].bstr) )
  506. {
  507. rkMyNodeType.CreateKeyEx (rkMyNodeTypes, g_aNodetypeGuids[i].bstr);
  508. ASSERT (rkMyNodeType.GetLastError () == ERROR_SUCCESS);
  509. rkMyNodeType.CloseKey ();
  510. }
  511. break;
  512. }
  513. }
  514. //
  515. // BryanWal 5/18/00
  516. // 94793: MUI: MMC: Certificates snap-in stores its display
  517. // information in the registry
  518. //
  519. // MMC now supports NameStringIndirect
  520. //
  521. WCHAR achModuleFileName[MAX_PATH+20];
  522. if (0 < ::GetModuleFileName(
  523. AfxGetInstanceHandle(),
  524. achModuleFileName,
  525. sizeof(achModuleFileName)/sizeof(WCHAR) )) // size of buffer in TCHARS
  526. {
  527. CString strNameIndirect;
  528. strNameIndirect.Format(L"@%s,-%d",
  529. achModuleFileName,
  530. IDS_CERT_MGR_SCE_EXTENSION_REGISTRY );
  531. rkCertMgrExtension.SetString( L"NameStringIndirect",
  532. strNameIndirect );
  533. }
  534. rkCertMgrExtension.CloseKey ();
  535. }
  536. hr = GuidToCString (&strGUID, cNodetypeSceTemplate);
  537. if ( FAILED (hr) )
  538. {
  539. ASSERT (FALSE);
  540. return SELFREG_E_CLASS;
  541. }
  542. rkNodeType.CreateKeyEx (rkNodeTypes, strGUID);
  543. ASSERT (rkNodeType.GetLastError () == ERROR_SUCCESS);
  544. if ( rkNodeType.GetLastError () == ERROR_SUCCESS )
  545. {
  546. AMC::CRegKey rkExtensions;
  547. ASSERT (rkExtensions.GetLastError () == ERROR_SUCCESS);
  548. rkExtensions.CreateKeyEx (rkNodeType, g_szExtensions);
  549. AMC::CRegKey rkNameSpace;
  550. rkNameSpace.CreateKeyEx (rkExtensions, g_szNameSpace);
  551. ASSERT (rkNameSpace.GetLastError () == ERROR_SUCCESS);
  552. rkNameSpace.SetString (strCertMgrExtPKPolGUID, (LPCWSTR) snapinName);
  553. rkNodeType.CloseKey ();
  554. }
  555. else
  556. return SELFREG_E_CLASS;
  557. }
  558. {
  559. // SAFER Windows Snap-in under Security Configuration Editor (SCE)
  560. // Certificate Manager extends "Computer Settings" and
  561. // "User Settings" node
  562. CString strSaferWindowsExtensionGUID;
  563. hr = GuidToCString (&strSaferWindowsExtensionGUID,
  564. CLSID_SaferWindowsExtension);
  565. if ( FAILED (hr) )
  566. {
  567. ASSERT (FALSE);
  568. return SELFREG_E_CLASS;
  569. }
  570. VERIFY (snapinName.LoadString (IDS_SAFER_WINDOWS_EXTENSION_REGISTRY));
  571. {
  572. AMC::CRegKey rkCertMgrExtension;
  573. rkCertMgrExtension.CreateKeyEx (rkSnapins, strSaferWindowsExtensionGUID);
  574. ASSERT (rkCertMgrExtension.GetLastError () == ERROR_SUCCESS);
  575. rkCertMgrExtension.SetString (g_szNameString, (LPCWSTR) snapinName);
  576. hr = GuidToCString (&strGUID, CLSID_SaferWindowsAbout);
  577. if ( FAILED (hr) )
  578. {
  579. ASSERT (FALSE);
  580. return SELFREG_E_CLASS;
  581. }
  582. rkCertMgrExtension.SetString (L"About", strGUID);
  583. rkCertMgrExtension.SetString (L"Provider", verProviderStr);
  584. rkCertMgrExtension.SetString (L"Version", verVersionStr);
  585. // Register the node types of the extension
  586. AMC::CRegKey rkMyNodeTypes;
  587. rkMyNodeTypes.CreateKeyEx (rkCertMgrExtension, g_szNodeTypes);
  588. ASSERT (rkMyNodeTypes.GetLastError () == ERROR_SUCCESS);
  589. AMC::CRegKey rkMyNodeType;
  590. for (int i = CERTMGR_SNAPIN; i < CERTMGR_NUMTYPES; i++)
  591. {
  592. switch (i)
  593. {
  594. case CERTMGR_CERTIFICATE:
  595. case CERTMGR_LOG_STORE:
  596. case CERTMGR_PHYS_STORE:
  597. case CERTMGR_USAGE:
  598. case CERTMGR_CRL_CONTAINER:
  599. case CERTMGR_CTL_CONTAINER:
  600. case CERTMGR_CERT_CONTAINER:
  601. case CERTMGR_CRL:
  602. case CERTMGR_CTL:
  603. case CERTMGR_AUTO_CERT_REQUEST:
  604. case CERTMGR_CERT_POLICIES_USER:
  605. case CERTMGR_CERT_POLICIES_COMPUTER:
  606. case CERTMGR_LOG_STORE_GPE:
  607. case CERTMGR_LOG_STORE_RSOP:
  608. case CERTMGR_PKP_AUTOENROLLMENT_USER_SETTINGS:
  609. case CERTMGR_PKP_AUTOENROLLMENT_COMPUTER_SETTINGS:
  610. // None of these are used in the Software Restriction Policies extension
  611. break;
  612. case CERTMGR_SAFER_COMPUTER_ROOT:
  613. case CERTMGR_SAFER_USER_ROOT:
  614. case CERTMGR_SAFER_COMPUTER_LEVELS:
  615. case CERTMGR_SAFER_USER_LEVELS:
  616. case CERTMGR_SAFER_COMPUTER_ENTRIES:
  617. case CERTMGR_SAFER_USER_ENTRIES:
  618. case CERTMGR_SAFER_COMPUTER_LEVEL:
  619. case CERTMGR_SAFER_USER_LEVEL:
  620. case CERTMGR_SAFER_COMPUTER_ENTRY:
  621. case CERTMGR_SAFER_USER_ENTRY:
  622. case CERTMGR_SAFER_COMPUTER_TRUSTED_PUBLISHERS:
  623. case CERTMGR_SAFER_USER_TRUSTED_PUBLISHERS:
  624. case CERTMGR_SAFER_COMPUTER_DEFINED_FILE_TYPES:
  625. case CERTMGR_SAFER_USER_DEFINED_FILE_TYPES:
  626. case CERTMGR_SAFER_USER_ENFORCEMENT:
  627. case CERTMGR_SAFER_COMPUTER_ENFORCEMENT:
  628. default:
  629. // security review 2/26/2002 BryanWal ok
  630. if ( g_aNodetypeGuids[i].bstr && wcslen (g_aNodetypeGuids[i].bstr) )
  631. {
  632. rkMyNodeType.CreateKeyEx (rkMyNodeTypes, g_aNodetypeGuids[i].bstr);
  633. ASSERT (rkMyNodeType.GetLastError () == ERROR_SUCCESS);
  634. rkMyNodeType.CloseKey ();
  635. }
  636. break;
  637. }
  638. }
  639. WCHAR achModuleFileName[MAX_PATH+20];
  640. if (0 < ::GetModuleFileName(
  641. AfxGetInstanceHandle(),
  642. achModuleFileName,
  643. sizeof(achModuleFileName)/sizeof(WCHAR) )) // size of buffer in TCHARS
  644. {
  645. CString strNameIndirect;
  646. strNameIndirect.Format( L"@%s,-%d",
  647. achModuleFileName,
  648. IDS_SAFER_WINDOWS_EXTENSION_REGISTRY );
  649. rkCertMgrExtension.SetString( L"NameStringIndirect",
  650. strNameIndirect );
  651. }
  652. rkCertMgrExtension.CloseKey ();
  653. }
  654. hr = GuidToCString (&strGUID, cNodetypeSceTemplate);
  655. if ( FAILED (hr) )
  656. {
  657. ASSERT (FALSE);
  658. return SELFREG_E_CLASS;
  659. }
  660. rkNodeType.CreateKeyEx (rkNodeTypes, strGUID);
  661. ASSERT (rkNodeType.GetLastError () == ERROR_SUCCESS);
  662. if ( rkNodeType.GetLastError () == ERROR_SUCCESS )
  663. {
  664. AMC::CRegKey rkExtensions;
  665. ASSERT (rkExtensions.GetLastError () == ERROR_SUCCESS);
  666. rkExtensions.CreateKeyEx (rkNodeType, g_szExtensions);
  667. AMC::CRegKey rkNameSpace;
  668. rkNameSpace.CreateKeyEx (rkExtensions, g_szNameSpace);
  669. ASSERT (rkNameSpace.GetLastError () == ERROR_SUCCESS);
  670. rkNameSpace.SetString (strSaferWindowsExtensionGUID,
  671. (LPCWSTR) snapinName);
  672. rkNodeType.CloseKey ();
  673. }
  674. else
  675. return SELFREG_E_CLASS;
  676. }
  677. // Deregister as extension to My Computer System Tools node
  678. // CODEWORK It would be good if we deregistered the server too
  679. // JonN 12/14/98
  680. try
  681. {
  682. fFound = rkNodeType.OpenKeyEx (rkNodeTypes, TEXT(struuidNodetypeSystemTools));
  683. // if this fails just carry on
  684. if ( fFound )
  685. {
  686. AMC::CRegKey rkExtensions;
  687. ASSERT (rkExtensions.GetLastError () == ERROR_SUCCESS);
  688. fFound = rkExtensions.OpenKeyEx (rkNodeType, g_szExtensions);
  689. // if this fails just carry on
  690. if ( fFound )
  691. {
  692. AMC::CRegKey rkNameSpace;
  693. ASSERT (rkNameSpace.GetLastError () == ERROR_SUCCESS);
  694. fFound = rkNameSpace.OpenKeyEx (rkExtensions, g_szNameSpace);
  695. // if this fails just carry on
  696. if ( fFound )
  697. {
  698. rkNameSpace.DeleteValue( L"{9C7910D2-4C01-11D1-856B-00C04FB94F17}" );
  699. }
  700. }
  701. }
  702. } catch (COleException* /*e*/)
  703. {
  704. // don't do anything
  705. }
  706. } // endif IsWindowsNT ()
  707. rkNodeTypes.CloseKey ();
  708. }
  709. else
  710. return SELFREG_E_CLASS;
  711. }
  712. else
  713. return SELFREG_E_CLASS;
  714. }
  715. catch (COleException* e)
  716. {
  717. ASSERT (FALSE);
  718. e->Delete ();
  719. return SELFREG_E_CLASS;
  720. }
  721. ASSERT (SUCCEEDED (hr));
  722. return hr;
  723. }
  724. /////////////////////////////////////////////////////////////////////////////
  725. // DllUnregisterServer - Removes entries from the system registry
  726. STDAPI DllUnregisterServer (void)
  727. {
  728. _Module.UnregisterServer ();
  729. return S_OK;
  730. }
  731. STDAPI DllInstall(BOOL /*bInstall*/, LPCWSTR pszCmdLine)
  732. {
  733. LPCWSTR wszCurrentCmd = pszCmdLine;
  734. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  735. // parse the cmd line
  736. while(wszCurrentCmd && *wszCurrentCmd)
  737. {
  738. while(*wszCurrentCmd == L' ')
  739. wszCurrentCmd++;
  740. if(*wszCurrentCmd == 0)
  741. break;
  742. switch(*wszCurrentCmd++)
  743. {
  744. case L'?':
  745. return S_OK;
  746. }
  747. }
  748. return S_OK;
  749. }
  750. ///////////////////////////////////////////////////////////////////////////
  751. // ConvertNameBlobToString ()
  752. //
  753. // nameBlob (IN) - Contains a CERT_NAME_BLOB to be decoded
  754. // pszName (OUT) - The decoded contents of the name blob
  755. //
  756. ///////////////////////////////////////////////////////////////////////////
  757. HRESULT ConvertNameBlobToString (CERT_NAME_BLOB nameBlob, CString & pszName)
  758. {
  759. HRESULT hr = S_OK;
  760. DWORD dwSize = 0;
  761. // Call CertNameToStr to get returned the string length.
  762. dwSize = CertNameToStr (
  763. MY_ENCODING_TYPE, // Encoding type
  764. &nameBlob, // CERT_NAME_BLOB
  765. CERT_SIMPLE_NAME_STR | CERT_NAME_STR_REVERSE_FLAG, // Type
  766. NULL, // Place to return string
  767. dwSize); // Size of string (chars),
  768. // including zero terminator.
  769. ASSERT (dwSize > 1);
  770. if ( dwSize > 1 ) // This function always returns a null char
  771. // (0), so the minimum count returned will
  772. // be 1, even if nothing got converted.
  773. {
  774. // Call CertNameToStr to get the string.
  775. dwSize = CertNameToStr (
  776. MY_ENCODING_TYPE, // Encoding type
  777. &nameBlob, // CERT_NAME_BLOB
  778. CERT_SIMPLE_NAME_STR | CERT_NAME_STR_REVERSE_FLAG, // Type
  779. pszName.GetBufferSetLength (dwSize), // Place to return string
  780. dwSize); // Size of string (chars)
  781. ASSERT (dwSize > 1);
  782. pszName.ReleaseBuffer ();
  783. if ( dwSize <= 1 )
  784. {
  785. hr = E_UNEXPECTED;
  786. }
  787. }
  788. return hr;
  789. }
  790. ///////////////////////////////////////////////////////////////////////////////
  791. // FormatDate ()
  792. //
  793. // utcDateTime (IN) - A FILETIME in UTC format.
  794. // pszDateTime (OUT) - A string containing the local date and time
  795. // formatted by locale and user preference
  796. //
  797. ///////////////////////////////////////////////////////////////////////////////
  798. HRESULT FormatDate (FILETIME utcDateTime, CString & pszDateTime, DWORD dwDateFlags, bool bGetTime)
  799. {
  800. // Time is returned as UTC, will be displayed as local.
  801. // Use FileTimeToLocalFileTime () to make it local,
  802. // then call FileTimeToSystemTime () to convert to system time, then
  803. // format with GetDateFormat () and GetTimeFormat () to display
  804. // according to user and locale preferences
  805. HRESULT hr = S_OK;
  806. FILETIME localDateTime;
  807. BOOL bResult = FileTimeToLocalFileTime (&utcDateTime, // pointer to UTC file time to convert
  808. &localDateTime); // pointer to converted file time
  809. ASSERT (bResult);
  810. if ( bResult )
  811. {
  812. SYSTEMTIME sysTime;
  813. bResult = FileTimeToSystemTime (
  814. &localDateTime, // pointer to file time to convert
  815. &sysTime); // pointer to structure to receive system time
  816. if ( bResult )
  817. {
  818. CString date;
  819. CString time;
  820. // Get date
  821. // Get length to allocate buffer of sufficient size
  822. int iLen = GetDateFormat (
  823. LOCALE_USER_DEFAULT, // locale for which date is to be formatted
  824. dwDateFlags, // flags specifying function options
  825. &sysTime, // date to be formatted
  826. 0, // date format string
  827. 0, // buffer for storing formatted string
  828. 0); // size of buffer
  829. ASSERT (iLen > 0);
  830. if ( iLen > 0 )
  831. {
  832. int iResult = GetDateFormat (
  833. LOCALE_USER_DEFAULT, // locale for which date is to be formatted
  834. dwDateFlags, // flags specifying function options
  835. &sysTime, // date to be formatted
  836. 0, // date format string
  837. date.GetBufferSetLength (iLen), // buffer for storing formatted string
  838. iLen); // size of buffer
  839. ASSERT (iResult);
  840. date.ReleaseBuffer ();
  841. if ( iResult )
  842. pszDateTime = date;
  843. else
  844. hr = HRESULT_FROM_WIN32 (GetLastError ());
  845. if ( iResult && bGetTime )
  846. {
  847. // Get time
  848. // Get length to allocate buffer of sufficient size
  849. iLen = GetTimeFormat (
  850. LOCALE_USER_DEFAULT, // locale for which date is to be formatted
  851. 0, // flags specifying function options
  852. &sysTime, // date to be formatted
  853. 0, // date format string
  854. 0, // buffer for storing formatted string
  855. 0); // size of buffer
  856. ASSERT (iLen > 0);
  857. if ( iLen > 0 )
  858. {
  859. iResult = GetTimeFormat (
  860. LOCALE_USER_DEFAULT, // locale for which date is to be formatted
  861. 0, // flags specifying function options
  862. &sysTime, // date to be formatted
  863. 0, // date format string
  864. time.GetBufferSetLength (iLen), // buffer for storing formatted string
  865. iLen); // size of buffer
  866. ASSERT (iResult);
  867. time.ReleaseBuffer ();
  868. if ( iResult )
  869. {
  870. pszDateTime = date + L" " + time;
  871. }
  872. else
  873. hr = E_UNEXPECTED;
  874. }
  875. else
  876. hr = E_UNEXPECTED;
  877. }
  878. }
  879. else
  880. {
  881. hr = HRESULT_FROM_WIN32 (GetLastError ());
  882. }
  883. }
  884. else
  885. {
  886. hr = HRESULT_FROM_WIN32 (GetLastError ());
  887. }
  888. }
  889. else
  890. {
  891. hr = HRESULT_FROM_WIN32 (GetLastError ());
  892. }
  893. return hr;
  894. }
  895. void DisplaySystemError (HWND hParent, DWORD dwErr)
  896. {
  897. AFX_MANAGE_STATE (AfxGetStaticModuleState ());
  898. LPVOID lpMsgBuf;
  899. // security review 2/26/2002 BryanWal ok - message is from system
  900. ::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  901. NULL,
  902. dwErr,
  903. MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  904. (LPWSTR) &lpMsgBuf, 0, NULL);
  905. // Display the string.
  906. CString caption;
  907. VERIFY (caption.LoadString (IDS_CERTIFICATE_MANAGER));
  908. CThemeContextActivator activator;
  909. ::MessageBox (hParent, (LPWSTR) lpMsgBuf, (LPCWSTR) caption, MB_OK);
  910. // Free the buffer.
  911. LocalFree (lpMsgBuf);
  912. }
  913. CString GetSystemMessage (DWORD dwErr)
  914. {
  915. AFX_MANAGE_STATE (AfxGetStaticModuleState ());
  916. CString message;
  917. LPVOID lpMsgBuf;
  918. // security review 2/26/2002 BryanWal ok - message is from system
  919. ::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  920. NULL,
  921. dwErr,
  922. MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  923. (LPWSTR) &lpMsgBuf, 0, NULL );
  924. message = (LPWSTR) lpMsgBuf;
  925. // Free the buffer.
  926. LocalFree (lpMsgBuf);
  927. return message;
  928. }
  929. bool MyGetOIDInfo (CString & string, LPCSTR pszObjId)
  930. {
  931. ASSERT (pszObjId);
  932. PCCRYPT_OID_INFO pOIDInfo; // This points to a constant data structure and must not be freed.
  933. bool bResult = true;
  934. pOIDInfo = ::CryptFindOIDInfo (CRYPT_OID_INFO_OID_KEY, (void *) pszObjId, 0);
  935. if ( pOIDInfo )
  936. {
  937. string = pOIDInfo->pwszName;
  938. string.TrimLeft ();
  939. string.TrimRight ();
  940. }
  941. else
  942. {
  943. // security review 2/26/2002 BryanWal ok
  944. // NOTICE: API returns required char count including null terminator if
  945. // last arg is 0
  946. int nLen = ::MultiByteToWideChar (CP_ACP, 0, pszObjId, -1, NULL, 0);
  947. ASSERT (nLen);
  948. if ( nLen )
  949. {
  950. // security review 2/26/2002 BryanWal ok
  951. nLen = ::MultiByteToWideChar (CP_ACP, 0, pszObjId, -1,
  952. string.GetBufferSetLength (nLen), nLen);
  953. ASSERT (nLen);
  954. string.ReleaseBuffer ();
  955. }
  956. bResult = (nLen > 0) ? true : false;
  957. }
  958. return bResult;
  959. }
  960. bool IsWindowsNT()
  961. {
  962. OSVERSIONINFO versionInfo;
  963. // security review 2/26/2002 BryanWal ok
  964. ::ZeroMemory (&versionInfo, sizeof (versionInfo));
  965. versionInfo.dwOSVersionInfoSize = sizeof (versionInfo);
  966. BOOL bResult = ::GetVersionEx (&versionInfo);
  967. ASSERT (bResult);
  968. if ( bResult )
  969. {
  970. if ( VER_PLATFORM_WIN32_NT == versionInfo.dwPlatformId )
  971. bResult = TRUE;
  972. }
  973. return bResult ? true : false;
  974. }
  975. bool GetNameStringByType (
  976. PCCERT_CONTEXT pCertContext,
  977. DWORD dwFlag,
  978. DWORD dwType,
  979. CString& szNameString)
  980. {
  981. bool bResult = false;
  982. DWORD dwTypePara = CERT_SIMPLE_NAME_STR | CERT_NAME_STR_REVERSE_FLAG;
  983. DWORD cchNameString = 0;
  984. DWORD dwResult = ::CertGetNameString (pCertContext,
  985. dwType,
  986. dwFlag,
  987. &dwTypePara,
  988. NULL,
  989. cchNameString);
  990. if ( dwResult > 1 )
  991. {
  992. cchNameString = dwResult;
  993. LPWSTR pszNameString = new WCHAR[cchNameString];
  994. if ( pszNameString )
  995. {
  996. // security review 2/26/2002 BryanWal ok
  997. ::ZeroMemory (pszNameString, cchNameString*sizeof (WCHAR));
  998. dwResult = ::CertGetNameString (pCertContext,
  999. dwType,
  1000. dwFlag,
  1001. &dwTypePara,
  1002. pszNameString,
  1003. cchNameString);
  1004. ASSERT (dwResult > 1);
  1005. if ( dwResult > 1 )
  1006. {
  1007. szNameString = pszNameString;
  1008. bResult = true;
  1009. }
  1010. delete [] pszNameString;
  1011. }
  1012. }
  1013. return bResult;
  1014. }
  1015. CString GetNameString (PCCERT_CONTEXT pCertContext, DWORD dwFlag)
  1016. {
  1017. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1018. CString szNameString;
  1019. DWORD dwTypes[] = {CERT_NAME_SIMPLE_DISPLAY_TYPE,
  1020. CERT_NAME_EMAIL_TYPE,
  1021. CERT_NAME_UPN_TYPE,
  1022. CERT_NAME_DNS_TYPE,
  1023. CERT_NAME_URL_TYPE,
  1024. (DWORD) -1};
  1025. int nIndex = 0;
  1026. while ( -1 != dwTypes[nIndex])
  1027. {
  1028. if ( GetNameStringByType (
  1029. pCertContext,
  1030. dwFlag,
  1031. dwTypes[nIndex],
  1032. szNameString) )
  1033. {
  1034. break;
  1035. }
  1036. nIndex++;
  1037. }
  1038. if ( szNameString.IsEmpty () )
  1039. szNameString.FormatMessage (IDS_NOT_AVAILABLE);
  1040. return szNameString;
  1041. }
  1042. bool CertHasEFSKeyUsage(PCCERT_CONTEXT pCertContext)
  1043. {
  1044. bool bFound = false;
  1045. BOOL bResult = FALSE;
  1046. DWORD cbUsage = 0;
  1047. bResult = ::CertGetEnhancedKeyUsage (pCertContext,
  1048. 0, // get extension and property
  1049. NULL, &cbUsage);
  1050. if ( bResult )
  1051. {
  1052. PCERT_ENHKEY_USAGE pUsage = (PCERT_ENHKEY_USAGE) new BYTE[cbUsage];
  1053. if ( pUsage )
  1054. {
  1055. bResult = ::CertGetEnhancedKeyUsage (pCertContext,
  1056. 0, // get extension and property
  1057. pUsage, &cbUsage);
  1058. if ( bResult )
  1059. {
  1060. for (DWORD dwIndex = 0; dwIndex < pUsage->cUsageIdentifier; dwIndex++)
  1061. {
  1062. // security review 2/26/2002 BryanWal ok
  1063. if ( !_stricmp (szOID_EFS_RECOVERY,
  1064. pUsage->rgpszUsageIdentifier[dwIndex]) )
  1065. {
  1066. bFound = true;
  1067. break;
  1068. }
  1069. }
  1070. }
  1071. else
  1072. {
  1073. ASSERT (GetLastError () == CRYPT_E_NOT_FOUND);
  1074. }
  1075. delete [] pUsage;
  1076. }
  1077. }
  1078. else
  1079. {
  1080. ASSERT (GetLastError () == CRYPT_E_NOT_FOUND);
  1081. }
  1082. return bFound;
  1083. }
  1084. ////// This stuff was stolen from windows\gina\snapins\gpedit (eric flo's stuff) //////
  1085. //*************************************************************
  1086. //
  1087. // RegDelnodeRecurse()
  1088. //
  1089. // Purpose: Deletes a registry key and all it's subkeys / values.
  1090. // Called by RegDelnode
  1091. //
  1092. // Parameters: hKeyRoot - Root key
  1093. // pwszSubKey - SubKey to delete
  1094. //
  1095. // Return: ERROR_SUCCESS if successful
  1096. // something else if an error occurs
  1097. //
  1098. // Comments:
  1099. //
  1100. // History: Date Author Comment
  1101. // 10/3/95 ericflo Created
  1102. // 5/13/98 BryanWal Modified to return LRESULT
  1103. //
  1104. //*************************************************************
  1105. LRESULT RegDelnodeRecurse (HKEY hKeyRoot, CString szSubKey)
  1106. {
  1107. ASSERT (hKeyRoot && !szSubKey.IsEmpty ());
  1108. if ( !hKeyRoot || szSubKey.IsEmpty () )
  1109. return ERROR_INVALID_PARAMETER;
  1110. //
  1111. // First, see if we can delete the key without having
  1112. // to recurse.
  1113. //
  1114. LONG lResult = ::RegDeleteKey(hKeyRoot, szSubKey);
  1115. if (lResult == ERROR_SUCCESS)
  1116. {
  1117. return lResult;
  1118. }
  1119. HKEY hKey = 0;
  1120. lResult = ::RegOpenKeyEx (hKeyRoot, szSubKey, 0, KEY_READ, &hKey);
  1121. if (lResult == ERROR_SUCCESS)
  1122. {
  1123. // ensure szSubKey ends with a slash
  1124. if ( L'\\' != szSubKey.GetAt (szSubKey.GetLength () - 1) )
  1125. {
  1126. szSubKey += L"\\";
  1127. }
  1128. //
  1129. // Enumerate the keys
  1130. //
  1131. DWORD dwSize = MAX_PATH;
  1132. FILETIME ftWrite;
  1133. WCHAR szName[MAX_PATH];
  1134. lResult = ::RegEnumKeyEx(hKey, 0,
  1135. szName,
  1136. &dwSize, // size in TCHARS of szName, including terminating NULL (on input)
  1137. NULL,
  1138. NULL, NULL, &ftWrite);
  1139. if (lResult == ERROR_SUCCESS)
  1140. {
  1141. do {
  1142. if ( ERROR_SUCCESS != RegDelnodeRecurse (hKeyRoot, szSubKey + szName) )
  1143. {
  1144. break;
  1145. }
  1146. //
  1147. // Enumerate again
  1148. //
  1149. dwSize = MAX_PATH;
  1150. lResult = ::RegEnumKeyEx(hKey, 0,
  1151. szName,
  1152. &dwSize, // size in TCHARS of szName, including terminating NULL (on input)
  1153. NULL,
  1154. NULL, NULL, &ftWrite);
  1155. } while (lResult == ERROR_SUCCESS);
  1156. }
  1157. ::RegCloseKey (hKey);
  1158. }
  1159. // remove slash from szSubKey
  1160. szSubKey.Delete (szSubKey.GetLength () - 1, 1);
  1161. //
  1162. // Try again to delete the key
  1163. //
  1164. lResult = ::RegDeleteKey(hKeyRoot, szSubKey);
  1165. if (lResult == ERROR_SUCCESS)
  1166. {
  1167. return lResult;
  1168. }
  1169. return lResult;
  1170. }
  1171. //*************************************************************
  1172. //
  1173. // RegDelnode()
  1174. //
  1175. // Purpose: Deletes a registry key and all it's subkeys / values
  1176. //
  1177. // Parameters: hKeyRoot - Root key
  1178. // pwszSubKey - SubKey to delete
  1179. //
  1180. // Return: ERROR_SUCCESS if successful
  1181. // something else if an error occurs
  1182. //
  1183. // Comments:
  1184. //
  1185. // History: Date Author Comment
  1186. // 10/3/95 ericflo Created
  1187. // 5/13/98 BryanWal Modified to return LRESULT
  1188. //
  1189. //*************************************************************
  1190. LRESULT RegDelnode (HKEY hKeyRoot, CString szSubKey)
  1191. {
  1192. ASSERT (hKeyRoot && !szSubKey.IsEmpty ());
  1193. if ( !hKeyRoot || szSubKey.IsEmpty () )
  1194. return ERROR_INVALID_PARAMETER;
  1195. return RegDelnodeRecurse (hKeyRoot, szSubKey);
  1196. }
  1197. HRESULT DisplayCertificateCountByStore(LPCONSOLE pConsole, CCertStore* pCertStore, bool bIsGPE)
  1198. {
  1199. if ( !pConsole || !pCertStore )
  1200. return E_POINTER;
  1201. _TRACE (1, L"Entering DisplayCertificateCountByStore- %s \n",
  1202. (LPCWSTR) pCertStore->GetStoreName ());
  1203. AFX_MANAGE_STATE (AfxGetStaticModuleState ( ));
  1204. IConsole2* pConsole2 = 0;
  1205. HRESULT hr = pConsole->QueryInterface (IID_PPV_ARG (IConsole2, &pConsole2));
  1206. if (SUCCEEDED (hr))
  1207. {
  1208. CString statusText;
  1209. int nCertCount = 0;
  1210. switch (pCertStore->GetStoreType ())
  1211. {
  1212. case ACRS_STORE:
  1213. nCertCount = pCertStore->GetCTLCount ();
  1214. break;
  1215. case TRUST_STORE:
  1216. if ( bIsGPE )
  1217. {
  1218. nCertCount = pCertStore->GetCTLCount ();
  1219. }
  1220. else
  1221. nCertCount = pCertStore->GetCertCount ();
  1222. break;
  1223. default:
  1224. nCertCount = pCertStore->GetCertCount ();
  1225. break;
  1226. }
  1227. switch (nCertCount)
  1228. {
  1229. case 0:
  1230. {
  1231. UINT formatID = 0;
  1232. switch (pCertStore->GetStoreType ())
  1233. {
  1234. case ACRS_STORE:
  1235. formatID = IDS_STATUS_NO_AUTOENROLLMENT_OBJECTS;
  1236. break;
  1237. case TRUST_STORE:
  1238. if ( bIsGPE )
  1239. {
  1240. formatID = IDS_STATUS_NO_CTLS;
  1241. }
  1242. else
  1243. formatID = IDS_STATUS_NO_CERTS;
  1244. break;
  1245. default:
  1246. formatID = IDS_STATUS_NO_CERTS;
  1247. break;
  1248. }
  1249. statusText.FormatMessage (formatID, pCertStore->GetLocalizedName ());
  1250. }
  1251. break;
  1252. case 1:
  1253. {
  1254. UINT formatID = 0;
  1255. switch (pCertStore->GetStoreType ())
  1256. {
  1257. case ACRS_STORE:
  1258. formatID = IDS_STATUS_ONE_AUTOENROLLMENT_OBJECT;
  1259. break;
  1260. case TRUST_STORE:
  1261. if ( bIsGPE )
  1262. {
  1263. formatID = IDS_STATUS_ONE_CTL;
  1264. }
  1265. else
  1266. formatID = IDS_STATUS_ONE_CERT;
  1267. break;
  1268. default:
  1269. formatID = IDS_STATUS_ONE_CERT;
  1270. break;
  1271. }
  1272. statusText.FormatMessage (formatID, pCertStore->GetLocalizedName ());
  1273. }
  1274. break;
  1275. default:
  1276. {
  1277. UINT formatID = 0;
  1278. switch (pCertStore->GetStoreType ())
  1279. {
  1280. case ACRS_STORE:
  1281. formatID = IDS_STATUS_X_AUTOENROLLMENT_OBJECTS;
  1282. break;
  1283. case TRUST_STORE:
  1284. if ( bIsGPE )
  1285. {
  1286. formatID = IDS_STATUS_X_CTLS;
  1287. }
  1288. else
  1289. formatID = IDS_STATUS_X_CERTS;
  1290. break;
  1291. default:
  1292. formatID = IDS_STATUS_X_CERTS;
  1293. break;
  1294. }
  1295. statusText.FormatMessage (formatID,
  1296. (LPCWSTR) pCertStore->GetLocalizedName (), nCertCount);
  1297. }
  1298. break;
  1299. }
  1300. hr = pConsole2->SetStatusText ((LPWSTR)(LPCWSTR) statusText);
  1301. pConsole2->Release ();
  1302. }
  1303. _TRACE (-1, L"Leaving DisplayCertificateCountByStore- %s \n",
  1304. (LPCWSTR) pCertStore->GetStoreName ());
  1305. return hr;
  1306. }
  1307. CString GetF1HelpFilename()
  1308. {
  1309. static CString helpFileName;
  1310. if ( helpFileName.IsEmpty () )
  1311. {
  1312. UINT result = ::GetSystemWindowsDirectory (
  1313. helpFileName.GetBufferSetLength (MAX_PATH+1), MAX_PATH);
  1314. ASSERT(result != 0 && result <= MAX_PATH);
  1315. helpFileName.ReleaseBuffer ();
  1316. if ( result != 0 && result <= MAX_PATH )
  1317. helpFileName += CM_CONTEXT_HELP;
  1318. }
  1319. return helpFileName;
  1320. }
  1321. //+---------------------------------------------------------------------------
  1322. //
  1323. // Function: LocaleStrCmp
  1324. //
  1325. // Synopsis: Do a case insensitive string compare that is safe for any
  1326. // locale.
  1327. //
  1328. // Arguments: [ptsz1] - strings to compare
  1329. // [ptsz2]
  1330. //
  1331. // Returns: -1, 0, or 1 just like lstrcmpi
  1332. //
  1333. // History: 10-28-96 DavidMun Created
  1334. //
  1335. // Notes: This is slower than lstrcmpi, but will work when sorting
  1336. // strings even in Japanese.
  1337. //
  1338. //----------------------------------------------------------------------------
  1339. int LocaleStrCmp(LPCWSTR ptsz1, LPCWSTR ptsz2)
  1340. {
  1341. ASSERT (ptsz1 && ptsz2);
  1342. if ( !ptsz1 || !ptsz2 )
  1343. return 0;
  1344. int iRet = 0;
  1345. iRet = CompareString(LOCALE_USER_DEFAULT,
  1346. NORM_IGNORECASE |
  1347. NORM_IGNOREKANATYPE |
  1348. NORM_IGNOREWIDTH,
  1349. ptsz1,
  1350. -1,
  1351. ptsz2,
  1352. -1);
  1353. if (iRet)
  1354. {
  1355. iRet -= 2; // convert to lstrcmpi-style return -1, 0, or 1
  1356. if ( 0 == iRet )
  1357. {
  1358. UNICODE_STRING unistr1;
  1359. // security review 2/26/2002 BryanWal ok
  1360. ::RtlInitUnicodeString (&unistr1, ptsz1);
  1361. UNICODE_STRING unistr2;
  1362. // security review 2/26/2002 BryanWal ok
  1363. ::RtlInitUnicodeString (&unistr2, ptsz2);
  1364. iRet = ::RtlCompareUnicodeString(
  1365. &unistr1,
  1366. &unistr2,
  1367. FALSE );
  1368. }
  1369. }
  1370. else
  1371. {
  1372. _TRACE (0, L"CompareString (%s, %s) failed: 0x%x\n", ptsz1, ptsz2, GetLastError ());
  1373. }
  1374. return iRet;
  1375. }
  1376. ///////////////////////////////////////////////////////////////////////////////
  1377. ///////////////////////////////////////////////////////////////////////////////
  1378. HPROPSHEETPAGE MyCreatePropertySheetPage(AFX_OLDPROPSHEETPAGE* psp)
  1379. {
  1380. ASSERT (psp);
  1381. if ( !psp )
  1382. return 0;
  1383. PROPSHEETPAGE_V3 sp_v3 = {0};
  1384. // security review 2/26/2002 BryanWal ok
  1385. ::CopyMemory (&sp_v3, psp, psp->dwSize);
  1386. sp_v3.dwSize = sizeof(sp_v3);
  1387. return (::CreatePropertySheetPage (&sp_v3));
  1388. }
  1389. ///////////////////////////////////////////////////////////////////////////////
  1390. ///////////////////////////////////////////////////////////////////////////////
  1391. #include <winldap.h>
  1392. #include <ntldap.h>
  1393. #include <dsrole.h>
  1394. #include <dsgetdc.h>
  1395. #include <accctrl.h>
  1396. #include <lmaccess.h>
  1397. #include <lmapibuf.h>
  1398. #include <lmerr.h>
  1399. //--------------------------------------------------------------------------
  1400. //
  1401. // Defines
  1402. //
  1403. //--------------------------------------------------------------------------
  1404. #define DS_RETEST_SECONDS 3
  1405. #define CVT_BASE (1000 * 1000 * 10)
  1406. #define CVT_SECONDS (1)
  1407. #define CERTTYPE_SECURITY_DESCRIPTOR_NAME L"NTSecurityDescriptor"
  1408. #define TEMPLATE_CONTAINER_NAME L"CN=Certificate Templates,CN=Public Key Services,CN=Services,"
  1409. #define SCHEMA_CONTAINER_NAME L"CN=Schema,"
  1410. HRESULT myHError(HRESULT hr)
  1411. {
  1412. if (S_OK != hr && S_FALSE != hr && !FAILED(hr))
  1413. {
  1414. hr = HRESULT_FROM_WIN32(hr);
  1415. if ( SUCCEEDED (hr) )
  1416. {
  1417. // A call failed without properly setting an error condition!
  1418. hr = E_UNEXPECTED;
  1419. }
  1420. }
  1421. return(hr);
  1422. }
  1423. void CheckDomainVersion ()
  1424. {
  1425. _TRACE (1, L"Entering CheckDomainVersion()\n");
  1426. bool bMachineIsStandAlone = false;
  1427. // Find out if we're joined to a domain.
  1428. PDSROLE_PRIMARY_DOMAIN_INFO_BASIC pInfo = 0;
  1429. DWORD dwErr = ::DsRoleGetPrimaryDomainInformation (
  1430. 0,
  1431. DsRolePrimaryDomainInfoBasic,
  1432. (PBYTE*) &pInfo);
  1433. if ( ERROR_SUCCESS == dwErr )
  1434. {
  1435. switch (pInfo->MachineRole)
  1436. {
  1437. case DsRole_RoleStandaloneWorkstation:
  1438. case DsRole_RoleStandaloneServer:
  1439. bMachineIsStandAlone = true;
  1440. break;
  1441. case DsRole_RoleMemberWorkstation:
  1442. case DsRole_RoleMemberServer:
  1443. case DsRole_RoleBackupDomainController:
  1444. case DsRole_RolePrimaryDomainController:
  1445. bMachineIsStandAlone = false;
  1446. break;
  1447. default:
  1448. break;
  1449. }
  1450. }
  1451. else
  1452. {
  1453. _TRACE (0, L"DsRoleGetPrimaryDomainInformation () failed: 0x%x\n", dwErr);
  1454. }
  1455. if ( !bMachineIsStandAlone )
  1456. {
  1457. CDSBasePathsInfo dsInfo;
  1458. if ( SUCCEEDED (dsInfo.InitFromName (pInfo->DomainNameFlat)) )
  1459. {
  1460. if ( dsInfo.GetSchemaVersion () <= 0x0000000d )
  1461. {
  1462. g_bSchemaIsW2K = true;
  1463. }
  1464. }
  1465. }
  1466. if ( pInfo )
  1467. NetApiBufferFree (pInfo);
  1468. _TRACE (1, L"Entering CheckDomainVersion ()\n");
  1469. }
  1470. VOID DataToHex(PBYTE pSrc, CString & dest, int cb, bool bIncludeSpaces)
  1471. {
  1472. // _TRACE (1, L"Entering DataToHex\n");
  1473. ASSERT (pSrc);
  1474. if ( !pSrc )
  1475. return;
  1476. unsigned char ch = 0;
  1477. WCHAR szDest[3];
  1478. UINT uLen = 0;
  1479. dest.Empty ();
  1480. while (cb-- > 0)
  1481. {
  1482. #pragma warning (once: 4244)
  1483. ch = 0x00FF & (unsigned char) (*pSrc++);
  1484. // ISSUE - change to wsnprintf
  1485. // NTRAID Bug9 538774 Security: certmgr.dll : convert to strsafe string functions
  1486. wsprintf(szDest, _T("%02X"), ch);
  1487. dest += szDest;
  1488. uLen++;
  1489. if ( bIncludeSpaces && !(uLen % 2) && cb )
  1490. dest += _T(" ");
  1491. }
  1492. // _TRACE (-1, L"Leaving DataToHex\n");
  1493. }
  1494. BOOL GetCertificateChain (CERT_CONTEXT* pCertContext, CERT_CONTEXT_LIST& certChainList)
  1495. {
  1496. ASSERT (pCertContext);
  1497. if ( !pCertContext )
  1498. return FALSE;
  1499. // Clean up the cert context list
  1500. while (!certChainList.IsEmpty () )
  1501. {
  1502. pCertContext = certChainList.RemoveHead ();
  1503. if ( pCertContext )
  1504. ::CertFreeCertificateContext (pCertContext);
  1505. }
  1506. CERT_CHAIN_PARA certChainPara;
  1507. // security review 2/26/2002 BryanWal ok
  1508. ::ZeroMemory (&certChainPara, sizeof (certChainPara));
  1509. certChainPara.cbSize = sizeof (CERT_CHAIN_PARA);
  1510. certChainPara.RequestedUsage.Usage.cUsageIdentifier = 1;
  1511. certChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = new LPSTR[1];
  1512. if ( !certChainPara.RequestedUsage.Usage.rgpszUsageIdentifier )
  1513. return FALSE; // E_OUTOFMEMORY;
  1514. certChainPara.RequestedUsage.Usage.rgpszUsageIdentifier[0] = szOID_EFS_RECOVERY;
  1515. PCCERT_CHAIN_CONTEXT pChainContext = 0;
  1516. BOOL bValidated = ::CertGetCertificateChain (
  1517. HCCE_LOCAL_MACHINE, // HCERTCHAINENGINE hChainEngine,
  1518. pCertContext,
  1519. 0, // LPFILETIME pTime,
  1520. 0, // HCERTSTORE hAdditionalStore,
  1521. &certChainPara,
  1522. 0, // dwFlags,
  1523. 0, // pvReserved,
  1524. &pChainContext);
  1525. if ( bValidated )
  1526. {
  1527. // Check to see if cert is self-signed
  1528. PCERT_SIMPLE_CHAIN pChain = pChainContext->rgpChain[pChainContext->cChain - 1];
  1529. if ( pChain )
  1530. {
  1531. PCERT_CHAIN_ELEMENT pElement = pChain->rgpElement[pChain->cElement - 1];
  1532. if ( pElement )
  1533. {
  1534. BOOL bSelfSigned = pElement->TrustStatus.dwInfoStatus & CERT_TRUST_IS_SELF_SIGNED;
  1535. DWORD dwErrorStatus = pChainContext->TrustStatus.dwErrorStatus;
  1536. bValidated = ((0 == dwErrorStatus) ||
  1537. (dwErrorStatus == CERT_TRUST_IS_UNTRUSTED_ROOT) && bSelfSigned);
  1538. if ( bValidated )
  1539. {
  1540. //
  1541. // Enumerate all certs in the chain
  1542. // Search for the cert in the global list
  1543. // If not found, then add to the end of the list
  1544. //
  1545. for (DWORD dwIndex = 0; dwIndex < pChainContext->cChain; dwIndex++)
  1546. {
  1547. DWORD i = 0;
  1548. while (i < pChainContext->rgpChain[dwIndex]->cElement)
  1549. {
  1550. PCCERT_CONTEXT pChainCertContext =
  1551. pChainContext->rgpChain[dwIndex]->rgpElement[i]->pCertContext;
  1552. certChainList.AddTail (
  1553. const_cast<CERT_CONTEXT*>
  1554. (::CertDuplicateCertificateContext (pChainCertContext)));
  1555. i++;
  1556. }
  1557. }
  1558. ::CertFreeCertificateChain(pChainContext);
  1559. pChainContext = 0;
  1560. }
  1561. }
  1562. else
  1563. bValidated = FALSE;
  1564. }
  1565. else
  1566. bValidated = FALSE;
  1567. }
  1568. else
  1569. bValidated = FALSE;
  1570. if ( pChainContext )
  1571. ::CertFreeCertificateChain(pChainContext);
  1572. delete [] certChainPara.RequestedUsage.Usage.rgpszUsageIdentifier;
  1573. return bValidated;
  1574. }