nsresult LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs, nsILoadInfo** outLoadInfo) { if (aOptionalLoadInfoArgs.type() == OptionalLoadInfoArgs::Tvoid_t) { *outLoadInfo = nullptr; return NS_OK; } const LoadInfoArgs& loadInfoArgs = aOptionalLoadInfoArgs.get_LoadInfoArgs(); nsresult rv = NS_OK; nsCOMPtr<nsIPrincipal> requestingPrincipal = PrincipalInfoToPrincipal(loadInfoArgs.requestingPrincipalInfo(), &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIPrincipal> triggeringPrincipal = PrincipalInfoToPrincipal(loadInfoArgs.triggeringPrincipalInfo(), &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsILoadInfo> loadInfo = new mozilla::LoadInfo(requestingPrincipal, triggeringPrincipal, loadInfoArgs.securityFlags(), loadInfoArgs.contentPolicyType(), loadInfoArgs.upgradeInsecureRequests(), loadInfoArgs.innerWindowID(), loadInfoArgs.outerWindowID(), loadInfoArgs.parentOuterWindowID()); loadInfo.forget(outLoadInfo); return NS_OK; }
nsresult LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs, nsILoadInfo** outLoadInfo) { if (aOptionalLoadInfoArgs.type() == OptionalLoadInfoArgs::Tvoid_t) { *outLoadInfo = nullptr; return NS_OK; } const LoadInfoArgs& loadInfoArgs = aOptionalLoadInfoArgs.get_LoadInfoArgs(); nsresult rv = NS_OK; nsCOMPtr<nsIPrincipal> requestingPrincipal = PrincipalInfoToPrincipal(loadInfoArgs.requestingPrincipalInfo(), &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIPrincipal> triggeringPrincipal = PrincipalInfoToPrincipal(loadInfoArgs.triggeringPrincipalInfo(), &rv); NS_ENSURE_SUCCESS(rv, rv); nsTArray<nsCOMPtr<nsIPrincipal>> redirectChainIncludingInternalRedirects; for (const PrincipalInfo& principalInfo : loadInfoArgs.redirectChainIncludingInternalRedirects()) { nsCOMPtr<nsIPrincipal> redirectedPrincipal = PrincipalInfoToPrincipal(principalInfo, &rv); NS_ENSURE_SUCCESS(rv, rv); redirectChainIncludingInternalRedirects.AppendElement(redirectedPrincipal.forget()); } nsTArray<nsCOMPtr<nsIPrincipal>> redirectChain; for (const PrincipalInfo& principalInfo : loadInfoArgs.redirectChain()) { nsCOMPtr<nsIPrincipal> redirectedPrincipal = PrincipalInfoToPrincipal(principalInfo, &rv); NS_ENSURE_SUCCESS(rv, rv); redirectChain.AppendElement(redirectedPrincipal.forget()); } nsCOMPtr<nsILoadInfo> loadInfo = new mozilla::LoadInfo(requestingPrincipal, triggeringPrincipal, loadInfoArgs.securityFlags(), loadInfoArgs.contentPolicyType(), loadInfoArgs.upgradeInsecureRequests(), loadInfoArgs.upgradeInsecurePreloads(), loadInfoArgs.innerWindowID(), loadInfoArgs.outerWindowID(), loadInfoArgs.parentOuterWindowID(), loadInfoArgs.enforceSecurity(), loadInfoArgs.initialSecurityCheckDone(), loadInfoArgs.isInThirdPartyContext(), loadInfoArgs.originAttributes(), redirectChainIncludingInternalRedirects, redirectChain); loadInfo.forget(outLoadInfo); return NS_OK; }
nsresult LoadInfoArgsToLoadInfo(const mozilla::net::LoadInfoArgs& aLoadInfoArgs, nsILoadInfo** outLoadInfo) { nsresult rv = NS_OK; nsCOMPtr<nsIPrincipal> requestingPrincipal = PrincipalInfoToPrincipal(aLoadInfoArgs.requestingPrincipalInfo(), &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIPrincipal> triggeringPrincipal = PrincipalInfoToPrincipal(aLoadInfoArgs.triggeringPrincipalInfo(), &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsILoadInfo> loadInfo = new mozilla::LoadInfo(requestingPrincipal, triggeringPrincipal, aLoadInfoArgs.securityFlags(), aLoadInfoArgs.contentPolicyType(), aLoadInfoArgs.innerWindowID(), aLoadInfoArgs.outerWindowID(), aLoadInfoArgs.parentOuterWindowID()); loadInfo.forget(outLoadInfo); return NS_OK; }
bool ServiceWorkerManagerChild::RecvNotifyUnregister(const PrincipalInfo& aPrincipalInfo, const nsString& aScope) { if (mShuttingDown) { return true; } nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance(); MOZ_ASSERT(swm); nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(aPrincipalInfo); if (NS_WARN_IF(!principal)) { return true; } nsresult rv = swm->Unregister(principal, nullptr, aScope); unused << NS_WARN_IF(NS_FAILED(rv)); return true; }
void ServiceWorkerManagerService::PropagateRegistration( uint64_t aParentID, ServiceWorkerRegistrationData& aData) { AssertIsOnBackgroundThread(); if (ServiceWorkerParentInterceptEnabled()) { return; } DebugOnly<bool> parentFound = false; for (auto iter = mAgents.Iter(); !iter.Done(); iter.Next()) { RefPtr<ServiceWorkerManagerParent> parent = iter.Get()->GetKey(); MOZ_ASSERT(parent); if (parent->ID() != aParentID) { Unused << parent->SendNotifyRegister(aData); #ifdef DEBUG } else { parentFound = true; #endif } } // Send permissions fot the newly registered service worker to all of the // content processes. PrincipalInfo pi = aData.principal(); NS_DispatchToMainThread(NS_NewRunnableFunction( "dom::ServiceWorkerManagerService::PropagateRegistration", [pi]() { nsTArray<ContentParent*> cps; ContentParent::GetAll(cps); for (auto* cp : cps) { nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(pi); if (principal) { cp->TransmitPermissionsForPrincipal(principal); } } })); #ifdef DEBUG MOZ_ASSERT(parentFound); #endif }
mozilla::ipc::IPCResult ServiceWorkerManagerChild::RecvNotifyUnregister( const PrincipalInfo& aPrincipalInfo, const nsString& aScope) { if (mShuttingDown) { return IPC_OK(); } RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance(); if (!swm) { // browser shutdown return IPC_OK(); } nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(aPrincipalInfo); if (NS_WARN_IF(!principal)) { return IPC_OK(); } nsresult rv = swm->NotifyUnregister(principal, aScope); Unused << NS_WARN_IF(NS_FAILED(rv)); return IPC_OK(); }
already_AddRefed<nsIPrincipal> PrincipalInfoToPrincipal(const PrincipalInfo& aPrincipalInfo, nsresult* aOptionalResult) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aPrincipalInfo.type() != PrincipalInfo::T__None); nsresult stackResult; nsresult& rv = aOptionalResult ? *aOptionalResult : stackResult; nsCOMPtr<nsIScriptSecurityManager> secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr; } nsCOMPtr<nsIPrincipal> principal; switch (aPrincipalInfo.type()) { case PrincipalInfo::TSystemPrincipalInfo: { rv = secMan->GetSystemPrincipal(getter_AddRefs(principal)); if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr; } return principal.forget(); } case PrincipalInfo::TNullPrincipalInfo: { const NullPrincipalInfo& info = aPrincipalInfo.get_NullPrincipalInfo(); principal = nsNullPrincipal::Create(info.attrs()); return principal.forget(); } case PrincipalInfo::TContentPrincipalInfo: { const ContentPrincipalInfo& info = aPrincipalInfo.get_ContentPrincipalInfo(); nsCOMPtr<nsIURI> uri; rv = NS_NewURI(getter_AddRefs(uri), info.spec()); if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr; } PrincipalOriginAttributes attrs; if (info.attrs().mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) { attrs = info.attrs(); } principal = BasePrincipal::CreateCodebasePrincipal(uri, attrs); rv = principal ? NS_OK : NS_ERROR_FAILURE; if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr; } return principal.forget(); } case PrincipalInfo::TExpandedPrincipalInfo: { const ExpandedPrincipalInfo& info = aPrincipalInfo.get_ExpandedPrincipalInfo(); nsTArray<nsCOMPtr<nsIPrincipal>> whitelist; nsCOMPtr<nsIPrincipal> wlPrincipal; for (uint32_t i = 0; i < info.whitelist().Length(); i++) { wlPrincipal = PrincipalInfoToPrincipal(info.whitelist()[i], &rv); if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr; } // append that principal to the whitelist whitelist.AppendElement(wlPrincipal); } RefPtr<nsExpandedPrincipal> expandedPrincipal = new nsExpandedPrincipal(whitelist, info.attrs()); if (!expandedPrincipal) { NS_WARNING("could not instantiate expanded principal"); return nullptr; } principal = expandedPrincipal; return principal.forget(); } default: MOZ_CRASH("Unknown PrincipalInfo type!"); } MOZ_CRASH("Should never get here!"); }
already_AddRefed<IDBOpenDBRequest> IDBFactory::OpenInternal(JSContext* aCx, nsIPrincipal* aPrincipal, const nsAString& aName, const Optional<uint64_t>& aVersion, const Optional<StorageType>& aStorageType, bool aDeleting, CallerType aCallerType, ErrorResult& aRv) { MOZ_ASSERT(mWindow || mOwningObject); MOZ_ASSERT_IF(!mWindow, !mPrivateBrowsingMode); CommonFactoryRequestParams commonParams; PrincipalInfo& principalInfo = commonParams.principalInfo(); if (aPrincipal) { if (!NS_IsMainThread()) { MOZ_CRASH("Figure out security checks for workers! What's this " "aPrincipal we have on a worker thread?"); } MOZ_ASSERT(aCallerType == CallerType::System); MOZ_DIAGNOSTIC_ASSERT(mPrivateBrowsingMode == (aPrincipal->GetPrivateBrowsingId() > 0)); if (NS_WARN_IF(NS_FAILED(PrincipalToPrincipalInfo(aPrincipal, &principalInfo)))) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } if (principalInfo.type() != PrincipalInfo::TContentPrincipalInfo && principalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } } else { principalInfo = *mPrincipalInfo; } uint64_t version = 0; if (!aDeleting && aVersion.WasPassed()) { if (aVersion.Value() < 1) { aRv.ThrowTypeError<MSG_INVALID_VERSION>(); return nullptr; } version = aVersion.Value(); } // Nothing can be done here if we have previously failed to create a // background actor. if (mBackgroundActorFailed) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } PersistenceType persistenceType; bool isInternal = principalInfo.type() == PrincipalInfo::TSystemPrincipalInfo; if (!isInternal && principalInfo.type() == PrincipalInfo::TContentPrincipalInfo) { nsCString origin = principalInfo.get_ContentPrincipalInfo().originNoSuffix(); isInternal = QuotaManager::IsOriginInternal(origin); } // Allow storage attributes for add-ons independent of the pref. // This works in the main thread only, workers don't have the principal. bool isAddon = false; if (NS_IsMainThread()) { // aPrincipal is passed inconsistently, so even when we are already on // the main thread, we may have been passed a null aPrincipal. nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(principalInfo); if (principal) { nsAutoString addonId; Unused << NS_WARN_IF(NS_FAILED(principal->GetAddonId(addonId))); isAddon = !addonId.IsEmpty(); } } if (isInternal) { // Chrome privilege and internal origins always get persistent storage. persistenceType = PERSISTENCE_TYPE_PERSISTENT; } else if (isAddon || DOMPrefs::IndexedDBStorageOptionsEnabled()) { persistenceType = PersistenceTypeFromStorage(aStorageType); } else { persistenceType = PERSISTENCE_TYPE_DEFAULT; } DatabaseMetadata& metadata = commonParams.metadata(); metadata.name() = aName; metadata.persistenceType() = persistenceType; FactoryRequestParams params; if (aDeleting) { metadata.version() = 0; params = DeleteDatabaseRequestParams(commonParams); } else { metadata.version() = version; params = OpenDatabaseRequestParams(commonParams); } if (!mBackgroundActor) { BackgroundChildImpl::ThreadLocal* threadLocal = BackgroundChildImpl::GetThreadLocalForCurrentThread(); nsAutoPtr<ThreadLocal> newIDBThreadLocal; ThreadLocal* idbThreadLocal; if (threadLocal && threadLocal->mIndexedDBThreadLocal) { idbThreadLocal = threadLocal->mIndexedDBThreadLocal; } else { nsCOMPtr<nsIUUIDGenerator> uuidGen = do_GetService("@mozilla.org/uuid-generator;1"); MOZ_ASSERT(uuidGen); nsID id; MOZ_ALWAYS_SUCCEEDS(uuidGen->GenerateUUIDInPlace(&id)); newIDBThreadLocal = idbThreadLocal = new ThreadLocal(id); } PBackgroundChild* backgroundActor = BackgroundChild::GetOrCreateForCurrentThread(); if (NS_WARN_IF(!backgroundActor)) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } { BackgroundFactoryChild* actor = new BackgroundFactoryChild(this); // Set EventTarget for the top-level actor. // All child actors created later inherit the same event target. backgroundActor->SetEventTargetForActor(actor, EventTarget()); MOZ_ASSERT(actor->GetActorEventTarget()); mBackgroundActor = static_cast<BackgroundFactoryChild*>( backgroundActor->SendPBackgroundIDBFactoryConstructor(actor, idbThreadLocal->GetLoggingInfo())); if (NS_WARN_IF(!mBackgroundActor)) { mBackgroundActorFailed = true; IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } } if (newIDBThreadLocal) { if (!threadLocal) { threadLocal = BackgroundChildImpl::GetThreadLocalForCurrentThread(); } MOZ_ASSERT(threadLocal); MOZ_ASSERT(!threadLocal->mIndexedDBThreadLocal); threadLocal->mIndexedDBThreadLocal = newIDBThreadLocal.forget(); } } RefPtr<IDBOpenDBRequest> request; if (mWindow) { JS::Rooted<JSObject*> scriptOwner(aCx, nsGlobalWindowInner::Cast(mWindow.get())->FastGetGlobalJSObject()); MOZ_ASSERT(scriptOwner); request = IDBOpenDBRequest::CreateForWindow(aCx, this, mWindow, scriptOwner); } else { JS::Rooted<JSObject*> scriptOwner(aCx, mOwningObject); request = IDBOpenDBRequest::CreateForJS(aCx, this, scriptOwner); if (!request) { MOZ_ASSERT(!NS_IsMainThread()); aRv.ThrowUncatchableException(); return nullptr; } } MOZ_ASSERT(request); if (aDeleting) { IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: " "indexedDB.deleteDatabase(\"%s\")", "IndexedDB %s: C R[%llu]: IDBFactory.deleteDatabase()", IDB_LOG_ID_STRING(), request->LoggingSerialNumber(), NS_ConvertUTF16toUTF8(aName).get()); } else { IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: " "indexedDB.open(\"%s\", %s)", "IndexedDB %s: C R[%llu]: IDBFactory.open()", IDB_LOG_ID_STRING(), request->LoggingSerialNumber(), NS_ConvertUTF16toUTF8(aName).get(), IDB_LOG_STRINGIFY(aVersion)); } nsresult rv = InitiateRequest(request, params); if (NS_WARN_IF(NS_FAILED(rv))) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } return request.forget(); }
already_AddRefed<IDBOpenDBRequest> IDBFactory::Open(JSContext* aCx, const nsAString& aName, const IDBOpenDBOptions& aOptions, CallerType aCallerType, ErrorResult& aRv) { if (!IsChrome() && aOptions.mStorage.WasPassed()) { if (mWindow && mWindow->GetExtantDoc()) { mWindow->GetExtantDoc()->WarnOnceAbout(nsIDocument::eIDBOpenDBOptions_StorageType); } else if (!NS_IsMainThread()) { // The method below reports on the main thread too, so we need to make sure we're on a worker. // Workers don't have a WarnOnceAbout mechanism, so this will be reported every time. WorkerPrivate::ReportErrorToConsole("IDBOpenDBOptions_StorageType"); } bool ignore = false; // Ignore internal usage on about: pages. if (NS_IsMainThread()) { nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(*mPrincipalInfo); if (principal) { nsCOMPtr<nsIURI> uri; nsresult rv = principal->GetURI(getter_AddRefs(uri)); if (NS_SUCCEEDED(rv) && uri) { bool isAbout; rv = uri->SchemeIs("about", &isAbout); if (NS_SUCCEEDED(rv) && isAbout) { ignore = true; } } } } if (!ignore) { switch (aOptions.mStorage.Value()) { case StorageType::Persistent: { Telemetry::ScalarAdd(Telemetry::ScalarID::IDB_TYPE_PERSISTENT_COUNT, 1); break; } case StorageType::Temporary: { Telemetry::ScalarAdd(Telemetry::ScalarID::IDB_TYPE_TEMPORARY_COUNT, 1); break; } case StorageType::Default: case StorageType::EndGuard_: break; default: MOZ_CRASH("Invalid storage type!"); } } } return OpenInternal(aCx, /* aPrincipal */ nullptr, aName, aOptions.mVersion, aOptions.mStorage, /* aDeleting */ false, aCallerType, aRv); }
nsresult LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs, nsILoadInfo** outLoadInfo) { if (aOptionalLoadInfoArgs.type() == OptionalLoadInfoArgs::Tvoid_t) { *outLoadInfo = nullptr; return NS_OK; } const LoadInfoArgs& loadInfoArgs = aOptionalLoadInfoArgs.get_LoadInfoArgs(); nsresult rv = NS_OK; nsCOMPtr<nsIPrincipal> loadingPrincipal; if (loadInfoArgs.requestingPrincipalInfo().type() != OptionalPrincipalInfo::Tvoid_t) { loadingPrincipal = PrincipalInfoToPrincipal(loadInfoArgs.requestingPrincipalInfo(), &rv); NS_ENSURE_SUCCESS(rv, rv); } NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIPrincipal> triggeringPrincipal = PrincipalInfoToPrincipal(loadInfoArgs.triggeringPrincipalInfo(), &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIPrincipal> principalToInherit; if (loadInfoArgs.principalToInheritInfo().type() != OptionalPrincipalInfo::Tvoid_t) { principalToInherit = PrincipalInfoToPrincipal(loadInfoArgs.principalToInheritInfo(), &rv); NS_ENSURE_SUCCESS(rv, rv); } nsTArray<nsCOMPtr<nsIPrincipal>> redirectChainIncludingInternalRedirects; for (const PrincipalInfo& principalInfo : loadInfoArgs.redirectChainIncludingInternalRedirects()) { nsCOMPtr<nsIPrincipal> redirectedPrincipal = PrincipalInfoToPrincipal(principalInfo, &rv); NS_ENSURE_SUCCESS(rv, rv); redirectChainIncludingInternalRedirects.AppendElement(redirectedPrincipal.forget()); } nsTArray<nsCOMPtr<nsIPrincipal>> redirectChain; for (const PrincipalInfo& principalInfo : loadInfoArgs.redirectChain()) { nsCOMPtr<nsIPrincipal> redirectedPrincipal = PrincipalInfoToPrincipal(principalInfo, &rv); NS_ENSURE_SUCCESS(rv, rv); redirectChain.AppendElement(redirectedPrincipal.forget()); } nsCOMPtr<nsILoadInfo> loadInfo = new mozilla::LoadInfo(loadingPrincipal, triggeringPrincipal, principalToInherit, loadInfoArgs.securityFlags(), loadInfoArgs.contentPolicyType(), static_cast<LoadTainting>(loadInfoArgs.tainting()), loadInfoArgs.upgradeInsecureRequests(), loadInfoArgs.verifySignedContent(), loadInfoArgs.enforceSRI(), loadInfoArgs.forceInheritPrincipalDropped(), loadInfoArgs.innerWindowID(), loadInfoArgs.outerWindowID(), loadInfoArgs.parentOuterWindowID(), loadInfoArgs.frameOuterWindowID(), loadInfoArgs.enforceSecurity(), loadInfoArgs.initialSecurityCheckDone(), loadInfoArgs.isInThirdPartyContext(), loadInfoArgs.originAttributes(), redirectChainIncludingInternalRedirects, redirectChain, loadInfoArgs.corsUnsafeHeaders(), loadInfoArgs.forcePreflight(), loadInfoArgs.isPreflight(), loadInfoArgs.forceHSTSPriming(), loadInfoArgs.mixedContentWouldBlock() ); loadInfo.forget(outLoadInfo); return NS_OK; }