Bug 1555438 - Remove getDetailedCertErrorInfo from NetErrorChild.jsm. r=johannh,fluent-reviewers,flod

Differential Revision: https://phabricator.services.mozilla.com/D33065

--HG--
extra : moz-landing-system : lando
This commit is contained in:
prathiksha 2019-06-26 20:24:05 +00:00
parent ace20f2933
commit 82a4475a6a
9 changed files with 148 additions and 146 deletions

View File

@ -67,7 +67,7 @@ class NetErrorChild extends ActorChild {
switch (aEvent.type) {
case "AboutNetErrorLoad":
this.onPageLoad(aEvent.originalTarget, doc.defaultView);
this.onPageLoad(doc.defaultView);
break;
case "AboutNetErrorSetAutomatic":
this.onSetAutomatic(aEvent);
@ -90,22 +90,6 @@ class NetErrorChild extends ActorChild {
}
}
receiveMessage(msg) {
if (msg.name == "CertErrorDetails") {
let frameDocShell = WebNavigationFrames.findDocShell(msg.data.frameId, this.docShell);
// We need nsIWebNavigation to access docShell.document.
frameDocShell && frameDocShell.QueryInterface(Ci.nsIWebNavigation);
if (!frameDocShell || !this.isAboutCertError(frameDocShell.document)) {
return;
}
let data = msg.data;
let win = frameDocShell.document.ownerGlobal;
let event = Cu.cloneInto({ detail: data }, win);
win.dispatchEvent(new win.CustomEvent("ShowCertErrorDetails", event));
}
}
changedCertPrefs() {
let prefSSLImpact = PREF_SSL_IMPACT_ROOTS.reduce((prefs, root) => {
return prefs.concat(Services.prefs.getChildList(root));
@ -165,17 +149,10 @@ class NetErrorChild extends ActorChild {
return msg;
}
onPageLoad(originalTarget, win) {
onPageLoad(win) {
// Values for telemtery bins: see TLS_ERROR_REPORT_UI in Histograms.json
const TLS_ERROR_REPORT_TELEMETRY_UI_SHOWN = 0;
let hideAddExceptionButton = false;
if (this.isAboutCertError(win.document)) {
this.onCertError(originalTarget, win);
hideAddExceptionButton =
Services.prefs.getBoolPref("security.certerror.hideAddException", false);
}
if (this.isAboutNetError(win.document)) {
let docShell = win.docShell;
if (docShell) {
@ -193,20 +170,19 @@ class NetErrorChild extends ActorChild {
let learnMoreLink = win.document.getElementById("learnMoreLink");
let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
learnMoreLink.setAttribute("href", baseURL + "connection-not-secure");
let automatic = Services.prefs.getBoolPref("security.ssl.errorReporting.automatic");
win.dispatchEvent(new win.CustomEvent("AboutNetErrorOptions", {
detail: JSON.stringify({
enabled: Services.prefs.getBoolPref("security.ssl.errorReporting.enabled"),
changedCertPrefs: this.changedCertPrefs(),
automatic,
}),
}));
this.mm.sendAsyncMessage("Browser:SSLErrorReportTelemetry",
{reportStatus: TLS_ERROR_REPORT_TELEMETRY_UI_SHOWN});
}
let automatic = Services.prefs.getBoolPref("security.ssl.errorReporting.automatic");
win.dispatchEvent(new win.CustomEvent("AboutNetErrorOptions", {
detail: JSON.stringify({
enabled: Services.prefs.getBoolPref("security.ssl.errorReporting.enabled"),
changedCertPrefs: this.changedCertPrefs(),
automatic,
hideAddExceptionButton,
}),
}));
this.mm.sendAsyncMessage("Browser:SSLErrorReportTelemetry",
{reportStatus: TLS_ERROR_REPORT_TELEMETRY_UI_SHOWN});
}
onResetPreferences(evt) {

View File

@ -349,19 +349,16 @@ function initPageCertError() {
}));
});
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;
}
if (options && options.hideAddExceptionButton) {
document.querySelector(".exceptionDialogButtonContainer").hidden = true;
}
}, true, true);
let errorReportingEnabled = RPMGetBoolPref("security.ssl.errorReporting.enabled");
if (errorReportingEnabled) {
document.getElementById("certificateErrorReporting").style.display = "block";
let errorReportingAutomatic = RPMGetBoolPref("security.ssl.errorReporting.automatic");
checkbox.checked = !!errorReportingAutomatic;
}
let hideAddExceptionButton = RPMGetBoolPref("security.certerror.hideAddException");
if (hideAddExceptionButton) {
document.querySelector(".exceptionDialogButtonContainer").hidden = true;
}
let failedCertInfo = document.getFailedCertSecurityInfo();
RPMSendAsyncMessage("RecordCertErrorLoad", {
@ -370,14 +367,60 @@ function initPageCertError() {
has_sts: getCSSClass() == "badStsCert",
is_frame: window.parent != window,
});
window.addEventListener("ShowCertErrorDetails", setCertErrorDetails);
let certErrorButtons = ["advancedButton", "copyToClipboard"];
for (let button of certErrorButtons) {
let elem = document.getElementById(button);
elem.addEventListener("click", onClickHandler);
}
setCertErrorDetails();
setTechnicalDetailsOnCertError();
// Dispatch this event only for tests.
let event = new CustomEvent("AboutNetErrorLoad", {bubbles: true});
document.getElementById("advancedButton").dispatchEvent(event);
document.dispatchEvent(event);
}
function setCertErrorDetails(event) {
async function onClickHandler(e) {
switch (e.target.id) {
case "advancedButton":
setCertErrorDetails();
break;
case "copyToClipboard":
let details = await getCertErrorInfo();
navigator.clipboard.writeText(details);
break;
}
}
async function getCertErrorInfo() {
let location = document.location.href;
let failedCertInfo = document.getFailedCertSecurityInfo();
let errorMessage = failedCertInfo.errorMessage;
let hasHSTS = failedCertInfo.hasHSTS.toString();
let hasHPKP = failedCertInfo.hasHPKP.toString();
let [hstsLabel] =
await document.l10n.formatValues([{id: "cert-error-details-hsts-label", args: { hasHSTS }}]);
let [hpkpLabel] =
await document.l10n.formatValues([{id: "cert-error-details-key-pinning-label", args: { hasHPKP }}]);
let certStrings = failedCertInfo.certChainStrings;
let failedChainCertificates = "";
for (let der64 of certStrings) {
let wrapped = der64.replace(/(\S{64}(?!$))/g, "$1\r\n");
failedChainCertificates += "-----BEGIN CERTIFICATE-----\r\n"
+ wrapped
+ "\r\n-----END CERTIFICATE-----\r\n";
}
let [failedChainLabel] = await document.l10n.formatValues([{id: "cert-error-details-cert-chain-label"}]);
let details = location + "\r\n\r\n" + errorMessage + "\r\n\r\n" + hstsLabel + "\r\n" + hpkpLabel +
"\r\n\r\n" + failedChainLabel + "\r\n\r\n" + failedChainCertificates;
return details;
}
async function setCertErrorDetails(event) {
// Check if the connection is being man-in-the-middled. When the parent
// detects an intercepted connection, the page may be reloaded with a new
// error code (MOZILLA_PKIX_ERROR_MITM_DETECTED).
@ -391,7 +434,7 @@ function setCertErrorDetails(event) {
}
let div = document.getElementById("certificateErrorText");
div.textContent = event.detail.info;
div.textContent = await getCertErrorInfo();
let learnMoreLink = document.getElementById("learnMoreLink");
let baseURL = RPMGetFormatURLPref("app.support.baseURL");
learnMoreLink.setAttribute("href", baseURL + "connection-not-secure");
@ -499,8 +542,8 @@ function setCertErrorDetails(event) {
learnMoreLink.href = baseURL + "time-errors";
// We check against the remote-settings server time first if available, because that allows us
// to give the user an approximation of what the correct time is.
let difference = event.detail.clockSkewDifference;
let lastFetched = event.detail.settingsLastFetched * 1000;
let difference = RPMGetIntPref("services.settings.clock_skew_seconds");
let lastFetched = RPMGetIntPref("services.settings.last_update_seconds") * 1000;
let now = Date.now();
let certRange = {
@ -516,7 +559,7 @@ function setCertErrorDetails(event) {
// If there is no clock skew with Kinto servers, check against the build date.
// (The Kinto ping could have happened when the time was still right, or not at all)
} else {
let appBuildID = event.detail.appBuildID;
let appBuildID = RPMGetAppBuildID();
let year = parseInt(appBuildID.substr(0, 4), 10);
let month = parseInt(appBuildID.substr(4, 2), 10) - 1;
let day = parseInt(appBuildID.substr(6, 2), 10);

View File

@ -3145,31 +3145,6 @@ var BrowserOnClick = {
case "advancedPanelReturnButton":
goBackFromErrorPage();
break;
case "advancedButton":
securityInfo = getSecurityInfo(securityInfoAsString);
let errorInfo = getDetailedCertErrorInfo(location,
securityInfo);
let clockSkewDifference = Services.prefs.getIntPref("services.settings.clock_skew_seconds", 0);
let settingsLastFetched = Services.prefs.getIntPref("services.settings.last_update_seconds", 0);
let appBuildID = Services.appinfo.appBuildID;
browser.messageManager.sendAsyncMessage("CertErrorDetails", {
info: errorInfo,
clockSkewDifference,
settingsLastFetched,
appBuildID,
frameId,
});
break;
case "copyToClipboard":
const gClipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"]
.getService(Ci.nsIClipboardHelper);
securityInfo = getSecurityInfo(securityInfoAsString);
let detailedInfo = getDetailedCertErrorInfo(location,
securityInfo);
gClipboardHelper.copyString(detailedInfo);
break;
}
},
@ -3417,54 +3392,6 @@ function getSecurityInfo(securityInfoAsString) {
return securityInfo;
}
/**
* Returns a string with detailed information about the certificate validation
* failure from the specified URI that can be used to send a report.
*/
function getDetailedCertErrorInfo(location, securityInfo) {
if (!securityInfo)
return "";
let certErrorDetails = location;
let code = securityInfo.errorCode;
let errors = Cc["@mozilla.org/nss_errors_service;1"]
.getService(Ci.nsINSSErrorsService);
certErrorDetails += "\r\n\r\n" + errors.getErrorMessage(errors.getXPCOMFromNSSError(code));
const sss = Cc["@mozilla.org/ssservice;1"]
.getService(Ci.nsISiteSecurityService);
// SiteSecurityService uses different storage if the channel is
// private. Thus we must give isSecureURI correct flags or we
// might get incorrect results.
let flags = PrivateBrowsingUtils.isWindowPrivate(window) ?
Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0;
let uri = Services.io.newURI(location);
let hasHSTS = sss.isSecureURI(sss.HEADER_HSTS, uri, flags);
let hasHPKP = sss.isSecureURI(sss.HEADER_HPKP, uri, flags);
certErrorDetails += "\r\n\r\n" +
gNavigatorBundle.getFormattedString("certErrorDetailsHSTS.label",
[hasHSTS]);
certErrorDetails += "\r\n" +
gNavigatorBundle.getFormattedString("certErrorDetailsKeyPinning.label",
[hasHPKP]);
let certChain = "";
if (securityInfo.failedCertChain) {
for (let cert of securityInfo.failedCertChain.getEnumerator()) {
certChain += getPEMString(cert);
}
}
certErrorDetails += "\r\n\r\n" +
gNavigatorBundle.getString("certErrorDetailsCertChain.label") +
"\r\n\r\n" + certChain;
return certErrorDetails;
}
// TODO: can we pull getDERString and getPEMString in from pippki.js instead of
// duplicating them here?
function getDERString(cert) {

View File

@ -20,8 +20,11 @@ const checkAdvancedAndGetTechnicalInfoText = async () => {
let badCertTechnicalInfo = doc.getElementById("badCertTechnicalInfo");
ok(badCertTechnicalInfo, "badCertTechnicalInfo found");
let errorCode = doc.getElementById("errorCode").innerHTML;
is(errorCode, "SSL_ERROR_BAD_CERT_DOMAIN");
// Wait until fluent sets the errorCode inner text.
await ContentTaskUtils.waitForCondition(() => {
let errorCode = doc.getElementById("errorCode");
return errorCode.textContent == "SSL_ERROR_BAD_CERT_DOMAIN";
}, "correct error code has been set inside the advanced button panel");
let viewCertificate = doc.getElementById("viewCertificate");
ok(viewCertificate, "viewCertificate found");

View File

@ -232,9 +232,6 @@ let LEGACY_ACTORS = {
},
matches: ["about:certerror?*", "about:neterror?*"],
allFrames: true,
messages: [
"CertErrorDetails",
],
},
},

View File

@ -70,3 +70,12 @@ cert-error-symantec-distrust-description = Websites prove their identity via cer
cert-error-symantec-distrust-admin = You may notify the websites administrator about this problem.
# Variables:
# $hasHSTS (Boolean) - Indicates whether HSTS header is present.
cert-error-details-hsts-label = HTTP Strict Transport Security: { $hasHSTS }
# Variables:
# $hasHPKP (Boolean) - Indicates whether HPKP header is present.
cert-error-details-key-pinning-label = HTTP Public Key Pinning: { $hasHPKP }
cert-error-details-cert-chain-label = Certificate chain:

View File

@ -999,13 +999,6 @@ sendTabsToDevice.accesskey = n
# #1 is the number of tabs sent to the device.
pageAction.sendTabsToDevice.label = Send Tab to Device;Send #1 Tabs to Device
# LOCALIZATION NOTE (certErrorDetails*.label): These are text strings that
# appear in the about:certerror page, so that the user can copy and send them to
# the server administrators for troubleshooting.
certErrorDetailsHSTS.label = HTTP Strict Transport Security: %S
certErrorDetailsKeyPinning.label = HTTP Public Key Pinning: %S
certErrorDetailsCertChain.label = Certificate chain:
# LOCALIZATION NOTE (pendingCrashReports2.label): Semi-colon list of plural forms
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
# #1 is the number of pending crash reports

View File

@ -0,0 +1,48 @@
# coding=utf8
# Any copyright is dedicated to the Public Domain.
# http://creativecommons.org/publicdomain/zero/1.0/
from __future__ import absolute_import
import fluent.syntax.ast as FTL
from fluent.migrate.helpers import transforms_from
from fluent.migrate.helpers import VARIABLE_REFERENCE
from fluent.migrate import COPY, REPLACE
def migrate(ctx):
"""Bug 1555438 - Migrate strings from pipnss.properties to aboutCertError.ftl"""
ctx.add_transforms(
'browser/browser/aboutCertError.ftl',
'browser/browser/aboutCertError.ftl',
[
FTL.Message(
id=FTL.Identifier('cert-error-details-hsts-label'),
value=REPLACE(
'browser/chrome/browser/browser.properties',
'certErrorDetailsHSTS.label',
{
"%1$S": VARIABLE_REFERENCE("hasHSTS"),
},
normalize_printf=True
),
),
FTL.Message(
id=FTL.Identifier('cert-error-details-key-pinning-label'),
value=REPLACE(
'browser/chrome/browser/browser.properties',
'certErrorDetailsKeyPinning.label',
{
"%1$S": VARIABLE_REFERENCE("hasHPKP"),
},
normalize_printf=True
),
),
]
)
ctx.add_transforms(
'browser/browser/aboutCertError.ftl',
'browser/browser/aboutCertError.ftl',
transforms_from(
"""
cert-error-details-cert-chain-label = { COPY(from_path, "certErrorDetailsCertChain.label") }
""", from_path="browser/chrome/browser/browser.properties"))

View File

@ -28,7 +28,13 @@ let RPMAccessManager = {
"about:certerror": {
"getFormatURLPref": ["app.support.baseURL"],
"getBoolPref": ["security.certerrors.mitm.priming.enabled",
"security.enterprise_roots.auto-enabled"],
"security.enterprise_roots.auto-enabled",
"security.certerror.hideAddException",
"security.ssl.errorReporting.automatic",
"security.ssl.errorReporting.enabled"],
"getIntPref": ["services.settings.clock_skew_seconds",
"services.settings.last_update_seconds"],
"getAppBuildID": ["yes"],
},
"about:privatebrowsing": {
// "sendAsyncMessage": handled within AboutPrivateBrowsingHandler.jsm
@ -321,12 +327,12 @@ class MessagePort {
return Services.prefs.getIntPref(aPref);
}
getBoolPref(aPref) {
getBoolPref(aPref, defaultValue = false) {
let principal = this.window.document.nodePrincipal;
if (!RPMAccessManager.checkAllowAccess(principal, "getBoolPref", aPref)) {
throw new Error("RPMAccessManager does not allow access to getBoolPref");
}
return Services.prefs.getBoolPref(aPref);
return Services.prefs.getBoolPref(aPref, defaultValue);
}
setBoolPref(aPref, aVal) {