browser/metro/base/content/sanitize.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 // -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 XPCOMUtils.defineLazyModuleGetter(this, "LoadContextInfo",
     7                                   "resource://gre/modules/LoadContextInfo.jsm");
     8 function Sanitizer() {}
    10 Sanitizer.prototype = {
    11   // warning to the caller: this one may raise an exception (e.g. bug #265028)
    12   clearItem: function (aItemName)
    13   {
    14     if (this.items[aItemName].canClear)
    15       this.items[aItemName].clear();
    16   },
    18   canClearItem: function (aItemName, aCallback, aArg)
    19   {
    20     let canClear = this.items[aItemName].canClear;
    21     if (typeof canClear == "function"){
    22       canClear(aCallback, aArg);
    23     } else {
    24       aCallback(aItemName, canClear, aArg);
    25     }
    26   },
    28   _prefDomain: "privacy.item.",
    29   getNameFromPreference: function (aPreferenceName)
    30   {
    31     return aPreferenceName.substr(this._prefDomain.length);
    32   },
    34   /**
    35    * Deletes privacy sensitive data in a batch, according to user preferences
    36    *
    37    * @returns  null if everything's fine;  an object in the form
    38    *           { itemName: error, ... } on (partial) failure
    39    */
    40   sanitize: function ()
    41   {
    42     var branch = Services.prefs.getBranch(this._prefDomain);
    43     var errors = null;
    44     for (var itemName in this.items) {
    45       if ("clear" in item && branch.getBoolPref(itemName)) {
    46         // Some of these clear() may raise exceptions (see bug #265028)
    47         // to sanitize as much as possible, we catch and store them, 
    48         // rather than fail fast.
    49         // Callers should check returned errors and give user feedback
    50         // about items that could not be sanitized
    51         let clearCallback = (itemName, aCanClear) => {
    52           let item = this.items[itemName];
    53           try{
    54             if (aCanClear){
    55               item.clear();
    56             }
    57           } catch(er){
    58             if (!errors){
    59               errors = {};
    60             }
    61             errors[itemName] = er;
    62             dump("Error sanitizing " + itemName + ":" + er + "\n");
    63           }
    64         }
    65         this.canClearItem(itemName, clearCallback);
    66       }
    67     }
    68     return errors;
    69   },
    71   items: {
    72     // Clear Sync account before passwords so that Sync still has access to the
    73     // credentials to clean up device-specific records on the server. Also
    74     // disable it before wiping history so we don't accidentally sync that.
    75     syncAccount: {
    76       clear: function ()
    77       {
    78         Sync.disconnect();
    79       },
    81       get canClear()
    82       {
    83         return (Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED);
    84       }
    85     },
    87     cache: {
    88       clear: function ()
    89       {
    90         var cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(Ci.nsICacheStorageService);
    91         try {
    92           cache.clear();
    93         } catch(er) {}
    95         let imageCache = Cc["@mozilla.org/image/cache;1"].getService(Ci.imgICache);
    96         try {
    97           imageCache.clearCache(false); // true=chrome, false=content
    98         } catch(er) {}
    99       },
   101       get canClear()
   102       {
   103         return true;
   104       }
   105     },
   107     cookies: {
   108       clear: function ()
   109       {
   110         var cookieMgr = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
   111         cookieMgr.removeAll();
   112       },
   114       get canClear()
   115       {
   116         return true;
   117       }
   118     },
   120     siteSettings: {
   121       clear: function ()
   122       {
   123         // Clear site-specific permissions like "Allow this site to open popups"
   124         Services.perms.removeAll();
   126         // Clear site-specific settings like page-zoom level
   127         var cps = Cc["@mozilla.org/content-pref/service;1"].getService(Ci.nsIContentPrefService2);
   128         cps.removeAllDomains(null);
   130         // Clear "Never remember passwords for this site", which is not handled by
   131         // the permission manager
   132         var pwmgr = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
   133         var hosts = pwmgr.getAllDisabledHosts({})
   134         for each (var host in hosts) {
   135           pwmgr.setLoginSavingEnabled(host, true);
   136         }
   137       },
   139       get canClear()
   140       {
   141         return true;
   142       }
   143     },
   145     offlineApps: {
   146       clear: function ()
   147       {
   148         var cacheService = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(Ci.nsICacheStorageService);
   149         var appCacheStorage = cacheService.appCacheStorage(LoadContextInfo.default, null);
   150         try {
   151           appCacheStorage.asyncEvictStorage(null);
   152         } catch(er) {}
   153       },
   155       get canClear()
   156       {
   157           return true;
   158       }
   159     },
   161     history: {
   162       clear: function ()
   163       {
   164         try {
   165           Services.obs.notifyObservers(null, "browser:purge-session-history", "");
   166         }
   167         catch (e) {
   168           Components.utils.reportError("Failed to notify observers of "
   169                                      + "browser:purge-session-history: "
   170                                      + e);
   171         }
   172       },
   174       get canClear()
   175       {
   176         // bug 347231: Always allow clearing history due to dependencies on
   177         // the browser:purge-session-history notification. (like error console)
   178         return true;
   179       }
   180     },
   182     formdata: {
   183       clear: function ()
   184       {
   185         //Clear undo history of all searchBars
   186         var windows = Services.wm.getEnumerator("navigator:browser");
   187         while (windows.hasMoreElements()) {
   188           var searchBar = windows.getNext().document.getElementById("searchbar");
   189           if (searchBar) {
   190             searchBar.value = "";
   191             searchBar.textbox.editor.transactionManager.clear();
   192           }
   193         }
   194         FormHistory.update({op : "remove"});
   195       },
   197       canClear : function(aCallback, aArg)
   198       {
   199         let count = 0;
   200         let countDone = {
   201           handleResult : function(aResult) { count = aResult; },
   202           handleError : function(aError) { Components.utils.reportError(aError); },
   203           handleCompletion : function(aReason) { aCallback("formdata", aReason == 0 && count > 0, aArg); }
   204         };
   205         FormHistory.count({}, countDone);
   206       }
   207     },
   209     downloads: {
   210       clear: function ()
   211       {
   212         var dlMgr = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager);
   213         dlMgr.cleanUp();
   214       },
   216       get canClear()
   217       {
   218         var dlMgr = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager);
   219         return dlMgr.canCleanUp;
   220       }
   221     },
   223     passwords: {
   224       clear: function ()
   225       {
   226         var pwmgr = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
   227         pwmgr.removeAllLogins();
   228       },
   230       get canClear()
   231       {
   232         var pwmgr = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
   233         var count = pwmgr.countLogins("", "", ""); // count all logins
   234         return (count > 0);
   235       }
   236     },
   238     sessions: {
   239       clear: function ()
   240       {
   241         // clear all auth tokens
   242         var sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing);
   243         sdr.logoutAndTeardown();
   245         // clear plain HTTP auth sessions
   246         var authMgr = Cc['@mozilla.org/network/http-auth-manager;1'].getService(Ci.nsIHttpAuthManager);
   247         authMgr.clearAll();
   248       },
   250       get canClear()
   251       {
   252         return true;
   253       }
   254     }
   255   }
   256 };
   259 // "Static" members
   260 Sanitizer.prefDomain          = "privacy.sanitize.";
   261 Sanitizer.prefShutdown        = "sanitizeOnShutdown";
   262 Sanitizer.prefDidShutdown     = "didShutdownSanitize";
   264 Sanitizer._prefs = null;
   265 Sanitizer.__defineGetter__("prefs", function() 
   266 {
   267   return Sanitizer._prefs ? Sanitizer._prefs
   268     : Sanitizer._prefs = Cc["@mozilla.org/preferences-service;1"]
   269                          .getService(Ci.nsIPrefService)
   270                          .getBranch(Sanitizer.prefDomain);
   271 });
   273 /** 
   274  * Deletes privacy sensitive data in a batch, optionally showing the 
   275  * sanitize UI, according to user preferences
   276  *
   277  * @returns  null if everything's fine
   278  *           an object in the form { itemName: error, ... } on (partial) failure
   279  */
   280 Sanitizer.sanitize = function() 
   281 {
   282   return new Sanitizer().sanitize();
   283 };
   285 Sanitizer.onStartup = function() 
   286 {
   287   // we check for unclean exit with pending sanitization
   288   Sanitizer._checkAndSanitize();
   289 };
   291 Sanitizer.onShutdown = function() 
   292 {
   293   // we check if sanitization is needed and perform it
   294   Sanitizer._checkAndSanitize();
   295 };
   297 // this is called on startup and shutdown, to perform pending sanitizations
   298 Sanitizer._checkAndSanitize = function() 
   299 {
   300   const prefs = Sanitizer.prefs;
   301   if (prefs.getBoolPref(Sanitizer.prefShutdown) && 
   302       !prefs.prefHasUserValue(Sanitizer.prefDidShutdown)) {
   303     // this is a shutdown or a startup after an unclean exit
   304     Sanitizer.sanitize() || // sanitize() returns null on full success
   305       prefs.setBoolPref(Sanitizer.prefDidShutdown, true);
   306   }
   307 };

mercurial