/** * Prepare the transferable object to be inserted into the clipboard * */ nsresult nsClipboardPrivacyHandler::PrepareDataForClipboard(nsITransferable * aTransferable) { NS_ASSERTION(aTransferable, "clipboard given a null transferable"); nsresult rv = NS_OK; if (InPrivateBrowsing()) { nsCOMPtr<nsISupportsPRBool> data = do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID); if (data) { rv = data->SetData(PR_TRUE); NS_ENSURE_SUCCESS(rv, rv); rv = aTransferable->AddDataFlavor(NS_MOZ_DATA_FROM_PRIVATEBROWSING); NS_ENSURE_SUCCESS(rv, rv); rv = aTransferable->SetTransferData(NS_MOZ_DATA_FROM_PRIVATEBROWSING, data, sizeof(PRBool)); NS_ENSURE_SUCCESS(rv, rv); } } return rv; }
NS_IMETHODIMP nsCookiePermission::CanSetCookie(nsIURI *aURI, nsIChannel *aChannel, nsICookie2 *aCookie, bool *aIsSession, PRInt64 *aExpiry, bool *aResult) { NS_ASSERTION(aURI, "null uri"); *aResult = kDefaultPolicy; // Lazily initialize ourselves if (!EnsureInitialized()) return NS_ERROR_UNEXPECTED; PRUint32 perm; mPermMgr->TestPermission(aURI, kPermissionType, &perm); switch (perm) { case nsICookiePermission::ACCESS_SESSION: *aIsSession = true; case nsIPermissionManager::ALLOW_ACTION: // ACCESS_ALLOW *aResult = true; break; case nsIPermissionManager::DENY_ACTION: // ACCESS_DENY *aResult = false; 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 PRInt64 currentTime = PR_Now() / PR_USEC_PER_SEC; PRInt64 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) || InPrivateBrowsing()) { *aResult = true; return NS_OK; } // default to rejecting, in case the prompting process fails *aResult = false; nsCAutoString 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; // try to get a nsIDOMWindow from the channel... nsCOMPtr<nsIDOMWindow> parent; if (aChannel) { nsCOMPtr<nsILoadContext> ctx; NS_QueryNotificationCallbacks(aChannel, ctx); if (ctx) { ctx->GetAssociatedWindow(getter_AddRefs(parent)); } } // 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; PRUint32 countFromHost; nsCOMPtr<nsICookieManager2> cookieManager = do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) { nsCAutoString 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; PRInt32 dialogRes = nsICookiePromptService::DENY_COOKIE; rv = cookiePromptService->CookieDialog(parent, 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, (PRUint32) nsIPermissionManager::DENY_ACTION, nsIPermissionManager::EXPIRE_NEVER, 0); break; case nsICookiePromptService::ACCEPT_COOKIE: mPermMgr->Add(aURI, kPermissionType, (PRUint32) 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; }