Bug 1207130 - Add a checkbox for automatic error reporting to about:certerror r=Gijs,past

--HG--
rename : browser/base/content/test/general/pinning_reports.sjs => browser/base/content/test/general/ssl_error_reports.sjs
This commit is contained in:
Tim Taubert 2016-01-13 15:29:54 +01:00
Родитель 9960a81092
Коммит d558566d6f
13 изменённых файлов: 402 добавлений и 330 удалений

Просмотреть файл

@ -260,15 +260,12 @@
var event = new CustomEvent("AboutNetErrorSetAutomatic",
{bubbles:true, detail:evt.target.checked});
document.dispatchEvent(event);
if (evt.target.checked && reportBtn.style.display != "none") {
if (evt.target.checked) {
sendErrorReport();
}
}, false);
var reportBtn = document.getElementById('reportCertificateError');
var retryBtn = document.getElementById('reportCertificateErrorRetry');
reportBtn.addEventListener('click', sendErrorReport, false);
retryBtn.addEventListener('click', sendErrorReport, false);
}
}
@ -532,7 +529,6 @@
<label for="automaticallyReportInFuture" id="automaticallyReportInFuture">&errorReporting.automatic2;</label>
<span id="reportingState">
<button id="reportCertificateError">&errorReporting.report;</button>
<button id="reportCertificateErrorRetry">&errorReporting.tryAgain;</button>
<span id="reportSendingMessage">&errorReporting.sending;</span>
<span id="reportSentMessage">&errorReporting.sent;</span>

Просмотреть файл

@ -88,6 +88,32 @@
toggleVisibility('advancedPanel');
}
var checkbox = document.getElementById("automaticallyReportInFuture");
checkbox.addEventListener("change", function ({target: {checked}}) {
document.dispatchEvent(new CustomEvent("AboutCertErrorSetAutomatic", {
detail: checked,
bubbles: true
}));
});
var retryBtn = document.getElementById("reportCertificateErrorRetry");
retryBtn.addEventListener("click", function () {
document.dispatchEvent(new CustomEvent("AboutCertErrorSendReport", {
bubbles: true
}));
});
addEventListener("AboutCertErrorOptions", 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);
// 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).
@ -254,11 +280,26 @@
<div id="buttonSpacer"></div>
<button id="advancedButton" autocomplete="off" onclick="toggleVisibility('advancedPanel');" autofocus="true">&certerror.advanced.label;</button>
</div>
<!-- Advanced panel, which is hidden by default -->
<div id="advancedPanel" style="visibility: hidden;">
<p id="technicalContentText"/>
<button id="exceptionDialogButton">&certerror.addException.label;</button>
</div>
</div>
<!-- UI for option to report certificate errors to Mozilla. -->
<div id="certificateErrorReporting">
<p>
<input type="checkbox" id="automaticallyReportInFuture" />
<label for="automaticallyReportInFuture" id="automaticallyReportInFuture">&errorReporting.automatic;</label>
<span id="reportingState">
<button id="reportCertificateErrorRetry">&errorReporting.tryAgain;</button>
<span id="reportSendingMessage">&errorReporting.sending;</span>
<span id="reportSentMessage">&errorReporting.sent;</span>
</span>
</p>
</div>
<!-- Advanced panel, which is hidden by default -->
<div id="advancedPanel" style="visibility: hidden;">
<p id="technicalContentText"/>
<button id="exceptionDialogButton">&certerror.addException.label;</button>
</div>
</div>

Просмотреть файл

@ -2673,7 +2673,7 @@ var BrowserOnClick = {
}
break;
case "Browser:SendSSLErrorReport":
this.onSSLErrorReport(msg.target, msg.data.elementId,
this.onSSLErrorReport(msg.target,
msg.data.documentURI,
msg.data.location,
msg.data.securityInfo);
@ -2704,7 +2704,7 @@ var BrowserOnClick = {
}
},
onSSLErrorReport: function(browser, elementId, documentURI, location, securityInfo) {
onSSLErrorReport: function(browser, documentURI, location, securityInfo) {
function showReportStatus(reportStatus) {
gBrowser.selectedBrowser
.messageManager

Просмотреть файл

@ -207,6 +207,143 @@ const TLS_ERROR_REPORT_TELEMETRY_EXPANDED = 1;
const TLS_ERROR_REPORT_TELEMETRY_SUCCESS = 6;
const TLS_ERROR_REPORT_TELEMETRY_FAILURE = 7;
var AboutCertErrorListener = {
init(chromeGlobal) {
addMessageListener("AboutCertErrorDetails", this);
addMessageListener("Browser:SSLErrorReportStatus", this);
chromeGlobal.addEventListener("AboutCertErrorLoad", this, false, true);
chromeGlobal.addEventListener("AboutCertErrorSetAutomatic", this, false, true);
chromeGlobal.addEventListener("AboutCertErrorSendReport", this, false, true);
},
get isAboutCertError() {
return content.document.documentURI.startsWith("about:certerror");
},
handleEvent(event) {
if (!this.isAboutCertError) {
return;
}
switch (event.type) {
case "AboutCertErrorLoad":
this.onLoad(event);
break;
case "AboutCertErrorSetAutomatic":
this.onSetAutomatic(event);
break;
case "AboutCertErrorSendReport":
this.onSendReport();
break;
}
},
receiveMessage(msg) {
if (!this.isAboutCertError) {
return;
}
switch (msg.name) {
case "AboutCertErrorDetails":
this.onDetails(msg);
break;
case "Browser:SSLErrorReportStatus":
this.onReportStatus(msg);
break;
}
},
onLoad(event) {
let originalTarget = event.originalTarget;
let ownerDoc = originalTarget.ownerDocument;
ClickEventHandler.onAboutCertError(originalTarget, ownerDoc);
let automatic = Services.prefs.getBoolPref("security.ssl.errorReporting.automatic");
content.dispatchEvent(new content.CustomEvent("AboutCertErrorOptions", {
detail: JSON.stringify({
enabled: Services.prefs.getBoolPref("security.ssl.errorReporting.enabled"),
automatic,
})
}));
if (automatic) {
this.onSendReport();
}
},
onDetails(msg) {
let div = content.document.getElementById("certificateErrorText");
div.textContent = msg.data.info;
},
onSetAutomatic(event) {
if (event.detail) {
this.onSendReport();
}
sendAsyncMessage("Browser:SetSSLErrorReportAuto", {
automatic: event.detail
});
},
onSendReport() {
let doc = content.document;
let location = doc.location.href;
let serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
.getService(Ci.nsISerializationHelper);
let serializable = docShell.failedChannel.securityInfo
.QueryInterface(Ci.nsITransportSecurityInfo)
.QueryInterface(Ci.nsISerializable);
let serializedSecurityInfo = serhelper.serializeToString(serializable);
sendAsyncMessage("Browser:SendSSLErrorReport", {
documentURI: doc.documentURI,
location: {hostname: doc.location.hostname, port: doc.location.port},
securityInfo: serializedSecurityInfo
});
},
onReportStatus(msg) {
let doc = content.document;
if (doc.documentURI != msg.data.documentURI) {
return;
}
let reportSendingMsg = doc.getElementById("reportSendingMessage");
let reportSentMsg = doc.getElementById("reportSentMessage");
let retryBtn = doc.getElementById("reportCertificateErrorRetry");
switch (msg.data.reportStatus) {
case "activity":
// Hide the button that was just clicked
retryBtn.style.removeProperty("display");
reportSentMsg.style.removeProperty("display");
reportSendingMsg.style.display = "block";
break;
case "error":
// show the retry button
retryBtn.style.display = "block";
reportSendingMsg.style.removeProperty("display");
sendAsyncMessage("Browser:SSLErrorReportTelemetry",
{reportStatus: TLS_ERROR_REPORT_TELEMETRY_FAILURE});
break;
case "complete":
// Show a success indicator
reportSentMsg.style.display = "block";
reportSendingMsg.style.removeProperty("display");
sendAsyncMessage("Browser:SSLErrorReportTelemetry",
{reportStatus: TLS_ERROR_REPORT_TELEMETRY_SUCCESS});
break;
}
}
};
AboutCertErrorListener.init(this);
var AboutNetErrorListener = {
init: function(chromeGlobal) {
chromeGlobal.addEventListener('AboutNetErrorLoad', this, false, true);
@ -283,7 +420,6 @@ var AboutNetErrorListener = {
let reportSendingMsg = contentDoc.getElementById("reportSendingMessage");
let reportSentMsg = contentDoc.getElementById("reportSentMessage");
let reportBtn = contentDoc.getElementById("reportCertificateError");
let retryBtn = contentDoc.getElementById("reportCertificateErrorRetry");
addMessageListener("Browser:SSLErrorReportStatus", function(message) {
@ -293,7 +429,6 @@ var AboutNetErrorListener = {
switch(message.data.reportStatus) {
case "activity":
// Hide the button that was just clicked
reportBtn.style.display = "none";
retryBtn.style.display = "none";
reportSentMsg.style.display = "none";
reportSendingMsg.style.removeProperty("display");
@ -319,20 +454,22 @@ var AboutNetErrorListener = {
let location = contentDoc.location.href;
let serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
.getService(Ci.nsISerializationHelper);
.getService(Ci.nsISerializationHelper);
let serializable = docShell.failedChannel.securityInfo
.QueryInterface(Ci.nsITransportSecurityInfo)
.QueryInterface(Ci.nsISerializable);
let serializable = docShell.failedChannel.securityInfo
.QueryInterface(Ci.nsITransportSecurityInfo)
.QueryInterface(Ci.nsISerializable);
let serializedSecurityInfo = serhelper.serializeToString(serializable);
sendAsyncMessage("Browser:SendSSLErrorReport", {
elementId: evt.target.id,
documentURI: contentDoc.documentURI,
location: {hostname: contentDoc.location.hostname, port: contentDoc.location.port},
securityInfo: serializedSecurityInfo
});
documentURI: contentDoc.documentURI,
location: {
hostname: contentDoc.location.hostname,
port: contentDoc.location.port
},
securityInfo: serializedSecurityInfo
});
},
onOverride: function(evt) {
@ -553,17 +690,6 @@ addEventListener("DOMServiceWorkerFocusClient", function(event) {
sendAsyncMessage("DOMServiceWorkerFocusClient", {});
}, false);
addEventListener("AboutCertErrorLoad", function(event) {
let originalTarget = event.originalTarget;
let ownerDoc = originalTarget.ownerDocument;
ClickEventHandler.onAboutCertError(originalTarget, ownerDoc);
}, false, true);
addMessageListener("AboutCertErrorDetails", function(message) {
let div = content.document.getElementById("certificateErrorText");
div.textContent = message.data.info;
});
ContentWebRTC.init();
addMessageListener("rtcpeer:Allow", ContentWebRTC);
addMessageListener("rtcpeer:Deny", ContentWebRTC);

Просмотреть файл

@ -16,7 +16,6 @@ support-files =
browser_fxa_oauth_with_keys.html
browser_fxa_web_channel.html
browser_registerProtocolHandler_notification.html
browser_ssl_error_reports_content.js
browser_star_hsts.sjs
browser_tab_dragdrop2_frame1.xul
browser_web_channel.html
@ -79,7 +78,7 @@ support-files =
page_style_sample.html
parsingTestHelpers.jsm
pinning_headers.sjs
pinning_reports.sjs
ssl_error_reports.sjs
popup_blocker.html
print_postdata.sjs
redirect_bug623155.sjs

Просмотреть файл

@ -1,307 +1,217 @@
"use strict";
var badChainURL = "https://badchain.include-subdomains.pinning.example.com";
var noCertURL = "https://fail-handshake.example.com";
var enabledPref = false;
var automaticPref = false;
var urlPref = "security.ssl.errorReporting.url";
var enforcement_level = 1;
var ROOT = getRootDirectory(gTestPath);
const URL_REPORTS = "https://example.com/browser/browser/base/content/test/general/ssl_error_reports.sjs?";
const URL_BAD_CHAIN = "https://badchain.include-subdomains.pinning.example.com/";
const URL_NO_CERT = "https://fail-handshake.example.com/";
const URL_BAD_CERT = "https://expired.example.com/";
const URL_BAD_STS_CERT = "https://badchain.include-subdomains.pinning.example.com:443/";
const ROOT = getRootDirectory(gTestPath);
const PREF_REPORT_ENABLED = "security.ssl.errorReporting.enabled";
const PREF_REPORT_AUTOMATIC = "security.ssl.errorReporting.automatic";
const PREF_REPORT_URL = "security.ssl.errorReporting.url";
SimpleTest.requestCompleteLog();
add_task(function* test_send_report_manual_badchain() {
yield testSendReportManual(badChainURL, "succeed");
});
Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 2);
add_task(function* test_send_report_manual_nocert() {
yield testSendReportManual(noCertURL, "nocert");
});
// creates a promise of the message in an error page
function createNetworkErrorMessagePromise(aBrowser) {
let promise = new Promise(function(resolve, reject) {
let originalDocumentURI = aBrowser.contentDocument.documentURI;
let loadedListener = function() {
let doc = aBrowser.contentDocument;
if (doc && doc.getElementById("reportCertificateError")) {
let documentURI = doc.documentURI;
aBrowser.removeEventListener("DOMContentLoaded", loadedListener, true);
let matchArray = /about:neterror\?.*&d=([^&]*)/.exec(documentURI);
if (!matchArray) {
reject("no network error message found in URI");
return;
}
let errorMsg = matchArray[1];
resolve(decodeURIComponent(errorMsg));
}
};
aBrowser.addEventListener("DOMContentLoaded", loadedListener, true);
});
return promise;
function cleanup() {
Services.prefs.clearUserPref(PREF_REPORT_ENABLED);
Services.prefs.clearUserPref(PREF_REPORT_AUTOMATIC);
Services.prefs.clearUserPref(PREF_REPORT_URL);
}
// check we can set the 'automatically send' pref
add_task(function* test_set_automatic() {
setup();
let tab = gBrowser.addTab(badChainURL, {skipAnimation: true});
let browser = tab.linkedBrowser;
let mm = browser.messageManager;
mm.loadFrameScript(ROOT + "browser_ssl_error_reports_content.js", true);
gBrowser.selectedTab = tab;
// ensure we have the correct error message from about:neterror
let netError = createNetworkErrorMessagePromise(browser);
yield netError;
// ensure that setting automatic when unset works
let prefEnabled = new Promise(function(resolve, reject){
let prefUpdateListener = function() {
mm.removeMessageListener("ssler-test:AutoPrefUpdated", prefUpdateListener);
if (Services.prefs.getBoolPref("security.ssl.errorReporting.automatic")) {
resolve();
} else {
reject();
}
};
mm.addMessageListener("ssler-test:AutoPrefUpdated", prefUpdateListener);
});
mm.sendAsyncMessage("ssler-test:SetAutoPref",{value:true});
yield prefEnabled;
// ensure un-setting automatic, when set, works
let prefDisabled = new Promise(function(resolve, reject){
let prefUpdateListener = function () {
mm.removeMessageListener("ssler-test:AutoPrefUpdated", prefUpdateListener);
if (!Services.prefs.getBoolPref("security.ssl.errorReporting.automatic")) {
resolve();
} else {
reject();
}
};
mm.addMessageListener("ssler-test:AutoPrefUpdated", prefUpdateListener);
});
mm.sendAsyncMessage("ssler-test:SetAutoPref",{value:false});
yield prefDisabled;
gBrowser.removeTab(tab);
registerCleanupFunction(() => {
Services.prefs.clearUserPref("security.cert_pinning.enforcement_level");
cleanup();
});
// test that manual report sending (with button clicks) works
var testSendReportManual = function*(testURL, suffix) {
setup();
Services.prefs.setBoolPref("security.ssl.errorReporting.enabled", true);
Services.prefs.setCharPref("security.ssl.errorReporting.url",
"https://example.com/browser/browser/base/content/test/general/pinning_reports.sjs?" + suffix);
add_task(function* test_send_report_neterror() {
yield testSendReportAutomatically(URL_BAD_CHAIN, "succeed", "neterror");
yield testSendReportAutomatically(URL_NO_CERT, "nocert", "neterror");
yield testSendReportFailRetry(URL_NO_CERT, "nocert", "neterror");
yield testSetAutomatic(URL_NO_CERT, "nocert", "neterror");
});
let tab = gBrowser.addTab(testURL, {skipAnimation: true});
add_task(function* test_send_report_certerror() {
yield testSendReportAutomatically(URL_BAD_CERT, "badcert", "certerror");
yield testSendReportFailRetry(URL_BAD_CERT, "badcert", "certerror");
yield testSetAutomatic(URL_BAD_CERT, "badcert", "certerror");
});
add_task(function* test_send_disabled() {
Services.prefs.setBoolPref(PREF_REPORT_ENABLED, false);
Services.prefs.setBoolPref(PREF_REPORT_AUTOMATIC, true);
Services.prefs.setCharPref(PREF_REPORT_URL, "https://example.com/invalid");
// Check with enabled=false but automatic=true.
yield testSendReportDisabled(URL_NO_CERT, "neterror");
yield testSendReportDisabled(URL_BAD_CERT, "certerror");
Services.prefs.setBoolPref(PREF_REPORT_AUTOMATIC, false);
// Check again with both prefs false.
yield testSendReportDisabled(URL_NO_CERT, "neterror");
yield testSendReportDisabled(URL_BAD_CERT, "certerror");
cleanup();
});
function* testSendReportAutomatically(testURL, suffix, errorURISuffix) {
Services.prefs.setBoolPref(PREF_REPORT_ENABLED, true);
Services.prefs.setBoolPref(PREF_REPORT_AUTOMATIC, true);
Services.prefs.setCharPref(PREF_REPORT_URL, URL_REPORTS + suffix);
// Add a tab and wait until it's loaded.
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
let browser = tab.linkedBrowser;
let mm = browser.messageManager;
mm.loadFrameScript(ROOT + "browser_ssl_error_reports_content.js", true);
gBrowser.selectedTab = tab;
// Load the page and wait for the error report submission.
let promiseReport = createErrorReportPromise(browser);
browser.loadURI(testURL);
yield promiseReport;
ok(true, "SSL error report submitted successfully");
// ensure we have the correct error message from about:neterror
let netError = createNetworkErrorMessagePromise(browser);
yield netError;
netError.then(function(val){
is(val.startsWith("An error occurred during a connection to"), true,
"ensure the correct error message came from about:neterror");
});
let btn = browser.contentDocument.getElementById("reportCertificateError");
let deferredReportSucceeds = Promise.defer();
// ensure we see the correct statuses in the correct order...
let statusListener = function() {
let active = false;
return function(message) {
switch(message.data.reportStatus) {
case "activity":
if (!active) {
active = true;
}
break;
case "complete":
mm.removeMessageListener("ssler-test:SSLErrorReportStatus", statusListener);
if (active) {
deferredReportSucceeds.resolve(message.data.reportStatus);
} else {
deferredReportSucceeds.reject('activity should be seen before success');
}
break;
case "error":
mm.removeMessageListener("ssler-test:SSLErrorReportStatus", statusListener);
deferredReportSucceeds.reject();
break;
}
};
}();
mm.addMessageListener("ssler-test:SSLErrorReportStatus", statusListener);
// ... once the button is clicked, that is
mm.sendAsyncMessage("ssler-test:SendBtnClick",{});
yield deferredReportSucceeds.promise;
// Check that we loaded the right error page.
yield checkErrorPage(browser, errorURISuffix);
// Cleanup.
gBrowser.removeTab(tab);
cleanup();
};
// test that automatic sending works
add_task(function* test_send_report_auto() {
setup();
Services.prefs.setBoolPref("security.ssl.errorReporting.enabled", true);
Services.prefs.setBoolPref("security.ssl.errorReporting.automatic", true);
Services.prefs.setCharPref("security.ssl.errorReporting.url", "https://example.com/browser/browser/base/content/test/general/pinning_reports.sjs?succeed");
function* testSendReportFailRetry(testURL, suffix, errorURISuffix) {
try {
yield testSendReportAutomatically(testURL, "error", errorURISuffix);
ok(false, "sending a report should have failed");
} catch (err) {
ok(err, "saw a failure notification");
}
let tab = gBrowser.addTab(badChainURL, {skipAnimation: true});
let browser = tab.linkedBrowser;
let mm = browser.messageManager;
mm.loadFrameScript(ROOT + "browser_ssl_error_reports_content.js", true);
Services.prefs.setCharPref(PREF_REPORT_URL, URL_REPORTS + suffix);
gBrowser.selectedTab = tab;
// Ensure the error page loads
let netError = createNetworkErrorMessagePromise(browser);
yield netError;
let reportWillStart = Promise.defer();
let startListener = function() {
mm.removeMessageListener("Browser:SendSSLErrorReport", startListener);
reportWillStart.resolve();
};
mm.addMessageListener("Browser:SendSSLErrorReport", startListener);
let deferredReportSucceeds = Promise.defer();
let statusListener = function(message) {
switch(message.data.reportStatus) {
case "complete":
mm.removeMessageListener("ssler-test:SSLErrorReportStatus", statusListener);
deferredReportSucceeds.resolve(message.data.reportStatus);
break;
case "error":
mm.removeMessageListener("ssler-test:SSLErrorReportStatus", statusListener);
deferredReportSucceeds.reject();
break;
}
};
mm.addMessageListener("ssler-test:SSLErrorReportStatus", statusListener);
// Ensure the report is sent with no interaction
yield deferredReportSucceeds.promise;
gBrowser.removeTab(tab);
cleanup();
});
// test that an error is shown if there's a problem with the report server
add_task(function* test_send_report_error() {
setup();
// set up prefs so error send is automatic and an error will occur
Services.prefs.setBoolPref("security.ssl.errorReporting.enabled", true);
Services.prefs.setBoolPref("security.ssl.errorReporting.automatic", true);
Services.prefs.setCharPref("security.ssl.errorReporting.url", "https://example.com/browser/browser/base/content/test/general/pinning_reports.sjs?error");
// load the test URL so error page is seen
let tab = gBrowser.addTab(badChainURL, {skipAnimation: true});
let browser = tab.linkedBrowser;
gBrowser.selectedTab = tab;
let mm = browser.messageManager;
mm.loadFrameScript(ROOT + "browser_ssl_error_reports_content.js", true);
let reportErrors = new Promise(function(resolve, reject) {
let statusListener = function(message) {
switch(message.data.reportStatus) {
case "complete":
reject(message.data.reportStatus);
mm.removeMessageListener("ssler-test:SSLErrorReportStatus", statusListener);
break;
case "error":
resolve(message.data.reportStatus);
mm.removeMessageListener("ssler-test:SSLErrorReportStatus", statusListener);
break;
}
};
mm.addMessageListener("ssler-test:SSLErrorReportStatus", statusListener);
let browser = gBrowser.selectedBrowser;
let promiseReport = createErrorReportPromise(browser);
let promiseRetry = ContentTask.spawn(browser, null, function* () {
content.document.getElementById("reportCertificateErrorRetry").click();
});
// check that errors are sent
yield reportErrors;
yield Promise.all([promiseReport, promiseRetry]);
ok(true, "SSL error report submitted successfully");
gBrowser.removeTab(tab);
// Cleanup.
gBrowser.removeCurrentTab();
cleanup();
});
}
add_task(function* test_send_report_disabled() {
setup();
Services.prefs.setBoolPref("security.ssl.errorReporting.enabled", false);
Services.prefs.setCharPref("security.ssl.errorReporting.url", "https://offdomain.com");
function* testSetAutomatic(testURL, suffix, errorURISuffix) {
Services.prefs.setBoolPref(PREF_REPORT_ENABLED, true);
Services.prefs.setBoolPref(PREF_REPORT_AUTOMATIC, false);
Services.prefs.setCharPref(PREF_REPORT_URL, URL_REPORTS + suffix);
let tab = gBrowser.addTab(badChainURL, {skipAnimation: true});
// Add a tab and wait until it's loaded.
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
let browser = tab.linkedBrowser;
let mm = browser.messageManager;
mm.loadFrameScript(ROOT + "browser_ssl_error_reports_content.js", true);
gBrowser.selectedTab = tab;
// Load the page.
browser.loadURI(testURL);
yield promiseErrorPageLoaded(browser);
// Ensure we have an error page
let netError = createNetworkErrorMessagePromise(browser);
yield netError;
// Check that we loaded the right error page.
yield checkErrorPage(browser, errorURISuffix);
let reportErrors = new Promise(function(resolve, reject) {
let statusListener = function(message) {
switch(message.data.reportStatus) {
case "complete":
mm.removeMessageListener("ssler-test:SSLErrorReportStatus", statusListener);
reject(message.data.reportStatus);
break;
case "error":
mm.removeMessageListener("ssler-test:SSLErrorReportStatus", statusListener);
resolve(message.data.reportStatus);
break;
}
};
mm.addMessageListener("ssler-test:SSLErrorReportStatus", statusListener);
// Click the checkbox, enable automatic error reports.
let promiseReport = createErrorReportPromise(browser);
yield ContentTask.spawn(browser, null, function* () {
content.document.getElementById("automaticallyReportInFuture").click();
});
// click the button
mm.sendAsyncMessage("ssler-test:SendBtnClick",{forceUI:true});
// Wait for the error report submission.
yield promiseReport;
ok(true, "SSL error report submitted successfully");
// check we get an error
yield reportErrors;
let isAutomaticReportingEnabled = () =>
Services.prefs.getBoolPref(PREF_REPORT_AUTOMATIC);
// Check that the pref was flipped.
ok(isAutomaticReportingEnabled(), "automatic SSL report submission enabled");
// Disable automatic error reports.
yield ContentTask.spawn(browser, null, function* () {
content.document.getElementById("automaticallyReportInFuture").click();
});
// Check that the pref was flipped.
ok(!isAutomaticReportingEnabled(), "automatic SSL report submission disabled");
// Cleanup.
gBrowser.removeTab(tab);
cleanup();
});
function setup() {
// ensure the relevant prefs are set
enabledPref = Services.prefs.getBoolPref("security.ssl.errorReporting.enabled");
automaticPref = Services.prefs.getBoolPref("security.ssl.errorReporting.automatic");
urlPref = Services.prefs.getCharPref("security.ssl.errorReporting.url");
enforcement_level = Services.prefs.getIntPref("security.cert_pinning.enforcement_level");
Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 2);
}
function cleanup() {
// reset prefs for other tests in the run
Services.prefs.setBoolPref("security.ssl.errorReporting.enabled", enabledPref);
Services.prefs.setBoolPref("security.ssl.errorReporting.automatic", automaticPref);
Services.prefs.setCharPref("security.ssl.errorReporting.url", urlPref);
function* testSendReportDisabled(testURL, errorURISuffix) {
// Add a tab and wait until it's loaded.
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
let browser = tab.linkedBrowser;
// Load the page.
browser.loadURI(testURL);
yield promiseErrorPageLoaded(browser);
// Check that we loaded the right error page.
yield checkErrorPage(browser, errorURISuffix);
// Check that the error reporting section is hidden.
let hidden = yield ContentTask.spawn(browser, null, function* () {
let section = content.document.getElementById("certificateErrorReporting");
return content.getComputedStyle(section).display == "none";
});
ok(hidden, "error reporting section should be hidden");
// Cleanup.
gBrowser.removeTab(tab);
}
function createErrorReportPromise(browser) {
return ContentTask.spawn(browser, null, function* () {
let type = "Browser:SSLErrorReportStatus";
let active = false;
yield new Promise((resolve, reject) => {
addMessageListener(type, function onReportStatus(message) {
switch (message.data.reportStatus) {
case "activity":
active = true;
break;
case "complete":
removeMessageListener(type, onReportStatus);
if (active) {
resolve(message.data.reportStatus);
} else {
reject("activity should be seen before success");
}
break;
case "error":
removeMessageListener(type, onReportStatus);
reject("sending the report failed");
break;
}
});
});
});
}
function promiseErrorPageLoaded(browser) {
return new Promise(resolve => {
browser.addEventListener("DOMContentLoaded", function onLoad() {
browser.removeEventListener("DOMContentLoaded", onLoad, false, true);
resolve();
}, false, true);
});
}
function checkErrorPage(browser, suffix) {
return ContentTask.spawn(browser, null, function* () {
return content.document.documentURI;
}).then(uri => {
ok(uri.startsWith(`about:${suffix}`), "correct error page loaded");
});
}

Просмотреть файл

@ -1,25 +0,0 @@
addMessageListener("Browser:SSLErrorReportStatus", function(message) {
sendSyncMessage("ssler-test:SSLErrorReportStatus", {reportStatus:message.data.reportStatus});
});
addMessageListener("ssler-test:SetAutoPref", function(message) {
let checkbox = content.document.getElementById("automaticallyReportInFuture");
// we use "click" because otherwise the 'changed' event will not fire
if (checkbox.checked != message.data.value) {
checkbox.click();
}
sendSyncMessage("ssler-test:AutoPrefUpdated", {});
});
addMessageListener("ssler-test:SendBtnClick", function(message) {
if (message.data && message.data.forceUI) {
content.dispatchEvent(new content.CustomEvent("AboutNetErrorOptions",
{
detail: "{\"enabled\": true, \"automatic\": false}"
}));
}
let btn = content.document.getElementById("reportCertificateError");
btn.click();
});

Просмотреть файл

@ -61,6 +61,20 @@ function handleRequest(request, response) {
return;
}
// if all is as expected, send the 201 the client expects
response.setStatusLine("1.1", 201, "Created");
response.write("<html>OK</html>");
break;
case "badcert":
report = parseReport(request);
certChain = report.failedCertChain;
if (!certChain || certChain.length != 2) {
response.setStatusLine("1.1", 500, "Server error");
response.write("<html>The report contained an unexpected chain</html>");
return;
}
// if all is as expected, send the 201 the client expects
response.setStatusLine("1.1", 201, "Created");
response.write("<html>OK</html>");

Просмотреть файл

@ -34,3 +34,8 @@ tampering with your connection.</b>">
you know there's a good reason why this site doesn't use trusted identification.">
<!ENTITY certerror.addException.label "Add Exception…">
<!ENTITY certerror.copyToClipboard.label "Copy text to clipboard">
<!ENTITY errorReporting.automatic "Report errors like this to help Mozilla identify misconfigured sites">
<!ENTITY errorReporting.sending "Sending report">
<!ENTITY errorReporting.sent "Report sent">
<!ENTITY errorReporting.tryAgain "Try again">

Просмотреть файл

@ -208,7 +208,6 @@ functionality specific to firefox. -->
<!ENTITY errorReporting.learnMore "Learn more…">
<!ENTITY errorReporting.sending "Sending report">
<!ENTITY errorReporting.sent "Report sent">
<!ENTITY errorReporting.report "Report">
<!ENTITY errorReporting.tryAgain "Try again">
<!ENTITY remoteXUL.title "Remote XUL">

Просмотреть файл

@ -96,6 +96,7 @@ body {
/* Advanced section is hidden via inline styles until the link is clicked */
#advancedPanel {
position: absolute;
background-color: white;
color: var(--in-content-text-color);
border: 1px lightgray solid;
@ -110,3 +111,10 @@ body {
.hostname {
font-weight: bold;
}
#reportCertificateErrorRetry,
#certificateErrorReporting,
#reportSendingMessage,
#reportSentMessage {
display: none;
}

Просмотреть файл

@ -116,7 +116,6 @@ button:disabled {
}
#certificateErrorReporting,
#reportCertificateError,
#reportSentMessage {
display: none;
}

Просмотреть файл

@ -265,7 +265,7 @@ user_pref('identity.fxaccounts.skipDeviceRegistration', true);
user_pref("apz.content_response_timeout", 60000);
// Make sure SSL Error reports don't hit the network
user_pref("security.ssl.errorReporting.url", "https://example.com/browser/browser/base/content/test/general/pinning_reports.sjs?succeed");
user_pref("security.ssl.errorReporting.url", "https://example.com/browser/browser/base/content/test/general/ssl_error_reports.sjs?succeed");
// Make sure Translation won't hit the network.
user_pref("browser.translation.bing.authURL", "http://%(server)s/browser/browser/components/translation/test/bing.sjs");