BasePrincipal.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "mozilla/BasePrincipal.h"
  6. #include "nsDocShell.h"
  7. #include "nsIAddonPolicyService.h"
  8. #include "nsIContentSecurityPolicy.h"
  9. #include "nsIEffectiveTLDService.h"
  10. #include "nsIObjectInputStream.h"
  11. #include "nsIObjectOutputStream.h"
  12. #include "nsPrincipal.h"
  13. #include "nsNetUtil.h"
  14. #include "nsIURIWithPrincipal.h"
  15. #include "nsNullPrincipal.h"
  16. #include "nsScriptSecurityManager.h"
  17. #include "nsServiceManagerUtils.h"
  18. #include "mozilla/dom/ChromeUtils.h"
  19. #include "mozilla/dom/CSPDictionariesBinding.h"
  20. #include "mozilla/dom/quota/QuotaManager.h"
  21. #include "mozilla/dom/ToJSValue.h"
  22. #include "mozilla/dom/URLSearchParams.h"
  23. namespace mozilla {
  24. using dom::URLParams;
  25. void
  26. PrincipalOriginAttributes::InheritFromDocShellToDoc(const DocShellOriginAttributes& aAttrs,
  27. const nsIURI* aURI)
  28. {
  29. mAppId = aAttrs.mAppId;
  30. mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser;
  31. // addonId is computed from the principal URI and never propagated
  32. mUserContextId = aAttrs.mUserContextId;
  33. mPrivateBrowsingId = aAttrs.mPrivateBrowsingId;
  34. mFirstPartyDomain = aAttrs.mFirstPartyDomain;
  35. }
  36. void
  37. PrincipalOriginAttributes::InheritFromNecko(const NeckoOriginAttributes& aAttrs)
  38. {
  39. mAppId = aAttrs.mAppId;
  40. mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser;
  41. // addonId is computed from the principal URI and never propagated
  42. mUserContextId = aAttrs.mUserContextId;
  43. mPrivateBrowsingId = aAttrs.mPrivateBrowsingId;
  44. mFirstPartyDomain = aAttrs.mFirstPartyDomain;
  45. }
  46. void
  47. PrincipalOriginAttributes::StripUserContextIdAndFirstPartyDomain()
  48. {
  49. mUserContextId = nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID;
  50. mFirstPartyDomain.Truncate();
  51. }
  52. void
  53. DocShellOriginAttributes::InheritFromDocToChildDocShell(const PrincipalOriginAttributes& aAttrs)
  54. {
  55. mAppId = aAttrs.mAppId;
  56. mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser;
  57. // addonId is computed from the principal URI and never propagated
  58. mUserContextId = aAttrs.mUserContextId;
  59. mPrivateBrowsingId = aAttrs.mPrivateBrowsingId;
  60. mFirstPartyDomain = aAttrs.mFirstPartyDomain;
  61. }
  62. void
  63. NeckoOriginAttributes::InheritFromDocToNecko(const PrincipalOriginAttributes& aAttrs)
  64. {
  65. mAppId = aAttrs.mAppId;
  66. mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser;
  67. // addonId is computed from the principal URI and never propagated
  68. mUserContextId = aAttrs.mUserContextId;
  69. mPrivateBrowsingId = aAttrs.mPrivateBrowsingId;
  70. mFirstPartyDomain = aAttrs.mFirstPartyDomain;
  71. }
  72. void
  73. NeckoOriginAttributes::InheritFromDocShellToNecko(const DocShellOriginAttributes& aAttrs,
  74. const bool aIsTopLevelDocument,
  75. nsIURI* aURI)
  76. {
  77. mAppId = aAttrs.mAppId;
  78. mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser;
  79. // addonId is computed from the principal URI and never propagated
  80. mUserContextId = aAttrs.mUserContextId;
  81. mPrivateBrowsingId = aAttrs.mPrivateBrowsingId;
  82. bool isFirstPartyEnabled = IsFirstPartyEnabled();
  83. // When the pref is on, we also compute the firstPartyDomain attribute
  84. // if this is for top-level document.
  85. if (isFirstPartyEnabled && aIsTopLevelDocument) {
  86. nsCOMPtr<nsIEffectiveTLDService> tldService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
  87. MOZ_ASSERT(tldService);
  88. if (!tldService) {
  89. return;
  90. }
  91. nsAutoCString baseDomain;
  92. tldService->GetBaseDomain(aURI, 0, baseDomain);
  93. mFirstPartyDomain = NS_ConvertUTF8toUTF16(baseDomain);
  94. } else {
  95. mFirstPartyDomain = aAttrs.mFirstPartyDomain;
  96. }
  97. }
  98. void
  99. OriginAttributes::CreateSuffix(nsACString& aStr) const
  100. {
  101. UniquePtr<URLParams> params(new URLParams());
  102. nsAutoString value;
  103. //
  104. // Important: While serializing any string-valued attributes, perform a
  105. // release-mode assertion to make sure that they don't contain characters that
  106. // will break the quota manager when it uses the serialization for file
  107. // naming (see addonId below).
  108. //
  109. if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
  110. value.AppendInt(mAppId);
  111. params->Set(NS_LITERAL_STRING("appId"), value);
  112. }
  113. if (mInIsolatedMozBrowser) {
  114. params->Set(NS_LITERAL_STRING("inBrowser"), NS_LITERAL_STRING("1"));
  115. }
  116. if (!mAddonId.IsEmpty()) {
  117. if (mAddonId.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) != kNotFound) {
  118. MOZ_CRASH();
  119. }
  120. params->Set(NS_LITERAL_STRING("addonId"), mAddonId);
  121. }
  122. if (mUserContextId != nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) {
  123. value.Truncate();
  124. value.AppendInt(mUserContextId);
  125. params->Set(NS_LITERAL_STRING("userContextId"), value);
  126. }
  127. if (mPrivateBrowsingId) {
  128. value.Truncate();
  129. value.AppendInt(mPrivateBrowsingId);
  130. params->Set(NS_LITERAL_STRING("privateBrowsingId"), value);
  131. }
  132. if (!mFirstPartyDomain.IsEmpty()) {
  133. MOZ_RELEASE_ASSERT(mFirstPartyDomain.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
  134. params->Set(NS_LITERAL_STRING("firstPartyDomain"), mFirstPartyDomain);
  135. }
  136. aStr.Truncate();
  137. params->Serialize(value);
  138. if (!value.IsEmpty()) {
  139. aStr.AppendLiteral("^");
  140. aStr.Append(NS_ConvertUTF16toUTF8(value));
  141. }
  142. // In debug builds, check the whole string for illegal characters too (just in case).
  143. #ifdef DEBUG
  144. nsAutoCString str;
  145. str.Assign(aStr);
  146. MOZ_ASSERT(str.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
  147. #endif
  148. }
  149. void
  150. OriginAttributes::CreateAnonymizedSuffix(nsACString& aStr) const
  151. {
  152. OriginAttributes attrs = *this;
  153. if (!attrs.mFirstPartyDomain.IsEmpty()) {
  154. attrs.mFirstPartyDomain.AssignLiteral("_anonymizedFirstPartyDomain_");
  155. }
  156. attrs.CreateSuffix(aStr);
  157. }
  158. namespace {
  159. class MOZ_STACK_CLASS PopulateFromSuffixIterator final
  160. : public URLParams::ForEachIterator
  161. {
  162. public:
  163. explicit PopulateFromSuffixIterator(OriginAttributes* aOriginAttributes)
  164. : mOriginAttributes(aOriginAttributes)
  165. {
  166. MOZ_ASSERT(aOriginAttributes);
  167. // If mPrivateBrowsingId is passed in as >0 and is not present in the suffix,
  168. // then it will remain >0 when it should be 0 according to the suffix. Set to 0 before
  169. // iterating to fix this.
  170. mOriginAttributes->mPrivateBrowsingId = 0;
  171. }
  172. bool URLParamsIterator(const nsString& aName,
  173. const nsString& aValue) override
  174. {
  175. if (aName.EqualsLiteral("appId")) {
  176. nsresult rv;
  177. int64_t val = aValue.ToInteger64(&rv);
  178. NS_ENSURE_SUCCESS(rv, false);
  179. NS_ENSURE_TRUE(val <= UINT32_MAX, false);
  180. mOriginAttributes->mAppId = static_cast<uint32_t>(val);
  181. return true;
  182. }
  183. if (aName.EqualsLiteral("inBrowser")) {
  184. if (!aValue.EqualsLiteral("1")) {
  185. return false;
  186. }
  187. mOriginAttributes->mInIsolatedMozBrowser = true;
  188. return true;
  189. }
  190. if (aName.EqualsLiteral("addonId")) {
  191. MOZ_RELEASE_ASSERT(mOriginAttributes->mAddonId.IsEmpty());
  192. mOriginAttributes->mAddonId.Assign(aValue);
  193. return true;
  194. }
  195. if (aName.EqualsLiteral("userContextId")) {
  196. nsresult rv;
  197. int64_t val = aValue.ToInteger64(&rv);
  198. NS_ENSURE_SUCCESS(rv, false);
  199. NS_ENSURE_TRUE(val <= UINT32_MAX, false);
  200. mOriginAttributes->mUserContextId = static_cast<uint32_t>(val);
  201. return true;
  202. }
  203. if (aName.EqualsLiteral("privateBrowsingId")) {
  204. nsresult rv;
  205. int64_t val = aValue.ToInteger64(&rv);
  206. NS_ENSURE_SUCCESS(rv, false);
  207. NS_ENSURE_TRUE(val >= 0 && val <= UINT32_MAX, false);
  208. mOriginAttributes->mPrivateBrowsingId = static_cast<uint32_t>(val);
  209. return true;
  210. }
  211. if (aName.EqualsLiteral("firstPartyDomain")) {
  212. MOZ_RELEASE_ASSERT(mOriginAttributes->mFirstPartyDomain.IsEmpty());
  213. mOriginAttributes->mFirstPartyDomain.Assign(aValue);
  214. return true;
  215. }
  216. // No other attributes are supported.
  217. return false;
  218. }
  219. private:
  220. OriginAttributes* mOriginAttributes;
  221. };
  222. } // namespace
  223. bool
  224. OriginAttributes::PopulateFromSuffix(const nsACString& aStr)
  225. {
  226. if (aStr.IsEmpty()) {
  227. return true;
  228. }
  229. if (aStr[0] != '^') {
  230. return false;
  231. }
  232. UniquePtr<URLParams> params(new URLParams());
  233. params->ParseInput(Substring(aStr, 1, aStr.Length() - 1));
  234. PopulateFromSuffixIterator iterator(this);
  235. return params->ForEach(iterator);
  236. }
  237. bool
  238. OriginAttributes::PopulateFromOrigin(const nsACString& aOrigin,
  239. nsACString& aOriginNoSuffix)
  240. {
  241. // RFindChar is only available on nsCString.
  242. nsCString origin(aOrigin);
  243. int32_t pos = origin.RFindChar('^');
  244. if (pos == kNotFound) {
  245. aOriginNoSuffix = origin;
  246. return true;
  247. }
  248. aOriginNoSuffix = Substring(origin, 0, pos);
  249. return PopulateFromSuffix(Substring(origin, pos));
  250. }
  251. void
  252. OriginAttributes::SyncAttributesWithPrivateBrowsing(bool aInPrivateBrowsing)
  253. {
  254. mPrivateBrowsingId = aInPrivateBrowsing ? 1 : 0;
  255. }
  256. void
  257. OriginAttributes::SetFromGenericAttributes(const GenericOriginAttributes& aAttrs)
  258. {
  259. mAppId = aAttrs.mAppId;
  260. mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser;
  261. mAddonId = aAttrs.mAddonId;
  262. mUserContextId = aAttrs.mUserContextId;
  263. mPrivateBrowsingId = aAttrs.mPrivateBrowsingId;
  264. mFirstPartyDomain = aAttrs.mFirstPartyDomain;
  265. }
  266. /* static */
  267. bool
  268. OriginAttributes::IsFirstPartyEnabled()
  269. {
  270. // Cache the privacy.firstparty.isolate pref.
  271. static bool sFirstPartyIsolation = false;
  272. static bool sCachedFirstPartyPref = false;
  273. if (!sCachedFirstPartyPref) {
  274. sCachedFirstPartyPref = true;
  275. Preferences::AddBoolVarCache(&sFirstPartyIsolation, "privacy.firstparty.isolate");
  276. }
  277. return sFirstPartyIsolation;
  278. }
  279. BasePrincipal::BasePrincipal()
  280. {}
  281. BasePrincipal::~BasePrincipal()
  282. {}
  283. NS_IMETHODIMP
  284. BasePrincipal::GetOrigin(nsACString& aOrigin)
  285. {
  286. nsresult rv = GetOriginInternal(aOrigin);
  287. NS_ENSURE_SUCCESS(rv, rv);
  288. nsAutoCString suffix;
  289. mOriginAttributes.CreateSuffix(suffix);
  290. aOrigin.Append(suffix);
  291. return NS_OK;
  292. }
  293. NS_IMETHODIMP
  294. BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin)
  295. {
  296. return GetOriginInternal(aOrigin);
  297. }
  298. bool
  299. BasePrincipal::Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration)
  300. {
  301. MOZ_ASSERT(aOther);
  302. // Expanded principals handle origin attributes for each of their
  303. // sub-principals individually, null principals do only simple checks for
  304. // pointer equality, and system principals are immune to origin attributes
  305. // checks, so only do this check for codebase principals.
  306. if (Kind() == eCodebasePrincipal &&
  307. OriginAttributesRef() != Cast(aOther)->OriginAttributesRef()) {
  308. return false;
  309. }
  310. return SubsumesInternal(aOther, aConsideration);
  311. }
  312. NS_IMETHODIMP
  313. BasePrincipal::Equals(nsIPrincipal *aOther, bool *aResult)
  314. {
  315. NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
  316. *aResult = Subsumes(aOther, DontConsiderDocumentDomain) &&
  317. Cast(aOther)->Subsumes(this, DontConsiderDocumentDomain);
  318. return NS_OK;
  319. }
  320. NS_IMETHODIMP
  321. BasePrincipal::EqualsConsideringDomain(nsIPrincipal *aOther, bool *aResult)
  322. {
  323. NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
  324. *aResult = Subsumes(aOther, ConsiderDocumentDomain) &&
  325. Cast(aOther)->Subsumes(this, ConsiderDocumentDomain);
  326. return NS_OK;
  327. }
  328. bool
  329. BasePrincipal::EqualsIgnoringAddonId(nsIPrincipal *aOther)
  330. {
  331. MOZ_ASSERT(aOther);
  332. // Note that this will not work for expanded principals, nor is it intended
  333. // to.
  334. if (!dom::ChromeUtils::IsOriginAttributesEqualIgnoringAddonId(
  335. OriginAttributesRef(), Cast(aOther)->OriginAttributesRef())) {
  336. return false;
  337. }
  338. return SubsumesInternal(aOther, DontConsiderDocumentDomain) &&
  339. Cast(aOther)->SubsumesInternal(this, DontConsiderDocumentDomain);
  340. }
  341. NS_IMETHODIMP
  342. BasePrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
  343. {
  344. NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
  345. *aResult = Subsumes(aOther, DontConsiderDocumentDomain);
  346. return NS_OK;
  347. }
  348. NS_IMETHODIMP
  349. BasePrincipal::SubsumesConsideringDomain(nsIPrincipal *aOther, bool *aResult)
  350. {
  351. NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
  352. *aResult = Subsumes(aOther, ConsiderDocumentDomain);
  353. return NS_OK;
  354. }
  355. NS_IMETHODIMP
  356. BasePrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsPrincipal)
  357. {
  358. // Check the internal method first, which allows us to quickly approve loads
  359. // for the System Principal.
  360. if (MayLoadInternal(aURI)) {
  361. return NS_OK;
  362. }
  363. nsresult rv;
  364. if (aAllowIfInheritsPrincipal) {
  365. // If the caller specified to allow loads of URIs that inherit
  366. // our principal, allow the load if this URI inherits its principal.
  367. bool doesInheritSecurityContext;
  368. rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
  369. &doesInheritSecurityContext);
  370. if (NS_SUCCEEDED(rv) && doesInheritSecurityContext) {
  371. return NS_OK;
  372. }
  373. }
  374. bool fetchableByAnyone;
  375. rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_FETCHABLE_BY_ANYONE, &fetchableByAnyone);
  376. if (NS_SUCCEEDED(rv) && fetchableByAnyone) {
  377. return NS_OK;
  378. }
  379. if (aReport) {
  380. nsCOMPtr<nsIURI> prinURI;
  381. rv = GetURI(getter_AddRefs(prinURI));
  382. if (NS_SUCCEEDED(rv) && prinURI) {
  383. nsScriptSecurityManager::ReportError(nullptr, NS_LITERAL_STRING("CheckSameOriginError"), prinURI, aURI);
  384. }
  385. }
  386. return NS_ERROR_DOM_BAD_URI;
  387. }
  388. NS_IMETHODIMP
  389. BasePrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
  390. {
  391. NS_IF_ADDREF(*aCsp = mCSP);
  392. return NS_OK;
  393. }
  394. NS_IMETHODIMP
  395. BasePrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
  396. {
  397. // Never destroy an existing CSP on the principal.
  398. // This method should only be called in rare cases.
  399. MOZ_ASSERT(!mCSP, "do not destroy an existing CSP");
  400. if (mCSP) {
  401. return NS_ERROR_ALREADY_INITIALIZED;
  402. }
  403. mCSP = aCsp;
  404. return NS_OK;
  405. }
  406. NS_IMETHODIMP
  407. BasePrincipal::EnsureCSP(nsIDOMDocument* aDocument,
  408. nsIContentSecurityPolicy** aCSP)
  409. {
  410. if (mCSP) {
  411. // if there is a CSP already associated with this principal
  412. // then just return that - do not overwrite it!!!
  413. NS_IF_ADDREF(*aCSP = mCSP);
  414. return NS_OK;
  415. }
  416. nsresult rv = NS_OK;
  417. mCSP = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
  418. NS_ENSURE_SUCCESS(rv, rv);
  419. // Store the request context for violation reports
  420. rv = aDocument ? mCSP->SetRequestContext(aDocument, nullptr)
  421. : mCSP->SetRequestContext(nullptr, this);
  422. NS_ENSURE_SUCCESS(rv, rv);
  423. NS_IF_ADDREF(*aCSP = mCSP);
  424. return NS_OK;
  425. }
  426. NS_IMETHODIMP
  427. BasePrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP)
  428. {
  429. NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
  430. return NS_OK;
  431. }
  432. NS_IMETHODIMP
  433. BasePrincipal::EnsurePreloadCSP(nsIDOMDocument* aDocument,
  434. nsIContentSecurityPolicy** aPreloadCSP)
  435. {
  436. if (mPreloadCSP) {
  437. // if there is a speculative CSP already associated with this principal
  438. // then just return that - do not overwrite it!!!
  439. NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
  440. return NS_OK;
  441. }
  442. nsresult rv = NS_OK;
  443. mPreloadCSP = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
  444. NS_ENSURE_SUCCESS(rv, rv);
  445. // Store the request context for violation reports
  446. rv = aDocument ? mPreloadCSP->SetRequestContext(aDocument, nullptr)
  447. : mPreloadCSP->SetRequestContext(nullptr, this);
  448. NS_ENSURE_SUCCESS(rv, rv);
  449. NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
  450. return NS_OK;
  451. }
  452. NS_IMETHODIMP
  453. BasePrincipal::GetCspJSON(nsAString& outCSPinJSON)
  454. {
  455. outCSPinJSON.Truncate();
  456. dom::CSPPolicies jsonPolicies;
  457. if (!mCSP) {
  458. jsonPolicies.ToJSON(outCSPinJSON);
  459. return NS_OK;
  460. }
  461. return mCSP->ToJSON(outCSPinJSON);
  462. }
  463. NS_IMETHODIMP
  464. BasePrincipal::GetIsNullPrincipal(bool* aResult)
  465. {
  466. *aResult = Kind() == eNullPrincipal;
  467. return NS_OK;
  468. }
  469. NS_IMETHODIMP
  470. BasePrincipal::GetIsCodebasePrincipal(bool* aResult)
  471. {
  472. *aResult = Kind() == eCodebasePrincipal;
  473. return NS_OK;
  474. }
  475. NS_IMETHODIMP
  476. BasePrincipal::GetIsExpandedPrincipal(bool* aResult)
  477. {
  478. *aResult = Kind() == eExpandedPrincipal;
  479. return NS_OK;
  480. }
  481. NS_IMETHODIMP
  482. BasePrincipal::GetIsSystemPrincipal(bool* aResult)
  483. {
  484. *aResult = Kind() == eSystemPrincipal;
  485. return NS_OK;
  486. }
  487. NS_IMETHODIMP
  488. BasePrincipal::GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
  489. {
  490. if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
  491. return NS_ERROR_FAILURE;
  492. }
  493. return NS_OK;
  494. }
  495. NS_IMETHODIMP
  496. BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes)
  497. {
  498. mOriginAttributes.CreateSuffix(aOriginAttributes);
  499. return NS_OK;
  500. }
  501. NS_IMETHODIMP
  502. BasePrincipal::GetAppStatus(uint16_t* aAppStatus)
  503. {
  504. if (AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
  505. NS_WARNING("Asking for app status on a principal with an unknown app id");
  506. *aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
  507. return NS_OK;
  508. }
  509. *aAppStatus = nsScriptSecurityManager::AppStatusForPrincipal(this);
  510. return NS_OK;
  511. }
  512. NS_IMETHODIMP
  513. BasePrincipal::GetAppId(uint32_t* aAppId)
  514. {
  515. if (AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
  516. MOZ_ASSERT(false);
  517. *aAppId = nsIScriptSecurityManager::NO_APP_ID;
  518. return NS_OK;
  519. }
  520. *aAppId = AppId();
  521. return NS_OK;
  522. }
  523. NS_IMETHODIMP
  524. BasePrincipal::GetAddonId(nsAString& aAddonId)
  525. {
  526. aAddonId.Assign(mOriginAttributes.mAddonId);
  527. return NS_OK;
  528. }
  529. NS_IMETHODIMP
  530. BasePrincipal::GetUserContextId(uint32_t* aUserContextId)
  531. {
  532. *aUserContextId = UserContextId();
  533. return NS_OK;
  534. }
  535. NS_IMETHODIMP
  536. BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId)
  537. {
  538. *aPrivateBrowsingId = PrivateBrowsingId();
  539. return NS_OK;
  540. }
  541. NS_IMETHODIMP
  542. BasePrincipal::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement)
  543. {
  544. *aIsInIsolatedMozBrowserElement = IsInIsolatedMozBrowserElement();
  545. return NS_OK;
  546. }
  547. NS_IMETHODIMP
  548. BasePrincipal::GetUnknownAppId(bool* aUnknownAppId)
  549. {
  550. *aUnknownAppId = AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID;
  551. return NS_OK;
  552. }
  553. bool
  554. BasePrincipal::AddonHasPermission(const nsAString& aPerm)
  555. {
  556. if (mOriginAttributes.mAddonId.IsEmpty()) {
  557. return false;
  558. }
  559. nsCOMPtr<nsIAddonPolicyService> aps =
  560. do_GetService("@mozilla.org/addons/policy-service;1");
  561. NS_ENSURE_TRUE(aps, false);
  562. bool retval = false;
  563. nsresult rv = aps->AddonHasPermission(mOriginAttributes.mAddonId, aPerm, &retval);
  564. NS_ENSURE_SUCCESS(rv, false);
  565. return retval;
  566. }
  567. already_AddRefed<BasePrincipal>
  568. BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, const PrincipalOriginAttributes& aAttrs)
  569. {
  570. // If the URI is supposed to inherit the security context of whoever loads it,
  571. // we shouldn't make a codebase principal for it.
  572. bool inheritsPrincipal;
  573. nsresult rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
  574. &inheritsPrincipal);
  575. if (NS_FAILED(rv) || inheritsPrincipal) {
  576. return nsNullPrincipal::Create(aAttrs);
  577. }
  578. // Check whether the URI knows what its principal is supposed to be.
  579. nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
  580. if (uriPrinc) {
  581. nsCOMPtr<nsIPrincipal> principal;
  582. uriPrinc->GetPrincipal(getter_AddRefs(principal));
  583. if (!principal) {
  584. return nsNullPrincipal::Create(aAttrs);
  585. }
  586. RefPtr<BasePrincipal> concrete = Cast(principal);
  587. return concrete.forget();
  588. }
  589. // Mint a codebase principal.
  590. RefPtr<nsPrincipal> codebase = new nsPrincipal();
  591. rv = codebase->Init(aURI, aAttrs);
  592. NS_ENSURE_SUCCESS(rv, nullptr);
  593. return codebase.forget();
  594. }
  595. already_AddRefed<BasePrincipal>
  596. BasePrincipal::CreateCodebasePrincipal(const nsACString& aOrigin)
  597. {
  598. MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING("[")),
  599. "CreateCodebasePrincipal does not support System and Expanded principals");
  600. MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":")),
  601. "CreateCodebasePrincipal does not support nsNullPrincipal");
  602. nsAutoCString originNoSuffix;
  603. mozilla::PrincipalOriginAttributes attrs;
  604. if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
  605. return nullptr;
  606. }
  607. nsCOMPtr<nsIURI> uri;
  608. nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
  609. NS_ENSURE_SUCCESS(rv, nullptr);
  610. return BasePrincipal::CreateCodebasePrincipal(uri, attrs);
  611. }
  612. already_AddRefed<BasePrincipal>
  613. BasePrincipal::CloneStrippingUserContextIdAndFirstPartyDomain()
  614. {
  615. PrincipalOriginAttributes attrs = OriginAttributesRef();
  616. attrs.StripUserContextIdAndFirstPartyDomain();
  617. nsAutoCString originNoSuffix;
  618. nsresult rv = GetOriginNoSuffix(originNoSuffix);
  619. NS_ENSURE_SUCCESS(rv, nullptr);
  620. nsCOMPtr<nsIURI> uri;
  621. rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
  622. NS_ENSURE_SUCCESS(rv, nullptr);
  623. return BasePrincipal::CreateCodebasePrincipal(uri, attrs);
  624. }
  625. bool
  626. BasePrincipal::AddonAllowsLoad(nsIURI* aURI)
  627. {
  628. if (mOriginAttributes.mAddonId.IsEmpty()) {
  629. return false;
  630. }
  631. nsCOMPtr<nsIAddonPolicyService> aps = do_GetService("@mozilla.org/addons/policy-service;1");
  632. NS_ENSURE_TRUE(aps, false);
  633. bool allowed = false;
  634. nsresult rv = aps->AddonMayLoadURI(mOriginAttributes.mAddonId, aURI, &allowed);
  635. return NS_SUCCEEDED(rv) && allowed;
  636. }
  637. } // namespace mozilla