Bug 894595 - part 1.5 - Move privacy level checks into a module; r=yoric

This commit is contained in:
Tim Taubert 2013-09-17 10:40:27 +02:00
parent cd1315901b
commit 48475f14c8
5 changed files with 99 additions and 39 deletions

View File

@ -0,0 +1,82 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["PrivacyLevel"];
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
const PREF_NORMAL = "browser.sessionstore.privacy_level";
const PREF_DEFERRED = "browser.sessionstore.privacy_level_deferred";
// The following constants represent the different possible privacy levels that
// can be set by the user and that we need to consider when collecting text
// data, cookies, and POSTDATA.
//
// Collect data from all sites (http and https).
const PRIVACY_NONE = 0;
// Collect data from unencrypted sites (http), only.
const PRIVACY_ENCRYPTED = 1;
// Collect no data.
const PRIVACY_FULL = 2;
/**
* Returns whether we will resume the session automatically on next startup.
*/
function willResumeAutomatically() {
return Services.prefs.getIntPref("browser.startup.page") == 3 ||
Services.prefs.getBoolPref("browser.sessionstore.resume_session_once");
}
/**
* Determines the current privacy level as set by the user.
*
* @param isPinned
* Whether to return the privacy level for pinned tabs.
* @return {int} The privacy level as read from the user's preferences.
*/
function getCurrentLevel(isPinned) {
let pref = PREF_NORMAL;
// If we're in the process of quitting and we're not autoresuming the session
// then we will use the deferred privacy level for non-pinned tabs.
if (!isPinned && Services.startup.shuttingDown && !willResumeAutomatically()) {
pref = PREF_DEFERRED;
}
return Services.prefs.getIntPref(pref);
}
/**
* The external API as exposed by this module.
*/
let PrivacyLevel = Object.freeze({
/**
* Checks whether we're allowed to save data for a specific site.
*
* @param {isHttps: boolean, isPinned: boolean}
* An object that must have two properties: 'isHttps' and 'isPinned'.
* 'isHttps' tells whether the site us secure communication (HTTPS).
* 'isPinned' tells whether the site is loaded in a pinned tab.
* @return {bool} Whether we can save data for the specified site.
*/
canSave: function ({isHttps, isPinned}) {
let level = getCurrentLevel(isPinned);
// Never save any data when full privacy is requested.
if (level == PRIVACY_FULL) {
return false;
}
// Don't save data for encrypted sites when requested.
if (isHttps && level == PRIVACY_ENCRYPTED) {
return false;
}
return true;
}
});

View File

@ -12,8 +12,8 @@ const Ci = Components.interfaces;
Cu.import("resource://gre/modules/Services.jsm", this);
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
XPCOMUtils.defineLazyModuleGetter(this, "SessionStore",
"resource:///modules/sessionstore/SessionStore.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivacyLevel",
"resource:///modules/sessionstore/PrivacyLevel.jsm");
// MAX_EXPIRY should be 2^63-1, but JavaScript can't handle that precision.
const MAX_EXPIRY = Math.pow(2, 62);
@ -67,8 +67,8 @@ let SessionCookiesInternal = {
for (let cookie of CookieStore.getCookiesForHost(host)) {
// _getCookiesForHost() will only return hosts with the right privacy
// rules, so there is no need to do anything special with this call
// to checkPrivacyLevel().
if (SessionStore.checkPrivacyLevel(cookie.secure, isPinned)) {
// to PrivacyLevel.canSave().
if (PrivacyLevel.canSave({isHttps: cookie.secure, isPinned: isPinned})) {
cookies.push(cookie);
}
}
@ -209,7 +209,7 @@ let SessionCookiesInternal = {
// case testing scheme will be sufficient.
if (/https?/.test(scheme) && !hosts[host] &&
(!checkPrivacy ||
SessionStore.checkPrivacyLevel(scheme == "https", isPinned))) {
PrivacyLevel.canSave({isHttps: scheme == "https", isPinned: isPinned}))) {
// By setting this to true or false, we can determine when looking at
// the host in update() if we should check for privacy.
hosts[host] = isPinned;

View File

@ -11,8 +11,8 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "SessionStore",
"resource:///modules/sessionstore/SessionStore.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivacyLevel",
"resource:///modules/sessionstore/PrivacyLevel.jsm");
this.SessionStorage = {
/**
@ -59,8 +59,8 @@ let DomStorage = {
continue;
// Check if we're allowed to store sessionStorage data.
let isHTTPS = principal.URI && principal.URI.schemeIs("https");
if (aFullData || SessionStore.checkPrivacyLevel(isHTTPS, isPinned)) {
let isHttps = principal.URI && principal.URI.schemeIs("https");
if (aFullData || PrivacyLevel.canSave({isHttps: isHttps, isPinned: isPinned})) {
let origin = principal.jarPrefix + principal.origin;
// Don't read a host twice.

View File

@ -21,10 +21,6 @@ const STATE_RUNNING_STR = "running";
const TAB_STATE_NEEDS_RESTORE = 1;
const TAB_STATE_RESTORING = 2;
const PRIVACY_NONE = 0;
const PRIVACY_ENCRYPTED = 1;
const PRIVACY_FULL = 2;
const NOTIFY_WINDOWS_RESTORED = "sessionstore-windows-restored";
const NOTIFY_BROWSER_STATE_RESTORED = "sessionstore-browser-state-restored";
@ -128,6 +124,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "ScratchpadManager",
"resource:///modules/devtools/scratchpad-manager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "DocumentUtils",
"resource:///modules/sessionstore/DocumentUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivacyLevel",
"resource:///modules/sessionstore/PrivacyLevel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "SessionSaver",
"resource:///modules/sessionstore/SessionSaver.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "SessionStorage",
@ -271,10 +269,6 @@ this.SessionStore = {
SessionStoreInternal.restoreLastSession();
},
checkPrivacyLevel: function ss_checkPrivacyLevel(aIsHTTPS, aUseDefaultPref) {
return SessionStoreInternal.checkPrivacyLevel(aIsHTTPS, aUseDefaultPref);
},
getCurrentState: function (aUpdateAll) {
return SessionStoreInternal.getCurrentState(aUpdateAll);
},
@ -3288,25 +3282,6 @@ let SessionStoreInternal = {
return !hasFirstArgument;
},
/**
* don't save sensitive data if the user doesn't want to
* (distinguishes between encrypted and non-encrypted sites)
* @param aIsHTTPS
* Bool is encrypted
* @param aUseDefaultPref
* don't do normal check for deferred
* @returns bool
*/
checkPrivacyLevel: function ssi_checkPrivacyLevel(aIsHTTPS, aUseDefaultPref) {
let pref = "sessionstore.privacy_level";
// If we're in the process of quitting and we're not autoresuming the session
// then we should treat it as a deferred session. We have a different privacy
// pref for that case.
if (!aUseDefaultPref && this._loadState == STATE_QUITTING && !this._doResumeSession())
pref = "sessionstore.privacy_level_deferred";
return this._prefBranch.getIntPref(pref) < (aIsHTTPS ? PRIVACY_ENCRYPTED : PRIVACY_FULL);
},
/**
* on popup windows, the XULWindow's attributes seem not to be set correctly
* we use thus JSDOMWindow attributes for sizemode and normal window attributes
@ -4552,9 +4527,10 @@ let TabState = {
entry.scroll = x.value + "," + y.value;
try {
let isHttps = shEntry.URI.schemeIs("https");
let prefPostdata = Services.prefs.getIntPref("browser.sessionstore.postdata");
if (shEntry.postData && (includePrivateData || prefPostdata &&
SessionStoreInternal.checkPrivacyLevel(shEntry.URI.schemeIs("https"), isPinned))) {
PrivacyLevel.canSave({isHttps: isHttps, isPinned: isPinned}))) {
shEntry.postData.QueryInterface(Ci.nsISeekableStream).
seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
let stream = Cc["@mozilla.org/binaryinputstream;1"].
@ -4714,10 +4690,11 @@ let TabState = {
includePrivateData, isPinned);
}
let href = (content.parent || content).document.location.href;
let isHTTPS = makeURI(href).schemeIs("https");
let isHttps = makeURI(href).schemeIs("https");
let topURL = content.top.document.location.href;
let isAboutSR = topURL == "about:sessionrestore" || topURL == "about:welcomeback";
if (includePrivateData || SessionStoreInternal.checkPrivacyLevel(isHTTPS, isPinned) || isAboutSR) {
if (includePrivateData || isAboutSR ||
PrivacyLevel.canSave({isHttps: isHttps, isPinned: isPinned})) {
let formData = DocumentUtils.getFormData(content.document);
// We want to avoid saving data for about:sessionrestore as a string.

View File

@ -14,6 +14,7 @@ JS_MODULES_PATH = 'modules/sessionstore'
EXTRA_JS_MODULES = [
'DocumentUtils.jsm',
'PrivacyLevel.jsm',
'SessionCookies.jsm',
'SessionMigration.jsm',
'SessionStorage.jsm',