Source code of Windows XP (NT5)
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.

439 lines
18 KiB

  1. // certmap.cpp : Implementation of CCertmapApp and DLL registration.
  2. #include "stdafx.h"
  3. #include "certmap.h"
  4. #ifdef _DEBUG
  5. #define new DEBUG_NEW
  6. #undef THIS_FILE
  7. static char THIS_FILE[] = __FILE__;
  8. #endif
  9. CCertmapApp /*NEAR*/ theApp; // tompop: does this have to be near? We are now getting errors when we finish refering to this var's addr
  10. const GUID CDECL BASED_CODE _tlid =
  11. { 0xbbd8f298, 0x6f61, 0x11d0, { 0xa2, 0x6e, 0x8, 0, 0x2b, 0x2c, 0x6f, 0x32 } };
  12. const WORD _wVerMajor = 1;
  13. const WORD _wVerMinor = 0;
  14. //--------------------------------------------------------------------------
  15. void CCertmapApp::WinHelp(DWORD dwData, UINT nCmd )
  16. {
  17. COleControlModule::WinHelp(dwData,nCmd);
  18. }
  19. ////////////////////////////////////////////////////////////////////////////
  20. // CCertmapApp::InitInstance - DLL initialization
  21. BOOL CCertmapApp::InitInstance()
  22. {
  23. BOOL bInit = COleControlModule::InitInstance();
  24. // init ole stuff
  25. HRESULT hRes = CoInitialize(NULL);
  26. // finally, we need to redirect the winhelp file location to something more desirable
  27. CString sz;
  28. CString szHelpLocation;
  29. sz.LoadString( IDS_HELPLOC_PWSHELP );
  30. // expand the path
  31. ExpandEnvironmentStrings(
  32. sz, // pointer to string with environment variables
  33. szHelpLocation.GetBuffer(MAX_PATH + 1), // pointer to string with expanded environment variables
  34. MAX_PATH // maximum characters in expanded string
  35. );
  36. szHelpLocation.ReleaseBuffer();
  37. // free the existing path, and copy in the new one
  38. if ( m_pszHelpFilePath )
  39. free((void*)m_pszHelpFilePath);
  40. m_pszHelpFilePath = _tcsdup(szHelpLocation);
  41. return bInit;
  42. }
  43. ////////////////////////////////////////////////////////////////////////////
  44. // CCertmapApp::ExitInstance - DLL termination
  45. // tjp: note that in 'CCertmapApp::InitInstance()' we add our help file to the
  46. // help path. do we need to remove it on clean up here?
  47. int CCertmapApp::ExitInstance()
  48. {
  49. CoUninitialize();
  50. return COleControlModule::ExitInstance();
  51. }
  52. /////////////////////////////////////////////////////////////////////////////
  53. // MigrateGUIDS - does all the GUID migration work. We pass back the
  54. // return value of True iff we find GUIDs in the registry and migrate
  55. // them to the metabase.
  56. //
  57. // We are called by top level fnct: InstallCertServerGUIDs that creates
  58. // our 'info' structure and handles all the metabase init work.
  59. /////////////////////////////////////////////////////////////////////////////
  60. // This code is written in response to bug # 167410.
  61. //
  62. // This fix will handle all the GUID migration work, moving GUIDS that
  63. // CertServer placed in the registry into the metabase for Beta2.
  64. // A more general install/deinstall mechanism for products that
  65. // work with IIS will be come post-Beta2.
  66. //
  67. // DETAILS:
  68. // --------
  69. //
  70. // We look for evidence of CertServer by examing the Registry because
  71. // CertServer will write some entries under:
  72. // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\KeyRing\Parameters\Certificate
  73. // Authorities\Microsoft Certificate Server
  74. //
  75. // CertServer currently outputs:
  76. // CertGetConfig "{C6CC49B0-CE17-11D0-8833-00A0C903B83C}"
  77. // CertRequest "{98AFF3F0-5524-11D0-8812-00A0C903B83C}"
  78. //
  79. // If we see the manditory 'CertRequest' entry, we will load as many strings
  80. // as we find, while defaulting the ones that are missing. See below
  81. // for the equivalent mdutil commands for what defaults are used
  82. //
  83. // => if we dont find 'CertRequest' we give up [meaning remove
  84. // any present MB GUID string entries]
  85. //
  86. // When we find that CertServer is installed, we dont fully believe that
  87. // certserver is still there. To prove that its there we will do a
  88. // CoCreateInstance on CertConfig. If that works we install metabase
  89. // entries that are the equivalent of the following mdutil commands:
  90. //
  91. // ## ICERTGETCONFIG default setting:
  92. // mdutil SET "w3svc/CertServers/Microsoft Certificate Server" -dtype:STRING -
  93. // -utype:UT_SERVER -prop 5571 -value "{C6CC49B0-CE17-11D0-8833-00A0C903B83C}"
  94. //
  95. // ## ICERTREQUEST default setting:
  96. // mdutil SET "w3svc/CertServers/Microsoft Certificate Server" -dtype:STRING
  97. // -utype:UT_SERVER -prop 5572 -value "{98AFF3F0-5524-11D0-8812-00A0C903B83C}"
  98. //
  99. // ## ICERTCONFIG default setting:
  100. // mdutil SET "w3svc/CertServers/Microsoft Certificate Server" -dtype:STRING
  101. // -utype:UT_SERVER -prop 5574 -value "{372fce38-4324-11d0-8810-00a0c903b83c}"
  102. //
  103. // If the CoCreateInstance fails, we give up and remove MB GUID entries.
  104. //
  105. // ---------------------------------------------------------------
  106. // NOTE that we will either install or DE-install the metabase
  107. // GUID strings based on its decision that CertServer is present.
  108. // If we find GUID strings in the metabase but can not do a
  109. // CoCreateInstance on CertConfig:
  110. // we remove them so that the rest of CertWizard will see CertServer
  111. // Guids iff we can use CertServer.
  112. // ---------------------------------------------------------------
  113. // NOTE also that if we make a decision to install GUID strings
  114. // into the metabase, we honor/preserve any present GUID strings that
  115. // are present in the metabase.
  116. // ---------------------------------------------------------------
  117. //
  118. /////////////////////////////////////////////////////////////////////////////
  119. /*ddddddddddddddd
  120. BOOL MigrateGUIDS( ADMIN_INFO& info )
  121. {
  122. BOOL bRet = FALSE; // value to return, set to F
  123. // for defensive reasons.
  124. BOOL bFoundCertSrvRegistryEntries = FALSE; // assume false for now
  125. TCHAR* szRegPath = _T("SOFTWARE\\Microsoft\\KeyRing\\Parameters\\Certificate Authorities\\Microsoft Certificate Server");
  126. //-----------------------------------------------------------------------
  127. // In each of the following 3 sets of parameters, we have (1) a string
  128. // like "CertRequest" that CertServer uses in the registry, (2) a default
  129. // value to use like "{98AFF3F0-5524-11D0-8812-00A0C903B83C}" that we
  130. // use if we can not find anything in the registry, and (3) a CString
  131. // to hold the GUID. The value in the CString will be stored in the MB.
  132. //-----------------------------------------------------------------------
  133. // CertRequest - variables
  134. TCHAR* szCertRequest = _T("CertRequest");
  135. TCHAR* szCertRequestGUIDdefault = _T( "{98AFF3F0-5524-11D0-8812-00A0C903B83C}" );
  136. CString szCertRequestGUID;
  137. // CertConfig - variables
  138. TCHAR* szCertConfig = _T("CertConfig");
  139. TCHAR* szCertConfigGUIDdefault = _T( "{372fce38-4324-11d0-8810-00a0c903b83c}" );
  140. CString szCertConfigGUID;
  141. // CertGetConfig - variables
  142. TCHAR* szCertGetConfig = _T("CertGetConfig");
  143. TCHAR* szCertGetConfigGUIDdefault = _T( "{C6CC49B0-CE17-11D0-8833-00A0C903B83C}");
  144. CString szCertGetConfigGUID;
  145. CString szCertServerMetabaseRoot( SZ_ROOT_CERT_SERV_MB_PATH );
  146. // SZ_ROOT_CERT_SERV_MB_PATH = "/LM/W3SVC/CertServers"
  147. szCertServerMetabaseRoot += _T("/Microsoft Certificate Server");
  148. #ifdef DEBUGGING
  149. CEditDialog dlg(szCertServerMetabaseRoot,
  150. _T("use this to test adding new CertServer entries."
  151. " In order for us to install a new key you have to change the path"
  152. " below to something [strange] and not already in the metabase."));
  153. dlg.DoModal();
  154. #endif
  155. // the following string will be restored into info.szMetaBasePath before
  156. // we exit this fnct. We switch out the [info.szMetaBasePath] so that
  157. // we can use our native Set/Get metabase string fncts.
  158. // We switch it to: "/LM/W3SVC/CertServers/Microsoft Certificate Server"
  159. //
  160. CString szSaved_info_szMetaBasePath( info.szMetaBasePath );
  161. info.szMetaBasePath = szCertServerMetabaseRoot;
  162. // if we dont find HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\KeyRing\Parameters\
  163. // Certificate Authorities\Microsoft Certificate Server"
  164. // with key: CertRequest quit! CertServer should have installed this.
  165. // We are forgiving about the other 2 Registry GUID strings
  166. //-------------------------------------------------------------------------
  167. if ( Reg::GetNameValueIn( szRegPath, szCertRequest,
  168. szCertRequestGUID, HKEY_LOCAL_MACHINE )) {
  169. bFoundCertSrvRegistryEntries = TRUE;
  170. }
  171. if (! Reg::GetNameValueIn( szRegPath, szCertConfig,
  172. szCertConfigGUID, HKEY_LOCAL_MACHINE )) {
  173. szCertConfigGUID = szCertConfigGUIDdefault; // assign default
  174. }
  175. if (! Reg::GetNameValueIn( szRegPath, szCertGetConfig,
  176. szCertGetConfigGUID, HKEY_LOCAL_MACHINE )) {
  177. szCertGetConfigGUID = szCertGetConfigGUIDdefault; // assign default
  178. }
  179. //------------------------------------------------------------------------
  180. // First lets try to create the directory path: the user might have
  181. // deleted it or this might be a virgin machine.
  182. //------------------------------------------------------------------------
  183. {
  184. CWrapMetaBase& MB = info.meta.m_mbWrap; // this is the MetaBase Wrapper
  185. // its already been openned by
  186. // openMetaDataForWrite
  187. if ( FALSE == openMetaDataForWrite(info, FALSE) ) {
  188. if (ERROR_PATH_NOT_FOUND == HRESULT_CODE( MB.getHRESULT() )) {
  189. // lets create the path in the metabase, using AddObject.
  190. // recursively creates a "pathway in the metabase". E.g. assume that you
  191. // want to make sure that "/LM/W3SVC/CertServers/Microsoft Certificate Server"
  192. // is in the metabase. you can open /LM/W3SVC and do a AddKey() on
  193. // "CertServers/Microsoft Certificate Server" to create that stub.
  194. // above we set: info.szMetaBasePath = szCertServerMetabaseRoot
  195. // here we will temporarily pretend that our root is at level
  196. // /LM/W3SVC which we assume is at the top of szCertServerMetabaseRoot
  197. // and then call AddKey
  198. TCHAR szPath[400];
  199. TCHAR* szRootPrefix = _T("/LM/W3SVC");
  200. UINT nRootPrefixLen = STRLEN(szRootPrefix);
  201. STRCPY(szPath, szCertServerMetabaseRoot);
  202. if (STRNICMP(szRootPrefix, szPath, nRootPrefixLen) != 0)
  203. goto returnFALSE; // we could not figure out a common Root
  204. info.szMetaBasePath = szRootPrefix;
  205. if ( FALSE == openMetaDataForWrite(info) )
  206. goto returnFALSE; // we could not open the metabase
  207. // the metabase path is already position to the proper directory
  208. // in the MB object. MB will prepend that path to the subDirectory
  209. // that we want to create, the following will jump past the trailing
  210. // '/' separating the root and the rest of the sub-directory
  211. // e.g. "/CertServers/Microsoft Certificate Server"
  212. //
  213. // We dont do any other error checking besides notifying and
  214. // returning FALSE.
  215. if (FALSE == MB.AddObject( &szPath[nRootPrefixLen] )) {
  216. NotifyUsers_CouldNotAccessMetaBase( MB.getHRESULT() );
  217. goto returnFALSE; // we could not create required path
  218. }
  219. // since we are continuing, we reset back our proper path.
  220. info.szMetaBasePath = szCertServerMetabaseRoot;
  221. } else {
  222. goto returnFALSE; // we could not open the metabase
  223. }
  224. }
  225. }
  226. //------------------------------------------------------------------------
  227. // Below we dont deal with the XENROLL GUID setting that is for future usage
  228. // PLUS its not CertServer Related, its Xenroll related. We dont touch it.
  229. //------------------------------------------------------------------------
  230. {
  231. // lets see if we can do a CoCreateInstance on CertRequest. If we can not
  232. // we believe that certServer is not installed and set/clear MB entries
  233. // The following values are set or cleared:
  234. //
  235. // # define MD_SSL_CERT_WIZGUID_ICERTGETCONFIG ( IIS_MD_SSL_BASE+71 )
  236. // # define MD_SSL_CERT_WIZGUID_ICERTREQUEST ( IIS_MD_SSL_BASE+72 )
  237. // # define MD_SSL_CERT_WIZGUID_XENROLL ( IIS_MD_SSL_BASE+73 ) FUTURE USAGE
  238. // # define MD_SSL_CERT_WIZGUID_ICERTCONFIG ( IIS_MD_SSL_BASE+74 )
  239. //------------------------------------------------------------------------
  240. IPtr<ICertConfig, &IID_ICertConfig> iptr;
  241. CString szRemoteDCOMTargetMachine;
  242. // REMEMBER bRet returns whether we were able to delete everything
  243. // or set everything that we were wanting to set
  244. // in both cases assume now that we have success and update bRet when
  245. // we find errors, we continue as long as possible. E.g. we add or delete
  246. // as many entries as possible and return our status value to the caller.
  247. bRet = TRUE;
  248. if ( (FALSE == bFoundCertSrvRegistryEntries) ||
  249. (FALSE == GetICertConfigIPtrFromGuid( iptr, szCertConfigGUID,
  250. &szRemoteDCOMTargetMachine)) )
  251. {
  252. // remove MB entries!
  253. #ifdef DEBUGGING
  254. DODBG MsgBox( _T("adding CertServer MB entries"));
  255. #endif
  256. if ( FALSE == openMetaDataForWrite(info) ) {
  257. goto returnFALSE; // we could not open the metabase
  258. }
  259. // We just need to blow away the cert info in the metabase
  260. // which we do using the meta data wrapper
  261. // deleting values
  262. CWrapMetaBase& MB = info.meta.m_mbWrap; // this is the MetaBase Wrapper
  263. // its already been openned by
  264. // openMetaDataForWrite
  265. // try deletes once
  266. // In C++ &&= does not exist. However [bRet &= FALSE;] is OK, but we dont
  267. // have a uniform single value of TRUE in C/C++ so its not safe to use &=
  268. // to chain a set of TRUE-value
  269. // so we can not do:
  270. // bRet &&= MB.DeleteData( _T(""),
  271. // MD_SSL_CERT_WIZGUID_ICERTGETCONFIG, STRING_METADATA);
  272. // so we will use a [if (! xxx) bRet=FALSE;] construct below
  273. if (! MB.DeleteData( _T(""),
  274. MD_SSL_CERT_WIZGUID_ICERTGETCONFIG, STRING_METADATA)) bRet=FALSE;
  275. if (! MB.DeleteData( _T(""),
  276. MD_SSL_CERT_WIZGUID_ICERTREQUEST, STRING_METADATA)) bRet=FALSE;
  277. if (! MB.DeleteData( _T(""),
  278. MD_SSL_CERT_WIZGUID_ICERTCONFIG, STRING_METADATA)) bRet=FALSE;
  279. MB.Close();
  280. } else {
  281. CString szPresentValue; // used to read the present value
  282. // any metabase value so that we
  283. // can preserve it.
  284. #ifdef DEBUGGING
  285. DODBG MsgBox( _T("adding CertServer MB entries"));
  286. #endif
  287. // add MB entries! If an entry already exists, leave it alone.
  288. if (! GetMetaBaseString ( info,
  289. IN MD_SSL_CERT_WIZGUID_ICERTREQUEST,
  290. IN szPresentValue ) )
  291. {
  292. if (!SetMetaBaseString ( info,
  293. IN MD_SSL_CERT_WIZGUID_ICERTREQUEST,
  294. IN szCertRequestGUID ) ) bRet=FALSE;
  295. }
  296. if (! GetMetaBaseString ( info,
  297. IN MD_SSL_CERT_WIZGUID_ICERTCONFIG,
  298. IN szPresentValue ) )
  299. {
  300. if (!SetMetaBaseString ( info,
  301. IN MD_SSL_CERT_WIZGUID_ICERTCONFIG,
  302. IN szCertConfigGUID ) ) bRet=FALSE;
  303. }
  304. if (! GetMetaBaseString ( info,
  305. IN MD_SSL_CERT_WIZGUID_ICERTGETCONFIG,
  306. IN szPresentValue ) )
  307. {
  308. if (!SetMetaBaseString ( info,
  309. IN MD_SSL_CERT_WIZGUID_ICERTGETCONFIG,
  310. IN szCertGetConfigGUID ) ) bRet=FALSE;
  311. }
  312. }
  313. }
  314. commonReturn: // this is the common return so that we an set
  315. // back the metabase path. We saved it so that
  316. // we can switch to where the GUIDs live:
  317. // the following will restore the original [info.szMetaBasePath] value
  318. // before we switched it to: "/LM/W3SVC/CertServers/..."
  319. //
  320. info.szMetaBasePath = szSaved_info_szMetaBasePath;
  321. return(bRet);
  322. returnFALSE: // this will cause a FALSE return and do all things
  323. // required in our "common return"
  324. bRet = FALSE;
  325. goto commonReturn;
  326. }
  327. */
  328. /////////////////////////////////////////////////////////////////////////////
  329. // DllRegisterServer - Adds entries to the system registry
  330. STDAPI DllRegisterServer(void)
  331. {
  332. AFX_MANAGE_STATE(_afxModuleAddrThis);
  333. if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
  334. return ResultFromScode(SELFREG_E_TYPELIB);
  335. if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
  336. return ResultFromScode(SELFREG_E_CLASS);
  337. return NOERROR;
  338. }
  339. /////////////////////////////////////////////////////////////////////////////
  340. // DllUnregisterServer - Removes entries from the system registry
  341. STDAPI DllUnregisterServer(void)
  342. {
  343. AFX_MANAGE_STATE(_afxModuleAddrThis);
  344. if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
  345. return ResultFromScode(SELFREG_E_TYPELIB);
  346. if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
  347. return ResultFromScode(SELFREG_E_CLASS);
  348. return NOERROR;
  349. }