// Return false when the channel comes from a Private browsing window. static bool TestNotInPBMode(nsIHttpAuthenticableChannel *authChannel) { nsCOMPtr<nsIChannel> bareChannel = do_QueryInterface(authChannel); MOZ_ASSERT(bareChannel); if (!NS_UsePrivateBrowsing(bareChannel)) { return true; } nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); if (!prefs) { return true; } // When the "Never remember history" option is set, all channels are // set PB mode flag, but here we want to make an exception, users // want their credentials go out. bool dontRememberHistory; if (NS_SUCCEEDED(prefs->GetBoolPref("browser.privatebrowsing.autostart", &dontRememberHistory)) && dontRememberHistory) { return true; } return false; }
NS_IMETHODIMP nsHttpChannelAuthProvider::Init(nsIHttpAuthenticableChannel *channel) { MOZ_ASSERT(channel, "channel expected!"); mAuthChannel = channel; nsresult rv = mAuthChannel->GetURI(getter_AddRefs(mURI)); if (NS_FAILED(rv)) return rv; mAuthChannel->GetIsSSL(&mUsingSSL); if (NS_FAILED(rv)) return rv; rv = mURI->GetAsciiHost(mHost); if (NS_FAILED(rv)) return rv; // reject the URL if it doesn't specify a host if (mHost.IsEmpty()) return NS_ERROR_MALFORMED_URI; rv = mURI->GetPort(&mPort); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIChannel> bareChannel = do_QueryInterface(channel); mIsPrivate = NS_UsePrivateBrowsing(bareChannel); return NS_OK; }
NS_IMETHODIMP HttpBaseChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks) { mCallbacks = aCallbacks; mProgressSink = nsnull; // Will never change unless SetNotificationCallbacks called again, so cache mPrivateBrowsing = NS_UsePrivateBrowsing(this); return NS_OK; }
NS_IMETHODIMP HttpBaseChannel::SetLoadGroup(nsILoadGroup *aLoadGroup) { if (!CanSetLoadGroup(aLoadGroup)) { return NS_ERROR_FAILURE; } mLoadGroup = aLoadGroup; mProgressSink = nullptr; mPrivateBrowsing = NS_UsePrivateBrowsing(this); return NS_OK; }
NS_IMETHODIMP HttpBaseChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks) { if (!CanSetCallbacks(aCallbacks)) { return NS_ERROR_FAILURE; } mCallbacks = aCallbacks; mProgressSink = nullptr; mPrivateBrowsing = NS_UsePrivateBrowsing(this); return NS_OK; }
NS_IMETHODIMP HttpBaseChannel::SetLoadGroup(nsILoadGroup *aLoadGroup) { MOZ_ASSERT(NS_IsMainThread(), "Should only be called on the main thread."); if (!CanSetLoadGroup(aLoadGroup)) { return NS_ERROR_FAILURE; } mLoadGroup = aLoadGroup; mProgressSink = nullptr; mPrivateBrowsing = NS_UsePrivateBrowsing(this); return NS_OK; }
NS_IMETHODIMP nsWyciwygChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks) { mCallbacks = aNotificationCallbacks; NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, NS_GET_IID(nsIProgressEventSink), getter_AddRefs(mProgressSink)); // Will never change unless SetNotificationCallbacks called again, so cache mPrivateBrowsing = NS_UsePrivateBrowsing(this); return NS_OK; }
NS_IMETHODIMP HttpBaseChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks) { MOZ_ASSERT(NS_IsMainThread(), "Should only be called on the main thread."); if (!CanSetCallbacks(aCallbacks)) { return NS_ERROR_FAILURE; } mCallbacks = aCallbacks; mProgressSink = nullptr; mPrivateBrowsing = NS_UsePrivateBrowsing(this); return NS_OK; }
NS_IMETHODIMP nsWyciwygChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) { if (!CanSetLoadGroup(aLoadGroup)) { return NS_ERROR_FAILURE; } mLoadGroup = aLoadGroup; NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, NS_GET_IID(nsIProgressEventSink), getter_AddRefs(mProgressSink)); mPrivateBrowsing = NS_UsePrivateBrowsing(this); NS_GetAppInfo(this, &mAppId, &mInBrowser); return NS_OK; }
NS_IMETHODIMP nsWyciwygChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks) { if (!CanSetCallbacks(aNotificationCallbacks)) { return NS_ERROR_FAILURE; } mCallbacks = aNotificationCallbacks; NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, NS_GET_IID(nsIProgressEventSink), getter_AddRefs(mProgressSink)); mPrivateBrowsing = NS_UsePrivateBrowsing(this); NS_GetAppInfo(this, &mAppId, &mInBrowser); return NS_OK; }
LoadContextInfo * GetLoadContextInfo(nsIChannel * aChannel) { bool pb = NS_UsePrivateBrowsing(aChannel); uint32_t appId; bool ib; if (!NS_GetAppInfo(aChannel, &appId, &ib)) { appId = nsILoadContextInfo::NO_APP_ID; ib = false; } bool anon = false; nsLoadFlags loadFlags; nsresult rv = aChannel->GetLoadFlags(&loadFlags); if (NS_SUCCEEDED(rv)) anon = !!(loadFlags & nsIChannel::LOAD_ANONYMOUS); return new LoadContextInfo(pb, appId, ib, anon); }
// Determine if First Party Isolation is currently active for the given // nsIChannel or nsIDocument. Depends on preference setting and // possibly the state of Private Browsing mode. NS_IMETHODIMP ThirdPartyUtil::IsFirstPartyIsolationActive(nsIChannel *aChannel, nsIDocument *aDoc, bool* aResult) { NS_ASSERTION(aResult, "null outparam pointer"); int32_t isolationState = mozilla::Preferences::GetInt("privacy.thirdparty.isolate"); if (isolationState == 1) { if (!aChannel && aDoc) { // No channel passed directly. Can we get a channel from aDoc? aChannel = aDoc->GetChannel(); } *aResult = aChannel && NS_UsePrivateBrowsing(aChannel); } else { // (isolationState == 0) || (isolationState == 2) *aResult = (isolationState == 2); } return NS_OK; }
// Return false when the channel comes from a Private browsing window. static bool TestNotInPBMode(nsIHttpAuthenticableChannel *authChannel, bool proxyAuth) { // Proxy should go all the time, it's not considered a privacy leak // to send default credentials to a proxy. if (proxyAuth) { return true; } nsCOMPtr<nsIChannel> bareChannel = do_QueryInterface(authChannel); MOZ_ASSERT(bareChannel); if (!NS_UsePrivateBrowsing(bareChannel)) { return true; } nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); if (prefs) { bool ssoInPb; if (NS_SUCCEEDED(prefs->GetBoolPref(kSSOinPBmode, &ssoInPb)) && ssoInPb) { return true; } // When the "Never remember history" option is set, all channels are // set PB mode flag, but here we want to make an exception, users // want their credentials go out. bool dontRememberHistory; if (NS_SUCCEEDED(prefs->GetBoolPref("browser.privatebrowsing.autostart", &dontRememberHistory)) && dontRememberHistory) { return true; } } return false; }
NS_IMETHODIMP nsCookiePermission::CanSetCookie(nsIURI *aURI, nsIChannel *aChannel, nsICookie2 *aCookie, bool *aIsSession, int64_t *aExpiry, bool *aResult) { NS_ASSERTION(aURI, "null uri"); *aResult = kDefaultPolicy; // Lazily initialize ourselves if (!EnsureInitialized()) return NS_ERROR_UNEXPECTED; uint32_t perm; mPermMgr->TestPermission(aURI, kPermissionType, &perm); bool isThirdParty = false; switch (perm) { case nsICookiePermission::ACCESS_SESSION: *aIsSession = true; case nsICookiePermission::ACCESS_ALLOW: *aResult = true; break; case nsICookiePermission::ACCESS_DENY: *aResult = false; break; case nsICookiePermission::ACCESS_ALLOW_FIRST_PARTY_ONLY: mThirdPartyUtil->IsThirdPartyChannel(aChannel, aURI, &isThirdParty); // If it's third party, we can't set the cookie if (isThirdParty) *aResult = false; break; case nsICookiePermission::ACCESS_LIMIT_THIRD_PARTY: mThirdPartyUtil->IsThirdPartyChannel(aChannel, aURI, &isThirdParty); // If it's third party, check whether cookies are already set if (isThirdParty) { nsresult rv; nsCOMPtr<nsICookieManager2> cookieManager = do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv); if (NS_FAILED(rv)) { *aResult = false; break; } uint32_t priorCookieCount = 0; nsAutoCString hostFromURI; aURI->GetHost(hostFromURI); cookieManager->CountCookiesFromHost(hostFromURI, &priorCookieCount); *aResult = priorCookieCount != 0; } break; default: // the permission manager has nothing to say about this cookie - // so, we apply the default prefs to it. NS_ASSERTION(perm == nsIPermissionManager::UNKNOWN_ACTION, "unknown permission"); // now we need to figure out what type of accept policy we're dealing with // if we accept cookies normally, just bail and return if (mCookiesLifetimePolicy == ACCEPT_NORMALLY) { *aResult = true; return NS_OK; } // declare this here since it'll be used in all of the remaining cases int64_t currentTime = PR_Now() / PR_USEC_PER_SEC; int64_t delta = *aExpiry - currentTime; // check whether the user wants to be prompted if (mCookiesLifetimePolicy == ASK_BEFORE_ACCEPT) { // if it's a session cookie and the user wants to accept these // without asking, or if we are in private browsing mode, just // accept the cookie and return if ((*aIsSession && mCookiesAlwaysAcceptSession) || (aChannel && NS_UsePrivateBrowsing(aChannel))) { *aResult = true; return NS_OK; } // default to rejecting, in case the prompting process fails *aResult = false; nsAutoCString hostPort; aURI->GetHostPort(hostPort); if (!aCookie) { return NS_ERROR_UNEXPECTED; } // If there is no host, use the scheme, and append "://", // to make sure it isn't a host or something. // This is done to make the dialog appear for javascript cookies from // file:// urls, and make the text on it not too weird. (bug 209689) if (hostPort.IsEmpty()) { aURI->GetScheme(hostPort); if (hostPort.IsEmpty()) { // still empty. Just return the default. return NS_OK; } hostPort = hostPort + NS_LITERAL_CSTRING("://"); } // we don't cache the cookiePromptService - it's not used often, so not // worth the memory. nsresult rv; nsCOMPtr<nsICookiePromptService> cookiePromptService = do_GetService(NS_COOKIEPROMPTSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; // get some useful information to present to the user: // whether a previous cookie already exists, and how many cookies this host // has set bool foundCookie = false; uint32_t countFromHost; nsCOMPtr<nsICookieManager2> cookieManager = do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) { nsAutoCString rawHost; aCookie->GetRawHost(rawHost); rv = cookieManager->CountCookiesFromHost(rawHost, &countFromHost); if (NS_SUCCEEDED(rv) && countFromHost > 0) rv = cookieManager->CookieExists(aCookie, &foundCookie); } if (NS_FAILED(rv)) return rv; // check if the cookie we're trying to set is already expired, and return; // but only if there's no previous cookie, because then we need to delete the previous // cookie. we need this check to avoid prompting the user for already-expired cookies. if (!foundCookie && !*aIsSession && delta <= 0) { // the cookie has already expired. accept it, and let the backend figure // out it's expired, so that we get correct logging & notifications. *aResult = true; return rv; } bool rememberDecision = false; int32_t dialogRes = nsICookiePromptService::DENY_COOKIE; rv = cookiePromptService->CookieDialog(nullptr, aCookie, hostPort, countFromHost, foundCookie, &rememberDecision, &dialogRes); if (NS_FAILED(rv)) return rv; *aResult = !!dialogRes; if (dialogRes == nsICookiePromptService::ACCEPT_SESSION_COOKIE) *aIsSession = true; if (rememberDecision) { switch (dialogRes) { case nsICookiePromptService::DENY_COOKIE: mPermMgr->Add(aURI, kPermissionType, (uint32_t) nsIPermissionManager::DENY_ACTION, nsIPermissionManager::EXPIRE_NEVER, 0); break; case nsICookiePromptService::ACCEPT_COOKIE: mPermMgr->Add(aURI, kPermissionType, (uint32_t) nsIPermissionManager::ALLOW_ACTION, nsIPermissionManager::EXPIRE_NEVER, 0); break; case nsICookiePromptService::ACCEPT_SESSION_COOKIE: mPermMgr->Add(aURI, kPermissionType, nsICookiePermission::ACCESS_SESSION, nsIPermissionManager::EXPIRE_NEVER, 0); break; default: break; } } } else { // we're not prompting, so we must be limiting the lifetime somehow // if it's a session cookie, we do nothing if (!*aIsSession && delta > 0) { if (mCookiesLifetimePolicy == ACCEPT_SESSION) { // limit lifetime to session *aIsSession = true; } else if (delta > mCookiesLifetimeSec) { // limit lifetime to specified time *aExpiry = currentTime + mCookiesLifetimeSec; } } } } return NS_OK; }