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.

1564 lines
42 KiB

  1. /**********************************************************************/
  2. /** Microsoft Passport **/
  3. /** Copyright(c) Microsoft Corporation, 1999 - 2001 **/
  4. /**********************************************************************/
  5. /*
  6. fastauth.cpp
  7. COM object for fast auth interface
  8. FILE HISTORY:
  9. */
  10. // FastAuth.cpp : Implementation of CFastAuth
  11. #include "stdafx.h"
  12. #include <time.h>
  13. #include <httpfilt.h>
  14. #include <httpext.h>
  15. #include "Passport.h"
  16. #include "FastAuth.h"
  17. #include "Ticket.h"
  18. #include "Profile.h"
  19. #include "VariantUtils.h"
  20. #include "PMErrorCodes.h"
  21. #include "HelperFuncs.h"
  22. #define DIMENSION(a) (sizeof(a) / sizeof(a[0]))
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CFastAuth
  25. //===========================================================================
  26. //
  27. // InterfaceSupportsErrorInfo
  28. //
  29. STDMETHODIMP CFastAuth::InterfaceSupportsErrorInfo(REFIID riid)
  30. {
  31. static const IID* arr[] =
  32. {
  33. &IID_IPassportFastAuth,
  34. &IID_IPassportFastAuth2,
  35. };
  36. for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
  37. {
  38. if (InlineIsEqualGUID(*arr[i],riid))
  39. return S_OK;
  40. }
  41. return S_FALSE;
  42. }
  43. //===========================================================================
  44. //
  45. // LogoTag
  46. //
  47. //
  48. // old API. href to login
  49. //
  50. STDMETHODIMP
  51. CFastAuth::LogoTag(
  52. BSTR bstrTicket,
  53. BSTR bstrProfile,
  54. VARIANT vRU,
  55. VARIANT vTimeWindow,
  56. VARIANT vForceLogin,
  57. VARIANT vCoBrand,
  58. VARIANT vLCID,
  59. VARIANT vSecure,
  60. VARIANT vLogoutURL,
  61. VARIANT vSiteName,
  62. VARIANT vNameSpace,
  63. VARIANT vKPP,
  64. VARIANT vUseSecureAuth,
  65. BSTR* pbstrLogoTag
  66. )
  67. {
  68. return CommonLogoTag(bstrTicket,
  69. bstrProfile,
  70. vRU,
  71. vTimeWindow,
  72. vForceLogin,
  73. vCoBrand,
  74. vLCID,
  75. vSecure,
  76. vLogoutURL,
  77. vSiteName,
  78. vNameSpace,
  79. vKPP,
  80. vUseSecureAuth,
  81. FALSE,
  82. pbstrLogoTag);
  83. }
  84. //===========================================================================
  85. //
  86. // LogoTag2
  87. //
  88. //
  89. // new API. href back to partner
  90. //
  91. STDMETHODIMP
  92. CFastAuth::LogoTag2(
  93. BSTR bstrTicket,
  94. BSTR bstrProfile,
  95. VARIANT vRU,
  96. VARIANT vTimeWindow,
  97. VARIANT vForceLogin,
  98. VARIANT vCoBrand,
  99. VARIANT vLCID,
  100. VARIANT vSecure,
  101. VARIANT vLogoutURL,
  102. VARIANT vSiteName,
  103. VARIANT vNameSpace,
  104. VARIANT vKPP,
  105. VARIANT vUseSecureAuth,
  106. BSTR* pbstrLogoTag
  107. )
  108. {
  109. return CommonLogoTag(bstrTicket,
  110. bstrProfile,
  111. vRU,
  112. vTimeWindow,
  113. vForceLogin,
  114. vCoBrand,
  115. vLCID,
  116. vSecure,
  117. vLogoutURL,
  118. vSiteName,
  119. vNameSpace,
  120. vKPP,
  121. vUseSecureAuth,
  122. TRUE,
  123. pbstrLogoTag);
  124. }
  125. //===========================================================================
  126. //
  127. // CommonLogoTag
  128. //
  129. //
  130. // logotag impl
  131. //
  132. STDMETHODIMP
  133. CFastAuth::CommonLogoTag(
  134. BSTR bstrTicket,
  135. BSTR bstrProfile,
  136. VARIANT vRU,
  137. VARIANT vTimeWindow,
  138. VARIANT vForceLogin,
  139. VARIANT vCoBrand,
  140. VARIANT vLCID,
  141. VARIANT vSecure,
  142. VARIANT vLogoutURL,
  143. VARIANT vSiteName,
  144. VARIANT vNameSpace,
  145. VARIANT vKPP,
  146. VARIANT vUseSecureAuth,
  147. BOOL fRedirToSelf,
  148. BSTR* pbstrLogoTag
  149. )
  150. {
  151. HRESULT hr;
  152. CComObject<CTicket> *pTicket = NULL;
  153. CComObject<CProfile> *pProfile = NULL;
  154. time_t ct;
  155. ULONG TimeWindow;
  156. int nKPP;
  157. VARIANT_BOOL ForceLogin, bSecure = VARIANT_FALSE;
  158. ULONG ulSecureLevel = 0;
  159. BSTR CBT = NULL, returnUrl = NULL, bstrSiteName = NULL, bstrNameSpace = NULL;
  160. int hasCB = -1, hasRU = -1, hasLCID, hasTW, hasFL, hasSec, hasSiteName, hasNameSpace = -1, hasUseSec;
  161. int hasKPP = -1;
  162. USHORT Lang;
  163. CNexusConfig* cnc = NULL;
  164. CRegistryConfig* crc = NULL;
  165. VARIANT_BOOL bTicketValid,bProfileValid;
  166. LPSTR szSiteName;
  167. VARIANT vFalse;
  168. USES_CONVERSION;
  169. PassportLog("CFastAuth::CommonLogoTag Enter:\r\n");
  170. if (NULL != bstrTicket)
  171. {
  172. PassportLog(" %ws\r\n", bstrTicket);
  173. }
  174. if (NULL != bstrProfile)
  175. {
  176. PassportLog(" %ws\r\n", bstrProfile);
  177. }
  178. if (NULL == pbstrLogoTag)
  179. {
  180. hr = E_INVALIDARG;
  181. goto Cleanup;
  182. }
  183. *pbstrLogoTag = NULL;
  184. if (!g_config->isValid()) // Guarantees config is non-null
  185. {
  186. AtlReportError(CLSID_FastAuth, PP_E_NOT_CONFIGUREDSTR,
  187. IID_IPassportFastAuth, PP_E_NOT_CONFIGURED);
  188. hr = PP_E_NOT_CONFIGURED;
  189. goto Cleanup;
  190. }
  191. //
  192. // due to STL the allocations of CTicket and CProfile can AV in low memory conditions
  193. //
  194. try
  195. {
  196. // ticket object
  197. pTicket = new CComObject<CTicket>();
  198. if (NULL == pTicket)
  199. {
  200. hr = E_OUTOFMEMORY;
  201. goto Cleanup;
  202. }
  203. else
  204. {
  205. pTicket->AddRef();
  206. }
  207. // profile object
  208. pProfile = new CComObject<CProfile>();
  209. if (NULL == pProfile)
  210. {
  211. hr = E_OUTOFMEMORY;
  212. goto Cleanup;
  213. }
  214. else
  215. {
  216. pProfile->AddRef();
  217. }
  218. }
  219. catch(...)
  220. {
  221. hr = E_OUTOFMEMORY;
  222. goto Cleanup;
  223. }
  224. // Get site name if any...
  225. hasSiteName = GetBstrArg(vSiteName, &bstrSiteName);
  226. if(hasSiteName == CV_OK || hasSiteName == CV_FREE)
  227. szSiteName = W2A(bstrSiteName);
  228. else
  229. szSiteName = NULL;
  230. if(hasSiteName == CV_FREE)
  231. SysFreeString(bstrSiteName);
  232. cnc = g_config->checkoutNexusConfig();
  233. crc = g_config->checkoutRegistryConfig(szSiteName);
  234. hr = DecryptTicketAndProfile(bstrTicket,
  235. bstrProfile,
  236. FALSE,
  237. NULL,
  238. crc,
  239. pTicket,
  240. pProfile);
  241. if (hr != S_OK)
  242. {
  243. goto Cleanup;
  244. }
  245. VariantInit(&vFalse);
  246. vFalse.vt = VT_BOOL;
  247. vFalse.boolVal = VARIANT_FALSE;
  248. pTicket->get_IsAuthenticated(0,
  249. VARIANT_FALSE,
  250. vFalse,
  251. &bTicketValid);
  252. pProfile->get_IsValid(&bProfileValid);
  253. time(&ct);
  254. // Make sure args are of the right type
  255. if ((hasTW = GetIntArg(vTimeWindow, (int*) &TimeWindow)) == CV_BAD)
  256. {
  257. hr = E_INVALIDARG;
  258. goto Cleanup;
  259. }
  260. if ((hasFL = GetBoolArg(vForceLogin, &ForceLogin)) == CV_BAD)
  261. {
  262. hr = E_INVALIDARG;
  263. goto Cleanup;
  264. }
  265. if ((hasSec = GetBoolArg(vSecure,&bSecure)) == CV_BAD)
  266. {
  267. hr = E_INVALIDARG;
  268. goto Cleanup;
  269. }
  270. if ((hasUseSec = GetIntArg(vUseSecureAuth,(int*)&ulSecureLevel)) == CV_BAD)
  271. {
  272. hr = E_INVALIDARG;
  273. goto Cleanup;
  274. }
  275. if ((hasLCID = GetShortArg(vLCID,&Lang)) == CV_BAD)
  276. {
  277. hr = E_INVALIDARG;
  278. goto Cleanup;
  279. }
  280. if ((hasKPP = GetIntArg(vKPP, &nKPP)) == CV_BAD)
  281. {
  282. hr = E_INVALIDARG;
  283. goto Cleanup;
  284. }
  285. hasCB = GetBstrArg(vCoBrand, &CBT);
  286. if (hasCB == CV_BAD)
  287. {
  288. hr = E_INVALIDARG;
  289. goto Cleanup;
  290. }
  291. if (hasCB == CV_FREE) { TAKEOVER_BSTR(CBT); }
  292. hasRU = GetBstrArg(vRU, &returnUrl);
  293. if (hasRU == CV_BAD)
  294. {
  295. if (hasCB == CV_FREE && CBT)
  296. SysFreeString(CBT);
  297. hr = E_INVALIDARG;
  298. goto Cleanup;
  299. }
  300. if (hasRU == CV_FREE) { TAKEOVER_BSTR(returnUrl); }
  301. hasNameSpace = GetBstrArg(vNameSpace, &bstrNameSpace);
  302. if (hasNameSpace == CV_BAD)
  303. {
  304. if (hasCB == CV_FREE && CBT) SysFreeString(CBT);
  305. if (hasRU == CV_FREE && returnUrl) SysFreeString(returnUrl);
  306. return E_INVALIDARG;
  307. }
  308. if (hasNameSpace == CV_FREE)
  309. {
  310. TAKEOVER_BSTR(bstrNameSpace);
  311. }
  312. if (hasNameSpace == CV_DEFAULT)
  313. {
  314. bstrNameSpace = crc->getNameSpace();
  315. }
  316. WCHAR *szSIAttrName, *szSOAttrName;
  317. if (hasSec == CV_OK && bSecure != VARIANT_FALSE)
  318. {
  319. szSIAttrName = L"SecureSigninLogo";
  320. szSOAttrName = L"SecureSignoutLogo";
  321. }
  322. else
  323. {
  324. szSIAttrName = L"SigninLogo";
  325. szSOAttrName = L"SignoutLogo";
  326. }
  327. WCHAR *szAUAttrName;
  328. if (hasUseSec == CV_OK && SECURELEVEL_USE_HTTPS(ulSecureLevel))
  329. szAUAttrName = L"AuthSecure";
  330. else
  331. szAUAttrName = L"Auth";
  332. if (hasLCID == CV_DEFAULT)
  333. Lang = crc->getDefaultLCID();
  334. if (hasTW == CV_DEFAULT)
  335. TimeWindow = crc->getDefaultTicketAge();
  336. if (hasFL == CV_DEFAULT)
  337. ForceLogin = crc->forceLoginP() ? VARIANT_TRUE : VARIANT_FALSE;
  338. if (hasCB == CV_DEFAULT)
  339. CBT = crc->getDefaultCoBrand();
  340. if (hasRU == CV_DEFAULT)
  341. returnUrl = crc->getDefaultRU();
  342. if (hasKPP == CV_DEFAULT)
  343. nKPP = -1;
  344. if (returnUrl == NULL)
  345. returnUrl = L"";
  346. if ((TimeWindow != 0 && TimeWindow < PPM_TIMEWINDOW_MIN) || TimeWindow > PPM_TIMEWINDOW_MAX)
  347. {
  348. //
  349. // 20 will always be more than large enough for a ULONG
  350. //
  351. WCHAR buf[20];
  352. _itow(TimeWindow,buf,10);
  353. if (g_pAlert)
  354. g_pAlert->report(PassportAlertInterface::WARNING_TYPE,
  355. PM_TIMEWINDOW_INVALID, buf);
  356. AtlReportError(CLSID_FastAuth, (LPCOLESTR) PP_E_INVALID_TIMEWINDOWSTR,
  357. IID_IPassportFastAuth, PP_E_INVALID_TIMEWINDOW);
  358. hr = PP_E_INVALID_TIMEWINDOW;
  359. goto Cleanup;
  360. }
  361. if (bTicketValid)
  362. {
  363. LPCWSTR domain = NULL;
  364. WCHAR url[1025];
  365. VARIANT freeMe;
  366. VariantInit(&freeMe);
  367. if (crc->DisasterModeP())
  368. {
  369. lstrcpynW(url, crc->getDisasterUrl(), DIMENSION(url) - 1);
  370. url[DIMENSION(url) - 1] = L'\0';
  371. }
  372. else
  373. {
  374. if (bProfileValid &&
  375. pProfile->get_ByIndex(MEMBERNAME_INDEX, &freeMe) == S_OK &&
  376. freeMe.vt == VT_BSTR)
  377. {
  378. domain = wcsrchr(freeMe.bstrVal, L'@');
  379. }
  380. cnc->getDomainAttribute(domain ? domain+1 : L"Default",
  381. L"Logout",
  382. DIMENSION(url) - 1,
  383. url,
  384. Lang);
  385. url[DIMENSION(url) - 1] = L'\0';
  386. }
  387. // find out if there are any updates
  388. WCHAR iurl[1025];
  389. BSTR upd = NULL;
  390. pProfile->get_updateString(&upd);
  391. if (upd)
  392. {
  393. TAKEOVER_BSTR(upd);
  394. // form the appropriate URL
  395. CCoCrypt* crypt = NULL;
  396. BSTR newCH = NULL;
  397. crypt = crc->getCurrentCrypt(); // IsValid ensures this is non-null
  398. // This should never fail... (famous last words)
  399. if (!crypt->Encrypt(crc->getCurrentCryptVersion(),
  400. (LPSTR)upd,
  401. SysStringByteLen(upd),
  402. &newCH))
  403. {
  404. AtlReportError(CLSID_Manager, (LPCOLESTR) PP_E_UNABLE_TO_ENCRYPTSTR,
  405. IID_IPassportManager, PP_E_UNABLE_TO_ENCRYPT);
  406. hr = PP_E_UNABLE_TO_ENCRYPT;
  407. goto Cleanup;
  408. }
  409. FREE_BSTR(upd);
  410. TAKEOVER_BSTR(newCH);
  411. cnc->getDomainAttribute(domain ? domain+1 : L"Default",
  412. L"Update",
  413. DIMENSION(iurl) - 1,
  414. iurl,
  415. Lang);
  416. iurl[DIMENSION(iurl) - 1] = L'\0';
  417. // This is a bit gross... we need to find the $1 in the update url...
  418. // We'll break if null, but won't crash...
  419. if (*url != L'\0')
  420. *pbstrLogoTag = FormatUpdateLogoTag(
  421. url,
  422. crc->getSiteId(),
  423. returnUrl,
  424. TimeWindow,
  425. ForceLogin,
  426. crc->getCurrentCryptVersion(),
  427. ct,
  428. CBT,
  429. nKPP,
  430. (*iurl == L'\0' ? NULL : iurl),
  431. bSecure,
  432. newCH,
  433. PM_LOGOTYPE_SIGNOUT,
  434. ulSecureLevel,
  435. crc,
  436. TRUE
  437. );
  438. FREE_BSTR(newCH);
  439. }
  440. else
  441. {
  442. cnc->getDomainAttribute(domain ? domain+1 : L"Default",
  443. szSOAttrName,
  444. DIMENSION(iurl),
  445. iurl,
  446. Lang);
  447. iurl[DIMENSION(iurl) - 1] = L'\0';
  448. if (*iurl != L'\0')
  449. *pbstrLogoTag = FormatNormalLogoTag(
  450. url,
  451. crc->getSiteId(),
  452. returnUrl,
  453. TimeWindow,
  454. ForceLogin,
  455. crc->getCurrentCryptVersion(),
  456. ct,
  457. CBT,
  458. iurl,
  459. NULL,
  460. nKPP,
  461. PM_LOGOTYPE_SIGNOUT,
  462. Lang,
  463. ulSecureLevel,
  464. crc,
  465. fRedirToSelf,
  466. TRUE
  467. );
  468. }
  469. VariantClear(&freeMe);
  470. if (NULL == *pbstrLogoTag)
  471. {
  472. hr = E_OUTOFMEMORY;
  473. goto Cleanup;
  474. }
  475. }
  476. else
  477. {
  478. WCHAR url[1025];
  479. WCHAR iurl[1025];
  480. if (!crc->DisasterModeP())
  481. {
  482. cnc->getDomainAttribute(L"Default",
  483. szAUAttrName,
  484. DIMENSION(url),
  485. url,
  486. Lang);
  487. url[DIMENSION(url) - 1] = L'\0';
  488. }
  489. else
  490. {
  491. lstrcpynW(url, crc->getDisasterUrl(), DIMENSION(url));
  492. url[DIMENSION(url) - 1] = L'\0';
  493. }
  494. cnc->getDomainAttribute(L"Default",
  495. szSIAttrName,
  496. DIMENSION(iurl),
  497. iurl,
  498. Lang);
  499. iurl[DIMENSION(iurl) - 1] = L'\0';
  500. if (*iurl != L'\0')
  501. {
  502. *pbstrLogoTag = FormatNormalLogoTag(
  503. url,
  504. crc->getSiteId(),
  505. returnUrl,
  506. TimeWindow,
  507. ForceLogin,
  508. crc->getCurrentCryptVersion(),
  509. ct,
  510. CBT,
  511. iurl,
  512. bstrNameSpace,
  513. nKPP,
  514. PM_LOGOTYPE_SIGNIN,
  515. Lang,
  516. ulSecureLevel,
  517. crc,
  518. fRedirToSelf,
  519. TRUE
  520. );
  521. if (NULL == *pbstrLogoTag)
  522. {
  523. hr = E_OUTOFMEMORY;
  524. goto Cleanup;
  525. }
  526. }
  527. }
  528. hr = S_OK;
  529. Cleanup:
  530. PassportLog("CFastAuth::CommonLogoTag Exit: %X\r\n", hr);
  531. if ((NULL != pbstrLogoTag) && (NULL != *pbstrLogoTag))
  532. {
  533. PassportLog(" %ws\r\n", *pbstrLogoTag);
  534. }
  535. if (pTicket)
  536. pTicket->Release();
  537. if (pProfile)
  538. pProfile->Release();
  539. if (crc) crc->Release();
  540. if (cnc) cnc->Release();
  541. if (hasRU == CV_FREE && returnUrl)
  542. FREE_BSTR(returnUrl);
  543. if (hasCB == CV_FREE && CBT)
  544. FREE_BSTR(CBT);
  545. if (hasNameSpace == CV_FREE && bstrNameSpace)
  546. FREE_BSTR(bstrNameSpace);
  547. return hr;
  548. }
  549. //===========================================================================
  550. //
  551. // IsAuthenticated
  552. //
  553. STDMETHODIMP
  554. CFastAuth::IsAuthenticated(
  555. BSTR bstrTicket,
  556. BSTR bstrProfile,
  557. VARIANT vSecure,
  558. VARIANT vTimeWindow,
  559. VARIANT vForceLogin,
  560. VARIANT vSiteName,
  561. VARIANT vDoSecureCheck,
  562. VARIANT_BOOL* pbAuthenticated
  563. )
  564. {
  565. HRESULT hr;
  566. CComObject<CTicket> *pTicket = NULL;
  567. CComObject<CProfile> *pProfile = NULL;
  568. CRegistryConfig* crc = NULL;
  569. ULONG TimeWindow;
  570. VARIANT_BOOL ForceLogin, bTicketValid, bProfileValid;
  571. int hasSec = CV_DEFAULT, hasTW = CV_DEFAULT, hasFL = CV_DEFAULT, hasSiteName = CV_DEFAULT;
  572. BSTR bstrSecure, bstrSiteName;
  573. LPSTR szSiteName;
  574. VARIANT vFalse;
  575. USES_CONVERSION;
  576. PassportLog("CFastAuth::IsAuthenticated Enter:\r\n");
  577. if (NULL != bstrTicket)
  578. {
  579. PassportLog(" %ws\r\n", bstrTicket);
  580. }
  581. if (NULL != bstrProfile)
  582. {
  583. PassportLog(" %ws\r\n", bstrProfile);
  584. }
  585. if (!g_config->isValid()) // Guarantees config is non-null
  586. {
  587. AtlReportError(CLSID_Manager, PP_E_NOT_CONFIGUREDSTR,
  588. IID_IPassportManager, PP_E_NOT_CONFIGURED);
  589. hr = PP_E_NOT_CONFIGURED;
  590. goto Cleanup;
  591. }
  592. hasSec = GetBstrArg(vSecure, &bstrSecure);
  593. if(hasSec == CV_BAD)
  594. {
  595. hr = E_INVALIDARG;
  596. goto Cleanup;
  597. }
  598. if(hasSec == CV_DEFAULT)
  599. bstrSecure = NULL;
  600. hasSiteName = GetBstrArg(vSiteName, &bstrSiteName);
  601. if(hasSiteName == CV_OK || hasSiteName == CV_FREE)
  602. {
  603. szSiteName = W2A(bstrSiteName);
  604. PassportLog(" %ws\r\n", szSiteName);
  605. }
  606. else
  607. szSiteName = NULL;
  608. if(hasSiteName == CV_FREE)
  609. SysFreeString(bstrSiteName);
  610. crc = g_config->checkoutRegistryConfig(szSiteName);
  611. //
  612. // due to STL the allocations of CTicket and CProfile can AV in low memory conditions
  613. //
  614. try
  615. {
  616. // ticket object
  617. pTicket = new CComObject<CTicket>();
  618. if (NULL == pTicket)
  619. {
  620. hr = E_OUTOFMEMORY;
  621. goto Cleanup;
  622. }
  623. else
  624. {
  625. pTicket->AddRef();
  626. }
  627. // profile object
  628. pProfile = new CComObject<CProfile>();
  629. if (NULL == pProfile)
  630. {
  631. hr = E_OUTOFMEMORY;
  632. goto Cleanup;
  633. }
  634. else
  635. {
  636. pProfile->AddRef();
  637. }
  638. }
  639. catch(...)
  640. {
  641. hr = E_OUTOFMEMORY;
  642. goto Cleanup;
  643. }
  644. hr = DecryptTicketAndProfile(bstrTicket,
  645. NULL,
  646. FALSE,
  647. NULL,
  648. crc,
  649. pTicket,
  650. pProfile);
  651. if(hr != S_OK)
  652. {
  653. goto Cleanup;
  654. }
  655. VariantInit(&vFalse);
  656. vFalse.vt = VT_BOOL;
  657. vFalse.boolVal = VARIANT_FALSE;
  658. pTicket->get_IsAuthenticated(0,
  659. VARIANT_FALSE,
  660. vFalse,
  661. &bTicketValid);
  662. /*
  663. // Both profile AND ticket must be valid to be authenticated
  664. // (as of 1.3, this is no longer true).
  665. Profile.get_IsValid(&bProfileValid);
  666. if (!bProfileValid)
  667. {
  668. hr = E_FAIL;
  669. goto Cleanup;
  670. }
  671. */
  672. if ((hasTW = GetIntArg(vTimeWindow,(int*)&TimeWindow)) == CV_BAD)
  673. {
  674. hr = E_INVALIDARG;
  675. goto Cleanup;
  676. }
  677. if (hasTW == CV_DEFAULT)
  678. TimeWindow = crc->getDefaultTicketAge();
  679. if ((hasFL = GetBoolArg(vForceLogin, &ForceLogin)) == CV_BAD)
  680. {
  681. hr = E_INVALIDARG;
  682. goto Cleanup;
  683. }
  684. if (hasFL == CV_DEFAULT)
  685. ForceLogin = crc->forceLoginP() ? VARIANT_TRUE : VARIANT_FALSE;
  686. PassportLog(" TW = %X\r\n", TimeWindow);
  687. hr = pTicket->get_IsAuthenticated(TimeWindow, ForceLogin, vDoSecureCheck, pbAuthenticated);
  688. Cleanup:
  689. PassportLog("CFastAuth::IsAuthenticated Exit\r\n");
  690. if (pTicket)
  691. pTicket->Release();
  692. if (pProfile)
  693. pProfile->Release();
  694. if (crc) crc->Release();
  695. if(hasSec == CV_FREE)
  696. SysFreeString(bstrSecure);
  697. if(hr != S_OK)
  698. {
  699. *pbAuthenticated = VARIANT_FALSE;
  700. }
  701. return hr;
  702. }
  703. //===========================================================================
  704. //
  705. // AuthURL
  706. //
  707. //
  708. // old API. Auth URL goes to login
  709. //
  710. STDMETHODIMP
  711. CFastAuth::AuthURL(
  712. VARIANT vTicket,
  713. VARIANT vProfile,
  714. VARIANT vRU,
  715. VARIANT vTimeWindow,
  716. VARIANT vForceLogin,
  717. VARIANT vCoBrand,
  718. VARIANT vLCID,
  719. VARIANT vSecure,
  720. VARIANT vLogoutURL,
  721. VARIANT vReserved1,
  722. VARIANT vSiteName,
  723. VARIANT vNameSpace,
  724. VARIANT vKPP,
  725. VARIANT vUseSecureAuth,
  726. BSTR* pbstrAuthURL
  727. )
  728. {
  729. return CommonAuthURL(vTicket,
  730. vProfile,
  731. vRU,
  732. vTimeWindow,
  733. vForceLogin,
  734. vCoBrand,
  735. vLCID,
  736. vSecure,
  737. vLogoutURL,
  738. vReserved1,
  739. vSiteName,
  740. vNameSpace,
  741. vKPP,
  742. vUseSecureAuth,
  743. FALSE,
  744. pbstrAuthURL);
  745. }
  746. //===========================================================================
  747. //
  748. // AuthURL2
  749. //
  750. //
  751. // new API. Auth URL points to partner
  752. //
  753. STDMETHODIMP
  754. CFastAuth::AuthURL2(
  755. VARIANT vTicket,
  756. VARIANT vProfile,
  757. VARIANT vRU,
  758. VARIANT vTimeWindow,
  759. VARIANT vForceLogin,
  760. VARIANT vCoBrand,
  761. VARIANT vLCID,
  762. VARIANT vSecure,
  763. VARIANT vLogoutURL,
  764. VARIANT vReserved1,
  765. VARIANT vSiteName,
  766. VARIANT vNameSpace,
  767. VARIANT vKPP,
  768. VARIANT vUseSecureAuth,
  769. BSTR* pbstrAuthURL
  770. )
  771. {
  772. return CommonAuthURL(vTicket,
  773. vProfile,
  774. vRU,
  775. vTimeWindow,
  776. vForceLogin,
  777. vCoBrand,
  778. vLCID,
  779. vSecure,
  780. vLogoutURL,
  781. vReserved1,
  782. vSiteName,
  783. vNameSpace,
  784. vKPP,
  785. vUseSecureAuth,
  786. TRUE,
  787. pbstrAuthURL);
  788. }
  789. //===========================================================================
  790. //
  791. // CommonAuthURL
  792. //
  793. STDMETHODIMP
  794. CFastAuth::CommonAuthURL(
  795. VARIANT vTicket,
  796. VARIANT vProfile,
  797. VARIANT vRU,
  798. VARIANT vTimeWindow,
  799. VARIANT vForceLogin,
  800. VARIANT vCoBrand,
  801. VARIANT vLCID,
  802. VARIANT vSecure,
  803. VARIANT vLogoutURL,
  804. VARIANT vReserved1,
  805. VARIANT vSiteName,
  806. VARIANT vNameSpace,
  807. VARIANT vKPP,
  808. VARIANT vUseSecureAuth,
  809. BOOL fRedirToSelf,
  810. BSTR* pbstrAuthURL
  811. )
  812. {
  813. HRESULT hr;
  814. BSTR bstrTicket = NULL;
  815. BSTR bstrProfile = NULL;
  816. CComObject<CTicket> *pTicket = NULL;
  817. CComObject<CProfile> *pProfile = NULL;
  818. time_t ct;
  819. WCHAR url[1025];
  820. VARIANT freeMe;
  821. UINT TimeWindow;
  822. int nKPP;
  823. VARIANT_BOOL ForceLogin;
  824. VARIANT_BOOL bTicketValid;
  825. VARIANT_BOOL bProfileValid;
  826. ULONG ulSecureLevel = 0;
  827. BSTR CBT = NULL, returnUrl = NULL, bstrSiteName = NULL, bstrNameSpace = NULL;
  828. int hasCB = -1, hasRU = -1, hasLCID, hasTW, hasFL, hasNameSpace = -1, hasUseSec;
  829. int hasTicket = -1, hasProfile = -1, hasSiteName = -1, hasKPP = -1;
  830. USHORT Lang;
  831. CNexusConfig* cnc = NULL;
  832. CRegistryConfig* crc = NULL;
  833. LPSTR szSiteName;
  834. VARIANT vFalse;
  835. USES_CONVERSION;
  836. PassportLog("CFastAuth::CommonAuthURL Enter:\r\n");
  837. if (!g_config->isValid()) // Guarantees config is non-null
  838. {
  839. AtlReportError(CLSID_FastAuth, PP_E_NOT_CONFIGUREDSTR,
  840. IID_IPassportFastAuth, PP_E_NOT_CONFIGURED);
  841. hr = PP_E_NOT_CONFIGURED;
  842. goto Cleanup;
  843. }
  844. hasSiteName = GetBstrArg(vSiteName, &bstrSiteName);
  845. if(hasSiteName == CV_OK || hasSiteName == CV_FREE)
  846. szSiteName = W2A(bstrSiteName);
  847. else
  848. szSiteName = NULL;
  849. if(hasSiteName == CV_FREE)
  850. SysFreeString(bstrSiteName);
  851. cnc = g_config->checkoutNexusConfig();
  852. crc = g_config->checkoutRegistryConfig(szSiteName);
  853. // Make sure args are of the right type
  854. if ((hasTicket = GetBstrArg(vTicket, &bstrTicket)) == CV_BAD)
  855. {
  856. hr = E_INVALIDARG;
  857. goto Cleanup;
  858. }
  859. if ((hasProfile = GetBstrArg(vProfile, &bstrProfile)) == CV_BAD)
  860. {
  861. hr = E_INVALIDARG;
  862. goto Cleanup;
  863. }
  864. if (NULL != bstrTicket)
  865. {
  866. PassportLog(" %ws\r\n", bstrTicket);
  867. }
  868. if (NULL != bstrProfile)
  869. {
  870. PassportLog(" %ws\r\n", bstrProfile);
  871. }
  872. //
  873. // due to STL the allocations of CTicket and CProfile can AV in low memory conditions
  874. //
  875. try
  876. {
  877. // ticket object
  878. pTicket = new CComObject<CTicket>();
  879. if (NULL == pTicket)
  880. {
  881. hr = E_OUTOFMEMORY;
  882. goto Cleanup;
  883. }
  884. else
  885. {
  886. pTicket->AddRef();
  887. }
  888. // profile object
  889. pProfile = new CComObject<CProfile>();
  890. if (NULL == pProfile)
  891. {
  892. hr = E_OUTOFMEMORY;
  893. goto Cleanup;
  894. }
  895. else
  896. {
  897. pProfile->AddRef();
  898. }
  899. }
  900. catch(...)
  901. {
  902. hr = E_OUTOFMEMORY;
  903. goto Cleanup;
  904. }
  905. if(hasTicket != CV_DEFAULT && hasProfile != CV_DEFAULT)
  906. {
  907. hr = DecryptTicketAndProfile(bstrTicket, bstrProfile, FALSE, NULL, crc, pTicket, pProfile);
  908. if(hr != S_OK)
  909. {
  910. bTicketValid = VARIANT_FALSE;
  911. bProfileValid = VARIANT_FALSE;
  912. }
  913. else
  914. {
  915. VariantInit(&vFalse);
  916. vFalse.vt = VT_BOOL;
  917. vFalse.boolVal = VARIANT_FALSE;
  918. pTicket->get_IsAuthenticated(0,
  919. VARIANT_FALSE,
  920. vFalse,
  921. &bTicketValid);
  922. pProfile->get_IsValid(&bProfileValid);
  923. }
  924. }
  925. else
  926. {
  927. bTicketValid = VARIANT_FALSE;
  928. bProfileValid = VARIANT_FALSE;
  929. }
  930. if ((hasTW = GetIntArg(vTimeWindow, (int*) &TimeWindow)) == CV_BAD)
  931. {
  932. hr = E_INVALIDARG;
  933. goto Cleanup;
  934. }
  935. if ((hasFL = GetBoolArg(vForceLogin, &ForceLogin)) == CV_BAD)
  936. {
  937. hr = E_INVALIDARG;
  938. goto Cleanup;
  939. }
  940. if ((hasUseSec = GetIntArg(vUseSecureAuth, (int*)&ulSecureLevel)) == CV_BAD)
  941. {
  942. hr = E_INVALIDARG;
  943. goto Cleanup;
  944. }
  945. if ((hasLCID = GetShortArg(vLCID,&Lang)) == CV_BAD)
  946. {
  947. hr = E_INVALIDARG;
  948. goto Cleanup;
  949. }
  950. if ((hasKPP = GetIntArg(vKPP, &nKPP)) == CV_BAD)
  951. {
  952. hr = E_INVALIDARG;
  953. goto Cleanup;
  954. }
  955. hasCB = GetBstrArg(vCoBrand, &CBT);
  956. if (hasCB == CV_BAD)
  957. {
  958. hr = E_INVALIDARG;
  959. goto Cleanup;
  960. }
  961. if (hasCB == CV_FREE) { TAKEOVER_BSTR(CBT); }
  962. hasRU = GetBstrArg(vRU, &returnUrl);
  963. if (hasRU == CV_BAD)
  964. {
  965. if (hasCB == CV_FREE && CBT)
  966. FREE_BSTR(CBT);
  967. hr = E_INVALIDARG;
  968. goto Cleanup;
  969. }
  970. if (hasRU == CV_FREE) { TAKEOVER_BSTR(returnUrl); }
  971. hasNameSpace = GetBstrArg(vNameSpace, &bstrNameSpace);
  972. if (hasNameSpace == CV_BAD)
  973. {
  974. hr = E_INVALIDARG;
  975. goto Cleanup;
  976. }
  977. if (hasNameSpace == CV_FREE)
  978. {
  979. TAKEOVER_BSTR(bstrNameSpace);
  980. }
  981. if (hasNameSpace == CV_DEFAULT)
  982. {
  983. bstrNameSpace = crc->getNameSpace();
  984. }
  985. if (hasLCID == CV_DEFAULT)
  986. Lang = crc->getDefaultLCID();
  987. if (hasKPP == CV_DEFAULT)
  988. nKPP = -1;
  989. WCHAR *szAUAttrName;
  990. if (hasUseSec == CV_OK && SECURELEVEL_USE_HTTPS(ulSecureLevel))
  991. szAUAttrName = L"AuthSecure";
  992. else
  993. szAUAttrName = L"Auth";
  994. VariantInit(&freeMe);
  995. if (!crc->DisasterModeP())
  996. {
  997. // If I'm authenticated, get my domain specific url
  998. if (bTicketValid && bProfileValid)
  999. {
  1000. hr = pProfile->get_ByIndex(MEMBERNAME_INDEX, &freeMe);
  1001. if (hr != S_OK || freeMe.vt != VT_BSTR)
  1002. {
  1003. cnc->getDomainAttribute(L"Default",
  1004. szAUAttrName,
  1005. DIMENSION(url) - 1,
  1006. url,
  1007. Lang);
  1008. url[DIMENSION(url) - 1] = L'\0';
  1009. }
  1010. else
  1011. {
  1012. LPCWSTR psz = wcsrchr(freeMe.bstrVal, L'@');
  1013. cnc->getDomainAttribute(psz ? psz+1 : L"Default",
  1014. szAUAttrName,
  1015. DIMENSION(url) - 1,
  1016. url,
  1017. Lang);
  1018. url[DIMENSION(url) - 1] = L'\0';
  1019. }
  1020. }
  1021. else
  1022. {
  1023. cnc->getDomainAttribute(L"Default",
  1024. szAUAttrName,
  1025. DIMENSION(url) - 1,
  1026. url,
  1027. Lang);
  1028. url[DIMENSION(url) - 1] = L'\0';
  1029. }
  1030. }
  1031. else
  1032. {
  1033. lstrcpynW(url, crc->getDisasterUrl(), DIMENSION(url) - 1);
  1034. url[DIMENSION(url) - 1] = L'\0';
  1035. }
  1036. time(&ct);
  1037. if (!url)
  1038. {
  1039. hr = S_OK;
  1040. goto Cleanup;
  1041. }
  1042. if (hasTW == CV_DEFAULT)
  1043. TimeWindow = crc->getDefaultTicketAge();
  1044. if (hasFL == CV_DEFAULT)
  1045. ForceLogin = crc->forceLoginP() ? VARIANT_TRUE : VARIANT_FALSE;
  1046. if (hasCB == CV_DEFAULT)
  1047. CBT = crc->getDefaultCoBrand();
  1048. if (hasRU == CV_DEFAULT)
  1049. returnUrl = crc->getDefaultRU();
  1050. if (returnUrl == NULL)
  1051. returnUrl = L"";
  1052. if ((TimeWindow != 0 && TimeWindow < PPM_TIMEWINDOW_MIN) || TimeWindow > PPM_TIMEWINDOW_MAX)
  1053. {
  1054. //
  1055. // 20 will always be more than large enough for a ULONG
  1056. //
  1057. WCHAR buf[20];
  1058. _itow(TimeWindow,buf,10);
  1059. if (g_pAlert)
  1060. g_pAlert->report(PassportAlertInterface::WARNING_TYPE,
  1061. PM_TIMEWINDOW_INVALID, buf);
  1062. AtlReportError(CLSID_FastAuth, (LPCOLESTR) PP_E_INVALID_TIMEWINDOWSTR,
  1063. IID_IPassportFastAuth, PP_E_INVALID_TIMEWINDOW);
  1064. hr = PP_E_INVALID_TIMEWINDOW;
  1065. goto Cleanup;
  1066. }
  1067. if (NULL == pbstrAuthURL)
  1068. {
  1069. hr = E_INVALIDARG;
  1070. goto Cleanup;
  1071. }
  1072. *pbstrAuthURL = FormatAuthURL(
  1073. url,
  1074. crc->getSiteId(),
  1075. returnUrl,
  1076. TimeWindow,
  1077. ForceLogin,
  1078. crc->getCurrentCryptVersion(),
  1079. ct,
  1080. CBT,
  1081. bstrNameSpace,
  1082. nKPP,
  1083. Lang,
  1084. ulSecureLevel,
  1085. crc,
  1086. fRedirToSelf,
  1087. TRUE
  1088. );
  1089. if (NULL == *pbstrAuthURL)
  1090. {
  1091. hr = E_OUTOFMEMORY;
  1092. goto Cleanup;
  1093. }
  1094. hr = S_OK;
  1095. Cleanup:
  1096. PassportLog("CFastAuth::CommonAuthURL Exit: %X\r\n", hr);
  1097. if (pTicket)
  1098. pTicket->Release();
  1099. if (pProfile)
  1100. pProfile->Release();
  1101. if(cnc) cnc->Release();
  1102. if(crc) crc->Release();
  1103. if (hasTicket == CV_FREE && bstrTicket)
  1104. FREE_BSTR(bstrTicket);
  1105. if (hasProfile == CV_FREE && bstrProfile)
  1106. FREE_BSTR(bstrProfile);
  1107. if (hasRU == CV_FREE && returnUrl)
  1108. FREE_BSTR(returnUrl);
  1109. if (hasCB == CV_FREE && CBT)
  1110. FREE_BSTR(CBT);
  1111. if (hasNameSpace == CV_FREE && bstrNameSpace)
  1112. FREE_BSTR(bstrNameSpace);
  1113. VariantClear(&freeMe);
  1114. return hr;
  1115. }
  1116. //===========================================================================
  1117. //
  1118. // GetTicketAndProfilePFC
  1119. //
  1120. HRESULT
  1121. CFastAuth::GetTicketAndProfilePFC(
  1122. BYTE* pbPFC,
  1123. BYTE* pbPPH,
  1124. BSTR* pbstrTicket,
  1125. BSTR* pbstrProfile,
  1126. BSTR* pbstrSecure,
  1127. BSTR* pbstrSiteName
  1128. )
  1129. {
  1130. HTTP_FILTER_CONTEXT* pfc = (HTTP_FILTER_CONTEXT*)pbPFC;
  1131. HTTP_FILTER_PREPROC_HEADERS* pph = (HTTP_FILTER_PREPROC_HEADERS*)pbPPH;
  1132. BSTR bstrF = NULL;
  1133. CHAR achBuf[2048];
  1134. DWORD dwBufLen;
  1135. LPSTR pszQueryString;
  1136. HRESULT hr = S_FALSE;
  1137. USES_CONVERSION;
  1138. dwBufLen = DIMENSION(achBuf);
  1139. if(GetSiteNamePFC(pfc, achBuf, &dwBufLen) == S_OK)
  1140. *pbstrSiteName = SysAllocString(A2W(achBuf));
  1141. else
  1142. *pbstrSiteName = NULL;
  1143. dwBufLen = DIMENSION(achBuf);
  1144. if(pph->GetHeader(pfc, "URL", achBuf, &dwBufLen))
  1145. {
  1146. pszQueryString = strchr(achBuf, '?');
  1147. if(pszQueryString)
  1148. {
  1149. pszQueryString++;
  1150. if(GetQueryData(achBuf, pbstrTicket, pbstrProfile, &bstrF))
  1151. {
  1152. PassportLog("CFastAuth::GetTicketAndProfilePFC URL: %s\r\n", achBuf);
  1153. *pbstrSecure = NULL;
  1154. hr = S_OK;
  1155. goto Cleanup;
  1156. }
  1157. }
  1158. }
  1159. dwBufLen = DIMENSION(achBuf);
  1160. if(pph->GetHeader(pfc, "Cookie:", achBuf, &dwBufLen))
  1161. {
  1162. if(!GetCookie(achBuf, "MSPAuth", pbstrTicket))
  1163. {
  1164. goto Cleanup;
  1165. }
  1166. GetCookie(achBuf, "MSPProf", pbstrProfile);
  1167. GetCookie(achBuf, "MSPSecAuth", pbstrSecure);
  1168. hr = S_OK;
  1169. }
  1170. Cleanup:
  1171. PassportLog("CFastAuth::GetTicketAndProfilePFC Exit: %X\r\n", hr);
  1172. if (bstrF)
  1173. {
  1174. FREE_BSTR(bstrF);
  1175. }
  1176. return hr;
  1177. }
  1178. //===========================================================================
  1179. //
  1180. // GetTicketAndProfileECB
  1181. //
  1182. HRESULT
  1183. CFastAuth::GetTicketAndProfileECB(
  1184. BYTE* pbECB,
  1185. BSTR* pbstrTicket,
  1186. BSTR* pbstrProfile,
  1187. BSTR* pbstrSecure,
  1188. BSTR* pbstrSiteName
  1189. )
  1190. {
  1191. EXTENSION_CONTROL_BLOCK* pECB = (EXTENSION_CONTROL_BLOCK*)pbECB;
  1192. CHAR achBuf[2048];
  1193. DWORD dwBufLen;
  1194. BSTR bstrF;
  1195. USES_CONVERSION;
  1196. dwBufLen = DIMENSION(achBuf);
  1197. if(GetSiteNameECB(pECB, achBuf, &dwBufLen) == S_OK)
  1198. *pbstrSiteName = SysAllocString(A2W(achBuf));
  1199. else
  1200. *pbstrSiteName = NULL;
  1201. dwBufLen = DIMENSION(achBuf);
  1202. if(pECB->GetServerVariable(pECB, "QUERY_STRING", achBuf, &dwBufLen))
  1203. {
  1204. if(GetQueryData(achBuf, pbstrTicket, pbstrProfile, &bstrF))
  1205. {
  1206. PassportLog("CFastAuth::GetTicketAndProfilePFC QS: %s\r\n", achBuf);
  1207. *pbstrSecure = NULL;
  1208. return S_OK;
  1209. }
  1210. }
  1211. dwBufLen = DIMENSION(achBuf);
  1212. if(pECB->GetServerVariable(pECB, "HTTP_COOKIE", achBuf, &dwBufLen))
  1213. {
  1214. if(!GetCookie(achBuf, "MSPAuth", pbstrTicket))
  1215. return S_FALSE;
  1216. GetCookie(achBuf, "MSPProf", pbstrProfile);
  1217. GetCookie(achBuf, "MSPSecAuth", pbstrSecure);
  1218. return S_OK;
  1219. }
  1220. PassportLog("CFastAuth::GetTicketAndProfilePFC Failed: %s\r\n", achBuf);
  1221. return S_FALSE;
  1222. }
  1223. //===========================================================================
  1224. //
  1225. // GetSiteName
  1226. //
  1227. HRESULT GetSiteName(
  1228. LPSTR szServerName,
  1229. LPSTR szPort,
  1230. LPSTR szSecure,
  1231. LPSTR szBuf,
  1232. LPDWORD lpdwBufLen
  1233. )
  1234. {
  1235. HRESULT hr;
  1236. DWORD dwSize;
  1237. int nLength;
  1238. LPSTR szPortTest;
  1239. if(!szServerName)
  1240. {
  1241. hr = E_FAIL;
  1242. goto Cleanup;
  1243. }
  1244. //
  1245. // Make sure the string (plus terminating null)
  1246. // isn't too long to fit into the buffer
  1247. //
  1248. dwSize = lstrlenA(szServerName);
  1249. if(dwSize + 1 > *lpdwBufLen)
  1250. {
  1251. hr = E_FAIL;
  1252. goto Cleanup;
  1253. }
  1254. //
  1255. // Copy the string.
  1256. //
  1257. lstrcpyA(szBuf, szServerName);
  1258. //
  1259. // Now, if the incoming port is a port other than
  1260. // 80/443, append it to the server name.
  1261. //
  1262. if(szPort && szSecure)
  1263. {
  1264. nLength = lstrlenA(szPort);
  1265. if(lstrcmpA(szSecure, "on") == 0)
  1266. szPortTest = "443";
  1267. else
  1268. szPortTest = "80";
  1269. if(lstrcmpA(szPort, szPortTest) != 0 &&
  1270. (dwSize + nLength + 2) <= *lpdwBufLen)
  1271. {
  1272. szBuf[dwSize] = ':';
  1273. lstrcpyA(&(szBuf[dwSize + 1]), szPort);
  1274. *lpdwBufLen = dwSize + nLength + 2;
  1275. }
  1276. else
  1277. *lpdwBufLen = dwSize + 1;
  1278. }
  1279. else
  1280. *lpdwBufLen = dwSize + 1;
  1281. hr = S_OK;
  1282. Cleanup:
  1283. return hr;
  1284. }
  1285. //===========================================================================
  1286. //
  1287. // GetSiteNamePFC
  1288. //
  1289. HRESULT
  1290. GetSiteNamePFC(
  1291. HTTP_FILTER_CONTEXT* pfc,
  1292. LPSTR szBuf,
  1293. LPDWORD lpdwBufLen
  1294. )
  1295. {
  1296. HRESULT hr;
  1297. LPSTR szServerName = GetServerVariablePFC(pfc, "SERVER_NAME");
  1298. LPSTR szPort = GetServerVariablePFC(pfc, "SERVER_PORT");
  1299. LPSTR szSecure = GetServerVariablePFC(pfc, "HTTPS");
  1300. hr = GetSiteName(szServerName, szPort, szSecure, szBuf, lpdwBufLen);
  1301. if(szServerName)
  1302. delete [] szServerName;
  1303. if(szPort)
  1304. delete [] szPort;
  1305. if(szSecure)
  1306. delete [] szSecure;
  1307. return hr;
  1308. }
  1309. //===========================================================================
  1310. //
  1311. // GetSiteNameECB
  1312. //
  1313. HRESULT
  1314. GetSiteNameECB(
  1315. EXTENSION_CONTROL_BLOCK* pECB,
  1316. LPSTR szBuf,
  1317. LPDWORD lpdwBufLen
  1318. )
  1319. {
  1320. HRESULT hr;
  1321. LPSTR szServerName = GetServerVariableECB(pECB, "SERVER_NAME");
  1322. LPSTR szPort = GetServerVariableECB(pECB, "SERVER_PORT");
  1323. LPSTR szSecure = GetServerVariableECB(pECB, "HTTPS");
  1324. hr = GetSiteName(szServerName, szPort, szSecure, szBuf, lpdwBufLen);
  1325. if(szServerName)
  1326. delete [] szServerName;
  1327. if(szPort)
  1328. delete [] szPort;
  1329. if(szSecure)
  1330. delete [] szSecure;
  1331. return hr;
  1332. }