Bug 989197 - Show alternate UI in cert error pages when a captive portal is active. r=Gijs

MozReview-Commit-ID: DnWdwcx8r9S

--HG--
extra : rebase_source : 537be91c2d9dd1482f3134d1833029fdfefd7c5f
extra : amend_source : ee3595059b4426ce9b35bb942dcdaa5793cc5ef7
This commit is contained in:
Nihanth Subramanya 2016-11-08 16:10:12 +05:30
parent f86fb95f77
commit 81dfc8023b
4 changed files with 132 additions and 45 deletions

View File

@ -30,6 +30,8 @@
// e - the error code
// s - custom CSS class to allow alternate styling/favicons
// d - error description
// captive - "true" to indicate we're behind a captive portal.
// Any other value is ignored.
// Note that this file uses document.documentURI to get
// the URL (with the format from above). This is because
@ -57,6 +59,10 @@
return searchParams.get("d");
}
function isCaptive() {
return searchParams.get("captive") == "true";
}
function retryThis(buttonEl)
{
// Note: The application may wish to handle switching off "offline mode"
@ -105,7 +111,7 @@
});
}
function showAdvancedButton(allowOverride) {
function setupAdvancedButton(allowOverride) {
// Get the hostname and add it to the panel
var panelId = gIsCertError ? "badCertAdvancedPanel" : "weakCryptoAdvancedPanel";
var panel = document.getElementById(panelId);
@ -141,19 +147,12 @@
var overrideLink = document.getElementById("overrideWeakCrypto");
overrideLink.addEventListener("click", () => doOverride(overrideLink), false);
}
}
function initPageCertError() {
document.body.className = "certerror";
document.title = document.getElementById("certErrorPageTitle").textContent;
for (let host of document.querySelectorAll(".hostname")) {
host.textContent = document.location.hostname;
if (!gIsCertError) {
return;
}
showAdvancedButton(true);
var cssClass = getCSSClass();
if (cssClass == "expertBadCert") {
if (getCSSClass() == "expertBadCert") {
toggleDisplay(document.getElementById("badCertAdvancedPanel"));
// Toggling the advanced panel must ensure that the debugging
// information panel is hidden as well, since it's opened by the
@ -162,27 +161,13 @@
div.style.display = "none";
}
document.getElementById("learnMoreContainer").style.display = "block";
disallowCertOverridesIfNeeded();
var checkbox = document.getElementById("automaticallyReportInFuture");
checkbox.addEventListener("change", function({target: {checked}}) {
document.dispatchEvent(new CustomEvent("AboutNetErrorSetAutomatic", {
detail: checked,
bubbles: true
}));
});
addEventListener("AboutNetErrorOptions", function(event) {
var options = JSON.parse(event.detail);
if (options && options.enabled) {
// Display error reporting UI
document.getElementById("certificateErrorReporting").style.display = "block";
// set the checkbox
checkbox.checked = !!options.automatic;
}
}, true, true);
document.getElementById("badCertTechnicalInfo").textContent = getDescription();
}
function disallowCertOverridesIfNeeded() {
var cssClass = getCSSClass();
// Disallow overrides if this is a Strict-Transport-Security
// host and the cert is bad (STS Spec section 7.3) or if the
// certerror is in a frame (bug 633691).
@ -192,19 +177,17 @@
if (cssClass == "badStsCert") {
document.getElementById("badStsCertExplanation").removeAttribute("hidden");
}
document.getElementById("badCertTechnicalInfo").textContent = getDescription();
var event = new CustomEvent("AboutNetErrorLoad", {bubbles:true});
document.getElementById("advancedButton").dispatchEvent(event);
addDomainErrorLinks();
}
function initPage()
{
var err = getErrorCode();
gIsCertError = (err == "nssBadCert");
// Only worry about captive portals if this is a cert error.
let showCaptivePortalUI = isCaptive() && gIsCertError;
if (showCaptivePortalUI) {
err = "captivePortal";
}
// if it's an unknown error or there's no title or description
// defined, get the generic message
@ -221,17 +204,23 @@
var sd = document.getElementById("errorShortDescText");
if (sd) {
if (gIsCertError) {
sd.innerHTML = document.getElementById("ed_nssBadCert").innerHTML;
sd.innerHTML = errDesc.innerHTML;
}
else {
sd.textContent = getDescription();
}
}
if (showCaptivePortalUI) {
initPageCaptivePortal();
return;
}
if (gIsCertError) {
initPageCertError();
return;
}
document.body.className = "neterror";
var ld = document.getElementById("errorLongDesc");
if (ld)
{
@ -325,7 +314,7 @@
}
}
if (getErrorCode() == "weakCryptoUsed" || getErrorCode() == "sslv3Used") {
showAdvancedButton(getErrorCode() == "weakCryptoUsed");
setupAdvancedButton(getErrorCode() == "weakCryptoUsed");
}
}.bind(this), true, true);
@ -346,6 +335,55 @@
addDomainErrorLinks();
}
function initPageCaptivePortal()
{
document.body.className = "captiveportal";
document.title = document.getElementById("captivePortalPageTitle").textContent;
document.getElementById("openPortalLoginPageButton")
.addEventListener("click", () => {
let event = new CustomEvent("AboutNetErrorOpenCaptivePortal", {bubbles:true});
document.dispatchEvent(event);
});
setupAdvancedButton(true);
addDomainErrorLinks();
}
function initPageCertError() {
document.body.className = "certerror";
document.title = document.getElementById("certErrorPageTitle").textContent;
setupAdvancedButton(true);
document.getElementById("learnMoreContainer").style.display = "block";
let checkbox = document.getElementById("automaticallyReportInFuture");
checkbox.addEventListener("change", function({target: {checked}}) {
document.dispatchEvent(new CustomEvent("AboutNetErrorSetAutomatic", {
detail: checked,
bubbles: true
}));
});
addEventListener("AboutNetErrorOptions", function(event) {
var options = JSON.parse(event.detail);
if (options && options.enabled) {
// Display error reporting UI
document.getElementById("certificateErrorReporting").style.display = "block";
// set the checkbox
checkbox.checked = !!options.automatic;
}
}, true, true);
let event = new CustomEvent("AboutNetErrorLoad", {bubbles:true});
document.getElementById("advancedButton").dispatchEvent(event);
addDomainErrorLinks();
}
/* Try to preserve the links contained in the error description, like
the error code.
@ -476,11 +514,13 @@
<body dir="&locale.dir;">
<!-- Contains an alternate page title set on page init for cert errors. -->
<div id="certErrorPageTitle" style="display: none;">&certerror.pagetitle1;</div>
<div id="captivePortalPageTitle" style="display: none;">&captivePortal.title;</div>
<!-- ERROR ITEM CONTAINER (removed during loading to avoid bug 39098) -->
<div id="errorContainer">
<div id="errorTitlesContainer">
<h1 id="et_generic">&generic.title;</h1>
<h1 id="et_captivePortal">&captivePortal.title;</h1>
<h1 id="et_dnsNotFound">&dnsNotFound.title;</h1>
<h1 id="et_fileNotFound">&fileNotFound.title;</h1>
<h1 id="et_fileAccessDenied">&fileAccessDenied.title;</h1>
@ -510,6 +550,7 @@
</div>
<div id="errorDescriptionsContainer">
<div id="ed_generic">&generic.longDesc;</div>
<div id="ed_captivePortal">&captivePortal.longDesc;</div>
<div id="ed_dnsNotFound">&dnsNotFound.longDesc;</div>
<div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
<div id="ed_fileAccessDenied">&fileAccessDenied.longDesc;</div>
@ -572,8 +613,9 @@
<button id="prefResetButton" class="primary" autocomplete="off">&prefReset.label;</button>
</div>
<div id="certErrorButtonContainer" class="button-container">
<div id="certErrorAndCaptivePortalButtonContainer" class="button-container">
<button id="returnButton" class="primary" autocomplete="off" autofocus="true">&returnToPreviousPage.label;</button>
<button id="openPortalLoginPageButton" class="primary" autocomplete="off" autofocus="true">&openPortalLoginPage.label;</button>
<div class="button-spacer"></div>
<button id="advancedButton" autocomplete="off" autofocus="true">&advanced.label;</button>
</div>

View File

@ -151,7 +151,6 @@ XPCOMUtils.defineLazyGetter(this, "Win7Features", function() {
return null;
});
const nsIWebNavigation = Ci.nsIWebNavigation;
var gLastBrowserCharset = null;
@ -2728,6 +2727,7 @@ var BrowserOnClick = {
init: function() {
let mm = window.messageManager;
mm.addMessageListener("Browser:CertExceptionError", this);
mm.addMessageListener("Browser:OpenCaptivePortalPage", this);
mm.addMessageListener("Browser:SiteBlockedError", this);
mm.addMessageListener("Browser:EnableOnlineMode", this);
mm.addMessageListener("Browser:SendSSLErrorReport", this);
@ -2776,6 +2776,9 @@ var BrowserOnClick = {
msg.data.isTopFrame, msg.data.location,
msg.data.securityInfoAsString);
break;
case "Browser:OpenCaptivePortalPage":
this.onOpenCaptivePortalPage();
break;
case "Browser:SiteBlockedError":
this.onAboutBlocked(msg.data.elementId, msg.data.reason,
msg.data.isTopFrame, msg.data.location);
@ -2910,6 +2913,28 @@ var BrowserOnClick = {
}
},
onOpenCaptivePortalPage: function() {
// Open a new tab with the canonical URL that we use to check for a captive portal.
// It will be redirected to the login page.
let canonicalURL = Services.prefs.getCharPref("captivedetect.canonicalURL");
let tab = gBrowser.addTab(canonicalURL);
let canonicalURI = makeURI(canonicalURL);
gBrowser.selectedTab = tab;
// When we are no longer captive, close the tab if it's at the canonical URL.
let tabCloser = () => {
Services.obs.removeObserver(tabCloser, "captive-portal-login-abort");
Services.obs.removeObserver(tabCloser, "captive-portal-login-success");
if (!tab || tab.closing || !tab.parentNode || !tab.linkedBrowser ||
!tab.linkedBrowser.currentURI.equalsExceptRef(canonicalURI)) {
return;
}
gBrowser.removeTab(tab);
}
Services.obs.addObserver(tabCloser, "captive-portal-login-abort", false);
Services.obs.addObserver(tabCloser, "captive-portal-login-success", false);
},
onAboutBlocked: function(elementId, reason, isTopFrame, location) {
// Depending on what page we are displaying here (malware/phishing/unwanted)
// use the right strings and links for each.

View File

@ -265,6 +265,7 @@ var AboutNetAndCertErrorListener = {
init: function(chromeGlobal) {
addMessageListener("CertErrorDetails", this);
chromeGlobal.addEventListener('AboutNetErrorLoad', this, false, true);
chromeGlobal.addEventListener('AboutNetErrorOpenCaptivePortal', this, false, true);
chromeGlobal.addEventListener('AboutNetErrorSetAutomatic', this, false, true);
chromeGlobal.addEventListener('AboutNetErrorOverride', this, false, true);
chromeGlobal.addEventListener('AboutNetErrorResetPreferences', this, false, true);
@ -348,6 +349,9 @@ var AboutNetAndCertErrorListener = {
case "AboutNetErrorLoad":
this.onPageLoad(aEvent);
break;
case "AboutNetErrorOpenCaptivePortal":
this.openCaptivePortalPage(aEvent);
break;
case "AboutNetErrorSetAutomatic":
this.onSetAutomatic(aEvent);
break;
@ -390,6 +394,10 @@ var AboutNetAndCertErrorListener = {
{reportStatus: TLS_ERROR_REPORT_TELEMETRY_UI_SHOWN});
},
openCaptivePortalPage: function(evt) {
sendAsyncMessage("Browser:OpenCaptivePortalPage");
},
onResetPreferences: function(evt) {
sendAsyncMessage("Browser:ResetSSLPreferences");

View File

@ -39,15 +39,15 @@ button:disabled {
display: none;
}
#certErrorButtonContainer {
#certErrorAndCaptivePortalButtonContainer {
display: none;
}
body.certerror #certErrorButtonContainer {
body:not(.neterror) #certErrorAndCaptivePortalButtonContainer {
display: flex;
}
body.certerror #netErrorButtonContainer {
body:not(.neterror) #netErrorButtonContainer {
display: none;
}
@ -64,7 +64,19 @@ body.certerror #netErrorButtonContainer {
display: none;
}
body.certerror #advancedButton {
body.captiveportal #returnButton {
display: none;
}
body:not(.captiveportal) #openPortalLoginPageButton {
display: none;
}
#openPortalLoginPageButton {
margin-inline-start: 0;
}
body:not(.neterror) #advancedButton {
display: block;
}