Bug 697144 - Unable to interact with aboutCertError [r=mbrubeck]
authorMark Finkle <mfinkle@mozilla.com>
Fri, 28 Oct 2011 00:55:12 -0400
changeset 83306 9fe52ea2201f3fbfe5ecba1a1512ba2fe68e0232
parent 83305 331fd009543cdc34d2dbe8c52c002408b66a1b1b
child 83307 cdb0a41ea68c991f1d2823f9e7cadd85ddcb8964
push id519
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 00:38:35 +0000
treeherdermozilla-beta@788ea1ef610b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmbrubeck
bugs697144
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 697144 - Unable to interact with aboutCertError [r=mbrubeck]
mobile/chrome/content/browser.js
mobile/chrome/content/browser.xul
mobile/chrome/content/exceptions.js
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -808,16 +808,29 @@ var BrowserEventHandler = {
           gecko: {
             type: "DOMContentLoaded",
             tabID: tabID,
             windowID: 0,
             uri: browser.currentURI.spec,
             title: browser.contentTitle
           }
         });
+
+        // Attach a listener to watch for "click" events bubbling up from error
+        // pages and other similar page. This lets us fix bugs like 401575 which
+        // require error page UI to do privileged things, without letting error
+        // pages have any privilege themselves.
+        if (/^about:/.test(aEvent.originalTarget.documentURI)) {
+          let browser = BrowserApp.getBrowserForDocument(aEvent.originalTarget);
+          browser.addEventListener("click", ErrorPageEventHandler, false);
+          browser.addEventListener("pagehide", function () {
+            browser.removeEventListener("click", ErrorPageEventHandler, false);
+            browser.removeEventListener("pagehide", arguments.callee, true);
+          }, true);
+        }
         break;
       }
 
       case "DOMLinkAdded": {
         let target = aEvent.originalTarget;
         if (!target.href || target.disabled)
           return;
 
@@ -1253,16 +1266,73 @@ var BrowserEventHandler = {
     } else if (elem.scrollTop >= (elem.scrollHeight - elem.clientHeight)) {
       scrollY = false;
     }
 
     return scrollX || scrollY;
   }
 };
 
+
+var ErrorPageEventHandler = {
+  handleEvent: function(aEvent) {
+    switch (aEvent.type) {
+      case "click": {
+        // Don't trust synthetic events
+        if (!aEvent.isTrusted)
+          return;
+
+        let target = aEvent.originalTarget;
+        let errorDoc = target.ownerDocument;
+
+        // If the event came from an ssl error page, it is probably either the "Add
+        // Exception…" or "Get me out of here!" button
+        if (/^about:certerror\?e=nssBadCert/.test(errorDoc.documentURI)) {
+          let perm = errorDoc.getElementById("permanentExceptionButton");
+          let temp = errorDoc.getElementById("temporaryExceptionButton");
+          if (target == temp || target == perm) {
+            // Handle setting an cert exception and reloading the page
+            try {
+              // Add a new SSL exception for this URL
+              let uri = Services.io.newURI(errorDoc.location.href, null, null);
+              let sslExceptions = new SSLExceptions();
+      
+              if (target == perm)
+                sslExceptions.addPermanentException(uri);
+              else
+                sslExceptions.addTemporaryException(uri);
+            } catch (e) {
+              dump("Failed to set cert exception: " + e + "\n");
+            }
+            errorDoc.location.reload();
+          } else if (target == errorDoc.getElementById("getMeOutOfHereButton")) {
+            errorDoc.location = this.getFallbackSafeURL();
+          }
+        }
+        break;
+      }
+    }
+  },
+
+  getFallbackSafeURL: function getFallbackSafeURL() {
+    // Get the start page from the *default* pref branch, not the user's
+    let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).getDefaultBranch(null);
+    let url = "about:home";
+    try {
+      url = prefs.getComplexValue("browser.startup.homepage", Ci.nsIPrefLocalizedString).data;
+      // If url is a pipe-delimited set of pages, just take the first one.
+      if (url.indexOf("|") != -1)
+        url = url.split("|")[0];
+    } catch(e) {
+      Cu.reportError("Couldn't get homepage pref: " + e);
+    }
+    return url;
+  }
+};
+
 var XPInstallObserver = {
   observe: function xpi_observer(aSubject, aTopic, aData) {
     switch (aTopic) {
       case "addon-install-started":
         NativeWindow.toast.show(Strings.browser.GetStringFromName("alertAddonsDownloading"), "short");
         break;
       case "addon-install-blocked":
         dump("XPInstallObserver addon-install-blocked");
--- a/mobile/chrome/content/browser.xul
+++ b/mobile/chrome/content/browser.xul
@@ -2,12 +2,13 @@
 
 <window id="main-window"
         onload="BrowserApp.startup();"
         windowtype="navigator:browser"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <script type="application/javascript" src="chrome://browser/content/browser.js"/>
   <script type="application/javascript" src="chrome://browser/content/downloads.js"/>
+  <script type="application/javascript" src="chrome://browser/content/exceptions.js"/>
 
   <deck id="browsers" flex="1"/>
 
 </window>
--- a/mobile/chrome/content/exceptions.js
+++ b/mobile/chrome/content/exceptions.js
@@ -76,19 +76,17 @@ SSLExceptions.prototype = {
 
   /**
     Returns true if the private browsing mode is currently active
    */
   _inPrivateBrowsingMode: function SSLE_inPrivateBrowsingMode() {
     try {
       var pb = Cc["@mozilla.org/privatebrowsing;1"].getService(Ci.nsIPrivateBrowsingService);
       return pb.privateBrowsingEnabled;
-    } catch (ex) {
-      Components.utils.reportError("Could not get the Private Browsing service");
-    }
+    } catch (ex) {}
     return false;
   },
 
   /**
     Attempt to download the certificate for the location specified to get the SSLState
     for the certificate and the errors.
    */
   _checkCert: function SSLE_checkCert(aURI) {