1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/metro/base/content/sanitize.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,309 @@ 1.4 +// -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +XPCOMUtils.defineLazyModuleGetter(this, "LoadContextInfo", 1.10 + "resource://gre/modules/LoadContextInfo.jsm"); 1.11 +function Sanitizer() {} 1.12 + 1.13 +Sanitizer.prototype = { 1.14 + // warning to the caller: this one may raise an exception (e.g. bug #265028) 1.15 + clearItem: function (aItemName) 1.16 + { 1.17 + if (this.items[aItemName].canClear) 1.18 + this.items[aItemName].clear(); 1.19 + }, 1.20 + 1.21 + canClearItem: function (aItemName, aCallback, aArg) 1.22 + { 1.23 + let canClear = this.items[aItemName].canClear; 1.24 + if (typeof canClear == "function"){ 1.25 + canClear(aCallback, aArg); 1.26 + } else { 1.27 + aCallback(aItemName, canClear, aArg); 1.28 + } 1.29 + }, 1.30 + 1.31 + _prefDomain: "privacy.item.", 1.32 + getNameFromPreference: function (aPreferenceName) 1.33 + { 1.34 + return aPreferenceName.substr(this._prefDomain.length); 1.35 + }, 1.36 + 1.37 + /** 1.38 + * Deletes privacy sensitive data in a batch, according to user preferences 1.39 + * 1.40 + * @returns null if everything's fine; an object in the form 1.41 + * { itemName: error, ... } on (partial) failure 1.42 + */ 1.43 + sanitize: function () 1.44 + { 1.45 + var branch = Services.prefs.getBranch(this._prefDomain); 1.46 + var errors = null; 1.47 + for (var itemName in this.items) { 1.48 + if ("clear" in item && branch.getBoolPref(itemName)) { 1.49 + // Some of these clear() may raise exceptions (see bug #265028) 1.50 + // to sanitize as much as possible, we catch and store them, 1.51 + // rather than fail fast. 1.52 + // Callers should check returned errors and give user feedback 1.53 + // about items that could not be sanitized 1.54 + let clearCallback = (itemName, aCanClear) => { 1.55 + let item = this.items[itemName]; 1.56 + try{ 1.57 + if (aCanClear){ 1.58 + item.clear(); 1.59 + } 1.60 + } catch(er){ 1.61 + if (!errors){ 1.62 + errors = {}; 1.63 + } 1.64 + errors[itemName] = er; 1.65 + dump("Error sanitizing " + itemName + ":" + er + "\n"); 1.66 + } 1.67 + } 1.68 + this.canClearItem(itemName, clearCallback); 1.69 + } 1.70 + } 1.71 + return errors; 1.72 + }, 1.73 + 1.74 + items: { 1.75 + // Clear Sync account before passwords so that Sync still has access to the 1.76 + // credentials to clean up device-specific records on the server. Also 1.77 + // disable it before wiping history so we don't accidentally sync that. 1.78 + syncAccount: { 1.79 + clear: function () 1.80 + { 1.81 + Sync.disconnect(); 1.82 + }, 1.83 + 1.84 + get canClear() 1.85 + { 1.86 + return (Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED); 1.87 + } 1.88 + }, 1.89 + 1.90 + cache: { 1.91 + clear: function () 1.92 + { 1.93 + var cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(Ci.nsICacheStorageService); 1.94 + try { 1.95 + cache.clear(); 1.96 + } catch(er) {} 1.97 + 1.98 + let imageCache = Cc["@mozilla.org/image/cache;1"].getService(Ci.imgICache); 1.99 + try { 1.100 + imageCache.clearCache(false); // true=chrome, false=content 1.101 + } catch(er) {} 1.102 + }, 1.103 + 1.104 + get canClear() 1.105 + { 1.106 + return true; 1.107 + } 1.108 + }, 1.109 + 1.110 + cookies: { 1.111 + clear: function () 1.112 + { 1.113 + var cookieMgr = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager); 1.114 + cookieMgr.removeAll(); 1.115 + }, 1.116 + 1.117 + get canClear() 1.118 + { 1.119 + return true; 1.120 + } 1.121 + }, 1.122 + 1.123 + siteSettings: { 1.124 + clear: function () 1.125 + { 1.126 + // Clear site-specific permissions like "Allow this site to open popups" 1.127 + Services.perms.removeAll(); 1.128 + 1.129 + // Clear site-specific settings like page-zoom level 1.130 + var cps = Cc["@mozilla.org/content-pref/service;1"].getService(Ci.nsIContentPrefService2); 1.131 + cps.removeAllDomains(null); 1.132 + 1.133 + // Clear "Never remember passwords for this site", which is not handled by 1.134 + // the permission manager 1.135 + var pwmgr = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager); 1.136 + var hosts = pwmgr.getAllDisabledHosts({}) 1.137 + for each (var host in hosts) { 1.138 + pwmgr.setLoginSavingEnabled(host, true); 1.139 + } 1.140 + }, 1.141 + 1.142 + get canClear() 1.143 + { 1.144 + return true; 1.145 + } 1.146 + }, 1.147 + 1.148 + offlineApps: { 1.149 + clear: function () 1.150 + { 1.151 + var cacheService = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(Ci.nsICacheStorageService); 1.152 + var appCacheStorage = cacheService.appCacheStorage(LoadContextInfo.default, null); 1.153 + try { 1.154 + appCacheStorage.asyncEvictStorage(null); 1.155 + } catch(er) {} 1.156 + }, 1.157 + 1.158 + get canClear() 1.159 + { 1.160 + return true; 1.161 + } 1.162 + }, 1.163 + 1.164 + history: { 1.165 + clear: function () 1.166 + { 1.167 + try { 1.168 + Services.obs.notifyObservers(null, "browser:purge-session-history", ""); 1.169 + } 1.170 + catch (e) { 1.171 + Components.utils.reportError("Failed to notify observers of " 1.172 + + "browser:purge-session-history: " 1.173 + + e); 1.174 + } 1.175 + }, 1.176 + 1.177 + get canClear() 1.178 + { 1.179 + // bug 347231: Always allow clearing history due to dependencies on 1.180 + // the browser:purge-session-history notification. (like error console) 1.181 + return true; 1.182 + } 1.183 + }, 1.184 + 1.185 + formdata: { 1.186 + clear: function () 1.187 + { 1.188 + //Clear undo history of all searchBars 1.189 + var windows = Services.wm.getEnumerator("navigator:browser"); 1.190 + while (windows.hasMoreElements()) { 1.191 + var searchBar = windows.getNext().document.getElementById("searchbar"); 1.192 + if (searchBar) { 1.193 + searchBar.value = ""; 1.194 + searchBar.textbox.editor.transactionManager.clear(); 1.195 + } 1.196 + } 1.197 + FormHistory.update({op : "remove"}); 1.198 + }, 1.199 + 1.200 + canClear : function(aCallback, aArg) 1.201 + { 1.202 + let count = 0; 1.203 + let countDone = { 1.204 + handleResult : function(aResult) { count = aResult; }, 1.205 + handleError : function(aError) { Components.utils.reportError(aError); }, 1.206 + handleCompletion : function(aReason) { aCallback("formdata", aReason == 0 && count > 0, aArg); } 1.207 + }; 1.208 + FormHistory.count({}, countDone); 1.209 + } 1.210 + }, 1.211 + 1.212 + downloads: { 1.213 + clear: function () 1.214 + { 1.215 + var dlMgr = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager); 1.216 + dlMgr.cleanUp(); 1.217 + }, 1.218 + 1.219 + get canClear() 1.220 + { 1.221 + var dlMgr = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager); 1.222 + return dlMgr.canCleanUp; 1.223 + } 1.224 + }, 1.225 + 1.226 + passwords: { 1.227 + clear: function () 1.228 + { 1.229 + var pwmgr = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager); 1.230 + pwmgr.removeAllLogins(); 1.231 + }, 1.232 + 1.233 + get canClear() 1.234 + { 1.235 + var pwmgr = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager); 1.236 + var count = pwmgr.countLogins("", "", ""); // count all logins 1.237 + return (count > 0); 1.238 + } 1.239 + }, 1.240 + 1.241 + sessions: { 1.242 + clear: function () 1.243 + { 1.244 + // clear all auth tokens 1.245 + var sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing); 1.246 + sdr.logoutAndTeardown(); 1.247 + 1.248 + // clear plain HTTP auth sessions 1.249 + var authMgr = Cc['@mozilla.org/network/http-auth-manager;1'].getService(Ci.nsIHttpAuthManager); 1.250 + authMgr.clearAll(); 1.251 + }, 1.252 + 1.253 + get canClear() 1.254 + { 1.255 + return true; 1.256 + } 1.257 + } 1.258 + } 1.259 +}; 1.260 + 1.261 + 1.262 +// "Static" members 1.263 +Sanitizer.prefDomain = "privacy.sanitize."; 1.264 +Sanitizer.prefShutdown = "sanitizeOnShutdown"; 1.265 +Sanitizer.prefDidShutdown = "didShutdownSanitize"; 1.266 + 1.267 +Sanitizer._prefs = null; 1.268 +Sanitizer.__defineGetter__("prefs", function() 1.269 +{ 1.270 + return Sanitizer._prefs ? Sanitizer._prefs 1.271 + : Sanitizer._prefs = Cc["@mozilla.org/preferences-service;1"] 1.272 + .getService(Ci.nsIPrefService) 1.273 + .getBranch(Sanitizer.prefDomain); 1.274 +}); 1.275 + 1.276 +/** 1.277 + * Deletes privacy sensitive data in a batch, optionally showing the 1.278 + * sanitize UI, according to user preferences 1.279 + * 1.280 + * @returns null if everything's fine 1.281 + * an object in the form { itemName: error, ... } on (partial) failure 1.282 + */ 1.283 +Sanitizer.sanitize = function() 1.284 +{ 1.285 + return new Sanitizer().sanitize(); 1.286 +}; 1.287 + 1.288 +Sanitizer.onStartup = function() 1.289 +{ 1.290 + // we check for unclean exit with pending sanitization 1.291 + Sanitizer._checkAndSanitize(); 1.292 +}; 1.293 + 1.294 +Sanitizer.onShutdown = function() 1.295 +{ 1.296 + // we check if sanitization is needed and perform it 1.297 + Sanitizer._checkAndSanitize(); 1.298 +}; 1.299 + 1.300 +// this is called on startup and shutdown, to perform pending sanitizations 1.301 +Sanitizer._checkAndSanitize = function() 1.302 +{ 1.303 + const prefs = Sanitizer.prefs; 1.304 + if (prefs.getBoolPref(Sanitizer.prefShutdown) && 1.305 + !prefs.prefHasUserValue(Sanitizer.prefDidShutdown)) { 1.306 + // this is a shutdown or a startup after an unclean exit 1.307 + Sanitizer.sanitize() || // sanitize() returns null on full success 1.308 + prefs.setBoolPref(Sanitizer.prefDidShutdown, true); 1.309 + } 1.310 +}; 1.311 + 1.312 +