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.

1161 lines
35 KiB

  1. /**********************************************************************/
  2. /** Microsoft Passport **/
  3. /** Copyright(c) Microsoft Corporation, 1999 - 2001 **/
  4. /**********************************************************************/
  5. /*
  6. RegistryConfig.cpp
  7. FILE HISTORY:
  8. */
  9. // RegistryConfig.cpp: implementation of the CRegistryConfig class.
  10. //
  11. //////////////////////////////////////////////////////////////////////
  12. #include "stdafx.h"
  13. #include "RegistryConfig.h"
  14. #include "KeyCrypto.h"
  15. #include "passport.h"
  16. #include "keyver.h"
  17. #include "dsysdbg.h"
  18. extern BOOL g_bRegistering;
  19. #define PASSPORT_KEY L"Software\\Microsoft\\Passport\\"
  20. #define PASSPORT_SITES_SUBKEY L"Sites"
  21. //===========================================================================
  22. //
  23. // Functions for verbose logging
  24. //
  25. // define for logging with dsysdbg.lib
  26. DEFINE_DEBUG2(Passport);
  27. DEBUG_KEY PassportDebugKeys[] = { {DEB_TRACE, "Trace"},
  28. {0, NULL}
  29. };
  30. BOOL g_fLoggingOn = FALSE;
  31. #define MAX_LOG_STRLEN 512
  32. void PassportLog(CHAR* Format, ...)
  33. {
  34. if (g_fLoggingOn)
  35. {
  36. if (NULL != Format) {
  37. SYSTEMTIME SysTime;
  38. CHAR rgch[MAX_LOG_STRLEN];
  39. int i, cch;
  40. // put the time at the front
  41. cch = sizeof(rgch) / sizeof(rgch[0]) - 1;
  42. GetSystemTime(&SysTime);
  43. i = GetDateFormatA (
  44. LOCALE_USER_DEFAULT, // locale for which date is to be formatted
  45. 0, // flags specifying function options
  46. &SysTime, // date to be formatted
  47. "ddd',' MMM dd yy ", // date format string
  48. rgch, // buffer for storing formatted string
  49. cch); // size of buffer
  50. if (i > 0)
  51. i--;
  52. i += GetTimeFormatA (
  53. LOCALE_USER_DEFAULT, // locale for which date is to be formatted
  54. 0, // flags specifying function options
  55. &SysTime, // date to be formatted
  56. "HH':'mm':'ss ", // time format string
  57. rgch + i, // buffer for storing formatted string
  58. cch - i); // size of buffer
  59. if (i > 0)
  60. i--;
  61. va_list ArgList; \
  62. va_start(ArgList, Format); \
  63. _vsnprintf(rgch + i, cch - i, Format, ArgList);
  64. rgch[MAX_LOG_STRLEN - 1] = '\0';
  65. PassportDebugPrint(DEB_TRACE, rgch);
  66. }
  67. }
  68. }
  69. //
  70. // This function opens the logging file. "%WINDIR%\system32\microsoftpassport\passport.log"
  71. //
  72. HANDLE OpenPassportLoggingFile()
  73. {
  74. WCHAR szLogPath[MAX_PATH + 13] = {0};
  75. UINT cchMax = sizeof(szLogPath) / sizeof(szLogPath[0]) - 1;
  76. UINT cch;
  77. HANDLE hLogFile = INVALID_HANDLE_VALUE;
  78. cch = GetWindowsDirectory(szLogPath, cchMax);
  79. if ((0 == cch) || (cch > cchMax))
  80. {
  81. goto Cleanup;
  82. }
  83. if (NULL == wcsncat(szLogPath, L"\\system32\\microsoftpassport\\passport.log", cchMax - cch))
  84. {
  85. goto Cleanup;
  86. }
  87. szLogPath[MAX_PATH] = L'\0';
  88. hLogFile = CreateFileW(szLogPath,
  89. GENERIC_READ | GENERIC_WRITE,
  90. FILE_SHARE_READ,
  91. NULL, //&sa,
  92. OPEN_ALWAYS,
  93. FILE_ATTRIBUTE_NORMAL,
  94. NULL);
  95. if (INVALID_HANDLE_VALUE != hLogFile)
  96. {
  97. SetFilePointer(hLogFile, 0, NULL, FILE_END);
  98. }
  99. Cleanup:
  100. return hLogFile;
  101. }
  102. //
  103. // This function checks if logging is supposed to be enabled and if it is then
  104. // it opens the log file and sets the appropriate global variables.
  105. // If logging is supposed to be off then the appropriate variables are also
  106. // changed to the correct values.
  107. //
  108. VOID CheckLogging(HKEY hPassport)
  109. {
  110. DWORD dwVerbose = 0;
  111. DWORD cb = sizeof(DWORD);
  112. HANDLE hLogFile = INVALID_HANDLE_VALUE;
  113. // first run off and get the reg value, if this call fails we simply assume no logging
  114. if (ERROR_SUCCESS == RegQueryValueExW(hPassport,
  115. L"Verbose",
  116. NULL,
  117. NULL,
  118. (LPBYTE)&dwVerbose,
  119. &cb))
  120. {
  121. // only start logging if it is off and only stop logging if it's already on
  122. if (!g_fLoggingOn && (0 != dwVerbose))
  123. {
  124. if (INVALID_HANDLE_VALUE != (hLogFile = OpenPassportLoggingFile()))
  125. {
  126. // set the logging file handle
  127. PassportSetLoggingFile(hLogFile);
  128. // set it to log to a file
  129. PassportSetLoggingOption(TRUE);
  130. g_fLoggingOn = TRUE;
  131. PassportLog("Start Logging\r\n");
  132. }
  133. }
  134. else if (g_fLoggingOn && (0 == dwVerbose))
  135. {
  136. PassportLog("Stop Logging\r\n");
  137. PassportSetLoggingOption(FALSE);
  138. g_fLoggingOn = FALSE;
  139. }
  140. }
  141. }
  142. void InitLogging()
  143. {
  144. //
  145. // Initialize the logging stuff
  146. //
  147. PassportInitDebug(PassportDebugKeys);
  148. PassportInfoLevel = DEB_TRACE;
  149. }
  150. void CloseLogging()
  151. {
  152. PassportUnloadDebug();
  153. }
  154. //////////////////////////////////////////////////////////////////////
  155. // Construction/Destruction
  156. //////////////////////////////////////////////////////////////////////
  157. using namespace ATL;
  158. //===========================================================================
  159. //
  160. // CRegistryConfig
  161. //
  162. CRegistryConfig::CRegistryConfig(
  163. LPSTR szSiteName
  164. ) :
  165. m_siteId(0), m_valid(FALSE), m_ticketPath(NULL), m_profilePath(NULL), m_securePath(NULL),
  166. m_hostName(NULL), m_hostIP(NULL), m_ticketDomain(NULL), m_profileDomain(NULL), m_secureDomain(NULL),
  167. m_disasterUrl(NULL), m_disasterMode(FALSE), m_forceLogin(FALSE), m_setCookies(TRUE),
  168. m_szReason(NULL), m_refs(0), m_coBrand(NULL), m_ru(NULL), m_ticketAge(1800), m_bInDA(FALSE),
  169. m_hkPassport(NULL), m_secureLevel(0),m_notUseHTTPOnly(0), m_pcrypts(NULL), m_pcryptValidTimes(NULL),
  170. m_KPP(-1),m_NameSpace(NULL),m_ExtraParams(NULL)
  171. {
  172. // Get site id, key from registry
  173. DWORD bufSize = sizeof(m_siteId);
  174. LONG lResult;
  175. HKEY hkSites = NULL;
  176. DWORD dwBufSize = 0, disMode;
  177. DWORD dwLCID;
  178. //
  179. // Record the current DLL state in case it changes
  180. // partway through this routine.
  181. //
  182. BOOL fRegistering = g_bRegistering;
  183. if(szSiteName)
  184. {
  185. lResult = RegOpenKeyEx(
  186. HKEY_LOCAL_MACHINE,
  187. PASSPORT_KEY PASSPORT_SITES_SUBKEY,
  188. 0,
  189. KEY_READ,
  190. &hkSites);
  191. if(lResult != ERROR_SUCCESS)
  192. {
  193. m_valid = FALSE;
  194. setReason(L"Invalid site name. Site not found.");
  195. goto Cleanup;
  196. }
  197. lResult = RegOpenKeyExA(
  198. hkSites,
  199. szSiteName,
  200. 0,
  201. KEY_READ,
  202. &m_hkPassport);
  203. if(lResult != ERROR_SUCCESS)
  204. {
  205. m_valid = FALSE;
  206. setReason(L"Invalid site name. Site not found.");
  207. goto Cleanup;
  208. }
  209. }
  210. else
  211. {
  212. lResult = RegOpenKeyEx(
  213. HKEY_LOCAL_MACHINE,
  214. PASSPORT_KEY,
  215. 0,
  216. KEY_READ,
  217. &m_hkPassport
  218. );
  219. if(lResult != ERROR_SUCCESS)
  220. {
  221. m_valid = FALSE;
  222. setReason(L"No RegKey HKLM\\SOFTWARE\\Microsoft\\Passport");
  223. goto Cleanup;
  224. }
  225. }
  226. // Get the current key
  227. bufSize = sizeof(m_currentKey);
  228. if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("CurrentKey"),
  229. NULL, NULL, (LPBYTE)&m_currentKey, &bufSize))
  230. {
  231. m_valid = FALSE;
  232. setReason(L"No CurrentKey defined in the registry.");
  233. goto Cleanup;
  234. }
  235. if(m_currentKey < KEY_VERSION_MIN || m_currentKey > KEY_VERSION_MAX)
  236. {
  237. m_valid = FALSE;
  238. setReason(L"Invalid CurrentKey value in the registry.");
  239. goto Cleanup;
  240. }
  241. // Get default LCID
  242. bufSize = sizeof(dwLCID);
  243. if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("LanguageID"),
  244. NULL, NULL, (LPBYTE)&dwLCID, &bufSize))
  245. {
  246. dwLCID = 0;
  247. }
  248. m_lcid = static_cast<short>(dwLCID & 0xFFFF);
  249. // Get disaster mode status
  250. bufSize = sizeof(disMode);
  251. if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("StandAlone"),
  252. NULL, NULL, (LPBYTE)&disMode, &bufSize))
  253. {
  254. m_disasterMode = FALSE;
  255. }
  256. else if (disMode != 0)
  257. {
  258. m_disasterMode = TRUE;
  259. }
  260. // Get the disaster URL
  261. if (m_disasterMode)
  262. {
  263. if (ERROR_SUCCESS == RegQueryValueEx(m_hkPassport,
  264. _T("DisasterURL"),
  265. NULL,
  266. NULL,
  267. NULL,
  268. &dwBufSize)
  269. &&
  270. dwBufSize > 1)
  271. {
  272. m_disasterUrl = new WCHAR[dwBufSize];
  273. if ((!m_disasterUrl)
  274. ||
  275. ERROR_SUCCESS != RegQueryValueEx(m_hkPassport,
  276. _T("DisasterURL"),
  277. NULL,
  278. NULL,
  279. (LPBYTE) m_disasterUrl,
  280. &dwBufSize))
  281. {
  282. m_valid = FALSE;
  283. setReason(L"Error reading DisasterURL from registry. (Query worked, but couldn't retrieve data)");
  284. goto Cleanup;
  285. }
  286. }
  287. else
  288. {
  289. m_valid = FALSE;
  290. setReason(L"DisasterURL missing from registry.");
  291. goto Cleanup;
  292. }
  293. }
  294. //
  295. // This function wraps the allocations of the crypt objects in a try/except
  296. // since the objects themselves do a poor job in low memory conditions
  297. //
  298. try
  299. {
  300. m_pcrypts = new INT2CRYPT;
  301. m_pcryptValidTimes = new INT2TIME;
  302. }
  303. catch(...)
  304. {
  305. m_valid = FALSE;
  306. setReason(L"Out of memory.");
  307. goto Cleanup;
  308. }
  309. if (!m_pcrypts || !m_pcryptValidTimes)
  310. {
  311. m_valid = FALSE;
  312. setReason(L"Out of memory.");
  313. goto Cleanup;
  314. }
  315. m_valid = readCryptoKeys(m_hkPassport);
  316. if (!m_valid)
  317. {
  318. if (!m_szReason)
  319. setReason(L"Error reading Passport crypto keys from registry.");
  320. goto Cleanup;
  321. }
  322. if (m_pcrypts->count(m_currentKey) == 0)
  323. {
  324. m_valid = FALSE;
  325. if (!m_szReason)
  326. setReason(L"Error reading Passport crypto keys from registry.");
  327. goto Cleanup;
  328. }
  329. // Get the optional default cobrand
  330. if (ERROR_SUCCESS == RegQueryValueExW(m_hkPassport, L"CoBrandTemplate",
  331. NULL, NULL, NULL, &dwBufSize))
  332. {
  333. if (dwBufSize > 2)
  334. {
  335. m_coBrand = (WCHAR*) new char[dwBufSize];
  336. if (!m_coBrand
  337. ||
  338. ERROR_SUCCESS != RegQueryValueExW(m_hkPassport, L"CoBrandTemplate",
  339. NULL, NULL,
  340. (LPBYTE) m_coBrand, &dwBufSize))
  341. {
  342. m_valid = FALSE;
  343. setReason(L"Error reading CoBrand from registry. (Query worked, but couldn't retrieve data)");
  344. goto Cleanup;
  345. }
  346. }
  347. }
  348. // Get the optional default return URL
  349. if (ERROR_SUCCESS == RegQueryValueExW(m_hkPassport, L"ReturnURL",
  350. NULL, NULL, NULL, &dwBufSize))
  351. {
  352. if (dwBufSize > 2)
  353. {
  354. m_ru = (WCHAR*) new char[dwBufSize];
  355. if (!m_ru
  356. ||
  357. ERROR_SUCCESS != RegQueryValueExW(m_hkPassport, L"ReturnURL",
  358. NULL, NULL,
  359. (LPBYTE) m_ru, &dwBufSize))
  360. {
  361. m_valid = FALSE;
  362. setReason(L"Error reading ReturnURL from registry. (Query worked, but couldn't retrieve data)");
  363. goto Cleanup;
  364. }
  365. }
  366. }
  367. // Get the host name
  368. if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "HostName",
  369. NULL, NULL, NULL, &dwBufSize))
  370. {
  371. if (dwBufSize > 1)
  372. {
  373. m_hostName = new char[dwBufSize];
  374. if (m_hostName == NULL
  375. ||
  376. ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "HostName",
  377. NULL, NULL,
  378. (LPBYTE) m_hostName, &dwBufSize))
  379. {
  380. m_valid = FALSE;
  381. setReason(L"Error reading HostName from registry. (Query worked, but couldn't retrieve data)");
  382. goto Cleanup;
  383. }
  384. }
  385. }
  386. // Get the host ip
  387. if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "HostIP",
  388. NULL, NULL, NULL, &dwBufSize))
  389. {
  390. if (dwBufSize > 1)
  391. {
  392. m_hostIP = new char[dwBufSize];
  393. if (!m_hostIP
  394. ||
  395. ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "HostIP",
  396. NULL, NULL,
  397. (LPBYTE) m_hostIP, &dwBufSize))
  398. {
  399. m_valid = FALSE;
  400. setReason(L"Error reading HostIP from registry. (Query worked, but couldn't retrieve data)");
  401. goto Cleanup;
  402. }
  403. }
  404. }
  405. // Get the optional domain to set ticket cookies into
  406. if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "TicketDomain",
  407. NULL, NULL, NULL, &dwBufSize))
  408. {
  409. if (dwBufSize > 1)
  410. {
  411. m_ticketDomain = new char[dwBufSize];
  412. if (!m_ticketDomain
  413. ||
  414. ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "TicketDomain",
  415. NULL, NULL,
  416. (LPBYTE) m_ticketDomain, &dwBufSize))
  417. {
  418. m_valid = FALSE;
  419. setReason(L"Error reading TicketDomain from registry. (Query worked, but couldn't retrieve data)");
  420. goto Cleanup;
  421. }
  422. }
  423. }
  424. // Get the optional domain to set profile cookies into
  425. if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "ProfileDomain",
  426. NULL, NULL, NULL, &dwBufSize))
  427. {
  428. if (dwBufSize > 1)
  429. {
  430. m_profileDomain = new char[dwBufSize];
  431. if (!m_profileDomain
  432. ||
  433. ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "ProfileDomain",
  434. NULL, NULL,
  435. (LPBYTE) m_profileDomain, &dwBufSize))
  436. {
  437. m_valid = FALSE;
  438. setReason(L"Error reading ProfileDomain from registry. (Query worked, but couldn't retrieve data)");
  439. goto Cleanup;
  440. }
  441. }
  442. }
  443. // Get the optional domain to set secure cookies into
  444. if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "SecureDomain",
  445. NULL, NULL, NULL, &dwBufSize))
  446. {
  447. if (dwBufSize > 1)
  448. {
  449. m_secureDomain = new char[dwBufSize];
  450. if (!m_secureDomain
  451. ||
  452. ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "SecureDomain",
  453. NULL, NULL,
  454. (LPBYTE) m_secureDomain, &dwBufSize))
  455. {
  456. m_valid = FALSE;
  457. setReason(L"Error reading SecureDomain from registry. (Query worked, but couldn't retrieve data)");
  458. goto Cleanup;
  459. }
  460. }
  461. }
  462. // Get the optional path to set ticket cookies into
  463. if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "TicketPath",
  464. NULL, NULL, NULL, &dwBufSize))
  465. {
  466. if (dwBufSize > 1)
  467. {
  468. m_ticketPath = new char[dwBufSize];
  469. if (!m_ticketPath
  470. ||
  471. ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "TicketPath",
  472. NULL, NULL,
  473. (LPBYTE) m_ticketPath, &dwBufSize))
  474. {
  475. m_valid = FALSE;
  476. setReason(L"Error reading TicketPath from registry. (Query worked, but couldn't retrieve data)");
  477. goto Cleanup;
  478. }
  479. }
  480. }
  481. // Get the optional path to set profile cookies into
  482. if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "ProfilePath",
  483. NULL, NULL, NULL, &dwBufSize))
  484. {
  485. if (dwBufSize > 1)
  486. {
  487. m_profilePath = new char[dwBufSize];
  488. if (!m_profilePath
  489. ||
  490. ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "ProfilePath",
  491. NULL, NULL,
  492. (LPBYTE) m_profilePath, &dwBufSize))
  493. {
  494. m_valid = FALSE;
  495. setReason(L"Error reading ProfilePath from registry. (Query worked, but couldn't retrieve data)");
  496. goto Cleanup;
  497. }
  498. }
  499. }
  500. // Get the optional path to set secure cookies into
  501. if (ERROR_SUCCESS == RegQueryValueExA(m_hkPassport, "SecurePath",
  502. NULL, NULL, NULL, &dwBufSize))
  503. {
  504. if (dwBufSize > 1)
  505. {
  506. m_securePath = new char[dwBufSize];
  507. if (!m_securePath
  508. ||
  509. ERROR_SUCCESS != RegQueryValueExA(m_hkPassport, "SecurePath",
  510. NULL, NULL,
  511. (LPBYTE) m_securePath, &dwBufSize))
  512. {
  513. m_valid = FALSE;
  514. setReason(L"Error reading SecurePath from registry. (Query worked, but couldn't retrieve data)");
  515. goto Cleanup;
  516. }
  517. }
  518. }
  519. bufSize = sizeof(m_siteId);
  520. // Now get the site id
  521. if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("SiteId"),
  522. NULL, NULL, (LPBYTE)&m_siteId, &bufSize))
  523. {
  524. m_valid = FALSE;
  525. setReason(L"No SiteId specified in registry");
  526. goto Cleanup;
  527. }
  528. // And the default ticket time window
  529. if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("TimeWindow"),
  530. NULL, NULL, (LPBYTE)&m_ticketAge, &bufSize))
  531. {
  532. m_ticketAge = 1800;
  533. }
  534. bufSize = sizeof(DWORD);
  535. DWORD forced;
  536. if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("ForceSignIn"),
  537. NULL, NULL, (LPBYTE)&forced, &bufSize))
  538. {
  539. m_forceLogin = FALSE;
  540. }
  541. else
  542. {
  543. m_forceLogin = forced == 0 ? FALSE : TRUE;
  544. }
  545. bufSize = sizeof(DWORD);
  546. DWORD noSetCookies;
  547. if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("DisableCookies"),
  548. NULL, NULL, (LPBYTE)&noSetCookies, &bufSize))
  549. {
  550. m_setCookies = TRUE;
  551. }
  552. else
  553. {
  554. m_setCookies = !noSetCookies;
  555. }
  556. bufSize = sizeof(DWORD);
  557. DWORD dwInDA;
  558. if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("InDA"),
  559. NULL, NULL, (LPBYTE)&dwInDA, &bufSize))
  560. {
  561. m_bInDA = FALSE;
  562. }
  563. else
  564. {
  565. m_bInDA = (dwInDA != 0);
  566. }
  567. bufSize = sizeof(m_secureLevel);
  568. // Now get the site id
  569. if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("SecureLevel"),
  570. NULL, NULL, (LPBYTE)&m_secureLevel, &bufSize))
  571. {
  572. m_secureLevel = 0;
  573. }
  574. bufSize = sizeof(m_notUseHTTPOnly);
  575. // Now get the NotUseHTTPOnly
  576. if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("NotUseHTTPOnly"),
  577. NULL, NULL, (LPBYTE)&m_notUseHTTPOnly, &bufSize))
  578. {
  579. m_notUseHTTPOnly = 0;
  580. }
  581. // Get the KPP value
  582. bufSize = sizeof(m_KPP);
  583. if (ERROR_SUCCESS != RegQueryValueEx(m_hkPassport, _T("KPP"),
  584. NULL, NULL, (LPBYTE)&m_KPP, &bufSize))
  585. {
  586. m_KPP = -1;
  587. }
  588. // Get the optional namespace
  589. if (ERROR_SUCCESS == RegQueryValueExW(m_hkPassport, L"NameSpace",
  590. NULL, NULL, NULL, &dwBufSize))
  591. {
  592. if (dwBufSize > 2)
  593. {
  594. m_NameSpace = (WCHAR*) new char[dwBufSize];
  595. if (!m_NameSpace
  596. ||
  597. ERROR_SUCCESS != RegQueryValueExW(m_hkPassport, L"NameSpace",
  598. NULL, NULL,
  599. (LPBYTE) m_NameSpace, &dwBufSize))
  600. {
  601. m_valid = FALSE;
  602. setReason(L"Error reading NameSpace from registry.");
  603. goto Cleanup;
  604. }
  605. }
  606. }
  607. // Get the optional extra parameters
  608. if (ERROR_SUCCESS == RegQueryValueExW(m_hkPassport, L"ExtraParams",
  609. NULL, NULL, NULL, &dwBufSize))
  610. {
  611. if (dwBufSize > 2)
  612. {
  613. m_ExtraParams = (WCHAR*) new char[dwBufSize];
  614. if (!m_ExtraParams
  615. ||
  616. ERROR_SUCCESS != RegQueryValueExW(m_hkPassport, L"ExtraParams",
  617. NULL, NULL,
  618. (LPBYTE) m_ExtraParams, &dwBufSize))
  619. {
  620. m_valid = FALSE;
  621. setReason(L"Error reading ExtraParams from registry.");
  622. goto Cleanup;
  623. }
  624. }
  625. }
  626. //
  627. // Check for the verbose flag in the registry and do the appropriate stuff to either
  628. // turn logging on or off.
  629. //
  630. // Only check if this is the default site.
  631. //
  632. if (!szSiteName)
  633. {
  634. CheckLogging(m_hkPassport);
  635. }
  636. m_szReason = NULL;
  637. m_valid = TRUE;
  638. Cleanup:
  639. if ( NULL != hkSites )
  640. {
  641. RegCloseKey(hkSites);
  642. }
  643. if (m_valid == FALSE && !fRegistering)
  644. {
  645. g_pAlert->report(PassportAlertInterface::ERROR_TYPE,
  646. PM_INVALID_CONFIGURATION, m_szReason);
  647. }
  648. return;
  649. }
  650. //===========================================================================
  651. //
  652. // ~CRegistryConfig
  653. //
  654. CRegistryConfig::~CRegistryConfig()
  655. {
  656. if (m_pcrypts)
  657. {
  658. if (!m_pcrypts->empty())
  659. {
  660. INT2CRYPT::iterator itb = m_pcrypts->begin();
  661. for (; itb != m_pcrypts->end(); itb++)
  662. {
  663. delete itb->second;
  664. }
  665. m_pcrypts->clear();
  666. }
  667. delete m_pcrypts;
  668. }
  669. // may be a leak that we don't iterate through and delete the elements
  670. if (m_pcryptValidTimes)
  671. {
  672. delete m_pcryptValidTimes;
  673. }
  674. if (m_szReason)
  675. SysFreeString(m_szReason);
  676. if (m_ticketDomain)
  677. delete[] m_ticketDomain;
  678. if (m_profileDomain)
  679. delete[] m_profileDomain;
  680. if (m_secureDomain)
  681. delete[] m_secureDomain;
  682. if (m_ticketPath)
  683. delete[] m_ticketPath;
  684. if (m_profilePath)
  685. delete[] m_profilePath;
  686. if (m_securePath)
  687. delete[] m_securePath;
  688. if (m_disasterUrl)
  689. delete[] m_disasterUrl;
  690. if (m_coBrand)
  691. delete[] m_coBrand;
  692. if (m_hostName)
  693. delete[] m_hostName;
  694. if (m_hostIP)
  695. delete[] m_hostIP;
  696. if (m_ru)
  697. delete[] m_ru;
  698. if (m_NameSpace)
  699. delete[] m_NameSpace;
  700. if (m_ExtraParams)
  701. delete[] m_ExtraParams;
  702. if (m_hkPassport != NULL)
  703. {
  704. RegCloseKey(m_hkPassport);
  705. }
  706. }
  707. //===========================================================================
  708. //
  709. // GetCurrentConfig
  710. //
  711. #define __MAX_STRING_LENGTH__ 1024
  712. HRESULT CRegistryConfig::GetCurrentConfig(LPCWSTR name, VARIANT* pVal)
  713. {
  714. if(m_hkPassport == NULL || !m_valid)
  715. {
  716. AtlReportError(CLSID_Profile, PP_E_SITE_NOT_EXISTSSTR,
  717. IID_IPassportProfile, PP_E_SITE_NOT_EXISTS);
  718. return PP_E_SITE_NOT_EXISTS;
  719. }
  720. if(!name || !pVal) return E_INVALIDARG;
  721. HRESULT hr = S_OK;
  722. BYTE *pBuf = NULL;
  723. ATL::CComVariant v;
  724. BYTE dataBuf[__MAX_STRING_LENGTH__];
  725. DWORD bufLen = sizeof(dataBuf);
  726. BYTE *pData = dataBuf;
  727. DWORD dwErr = ERROR_SUCCESS;
  728. DWORD dataType = 0;
  729. dwErr = RegQueryValueEx(m_hkPassport, name, NULL, &dataType, (LPBYTE)pData, &bufLen);
  730. if (dwErr == ERROR_MORE_DATA)
  731. {
  732. pBuf = (PBYTE)malloc(bufLen);
  733. if (!pBuf)
  734. {
  735. hr = E_OUTOFMEMORY;
  736. goto Exit;
  737. }
  738. pData = pBuf;
  739. dwErr = RegQueryValueEx(m_hkPassport, name, NULL, &dataType, (LPBYTE)pData, &bufLen);
  740. }
  741. if (dwErr != ERROR_SUCCESS)
  742. {
  743. hr = PP_E_NO_ATTRIBUTE;
  744. AtlReportError(CLSID_Manager, PP_E_NO_ATTRIBUTESTR,
  745. IID_IPassportManager3, PP_E_NO_ATTRIBUTE);
  746. }
  747. else
  748. {
  749. switch(dataType)
  750. {
  751. case REG_DWORD:
  752. case REG_DWORD_BIG_ENDIAN:
  753. {
  754. DWORD* pdw = (DWORD*)pData;
  755. v = (long)*pdw;
  756. }
  757. break;
  758. case REG_SZ:
  759. case REG_EXPAND_SZ:
  760. {
  761. LPCWSTR pch = (LPCWSTR)pData;
  762. v = (LPCWSTR)pch;
  763. }
  764. break;
  765. default:
  766. AtlReportError(CLSID_Manager, PP_E_TYPE_NOT_SUPPORTEDSTR,
  767. IID_IPassportManager, PP_E_TYPE_NOT_SUPPORTED);
  768. hr = PP_E_TYPE_NOT_SUPPORTED;
  769. break;
  770. }
  771. }
  772. Exit:
  773. if(pBuf)
  774. free(pBuf);
  775. if (hr == S_OK)
  776. hr = v.Detach(pVal);
  777. return hr;
  778. }
  779. #define MAX_ENCKEYSIZE 1024
  780. //===========================================================================
  781. //
  782. // readCryptoKeys
  783. //
  784. BOOL CRegistryConfig::readCryptoKeys(
  785. HKEY hkPassport
  786. )
  787. {
  788. LONG lResult;
  789. BOOL retVal = FALSE;
  790. HKEY hkDataKey = NULL, hkTimeKey = NULL;
  791. DWORD iterIndex = 0, keySize, keyTime, keyNumSize;
  792. BYTE encKeyBuf[MAX_ENCKEYSIZE];
  793. int kNum;
  794. TCHAR szKeyNum[4];
  795. CKeyCrypto kc;
  796. int foundKeys = 0;
  797. HANDLE hToken = NULL;
  798. if (OpenThreadToken(GetCurrentThread(),
  799. MAXIMUM_ALLOWED,
  800. TRUE,
  801. &hToken))
  802. {
  803. if (FALSE == RevertToSelf())
  804. {
  805. setReason(L"Unable to revert to self");
  806. goto Cleanup;
  807. }
  808. }
  809. // Open both the keydata and keytimes key,
  810. // if there's no keytimes key, we'll assume all keys are valid forever,
  811. // or more importantly, we won't break if that key isn't there
  812. lResult = RegOpenKeyEx(hkPassport, TEXT("KeyData"), 0,
  813. KEY_READ, &hkDataKey);
  814. if(lResult != ERROR_SUCCESS)
  815. {
  816. setReason(L"No Valid Crypto Keys");
  817. goto Cleanup;
  818. }
  819. RegOpenKeyEx(hkPassport, TEXT("KeyTimes"), 0,
  820. KEY_READ, &hkTimeKey);
  821. // Ok, now enumerate the KeyData keys and create crypt objects
  822. while (1)
  823. {
  824. keySize = sizeof(encKeyBuf);
  825. keyNumSize = sizeof(szKeyNum) >> (sizeof(TCHAR) - 1);
  826. lResult = RegEnumValue(hkDataKey, iterIndex++, szKeyNum,
  827. &keyNumSize, NULL, NULL, (LPBYTE)&(encKeyBuf[0]), &keySize);
  828. if (lResult != ERROR_SUCCESS)
  829. {
  830. break;
  831. }
  832. kNum = KeyVerC2I(szKeyNum[0]);
  833. if (kNum > 0)
  834. {
  835. DATA_BLOB iBlob;
  836. DATA_BLOB oBlob = {0};
  837. iBlob.cbData = keySize;
  838. iBlob.pbData = (LPBYTE)&(encKeyBuf[0]);
  839. if(kc.decryptKey(&iBlob, &oBlob) != S_OK)
  840. {
  841. g_pAlert->report(PassportAlertInterface::ERROR_TYPE,
  842. PM_CANT_DECRYPT_CONFIG);
  843. break;
  844. }
  845. else
  846. {
  847. // Now set up a crypt object
  848. CCoCrypt* cr = new CCoCrypt();
  849. if (NULL == cr)
  850. {
  851. if(oBlob.pbData)
  852. {
  853. RtlSecureZeroMemory(oBlob.pbData, oBlob.cbData);
  854. ::LocalFree(oBlob.pbData);
  855. ZeroMemory(&oBlob, sizeof(oBlob));
  856. }
  857. setReason(L"Out of memory");
  858. goto Cleanup;
  859. }
  860. BSTR km = ::SysAllocStringByteLen((LPSTR)oBlob.pbData, oBlob.cbData);
  861. if (NULL == km)
  862. {
  863. if(oBlob.pbData)
  864. {
  865. RtlSecureZeroMemory(oBlob.pbData, oBlob.cbData);
  866. ::LocalFree(oBlob.pbData);
  867. ZeroMemory(&oBlob, sizeof(oBlob));
  868. }
  869. delete cr;
  870. setReason(L"Out of memory");
  871. goto Cleanup;
  872. }
  873. cr->setKeyMaterial(km);
  874. ::SysFreeString(km);
  875. if(oBlob.pbData)
  876. {
  877. RtlSecureZeroMemory(oBlob.pbData, oBlob.cbData);
  878. ::LocalFree(oBlob.pbData);
  879. ZeroMemory(&oBlob, sizeof(oBlob));
  880. }
  881. // Add it to the bucket...
  882. // wrap the STL calls since in low memory conditions they can AV
  883. try
  884. {
  885. INT2CRYPT::value_type pMapVal(kNum, cr);
  886. m_pcrypts->insert(pMapVal);
  887. }
  888. catch(...)
  889. {
  890. setReason(L"Out of memory");
  891. goto Cleanup;
  892. }
  893. foundKeys++;
  894. keySize = sizeof(DWORD);
  895. if (RegQueryValueEx(hkTimeKey, szKeyNum, NULL,NULL,(LPBYTE)&keyTime,&keySize) ==
  896. ERROR_SUCCESS && (m_currentKey != kNum))
  897. {
  898. // wrap the STL calls since in low memory conditions they can AV
  899. try
  900. {
  901. INT2TIME::value_type pTimeVal(kNum, keyTime);
  902. m_pcryptValidTimes->insert(pTimeVal);
  903. }
  904. catch(...)
  905. {
  906. setReason(L"Out of memory");
  907. goto Cleanup;
  908. }
  909. }
  910. }
  911. }
  912. if (iterIndex > 100) // Safety latch
  913. goto Cleanup;
  914. }
  915. retVal = foundKeys > 0 ? TRUE : FALSE;
  916. Cleanup:
  917. if (hToken)
  918. {
  919. // put the impersonation token back
  920. if (!SetThreadToken(NULL, hToken))
  921. {
  922. setReason(L"Unable to set thread token");
  923. retVal = FALSE;
  924. }
  925. CloseHandle(hToken);
  926. }
  927. if (hkDataKey)
  928. RegCloseKey(hkDataKey);
  929. if (hkTimeKey)
  930. RegCloseKey(hkTimeKey);
  931. return retVal;
  932. }
  933. //===========================================================================
  934. //
  935. // getCrypt
  936. //
  937. CCoCrypt* CRegistryConfig::getCrypt(int keyNum, time_t* validUntil)
  938. {
  939. if (validUntil) // If they asked for the validUntil information
  940. {
  941. INT2TIME::const_iterator timeIt = m_pcryptValidTimes->find(keyNum);
  942. if (timeIt == m_pcryptValidTimes->end())
  943. *validUntil = 0;
  944. else
  945. *validUntil = (*timeIt).second;
  946. }
  947. // Now look up the actual crypt object
  948. INT2CRYPT::const_iterator it = m_pcrypts->find(keyNum);
  949. if (it == m_pcrypts->end())
  950. return NULL;
  951. return (*it).second;
  952. }
  953. //===========================================================================
  954. //
  955. // getFailureString
  956. //
  957. BSTR CRegistryConfig::getFailureString()
  958. {
  959. if (m_valid)
  960. return NULL;
  961. return m_szReason;
  962. }
  963. //===========================================================================
  964. //
  965. // setReason
  966. //
  967. void CRegistryConfig::setReason(LPTSTR reason)
  968. {
  969. if (m_szReason)
  970. SysFreeString(m_szReason);
  971. m_szReason = SysAllocString(reason);
  972. }
  973. //===========================================================================
  974. //
  975. // AddRef
  976. //
  977. CRegistryConfig* CRegistryConfig::AddRef()
  978. {
  979. InterlockedIncrement(&m_refs);
  980. return this;
  981. }
  982. //===========================================================================
  983. //
  984. // Release
  985. //
  986. void CRegistryConfig::Release()
  987. {
  988. long refs = InterlockedDecrement(&m_refs);
  989. if (refs == 0)
  990. delete this;
  991. }
  992. //===========================================================================
  993. //
  994. // GetHostName
  995. //
  996. long
  997. CRegistryConfig::GetHostName(
  998. LPSTR szSiteName,
  999. LPSTR szHostName,
  1000. LPDWORD lpdwHostNameBufLen
  1001. )
  1002. {
  1003. long lResult;
  1004. HKEY hkSites = NULL;
  1005. HKEY hkPassport = NULL;
  1006. if(!szSiteName || szSiteName[0] == '\0')
  1007. {
  1008. lResult = E_UNEXPECTED;
  1009. goto Cleanup;
  1010. }
  1011. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1012. PASSPORT_KEY PASSPORT_SITES_SUBKEY,
  1013. 0,
  1014. KEY_READ,
  1015. &hkSites
  1016. );
  1017. if(lResult != ERROR_SUCCESS)
  1018. goto Cleanup;
  1019. lResult = RegOpenKeyExA(hkSites,
  1020. szSiteName,
  1021. 0,
  1022. KEY_READ,
  1023. &hkPassport
  1024. );
  1025. if(lResult != ERROR_SUCCESS)
  1026. goto Cleanup;
  1027. lResult = RegQueryValueExA(hkPassport,
  1028. "HostName",
  1029. NULL,
  1030. NULL,
  1031. (LPBYTE)szHostName,
  1032. lpdwHostNameBufLen
  1033. );
  1034. Cleanup:
  1035. if(hkSites != NULL)
  1036. RegCloseKey(hkSites);
  1037. if(hkPassport != NULL)
  1038. RegCloseKey(hkPassport);
  1039. return lResult;
  1040. }