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.

923 lines
24 KiB

  1. /**********************************************************************/
  2. /** Microsoft Passport **/
  3. /** Copyright(c) Microsoft Corporation, 1999 - 2001 **/
  4. /**********************************************************************/
  5. /*
  6. Ticket.cpp
  7. FILE HISTORY:
  8. */
  9. // Ticket.cpp : Implementation of CTicket
  10. #include "stdafx.h"
  11. #include "Passport.h"
  12. #include "Ticket.h"
  13. #include <time.h>
  14. #include <nsconst.h>
  15. #include "variantutils.h"
  16. #include "helperfuncs.h"
  17. // gmarks
  18. #include "Monitoring.h"
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CTicket
  21. //===========================================================================
  22. //
  23. // InterfaceSupportsErrorInfo
  24. //
  25. STDMETHODIMP CTicket::InterfaceSupportsErrorInfo(REFIID riid)
  26. {
  27. static const IID* arr[] =
  28. {
  29. &IID_IPassportTicket,
  30. &IID_IPassportTicket2
  31. };
  32. for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
  33. {
  34. if (InlineIsEqualGUID(*arr[i],riid))
  35. return S_OK;
  36. }
  37. return S_FALSE;
  38. }
  39. //===========================================================================
  40. //
  41. // SetTertiaryConsent
  42. //
  43. STDMETHODIMP CTicket::SetTertiaryConsent(BSTR bstrConsent)
  44. {
  45. _ASSERT(m_raw);
  46. if(!m_valid ) return S_FALSE;
  47. if(!bstrConsent) return E_INVALIDARG;
  48. HRESULT hr = S_OK;
  49. if(SysStringByteLen(bstrConsent) != sizeof(long) * 4 ||
  50. memcmp(m_raw, bstrConsent, sizeof(long) * 2) != 0 )
  51. hr = E_INVALIDARG;
  52. else
  53. {
  54. try{
  55. m_bstrTertiaryConsent = bstrConsent;
  56. }
  57. catch(...)
  58. {
  59. hr = E_OUTOFMEMORY;
  60. }
  61. }
  62. return hr;
  63. }
  64. //===========================================================================
  65. //
  66. // needConsent -- if consent cookie is needed,
  67. // return the flags related to kids passport
  68. //
  69. HRESULT CTicket::ConsentStatus(
  70. VARIANT_BOOL bRequireConsentCookie,
  71. ULONG* pStatus,
  72. ConsentStatusEnum* pConsentCode)
  73. {
  74. ConsentStatusEnum ret = ConsentStatus_Unknown;
  75. ULONG status = 0;
  76. u_long ulTmp;
  77. if (m_bstrTertiaryConsent &&
  78. SysStringByteLen(m_bstrTertiaryConsent) >= sizeof(long) * 4)
  79. {
  80. ULONG* pData = (ULONG*)(BSTR)m_bstrTertiaryConsent;
  81. memcpy((PBYTE)&ulTmp, (PBYTE)(pData + 3), sizeof(ulTmp));
  82. status = (ntohl(ulTmp) & k_ulFlagsConsentCookieMask);
  83. ret = ConsentStatus_Known;
  84. }
  85. else
  86. {
  87. TicketProperty prop;
  88. // 1.X ticket, with no flags in it
  89. if (S_OK != m_PropBag.GetProperty(ATTR_PASSPORTFLAGS, prop))
  90. {
  91. ret = ConsentStatus_NotDefinedInTicket;
  92. goto Exit;
  93. }
  94. ULONG flags = GetPassportFlags();
  95. if(flags & k_ulFlagsConsentCookieNeeded)
  96. {
  97. if (bRequireConsentCookie)
  98. {
  99. ret = ConsentStatus_Unknown;
  100. flags = flags & k_ulFlagsAccountType;
  101. }
  102. else
  103. {
  104. ret = ConsentStatus_Known;
  105. }
  106. }
  107. else
  108. ret = ConsentStatus_DoNotNeed;
  109. status = (flags & k_ulFlagsConsentCookieMask);
  110. }
  111. Exit:
  112. if(pConsentCode)
  113. *pConsentCode = ret;
  114. if (pStatus)
  115. *pStatus = status;
  116. return S_OK;
  117. }
  118. //===========================================================================
  119. //
  120. // get_unencryptedCookie
  121. //
  122. STDMETHODIMP
  123. CTicket::get_unencryptedCookie(ULONG cookieType, ULONG flags, BSTR *pVal)
  124. {
  125. PassportLog("CTicket::get_unencryptedCookie :\r\n");
  126. if (!m_raw) return S_FALSE;
  127. HRESULT hr = S_OK;
  128. if (!pVal || flags != 0) return E_INVALIDARG;
  129. switch(cookieType)
  130. {
  131. case MSPAuth:
  132. *pVal = SysAllocStringByteLen((LPSTR)m_raw, SysStringByteLen(m_raw));
  133. if (*pVal)
  134. {
  135. // if the secure flags is on, we should turn it off for this cookie always
  136. TicketProperty prop;
  137. if (S_OK == m_PropBag.GetProperty(ATTR_PASSPORTFLAGS, prop))
  138. {
  139. if (prop.value.vt == VT_I4
  140. && ((prop.value.lVal & k_ulFlagsSecuredTransportedTicket) != 0))
  141. // we need to turn off the bit
  142. {
  143. ULONG l = prop.value.lVal;
  144. l &= (~k_ulFlagsSecuredTransportedTicket); // unset the bit
  145. // put the modified flags into the buffer.
  146. u_long ulTmp;
  147. ulTmp = htonl(l);
  148. memcpy(((PBYTE)(*pVal)) + m_schemaDrivenOffset + prop.offset, (PBYTE)&ulTmp, sizeof(ulTmp));
  149. }
  150. }
  151. }
  152. break;
  153. case MSPSecAuth:
  154. // ticket should be long enough
  155. _ASSERT(SysStringByteLen(m_raw) > sizeof(long) * 3);
  156. // the first 3 long fields of the ticket
  157. // format:
  158. // four bytes network long - low memberId bytes
  159. // four bytes network long - high memberId bytes
  160. // four bytes network long - time of last refresh
  161. //
  162. // generate a shorter version of the cookie for secure signin
  163. *pVal = SysAllocStringByteLen((LPSTR)m_raw, sizeof(long) * 3);
  164. break;
  165. case MSPConsent:
  166. // ticket should be long enough
  167. _ASSERT(SysStringByteLen(m_raw) > sizeof(long) * 3);
  168. // check if there is consent
  169. // if (GetPassportFlags() & k_ulFlagsConsentStatus)
  170. // we always write consent cookie even if there is no consent
  171. if (GetPassportFlags() & k_ulFlagsConsentCookieNeeded)
  172. {
  173. // the first 3 long fields of the ticket
  174. // format:
  175. // four bytes network long - low memberId bytes
  176. // four bytes network long - high memberId bytes
  177. // four bytes network long - time of last refresh
  178. //
  179. // plus the consent flags -- long
  180. //
  181. // generate a shorter version of the cookie for secure signin
  182. *pVal = SysAllocStringByteLen((LPSTR)m_raw, sizeof(long) * 4);
  183. // plus the consent flags -- long
  184. //
  185. if (*pVal)
  186. {
  187. long* pl = (long*)pVal;
  188. // we mask the flags, and put into the cookie
  189. *(pl + 3) = htonl(GetPassportFlags() & k_ulFlagsConsentCookieMask);
  190. }
  191. }
  192. else
  193. {
  194. *pVal = NULL;
  195. hr = S_FALSE;
  196. }
  197. break;
  198. default:
  199. hr = E_INVALIDARG;
  200. break;
  201. }
  202. if (*pVal == 0 && hr == S_OK)
  203. hr = E_OUTOFMEMORY;
  204. return hr;
  205. }
  206. //===========================================================================
  207. //
  208. // get_unencryptedTicket
  209. //
  210. STDMETHODIMP CTicket::get_unencryptedTicket(BSTR *pVal)
  211. {
  212. PassportLog("CTicket::get_unencryptedTicket :\r\n");
  213. *pVal = SysAllocStringByteLen((LPSTR)m_raw, SysStringByteLen(m_raw));
  214. PassportLog(" %ws\r\n", m_raw);
  215. return S_OK;
  216. }
  217. //===========================================================================
  218. //
  219. // put_unencryptedTicket
  220. //
  221. STDMETHODIMP CTicket::put_unencryptedTicket(BSTR newVal)
  222. {
  223. DWORD dw13Xlen = 0;
  224. PassportLog("CTicket::put_unencryptedTicket Enter:\r\n");
  225. if (m_raw)
  226. {
  227. PassportLog(" T = %ws\r\n", m_raw);
  228. SysFreeString(m_raw);
  229. m_raw = NULL;
  230. }
  231. if (!newVal)
  232. {
  233. m_valid = FALSE;
  234. return S_OK;
  235. }
  236. m_bSecureCheckSucceeded = FALSE;
  237. // BOY do you have to be careful here. If you don't
  238. // call BYTE version, it truncates at first pair of NULLs
  239. // we also need to go past the key version byte
  240. DWORD dwByteLen = SysStringByteLen(newVal);
  241. {
  242. m_raw = SysAllocStringByteLen((LPSTR)newVal,
  243. dwByteLen);
  244. if (NULL == m_raw)
  245. {
  246. m_valid = FALSE;
  247. return E_OUTOFMEMORY;
  248. }
  249. }
  250. PPTracePrintBlob(PPTRACE_RAW, "Ticket:", (LPBYTE)newVal, dwByteLen, TRUE);
  251. // parse the 1.3X ticket data
  252. parse(m_raw, dwByteLen, &dw13Xlen);
  253. PPTracePrint(PPTRACE_RAW, "ticket: len=%d, len1.x=%d, len2=%d", dwByteLen, dw13Xlen, dwByteLen - dw13Xlen);
  254. // parse the schema driven data
  255. if (dwByteLen > dw13Xlen) // more data to parse
  256. {
  257. // the offset related to the raw data
  258. m_schemaDrivenOffset = dw13Xlen;
  259. // parse the schema driven properties
  260. LPCSTR pData = (LPCSTR)(LPWSTR)m_raw;
  261. pData += dw13Xlen;
  262. dwByteLen -= dw13Xlen;
  263. // parse the schema driven fields
  264. CNexusConfig* cnc = g_config->checkoutNexusConfig();
  265. if (NULL == cnc)
  266. {
  267. m_valid = FALSE;
  268. return S_FALSE;
  269. }
  270. CTicketSchema* pSchema = cnc->getTicketSchema(NULL);
  271. if ( pSchema )
  272. {
  273. HRESULT hr = pSchema->parseTicket(pData, dwByteLen, m_PropBag);
  274. // passport flags is useful, should treat it special
  275. TicketProperty prop;
  276. if (S_OK == m_PropBag.GetProperty(ATTR_PASSPORTFLAGS, prop))
  277. {
  278. if (prop.value.vt == VT_I4)
  279. m_passportFlags = prop.value.lVal;
  280. }
  281. /*
  282. if (FAILED(hr) )
  283. event log
  284. */
  285. }
  286. cnc->Release();
  287. }
  288. PPTracePrint(PPTRACE_RAW, "ticket propertybag: size=%d, flags=%lx", m_PropBag.Size(), m_passportFlags);
  289. PassportLog("CTicket::put_unencryptedTicket Exit:\r\n");
  290. return S_OK;
  291. }
  292. //===========================================================================
  293. //
  294. // get_IsAuthenticated
  295. //
  296. STDMETHODIMP CTicket::get_IsAuthenticated(
  297. ULONG timeWindow,
  298. VARIANT_BOOL forceLogin,
  299. VARIANT SecureLevel,
  300. VARIANT_BOOL* pVal
  301. )
  302. {
  303. int hasSecureLevel = CV_DEFAULT;
  304. PassportLog("CTicket::get_IsAuthenticated Enter:\r\n");
  305. PPTraceFunc<VARIANT_BOOL> func(PPTRACE_FUNC, *pVal,
  306. "get_IsAuthenticated", "<<< %lx, %lx, %1x, %p",
  307. timeWindow, forceLogin, V_I4(&SecureLevel), pVal);
  308. if(!pVal)
  309. return E_INVALIDARG;
  310. *pVal = VARIANT_FALSE;
  311. if ((timeWindow != 0 && timeWindow < PPM_TIMEWINDOW_MIN) || timeWindow > PPM_TIMEWINDOW_MAX)
  312. {
  313. AtlReportError(CLSID_Ticket, (LPCOLESTR) PP_E_INVALID_TIMEWINDOWSTR,
  314. IID_IPassportTicket, PP_E_INVALID_TIMEWINDOW);
  315. return PP_E_INVALID_TIMEWINDOW;
  316. }
  317. if (m_valid == FALSE)
  318. {
  319. *pVal = VARIANT_FALSE;
  320. return S_OK;
  321. }
  322. long lSecureLevel = 0;
  323. time_t now;
  324. long interval = 0;
  325. PassportLog(" TW = %X, LT = %X, TT = %X\r\n", timeWindow, m_lastSignInTime, m_ticketTime);
  326. // time window checking
  327. if (timeWindow != 0) // check time window
  328. {
  329. time(&now);
  330. interval = forceLogin ? now - m_lastSignInTime :
  331. now - m_ticketTime;
  332. if (interval < 0) interval = 0;
  333. PPTracePrint(PPTRACE_RAW, "timwindow:%ld, interval:%ld", timeWindow, interval);
  334. if ((unsigned long)(interval) > timeWindow)
  335. {
  336. // Make sure we're not in standalone mode
  337. CRegistryConfig* crc = g_config->checkoutRegistryConfig();
  338. if ((!crc) || (crc->DisasterModeP() == FALSE))
  339. {
  340. if(forceLogin)
  341. {
  342. if(g_pPerf)
  343. {
  344. g_pPerf->incrementCounter(PM_FORCEDSIGNIN_TOTAL);
  345. g_pPerf->incrementCounter(PM_FORCEDSIGNIN_SEC);
  346. }
  347. else
  348. {
  349. _ASSERT(g_pPerf);
  350. }
  351. }
  352. }
  353. else
  354. *pVal = VARIANT_TRUE; // we're in disaster mode, any cookie is good.
  355. if (crc) crc->Release();
  356. goto Cleanup;
  357. }
  358. }
  359. // check secureLevel stuff
  360. hasSecureLevel = GetIntArg(SecureLevel, (int*)&lSecureLevel);
  361. if(hasSecureLevel == CV_BAD) // try the legacy type VT_BOOL, map VARIANT_TRUE to SecureChannel
  362. {
  363. PPTracePrint(PPTRACE_RAW, "SecureLevel Bad Param");
  364. return E_INVALIDARG;
  365. }
  366. else if (hasSecureLevel == CV_DEFAULT)
  367. {
  368. // Make sure we're not in standalone mode
  369. CRegistryConfig* crc = g_config->checkoutRegistryConfig();
  370. if(crc)
  371. lSecureLevel = crc->getSecureLevel();
  372. }
  373. PPTracePrint(PPTRACE_RAW, "check secureLevel:%ld", lSecureLevel);
  374. if(lSecureLevel != 0)
  375. {
  376. VARIANT_BOOL bCheckSecure = ( SECURELEVEL_USE_HTTPS(lSecureLevel) ?
  377. VARIANT_TRUE : VARIANT_FALSE );
  378. PPTracePrint(PPTRACE_RAW, "secure checked OK?:%ld", m_bSecureCheckSucceeded);
  379. // SSL checking
  380. if(bCheckSecure && !m_bSecureCheckSucceeded)
  381. goto Cleanup;
  382. // securelevel checking
  383. {
  384. TicketProperty prop;
  385. HRESULT hr = m_PropBag.GetProperty(ATTR_SECURELEVEL, prop);
  386. PPTracePrint(PPTRACE_RAW, "secure level in ticket:%ld, %lx", (long) (prop.value), hr);
  387. // secure level is not good enough
  388. if(hr != S_OK || SecureLevelFromSecProp((int) (long) (prop.value)) < lSecureLevel)
  389. goto Cleanup;
  390. // time window checking against pin time -- if Pin signin
  391. if(SecureLevelFromSecProp((int) (long) (prop.value)) == k_iSeclevelStrongCreds)
  392. {
  393. hr = m_PropBag.GetProperty(ATTR_PINTIME, prop);
  394. PPTracePrint(PPTRACE_RAW, "pin time:%ld, %lx", (long) (prop.value), hr);
  395. if (hr != S_OK)
  396. goto Cleanup;
  397. interval = now - (long) (prop.value);
  398. if (interval < 0) interval = 0;
  399. PPTracePrint(PPTRACE_RAW, "timewindow:%ld, pin-interval:%ld", timeWindow, interval);
  400. if ((unsigned long)(interval) > timeWindow)
  401. {
  402. goto Cleanup;
  403. }
  404. }
  405. }
  406. }
  407. // if code can reach here, is authenticated
  408. *pVal = VARIANT_TRUE;
  409. Cleanup:
  410. PassportLog("CTicket::get_IsAuthenticated Exit: %X\r\n", *pVal);
  411. return S_OK;
  412. }
  413. //===========================================================================
  414. //
  415. // get_TicketAge
  416. //
  417. STDMETHODIMP CTicket::get_TicketAge(int *pVal)
  418. {
  419. PassportLog("CTicket::get_TicketAge Enter: %X\r\n", m_ticketTime);
  420. if (m_valid == FALSE)
  421. {
  422. AtlReportError(CLSID_Ticket, (LPCOLESTR) PP_E_INVALID_TICKETSTR,
  423. IID_IPassportTicket, PP_E_INVALID_TICKET);
  424. return PP_E_INVALID_TICKET;
  425. }
  426. time_t now;
  427. time(&now);
  428. *pVal = now - m_ticketTime;
  429. if (*pVal < 0)
  430. *pVal = 0;
  431. PassportLog("CTicket::get_TicketAge Exit: %X\r\n", *pVal);
  432. return S_OK;
  433. }
  434. //===========================================================================
  435. //
  436. // get_TimeSinceSignIn
  437. //
  438. STDMETHODIMP CTicket::get_TimeSinceSignIn(int *pVal)
  439. {
  440. PassportLog("CTicket::get_TimeSinceSignIn Enter: %X\r\n", m_lastSignInTime);
  441. if (m_valid == FALSE)
  442. {
  443. AtlReportError(CLSID_Ticket, (LPCOLESTR) PP_E_INVALID_TICKETSTR,
  444. IID_IPassportTicket, PP_E_INVALID_TICKET);
  445. return PP_E_INVALID_TICKET;
  446. }
  447. time_t now;
  448. time(&now);
  449. *pVal = now - m_lastSignInTime;
  450. if (*pVal < 0)
  451. *pVal = 0;
  452. PassportLog("CTicket::get_TimeSinceSignIn Exit: %X\r\n", *pVal);
  453. return S_OK;
  454. }
  455. //===========================================================================
  456. //
  457. // get_MemberId
  458. //
  459. STDMETHODIMP CTicket::get_MemberId(BSTR *pVal)
  460. {
  461. HRESULT hr = S_OK;
  462. if (m_valid == FALSE)
  463. {
  464. AtlReportError(CLSID_Ticket, (LPCOLESTR) PP_E_INVALID_TICKETSTR,
  465. IID_IPassportTicket, PP_E_INVALID_TICKET);
  466. hr = PP_E_INVALID_TICKET;
  467. goto Cleanup;
  468. }
  469. if(pVal == NULL)
  470. {
  471. hr = E_POINTER;
  472. goto Cleanup;
  473. }
  474. *pVal = SysAllocString(m_memberId);
  475. if(*pVal == NULL)
  476. {
  477. hr = E_OUTOFMEMORY;
  478. goto Cleanup;
  479. }
  480. Cleanup:
  481. return hr;
  482. }
  483. //===========================================================================
  484. //
  485. // get_MemberIdLow
  486. //
  487. STDMETHODIMP CTicket::get_MemberIdLow(int *pVal)
  488. {
  489. if (m_valid == FALSE)
  490. {
  491. AtlReportError(CLSID_Ticket, (LPCOLESTR) PP_E_INVALID_TICKETSTR,
  492. IID_IPassportTicket, PP_E_INVALID_TICKET);
  493. return PP_E_INVALID_TICKET;
  494. }
  495. PassportLog("CTicket::get_MemberIdLow: %X\r\n", m_mIdLow);
  496. *pVal = m_mIdLow;
  497. return S_OK;
  498. }
  499. //===========================================================================
  500. //
  501. // get_MemberIdHigh
  502. //
  503. STDMETHODIMP CTicket::get_MemberIdHigh(int *pVal)
  504. {
  505. if (m_valid == FALSE)
  506. {
  507. AtlReportError(CLSID_Ticket, (LPCOLESTR) PP_E_INVALID_TICKETSTR,
  508. IID_IPassportTicket, PP_E_INVALID_TICKET);
  509. return PP_E_INVALID_TICKET;
  510. }
  511. PassportLog("CTicket::get_MemberIdHigh: %X\r\n", m_mIdHigh);
  512. *pVal = m_mIdHigh;
  513. return S_OK;
  514. }
  515. //===========================================================================
  516. //
  517. // get_HasSavedPassword
  518. //
  519. STDMETHODIMP CTicket::get_HasSavedPassword(VARIANT_BOOL *pVal)
  520. {
  521. if (m_valid == FALSE)
  522. {
  523. AtlReportError(CLSID_Ticket, (LPCOLESTR) PP_E_INVALID_TICKETSTR,
  524. IID_IPassportTicket, PP_E_INVALID_TICKET);
  525. return PP_E_INVALID_TICKET;
  526. }
  527. PassportLog("CTicket::get_HasSavedPassword: %X\r\n", m_savedPwd);
  528. *pVal = m_savedPwd ? VARIANT_TRUE : VARIANT_FALSE;
  529. return S_OK;
  530. }
  531. //===========================================================================
  532. //
  533. // get_SignInServer
  534. //
  535. STDMETHODIMP CTicket::get_SignInServer(BSTR *pVal)
  536. {
  537. if (m_valid == FALSE)
  538. {
  539. AtlReportError(CLSID_Ticket, (LPCOLESTR) PP_E_INVALID_TICKETSTR,
  540. IID_IPassportTicket, PP_E_INVALID_TICKET);
  541. return PP_E_INVALID_TICKET;
  542. }
  543. // BUGBUG
  544. return E_NOTIMPL;
  545. }
  546. //===========================================================================
  547. //
  548. // parse
  549. //
  550. // parse the 1.3X ticket fields
  551. void CTicket::parse(
  552. LPCOLESTR raw,
  553. DWORD dwByteLen,
  554. DWORD* pcParsed
  555. )
  556. {
  557. LPSTR lpBase;
  558. UINT byteLen, spot=0;
  559. long curTime;
  560. time_t curTime_t;
  561. u_long ulTmp;
  562. if (!raw)
  563. {
  564. m_valid = false;
  565. goto Cleanup;
  566. }
  567. // format:
  568. // four bytes network long - low memberId bytes
  569. // four bytes network long - high memberId bytes
  570. // four bytes network long - time of last refresh
  571. // four bytes network long - time of last password entry
  572. // four bytes network long - time of ticket generation
  573. // one byte - is this a saved password (Y/N)
  574. // four bytes network long - flags
  575. lpBase = (LPSTR)(LPWSTR) raw;
  576. byteLen = dwByteLen;
  577. spot=0;
  578. // 1.3x ticket length, excluding HM which is 1 long shorter
  579. DWORD dw13XLen = sizeof(u_long)*6 + sizeof(char);
  580. if (byteLen < dw13XLen && byteLen != dw13XLen - sizeof(u_long))
  581. {
  582. m_valid = FALSE;
  583. goto Cleanup;
  584. }
  585. memcpy((PBYTE)&ulTmp, lpBase, sizeof(ulTmp));
  586. m_mIdLow = ntohl(ulTmp);
  587. spot += sizeof(u_long);
  588. memcpy((PBYTE)&ulTmp, lpBase + spot, sizeof(ulTmp));
  589. m_mIdHigh = ntohl(ulTmp);
  590. spot += sizeof(u_long);
  591. wsprintfW(m_memberId, L"%08X%08X", m_mIdHigh, m_mIdLow);
  592. memcpy((PBYTE)&ulTmp, lpBase + spot, sizeof(ulTmp));
  593. m_ticketTime = ntohl(ulTmp);
  594. spot += sizeof(u_long);
  595. memcpy((PBYTE)&ulTmp, lpBase + spot, sizeof(ulTmp));
  596. m_lastSignInTime = ntohl(ulTmp);
  597. spot += sizeof(u_long);
  598. time(&curTime_t);
  599. curTime = (ULONG) curTime_t;
  600. // If the current time is "too" negative, bail (5 mins)
  601. memcpy((PBYTE)&ulTmp, lpBase + spot, sizeof(ulTmp));
  602. if ((unsigned long)(curTime+300) < ntohl(ulTmp))
  603. {
  604. if (g_pAlert)
  605. {
  606. memcpy((PBYTE)&ulTmp, lpBase + spot, sizeof(ulTmp));
  607. DWORD dwTimes[2] = { curTime, ntohl(ulTmp) };
  608. g_pAlert->report(PassportAlertInterface::ERROR_TYPE, PM_TIMESTAMP_BAD,
  609. 0, NULL, sizeof(DWORD) << 1, (LPVOID)dwTimes);
  610. }
  611. m_valid = FALSE;
  612. goto Cleanup;
  613. }
  614. spot += sizeof(u_long);
  615. m_savedPwd = (*(char*)(lpBase+spot)) == 'Y' ? TRUE : FALSE;
  616. spot += sizeof(char);
  617. if (dwByteLen == dw13XLen)
  618. {
  619. memcpy((PBYTE)&ulTmp, lpBase + spot, sizeof(ulTmp));
  620. m_flags = ntohl(ulTmp);
  621. }
  622. else
  623. {
  624. // HM cookie
  625. m_flags = 0;
  626. }
  627. spot += sizeof(u_long);
  628. m_valid = TRUE;
  629. if(pcParsed) *pcParsed = spot;
  630. Cleanup:
  631. if (m_valid == FALSE)
  632. {
  633. if(g_pAlert)
  634. g_pAlert->report(PassportAlertInterface::WARNING_TYPE, PM_INVALID_TICKET);
  635. if(g_pPerf)
  636. {
  637. g_pPerf->incrementCounter(PM_INVALIDREQUESTS_TOTAL);
  638. g_pPerf->incrementCounter(PM_INVALIDREQUESTS_SEC);
  639. }
  640. else
  641. {
  642. _ASSERT(g_pPerf);
  643. }
  644. }
  645. }
  646. //===========================================================================
  647. //
  648. // get_TicketTime
  649. //
  650. STDMETHODIMP CTicket::get_TicketTime(long *pVal)
  651. {
  652. PassportLog("CTicket::get_TicketTime: %X\r\n", m_ticketTime);
  653. *pVal = m_ticketTime;
  654. return S_OK;
  655. }
  656. //===========================================================================
  657. //
  658. // get_SignInTime
  659. //
  660. STDMETHODIMP CTicket::get_SignInTime(long *pVal)
  661. {
  662. PassportLog("CTicket::get_SignInTime: %X\r\n", m_lastSignInTime);
  663. *pVal = m_lastSignInTime;
  664. return S_OK;
  665. }
  666. //===========================================================================
  667. //
  668. // get_Error
  669. //
  670. STDMETHODIMP CTicket::get_Error(long* pVal)
  671. {
  672. PassportLog("CTicket::get_Error: %X\r\n", m_flags);
  673. *pVal = m_flags;
  674. return S_OK;
  675. }
  676. //===========================================================================
  677. //
  678. // GetPassportFlags
  679. //
  680. ULONG CTicket::GetPassportFlags()
  681. {
  682. return m_passportFlags;
  683. }
  684. //===========================================================================
  685. //
  686. // IsSecure
  687. //
  688. BOOL CTicket::IsSecure()
  689. {
  690. return ((m_passportFlags & k_ulFlagsSecuredTransportedTicket) != 0);
  691. }
  692. //===========================================================================
  693. //
  694. // DoSecureCheckInTicket -- use the information in the ticket to determine if secure signin
  695. //
  696. STDMETHODIMP CTicket::DoSecureCheckInTicket(/* [in] */ BOOL fSecureTransported)
  697. {
  698. m_bSecureCheckSucceeded =
  699. (fSecureTransported
  700. && (m_passportFlags & k_ulFlagsSecuredTransportedTicket) != 0);
  701. return S_OK;
  702. }
  703. //===========================================================================
  704. //
  705. // DoSecureCheck
  706. //
  707. STDMETHODIMP CTicket::DoSecureCheck(BSTR bstrSec)
  708. {
  709. if(bstrSec == NULL)
  710. return E_INVALIDARG;
  711. // make sure that the member id in the ticket
  712. // matches the member id in the secure cookie.
  713. m_bSecureCheckSucceeded = (memcmp(bstrSec, m_raw, sizeof(long) * 3) == 0);
  714. return S_OK;
  715. }
  716. //===========================================================================
  717. //
  718. // GetProperty
  719. //
  720. STDMETHODIMP CTicket::GetProperty(BSTR propName, VARIANT* pVal)
  721. {
  722. HRESULT hr = S_OK;
  723. TicketProperty prop;
  724. if (m_valid == FALSE)
  725. {
  726. AtlReportError(CLSID_Ticket, (LPCOLESTR) PP_E_INVALID_TICKETSTR,
  727. IID_IPassportTicket, PP_E_INVALID_TICKET);
  728. return PP_E_INVALID_TICKET;
  729. }
  730. if (!pVal) return E_POINTER;
  731. VariantInit(pVal);
  732. hr = m_PropBag.GetProperty(propName, prop);
  733. if (FAILED(hr)) goto Cleanup;
  734. if (hr == S_FALSE) // no such property back
  735. {
  736. AtlReportError(CLSID_Ticket, (LPCOLESTR) PP_E_NO_ATTRIBUTESTR,
  737. IID_IPassportTicket, PP_E_NO_ATTRIBUTE);
  738. hr = PP_E_NO_SUCH_ATTRIBUTE;
  739. goto Cleanup;
  740. }
  741. if (hr == S_OK)
  742. {
  743. // if(prop.flags & TPF_NO_RETRIEVE)
  744. *pVal = prop.value; // skin level copy
  745. prop.value.Detach();
  746. }
  747. Cleanup:
  748. return hr;
  749. }