gecko-dev/toolkit/content/aboutNetError.mjs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1452 строки
47 KiB
JavaScript
Исходник Обычный вид История

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/* eslint-env mozilla/remote-page */
/* eslint-disable import/no-unassigned-import */
import {
parse,
pemToDER,
} from "chrome://global/content/certviewer/certDecoder.mjs";
2022-10-07 21:40:27 +03:00
const formatter = new Intl.DateTimeFormat();
const HOST_NAME = getHostName();
function getHostName() {
try {
return new URL(RPMGetInnerMostURI(document.location.href)).hostname;
} catch (error) {
console.error("Could not parse URL", error);
}
return "";
}
// Used to check if we have a specific localized message for an error.
const KNOWN_ERROR_TITLE_IDS = new Set([
// Error titles:
"connectionFailure-title",
"deniedPortAccess-title",
"dnsNotFound-title",
"dns-not-found-trr-only-title2",
"fileNotFound-title",
"fileAccessDenied-title",
"generic-title",
"captivePortal-title",
"malformedURI-title",
"netInterrupt-title",
"notCached-title",
"netOffline-title",
"contentEncodingError-title",
"unsafeContentType-title",
"netReset-title",
"netTimeout-title",
"unknownProtocolFound-title",
"proxyConnectFailure-title",
"proxyResolveFailure-title",
"redirectLoop-title",
"unknownSocketType-title",
"nssFailure2-title",
"csp-xfo-error-title",
"corruptedContentError-title",
"sslv3Used-title",
"inadequateSecurityError-title",
"blockedByPolicy-title",
"clockSkewError-title",
"networkProtocolError-title",
"nssBadCert-title",
"nssBadCert-sts-title",
"certerror-mitm-title",
]);
/* The error message IDs from nsserror.ftl get processed into
* aboutNetErrorCodes.js which is loaded before we are: */
/* global KNOWN_ERROR_MESSAGE_IDS */
const ERROR_MESSAGES_FTL = "toolkit/neterror/nsserrors.ftl";
// The following parameters are parsed from the error URL:
// 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
// document.location.href gets the current URI off the docshell,
// which is the URL displayed in the location bar, i.e.
// the URI that the user attempted to load.
let searchParams = new URLSearchParams(document.documentURI.split("?")[1]);
let gErrorCode = searchParams.get("e");
let gIsCertError = gErrorCode == "nssBadCert";
2022-10-07 21:40:27 +03:00
let gHasSts = gIsCertError && getCSSClass() === "badStsCert";
// If the location of the favicon changes, FAVICON_CERTERRORPAGE_URL and/or
// FAVICON_ERRORPAGE_URL in toolkit/components/places/nsFaviconService.idl
// should also be updated.
document.getElementById("favicon").href =
gIsCertError || gErrorCode == "nssFailure2"
? "chrome://global/skin/icons/warning.svg"
: "chrome://global/skin/icons/info.svg";
function getCSSClass() {
return searchParams.get("s");
}
function getDescription() {
return searchParams.get("d");
}
function isCaptive() {
return searchParams.get("captive") == "true";
}
2022-10-07 21:40:27 +03:00
/**
* We don't actually know what the MitM is called (since we don't
* maintain a list), so we'll try and display the common name of the
* root issuer to the user. In the worst case they are as clueless as
* before, in the best case this gives them an actionable hint.
* This may be revised in the future.
*/
function getMitmName(failedCertInfo) {
return failedCertInfo.issuerCommonName;
}
function retryThis(buttonEl) {
RPMSendAsyncMessage("Browser:EnableOnlineMode");
buttonEl.disabled = true;
}
function showPrefChangeContainer() {
const panel = document.getElementById("prefChangeContainer");
panel.hidden = false;
document.getElementById("netErrorButtonContainer").hidden = true;
document
.getElementById("prefResetButton")
.addEventListener("click", function resetPreferences() {
RPMSendAsyncMessage("Browser:ResetSSLPreferences");
});
setFocus("#prefResetButton", "beforeend");
}
function toggleCertErrorDebugInfoVisibility(shouldShow) {
let debugInfo = document.getElementById("certificateErrorDebugInformation");
let copyButton = document.getElementById("copyToClipboardTop");
if (shouldShow === undefined) {
shouldShow = debugInfo.hidden;
}
debugInfo.hidden = !shouldShow;
if (shouldShow) {
copyButton.scrollIntoView({ block: "start", behavior: "smooth" });
copyButton.focus();
}
}
function setupAdvancedButton() {
// Get the hostname and add it to the panel
var panel = document.getElementById("badCertAdvancedPanel");
// Register click handler for the weakCryptoAdvancedPanel
document
.getElementById("advancedButton")
.addEventListener("click", togglePanelVisibility);
function togglePanelVisibility() {
panel.hidden = !panel.hidden;
2022-10-07 21:40:27 +03:00
// Toggling the advanced panel must ensure that the debugging
// information panel is hidden as well, since it's opened by the
// error code link in the advanced panel.
toggleCertErrorDebugInfoVisibility(false);
if (!panel.hidden) {
// send event to trigger telemetry ping
document.dispatchEvent(
new CustomEvent("AboutNetErrorUIExpanded", { bubbles: true })
);
}
}
if (getCSSClass() == "expertBadCert") {
panel.hidden = false;
}
}
function disallowCertOverridesIfNeeded() {
// 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).
2022-10-07 21:40:27 +03:00
if (gHasSts || window != top) {
document.getElementById("exceptionDialogButton").hidden = true;
}
2022-10-07 21:40:27 +03:00
if (gHasSts) {
const stsExplanation = document.getElementById("badStsCertExplanation");
document.l10n.setAttributes(
stsExplanation,
"certerror-what-should-i-do-bad-sts-cert-explanation",
{ hostname: HOST_NAME }
);
stsExplanation.hidden = false;
2022-10-07 21:40:27 +03:00
document.l10n.setAttributes(
document.getElementById("returnButton"),
"neterror-return-to-previous-page-button"
);
document.l10n.setAttributes(
document.getElementById("advancedPanelReturnButton"),
"neterror-return-to-previous-page-button"
);
}
}
function initPage() {
// We show an offline support page in case of a system-wide error,
// when a user cannot connect to the internet and access the SUMO website.
// For example, clock error, which causes certerrors across the web or
// a security software conflict where the user is unable to connect
// to the internet.
// The URL that prompts us to show an offline support page should have the following
// format: "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/supportPageSlug",
// so we can extract the support page slug.
let baseURL = RPMGetFormatURLPref("app.support.baseURL");
if (document.location.href.startsWith(baseURL)) {
let supportPageSlug = document.location.pathname.split("/").pop();
RPMSendAsyncMessage("DisplayOfflineSupportPage", {
supportPageSlug,
});
}
2022-10-07 21:40:27 +03:00
const className = getCSSClass();
if (className) {
document.body.classList.add(className);
}
2022-12-23 12:26:16 +03:00
const isTRROnlyFailure = gErrorCode == "dnsNotFound" && RPMIsTRROnlyFailure();
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz Similar to Bug 1596845 - Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug 1596845, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
2023-01-16 16:12:04 +03:00
let isNativeFallbackWarning = false;
if (RPMGetBoolPref("network.trr.display_fallback_warning")) {
isNativeFallbackWarning =
gErrorCode == "dnsNotFound" && RPMIsNativeFallbackFailure();
}
2022-10-07 21:40:27 +03:00
const docTitle = document.querySelector("title");
const bodyTitle = document.querySelector(".title-text");
const shortDesc = document.getElementById("errorShortDesc");
if (gIsCertError) {
2022-10-07 21:40:27 +03:00
const isStsError = window !== window.top || gHasSts;
const errArgs = { hostname: HOST_NAME };
if (isCaptive()) {
document.l10n.setAttributes(
docTitle,
"neterror-captive-portal-page-title"
);
document.l10n.setAttributes(bodyTitle, "captivePortal-title");
document.l10n.setAttributes(
shortDesc,
"neterror-captive-portal",
errArgs
);
initPageCaptivePortal();
} else {
2022-10-07 21:40:27 +03:00
if (isStsError) {
document.l10n.setAttributes(docTitle, "certerror-sts-page-title");
document.l10n.setAttributes(bodyTitle, "nssBadCert-sts-title");
document.l10n.setAttributes(shortDesc, "certerror-sts-intro", errArgs);
} else {
document.l10n.setAttributes(docTitle, "certerror-page-title");
document.l10n.setAttributes(bodyTitle, "nssBadCert-title");
document.l10n.setAttributes(shortDesc, "certerror-intro", errArgs);
}
initPageCertError();
}
initCertErrorPageActions();
setTechnicalDetailsOnCertError();
return;
}
document.body.classList.add("neterror");
2022-10-07 21:40:27 +03:00
let longDesc = document.getElementById("errorLongDesc");
const tryAgain = document.getElementById("netErrorButtonContainer");
tryAgain.hidden = false;
2022-10-07 21:40:27 +03:00
const learnMore = document.getElementById("learnMoreContainer");
const learnMoreLink = document.getElementById("learnMoreLink");
learnMoreLink.setAttribute("href", baseURL + "connection-not-secure");
2022-10-07 21:40:27 +03:00
let pageTitleId = "neterror-page-title";
let bodyTitleId = gErrorCode + "-title";
2022-10-07 21:40:27 +03:00
switch (gErrorCode) {
case "blockedByPolicy":
pageTitleId = "neterror-blocked-by-policy-page-title";
document.body.classList.add("blocked");
2022-10-07 21:40:27 +03:00
// Remove the "Try again" button from pages that don't need it.
// For pages blocked by policy, trying again won't help.
tryAgain.hidden = true;
2022-10-07 21:40:27 +03:00
break;
2022-10-07 21:40:27 +03:00
case "cspBlocked":
case "xfoBlocked": {
bodyTitleId = "csp-xfo-error-title";
2022-10-07 21:40:27 +03:00
// Remove the "Try again" button for XFO and CSP violations,
// since it's almost certainly useless. (Bug 553180)
tryAgain.hidden = true;
2022-10-07 21:40:27 +03:00
// Adding a button for opening websites blocked for CSP and XFO violations
// in a new window. (Bug 1461195)
document.getElementById("errorShortDesc").hidden = true;
2022-10-07 21:40:27 +03:00
document.l10n.setAttributes(longDesc, "csp-xfo-blocked-long-desc", {
hostname: HOST_NAME,
2022-10-07 21:40:27 +03:00
});
longDesc = null;
document.getElementById("openInNewWindowContainer").hidden = false;
2022-10-07 21:40:27 +03:00
const openInNewWindowButton = document.getElementById(
"openInNewWindowButton"
);
openInNewWindowButton.href = document.location.href;
2022-10-07 21:40:27 +03:00
// Add a learn more link
learnMore.hidden = false;
2022-10-07 21:40:27 +03:00
learnMoreLink.setAttribute("href", baseURL + "xframe-neterror-page");
2022-10-07 21:40:27 +03:00
setupBlockingReportingUI();
break;
}
2022-10-07 21:40:27 +03:00
case "dnsNotFound":
pageTitleId = "neterror-dns-not-found-title";
2022-12-23 12:26:16 +03:00
if (!isTRROnlyFailure) {
RPMCheckAlternateHostAvailable();
}
2022-12-23 12:26:16 +03:00
break;
2022-10-07 21:40:27 +03:00
case "inadequateSecurityError":
// Remove the "Try again" button from pages that don't need it.
// For HTTP/2 inadequate security, trying again won't help.
tryAgain.hidden = true;
2022-10-07 21:40:27 +03:00
break;
case "malformedURI":
pageTitleId = "neterror-malformed-uri-page-title";
// Remove the "Try again" button from pages that don't need it.
tryAgain.hidden = true;
2022-10-07 21:40:27 +03:00
break;
2022-10-07 21:40:27 +03:00
// Pinning errors are of type nssFailure2
case "nssFailure2": {
learnMore.hidden = false;
2022-10-07 21:40:27 +03:00
const errorCode = document.getNetErrorInfo().errorCodeString;
switch (errorCode) {
case "SSL_ERROR_UNSUPPORTED_VERSION":
case "SSL_ERROR_PROTOCOL_VERSION_ALERT": {
const tlsNotice = document.getElementById("tlsVersionNotice");
tlsNotice.hidden = false;
document.l10n.setAttributes(tlsNotice, "cert-error-old-tls-version");
}
// fallthrough
case "interrupted": // This happens with subresources that are above the max tls
case "SSL_ERROR_NO_CIPHERS_SUPPORTED":
case "SSL_ERROR_NO_CYPHER_OVERLAP":
case "SSL_ERROR_SSL_DISABLED":
RPMAddMessageListener("HasChangedCertPrefs", msg => {
if (msg.data.hasChangedCertPrefs) {
// Configuration overrides might have caused this; offer to reset.
showPrefChangeContainer();
}
});
RPMSendAsyncMessage("GetChangedCertPrefs");
}
2022-10-07 21:40:27 +03:00
break;
}
2022-10-07 21:40:27 +03:00
case "sslv3Used":
learnMore.hidden = false;
2022-10-07 21:40:27 +03:00
document.body.className = "certerror";
break;
}
2022-10-07 21:40:27 +03:00
if (!KNOWN_ERROR_TITLE_IDS.has(bodyTitleId)) {
console.error("No strings exist for error:", gErrorCode);
2022-10-07 21:40:27 +03:00
bodyTitleId = "generic-title";
}
2022-12-23 12:26:16 +03:00
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz Similar to Bug 1596845 - Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug 1596845, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
2023-01-16 16:12:04 +03:00
// The TRR errors may present options that direct users to settings only available on Firefox Desktop
if (RPMIsFirefox()) {
if (isTRROnlyFailure) {
document.body.className = "certerror"; // Shows warning icon
pageTitleId = "dns-not-found-trr-only-title2";
document.l10n.setAttributes(docTitle, pageTitleId);
bodyTitleId = "dns-not-found-trr-only-title2";
document.l10n.setAttributes(bodyTitle, bodyTitleId);
2022-12-23 12:26:16 +03:00
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz Similar to Bug 1596845 - Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug 1596845, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
2023-01-16 16:12:04 +03:00
shortDesc.textContent = "";
let skipReason = RPMGetTRRSkipReason();
2022-12-23 12:26:16 +03:00
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz Similar to Bug 1596845 - Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug 1596845, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
2023-01-16 16:12:04 +03:00
// enable buttons
let trrExceptionButton = document.getElementById("trrExceptionButton");
trrExceptionButton.addEventListener("click", () => {
RPMSendQuery("Browser:AddTRRExcludedDomain", {
hostname: HOST_NAME,
}).then(msg => {
retryThis(this);
});
});
let isTrrServerError = true;
if (RPMIsSiteSpecificTRRError()) {
// Only show the exclude button if the failure is specific to this
// domain. If the TRR server is inaccessible we don't want to allow
// the user to add an exception just for this domain.
trrExceptionButton.hidden = false;
isTrrServerError = false;
}
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz Similar to Bug 1596845 - Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug 1596845, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
2023-01-16 16:12:04 +03:00
let trrSettingsButton = document.getElementById("trrSettingsButton");
trrSettingsButton.addEventListener("click", () => {
RPMSendAsyncMessage("OpenTRRPreferences");
});
trrSettingsButton.hidden = false;
let message = document.getElementById("trrOnlyMessage");
document.l10n.setAttributes(
message,
"neterror-dns-not-found-trr-only-reason",
{
hostname: HOST_NAME,
}
);
2022-12-23 12:26:16 +03:00
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz Similar to Bug 1596845 - Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug 1596845, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
2023-01-16 16:12:04 +03:00
let descriptionTag = "neterror-dns-not-found-trr-unknown-problem";
let args = { trrDomain: RPMGetTRRDomain() };
if (
skipReason == "TRR_FAILED" ||
skipReason == "TRR_CHANNEL_DNS_FAIL" ||
skipReason == "TRR_UNKNOWN_CHANNEL_FAILURE" ||
skipReason == "TRR_NET_REFUSED" ||
skipReason == "TRR_NET_INTERRUPT" ||
skipReason == "TRR_NET_INADEQ_SEQURITY"
) {
descriptionTag = "neterror-dns-not-found-trr-only-could-not-connect";
} else if (skipReason == "TRR_TIMEOUT") {
descriptionTag = "neterror-dns-not-found-trr-only-timeout";
} else if (
skipReason == "TRR_IS_OFFLINE" ||
skipReason == "TRR_NO_CONNECTIVITY"
) {
descriptionTag = "neterror-dns-not-found-trr-offline";
} else if (
skipReason == "TRR_NO_ANSWERS" ||
skipReason == "TRR_NXDOMAIN"
) {
descriptionTag = "neterror-dns-not-found-trr-unknown-host2";
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz Similar to Bug 1596845 - Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug 1596845, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
2023-01-16 16:12:04 +03:00
} else if (
skipReason == "TRR_DECODE_FAILED" ||
skipReason == "TRR_SERVER_RESPONSE_ERR"
) {
descriptionTag = "neterror-dns-not-found-trr-server-problem";
}
2022-12-23 12:26:16 +03:00
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz Similar to Bug 1596845 - Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug 1596845, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
2023-01-16 16:12:04 +03:00
let description = document.getElementById("trrOnlyDescription");
document.l10n.setAttributes(description, descriptionTag, args);
2022-12-23 12:26:16 +03:00
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz Similar to Bug 1596845 - Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug 1596845, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
2023-01-16 16:12:04 +03:00
const trrLearnMoreContainer = document.getElementById(
"trrLearnMoreContainer"
);
trrLearnMoreContainer.hidden = false;
let trrOnlyLearnMoreLink = document.getElementById(
"trrOnlylearnMoreLink"
);
if (isTrrServerError) {
// Go to DoH settings page
trrOnlyLearnMoreLink.href = "about:preferences#privacy-doh";
trrOnlyLearnMoreLink.addEventListener("click", event => {
event.preventDefault();
RPMSendAsyncMessage("OpenTRRPreferences");
});
} else {
// This will be replaced at a later point with a link to an offline support page
// https://bugzilla.mozilla.org/show_bug.cgi?id=1806257
trrOnlyLearnMoreLink.href =
RPMGetFormatURLPref("network.trr_ui.skip_reason_learn_more_url") +
skipReason.toLowerCase().replaceAll("_", "-");
}
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz Similar to Bug 1596845 - Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug 1596845, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
2023-01-16 16:12:04 +03:00
let div = document.getElementById("trrOnlyContainer");
div.hidden = false;
return;
} else if (isNativeFallbackWarning) {
showNativeFallbackWarning();
return;
}
2022-12-23 12:26:16 +03:00
}
document.l10n.setAttributes(docTitle, pageTitleId);
2022-10-07 21:40:27 +03:00
document.l10n.setAttributes(bodyTitle, bodyTitleId);
shortDesc.textContent = getDescription();
setFocus("#netErrorButtonContainer > .try-again");
2022-10-07 21:40:27 +03:00
if (longDesc) {
const parts = getNetErrorDescParts();
setNetErrorMessageFromParts(longDesc, parts);
}
2022-10-07 21:40:27 +03:00
setNetErrorMessageFromCode();
}
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz Similar to Bug 1596845 - Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug 1596845, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
2023-01-16 16:12:04 +03:00
function showNativeFallbackWarning() {
const docTitle = document.querySelector("title");
const bodyTitle = document.querySelector(".title-text");
const shortDesc = document.getElementById("errorShortDesc");
let pageTitleId = "neterror-page-title";
let bodyTitleId = gErrorCode + "-title";
document.body.className = "certerror"; // Shows warning icon
pageTitleId = "dns-not-found-native-fallback-title2";
document.l10n.setAttributes(docTitle, pageTitleId);
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz Similar to Bug 1596845 - Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug 1596845, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
2023-01-16 16:12:04 +03:00
bodyTitleId = "dns-not-found-native-fallback-title2";
document.l10n.setAttributes(bodyTitle, bodyTitleId);
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz Similar to Bug 1596845 - Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug 1596845, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
2023-01-16 16:12:04 +03:00
shortDesc.textContent = "";
let nativeFallbackIgnoreButton = document.getElementById(
"nativeFallbackIgnoreButton"
);
nativeFallbackIgnoreButton.addEventListener("click", () => {
RPMSetBoolPref("network.trr.display_fallback_warning", false);
retryThis(nativeFallbackIgnoreButton);
});
let continueThisTimeButton = document.getElementById(
"nativeFallbackContinueThisTimeButton"
);
continueThisTimeButton.addEventListener("click", () => {
RPMSetTRRDisabledLoadFlags();
document.location.reload();
});
continueThisTimeButton.hidden = false;
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz Similar to Bug 1596845 - Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug 1596845, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
2023-01-16 16:12:04 +03:00
nativeFallbackIgnoreButton.hidden = false;
let message = document.getElementById("nativeFallbackMessage");
document.l10n.setAttributes(
message,
"neterror-dns-not-found-native-fallback-reason",
{
hostname: HOST_NAME,
}
);
let skipReason = RPMGetTRRSkipReason();
let descriptionTag = "neterror-dns-not-found-trr-unknown-problem";
let args = { trrDomain: RPMGetTRRDomain() };
if (skipReason.includes("HEURISTIC_TRIPPED")) {
descriptionTag = "neterror-dns-not-found-native-fallback-heuristic";
} else if (skipReason == "TRR_NOT_CONFIRMED") {
descriptionTag = "neterror-dns-not-found-native-fallback-not-confirmed2";
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz Similar to Bug 1596845 - Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug 1596845, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
2023-01-16 16:12:04 +03:00
}
let description = document.getElementById("nativeFallbackDescription");
document.l10n.setAttributes(description, descriptionTag, args);
let learnMoreContainer = document.getElementById(
"nativeFallbackLearnMoreContainer"
);
learnMoreContainer.hidden = false;
let learnMoreLink = document.getElementById("nativeFallbackLearnMoreLink");
learnMoreLink.href =
RPMGetFormatURLPref("network.trr_ui.skip_reason_learn_more_url") +
skipReason.toLowerCase().replaceAll("_", "-");
let div = document.getElementById("nativeFallbackContainer");
div.hidden = false;
}
2022-10-07 21:40:27 +03:00
/**
* Builds HTML elements from `parts` and appends them to `parentElement`.
2022-10-07 21:40:27 +03:00
*
* @param {HTMLElement} parentElement
2022-10-07 21:40:27 +03:00
* @param {Array<["li" | "p" | "span", string, Record<string, string> | undefined]>} parts
*/
function setNetErrorMessageFromParts(parentElement, parts) {
2022-10-07 21:40:27 +03:00
let list = null;
for (let [tag, l10nId, l10nArgs] of parts) {
const elem = document.createElement(tag);
elem.dataset.l10nId = l10nId;
if (l10nArgs) {
elem.dataset.l10nArgs = JSON.stringify(l10nArgs);
}
2022-10-07 21:40:27 +03:00
if (tag === "li") {
if (!list) {
list = document.createElement("ul");
parentElement.appendChild(list);
2022-10-07 21:40:27 +03:00
}
list.appendChild(elem);
} else {
if (list) {
list = null;
}
parentElement.appendChild(elem);
2022-10-07 21:40:27 +03:00
}
}
}
/**
* Returns an array of tuples determining the parts of an error message:
* - HTML tag name
* - l10n id
* - l10n args (optional)
*
* @returns { Array<["li" | "p" | "span", string, Record<string, string> | undefined]> }
*/
function getNetErrorDescParts() {
switch (gErrorCode) {
case "connectionFailure":
case "netInterrupt":
case "netReset":
case "netTimeout":
return [
["li", "neterror-load-error-try-again"],
["li", "neterror-load-error-connection"],
["li", "neterror-load-error-firewall"],
];
case "blockedByPolicy":
case "deniedPortAccess":
case "malformedURI":
return [];
case "captivePortal":
return [["p", ""]];
case "contentEncodingError":
return [["li", "neterror-content-encoding-error"]];
case "corruptedContentErrorv2":
return [
["p", "neterror-corrupted-content-intro"],
["li", "neterror-corrupted-content-contact-website"],
];
case "dnsNotFound":
return [
["span", "neterror-dns-not-found-hint-header"],
["li", "neterror-dns-not-found-hint-try-again"],
["li", "neterror-dns-not-found-hint-check-network"],
["li", "neterror-dns-not-found-hint-firewall"],
];
case "fileAccessDenied":
return [["li", "neterror-access-denied"]];
case "fileNotFound":
return [
["li", "neterror-file-not-found-filename"],
["li", "neterror-file-not-found-moved"],
];
case "inadequateSecurityError":
return [
["p", "neterror-inadequate-security-intro", { hostname: HOST_NAME }],
["p", "neterror-inadequate-security-code"],
];
case "mitm": {
const failedCertInfo = document.getFailedCertSecurityInfo();
const errArgs = {
hostname: HOST_NAME,
mitm: getMitmName(failedCertInfo),
};
return [["span", "certerror-mitm", errArgs]];
}
case "netOffline":
return [["li", "neterror-net-offline"]];
case "networkProtocolError":
return [
["p", "neterror-network-protocol-error-intro"],
["li", "neterror-network-protocol-error-contact-website"],
];
case "notCached":
return [
["p", "neterror-not-cached-intro"],
["li", "neterror-not-cached-sensitive"],
["li", "neterror-not-cached-try-again"],
];
case "nssFailure2":
return [
["li", "neterror-nss-failure-not-verified"],
["li", "neterror-nss-failure-contact-website"],
];
case "proxyConnectFailure":
return [
["li", "neterror-proxy-connect-failure-settings"],
["li", "neterror-proxy-connect-failure-contact-admin"],
];
case "proxyResolveFailure":
return [
["li", "neterror-proxy-resolve-failure-settings"],
["li", "neterror-proxy-resolve-failure-connection"],
["li", "neterror-proxy-resolve-failure-firewall"],
];
case "redirectLoop":
return [["li", "neterror-redirect-loop"]];
case "sslv3Used":
return [["span", "neterror-sslv3-used"]];
case "unknownProtocolFound":
return [["li", "neterror-unknown-protocol"]];
case "unknownSocketType":
return [
["li", "neterror-unknown-socket-type-psm-installed"],
["li", "neterror-unknown-socket-type-server-config"],
];
case "unsafeContentType":
return [["li", "neterror-unsafe-content-type"]];
default:
return [["p", "neterror-generic-error"]];
}
}
function setNetErrorMessageFromCode() {
let errorCode;
try {
errorCode = document.getNetErrorInfo().errorCodeString;
} catch (ex) {
// We don't have a securityInfo when this is for example a DNS error.
return;
}
let errorMessage;
if (errorCode) {
const l10nId = errorCode.replace(/_/g, "-").toLowerCase();
if (KNOWN_ERROR_MESSAGE_IDS.has(l10nId)) {
const l10n = new Localization([ERROR_MESSAGES_FTL], true);
errorMessage = l10n.formatValueSync(l10nId);
}
const shortDesc2 = document.getElementById("errorShortDesc2");
document.l10n.setAttributes(shortDesc2, "cert-error-code-prefix", {
error: errorCode,
});
} else {
console.warn("This error page has no error code in its security info");
}
let hostname = HOST_NAME;
const { port } = document.location;
if (port && port != 443) {
hostname += ":" + port;
}
const shortDesc = document.getElementById("errorShortDesc");
document.l10n.setAttributes(shortDesc, "cert-error-ssl-connection-error", {
errorMessage: errorMessage ?? errorCode ?? "",
hostname,
});
}
function setupBlockingReportingUI() {
let checkbox = document.getElementById("automaticallyReportBlockingInFuture");
let reportingAutomatic = RPMGetBoolPref(
"security.xfocsp.errorReporting.automatic"
);
checkbox.checked = !!reportingAutomatic;
checkbox.addEventListener("change", function({ target: { checked } }) {
2022-10-07 21:40:27 +03:00
RPMSetBoolPref("security.xfocsp.errorReporting.automatic", checked);
// If we're enabling reports, send a report for this failure.
if (checked) {
reportBlockingError();
}
});
let reportingEnabled = RPMGetBoolPref(
"security.xfocsp.errorReporting.enabled"
);
2022-10-07 21:40:27 +03:00
if (reportingEnabled) {
// Display blocking error reporting UI for XFO error and CSP error.
document.getElementById("blockingErrorReporting").hidden = false;
2022-10-07 21:40:27 +03:00
if (reportingAutomatic) {
reportBlockingError();
}
}
}
function reportBlockingError() {
// We only report if we are in a frame.
if (window === window.top) {
return;
}
let err = gErrorCode;
// Ensure we only deal with XFO and CSP here.
if (!["xfoBlocked", "cspBlocked"].includes(err)) {
return;
}
let xfo_header = RPMGetHttpResponseHeader("X-Frame-Options");
let csp_header = RPMGetHttpResponseHeader("Content-Security-Policy");
// Extract the 'CSP: frame-ancestors' from the CSP header.
let reg = /(?:^|\s)frame-ancestors\s([^;]*)[$]*/i;
let match = reg.exec(csp_header);
csp_header = match ? match[1] : "";
// If it's the csp error page without the CSP: frame-ancestors, this means
// this error page is not triggered by CSP: frame-ancestors. So, we bail out
// early.
if (err === "cspBlocked" && !csp_header) {
return;
}
let xfoAndCspInfo = {
error_type: err === "xfoBlocked" ? "xfo" : "csp",
xfo_header,
csp_header,
};
// Trimming the tail colon symbol.
let scheme = document.location.protocol.slice(0, -1);
RPMSendAsyncMessage("ReportBlockingError", {
scheme,
host: document.location.host,
port: parseInt(document.location.port) || -1,
path: document.location.pathname,
xfoAndCspInfo,
});
}
function initPageCaptivePortal() {
document.body.className = "captiveportal";
document.getElementById("returnButton").hidden = true;
const openButton = document.getElementById("openPortalLoginPageButton");
openButton.hidden = false;
openButton.addEventListener("click", () => {
RPMSendAsyncMessage("Browser:OpenCaptivePortalPage");
});
setFocus("#openPortalLoginPageButton");
setupAdvancedButton();
2022-10-07 21:40:27 +03:00
disallowCertOverridesIfNeeded();
// When the portal is freed, an event is sent by the parent process
// that we can pick up and attempt to reload the original page.
RPMAddMessageListener("AboutNetErrorCaptivePortalFreed", () => {
document.location.reload();
});
}
function initPageCertError() {
document.body.classList.add("certerror");
setFocus("#returnButton");
setupAdvancedButton();
2022-10-07 21:40:27 +03:00
disallowCertOverridesIfNeeded();
2022-10-07 21:40:27 +03:00
const hideAddExceptionButton = RPMGetBoolPref(
"security.certerror.hideAddException",
false
);
if (hideAddExceptionButton) {
document.getElementById("exceptionDialogButton").hidden = true;
}
2022-10-07 21:40:27 +03:00
const els = document.querySelectorAll("[data-telemetry-id]");
for (let el of els) {
el.addEventListener("click", recordClickTelemetry);
}
2022-10-07 21:40:27 +03:00
const failedCertInfo = document.getFailedCertSecurityInfo();
// Truncate the error code to avoid going over the allowed
// string size limit for telemetry events.
2022-10-07 21:40:27 +03:00
const errorCode = failedCertInfo.errorCodeString.substring(0, 40);
RPMRecordTelemetryEvent(
"security.ui.certerror",
"load",
"aboutcerterror",
errorCode,
{
2022-10-07 21:40:27 +03:00
has_sts: gHasSts.toString(),
is_frame: (window.parent != window).toString(),
}
);
setCertErrorDetails();
}
function recordClickTelemetry(e) {
let target = e.originalTarget;
let telemetryId = target.dataset.telemetryId;
let failedCertInfo = document.getFailedCertSecurityInfo();
// Truncate the error code to avoid going over the allowed
// string size limit for telemetry events.
let errorCode = failedCertInfo.errorCodeString.substring(0, 40);
RPMRecordTelemetryEvent(
"security.ui.certerror",
"click",
telemetryId,
errorCode,
{
2022-10-07 21:40:27 +03:00
has_sts: gHasSts.toString(),
is_frame: (window.parent != window).toString(),
}
);
}
function initCertErrorPageActions() {
document.getElementById(
"certErrorAndCaptivePortalButtonContainer"
).hidden = false;
document
.getElementById("returnButton")
.addEventListener("click", onReturnButtonClick);
document
.getElementById("advancedPanelReturnButton")
.addEventListener("click", onReturnButtonClick);
document
.getElementById("copyToClipboardTop")
.addEventListener("click", copyPEMToClipboard);
document
.getElementById("copyToClipboardBottom")
.addEventListener("click", copyPEMToClipboard);
document
.getElementById("exceptionDialogButton")
.addEventListener("click", addCertException);
}
function addCertException() {
const isPermanent =
!RPMIsWindowPrivate() &&
RPMGetBoolPref("security.certerrors.permanentOverride");
document.addCertException(!isPermanent).then(
() => {
location.reload();
},
err => {}
);
}
function onReturnButtonClick(e) {
RPMSendAsyncMessage("Browser:SSLErrorGoBack");
}
function copyPEMToClipboard(e) {
const errorText = document.getElementById("certificateErrorText");
navigator.clipboard.writeText(errorText.textContent);
}
async function getFailedCertificatesAsPEMString() {
let locationUrl = document.location.href;
let failedCertInfo = document.getFailedCertSecurityInfo();
let errorMessage = failedCertInfo.errorMessage;
let hasHSTS = failedCertInfo.hasHSTS.toString();
let hasHPKP = failedCertInfo.hasHPKP.toString();
let [
hstsLabel,
hpkpLabel,
failedChainLabel,
] = await document.l10n.formatValues([
{ id: "cert-error-details-hsts-label", args: { hasHSTS } },
{ id: "cert-error-details-key-pinning-label", args: { hasHPKP } },
{ id: "cert-error-details-cert-chain-label" },
]);
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 details =
locationUrl +
"\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;
}
2022-10-07 21:40:27 +03:00
function setCertErrorDetails() {
// 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).
2022-10-07 21:40:27 +03:00
const failedCertInfo = document.getFailedCertSecurityInfo();
const mitmPrimingEnabled = RPMGetBoolPref(
"security.certerrors.mitm.priming.enabled"
);
if (
mitmPrimingEnabled &&
failedCertInfo.errorCodeString == "SEC_ERROR_UNKNOWN_ISSUER" &&
// Only do this check for top-level failures.
window.parent == window
) {
RPMSendAsyncMessage("Browser:PrimeMitm");
}
2022-10-07 21:40:27 +03:00
document.body.setAttribute("code", failedCertInfo.errorCodeString);
const learnMore = document.getElementById("learnMoreContainer");
learnMore.hidden = false;
2022-10-07 21:40:27 +03:00
const learnMoreLink = document.getElementById("learnMoreLink");
const baseURL = RPMGetFormatURLPref("app.support.baseURL");
learnMoreLink.href = baseURL + "connection-not-secure";
2022-10-07 21:40:27 +03:00
const bodyTitle = document.querySelector(".title-text");
const shortDesc = document.getElementById("errorShortDesc");
const shortDesc2 = document.getElementById("errorShortDesc2");
2022-10-07 21:40:27 +03:00
let whatToDoParts = null;
switch (failedCertInfo.errorCodeString) {
case "SSL_ERROR_BAD_CERT_DOMAIN":
2022-10-07 21:40:27 +03:00
whatToDoParts = [
["p", "certerror-bad-cert-domain-what-can-you-do-about-it"],
];
break;
case "SEC_ERROR_OCSP_INVALID_SIGNING_CERT": // FIXME - this would have thrown?
break;
case "SEC_ERROR_UNKNOWN_ISSUER":
2022-10-07 21:40:27 +03:00
whatToDoParts = [
["p", "certerror-unknown-issuer-what-can-you-do-about-it-website"],
[
"p",
"certerror-unknown-issuer-what-can-you-do-about-it-contact-admin",
],
];
break;
// This error code currently only exists for the Symantec distrust
// in Firefox 63, so we add copy explaining that to the user.
// In case of future distrusts of that scale we might need to add
// additional parameters that allow us to identify the affected party
// without replicating the complex logic from certverifier code.
2022-10-07 21:40:27 +03:00
case "MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED": {
document.l10n.setAttributes(
2022-10-07 21:40:27 +03:00
shortDesc2,
"cert-error-symantec-distrust-description",
2022-10-07 21:40:27 +03:00
{ hostname: HOST_NAME }
);
2022-10-07 21:40:27 +03:00
// FIXME - this does nothing
const adminDesc = document.createElement("p");
document.l10n.setAttributes(
adminDesc,
"cert-error-symantec-distrust-admin"
);
learnMoreLink.href = baseURL + "symantec-warning";
break;
2022-10-07 21:40:27 +03:00
}
2022-10-07 21:40:27 +03:00
case "MOZILLA_PKIX_ERROR_MITM_DETECTED": {
const autoEnabledEnterpriseRoots = RPMGetBoolPref(
"security.enterprise_roots.auto-enabled",
false
);
if (mitmPrimingEnabled && autoEnabledEnterpriseRoots) {
RPMSendAsyncMessage("Browser:ResetEnterpriseRootsPref");
}
learnMoreLink.href = baseURL + "security-error";
2022-10-07 21:40:27 +03:00
document.l10n.setAttributes(bodyTitle, "certerror-mitm-title");
2022-10-07 21:40:27 +03:00
document.l10n.setAttributes(shortDesc, "certerror-mitm", {
hostname: HOST_NAME,
mitm: getMitmName(failedCertInfo),
});
const id3 = gHasSts
? "certerror-mitm-what-can-you-do-about-it-attack-sts"
: "certerror-mitm-what-can-you-do-about-it-attack";
whatToDoParts = [
["li", "certerror-mitm-what-can-you-do-about-it-antivirus"],
["li", "certerror-mitm-what-can-you-do-about-it-corporate"],
["li", id3, { mitm: getMitmName(failedCertInfo) }],
];
break;
2022-10-07 21:40:27 +03:00
}
case "MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT":
learnMoreLink.href = baseURL + "security-error";
break;
// In case the certificate expired we make sure the system clock
// matches the remote-settings service (blocklist via Kinto) ping time
// and is not before the build date.
case "SEC_ERROR_EXPIRED_CERTIFICATE":
case "SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE":
case "MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE":
2022-10-07 21:40:27 +03:00
case "MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE": {
learnMoreLink.href = baseURL + "time-errors";
2022-10-07 21:40:27 +03:00
// 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.
2022-10-07 21:40:27 +03:00
const difference = RPMGetIntPref(
"services.settings.clock_skew_seconds",
0
);
const lastFetched =
RPMGetIntPref("services.settings.last_update_seconds", 0) * 1000;
2022-10-07 21:40:27 +03:00
// This is set to true later if the user's system clock is at fault for this error.
let clockSkew = false;
const now = Date.now();
const certRange = {
notBefore: failedCertInfo.certValidityRangeNotBefore,
notAfter: failedCertInfo.certValidityRangeNotAfter,
};
2022-10-07 21:40:27 +03:00
const approximateDate = now - difference * 1000;
// If the difference is more than a day, we last fetched the date in the last 5 days,
// and adjusting the date per the interval would make the cert valid, warn the user:
if (
Math.abs(difference) > 60 * 60 * 24 &&
now - lastFetched <= 60 * 60 * 24 * 5 * 1000 &&
certRange.notBefore < approximateDate &&
certRange.notAfter > approximateDate
) {
clockSkew = true;
// 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 {
2022-10-07 21:40:27 +03:00
const appBuildID = RPMGetAppBuildID();
const year = parseInt(appBuildID.substr(0, 4), 10);
const month = parseInt(appBuildID.substr(4, 2), 10) - 1;
const day = parseInt(appBuildID.substr(6, 2), 10);
2022-10-07 21:40:27 +03:00
const buildDate = new Date(year, month, day);
// We don't check the notBefore of the cert with the build date,
// as it is of course almost certain that it is now later than the build date,
// so we shouldn't exclude the possibility that the cert has become valid
// since the build date.
2022-10-07 21:40:27 +03:00
if (buildDate > now && new Date(certRange.notAfter) > buildDate) {
clockSkew = true;
}
}
if (clockSkew) {
document.body.classList.add("clockSkewError");
2022-10-07 21:40:27 +03:00
document.l10n.setAttributes(bodyTitle, "clockSkewError-title");
document.l10n.setAttributes(shortDesc, "neterror-clock-skew-error", {
hostname: HOST_NAME,
now,
});
document.getElementById("returnButton").hidden = true;
document.getElementById("certErrorTryAgainButton").hidden = false;
document.getElementById("advancedButton").hidden = true;
document.getElementById("advancedPanelReturnButton").hidden = true;
document.getElementById("advancedPanelTryAgainButton").hidden = false;
document.getElementById("exceptionDialogButton").hidden = true;
2022-10-07 21:40:27 +03:00
break;
}
2022-10-07 21:40:27 +03:00
document.l10n.setAttributes(shortDesc, "certerror-expired-cert-intro", {
hostname: HOST_NAME,
});
2022-10-07 21:40:27 +03:00
// The secondary description mentions expired certificates explicitly
// and should only be shown if the certificate has actually expired
// instead of being not yet valid.
if (failedCertInfo.errorCodeString == "SEC_ERROR_EXPIRED_CERTIFICATE") {
const sd2Id = gHasSts
? "certerror-expired-cert-sts-second-para"
: "certerror-expired-cert-second-para";
document.l10n.setAttributes(shortDesc2, sd2Id);
if (
Math.abs(difference) <= 60 * 60 * 24 &&
now - lastFetched <= 60 * 60 * 24 * 5 * 1000
) {
whatToDoParts = [
["p", "certerror-bad-cert-domain-what-can-you-do-about-it"],
];
}
}
2022-10-07 21:40:27 +03:00
whatToDoParts ??= [
[
"p",
"certerror-expired-cert-what-can-you-do-about-it-clock",
{ hostname: HOST_NAME, now },
],
[
"p",
"certerror-expired-cert-what-can-you-do-about-it-contact-website",
],
];
break;
2022-10-07 21:40:27 +03:00
}
}
if (whatToDoParts) {
setNetErrorMessageFromParts(
document.getElementById("errorWhatToDoText"),
whatToDoParts
2022-10-07 21:40:27 +03:00
);
document.getElementById("errorWhatToDo").hidden = false;
}
}
async function getSubjectAltNames(failedCertInfo) {
const serverCertBase64 = failedCertInfo.certChainStrings[0];
const parsed = await parse(pemToDER(serverCertBase64));
const subjectAltNamesExtension = parsed.ext.san;
const subjectAltNames = [];
if (subjectAltNamesExtension) {
for (let [key, value] of subjectAltNamesExtension.altNames) {
if (key === "DNS Name" && value.length) {
subjectAltNames.push(value);
}
}
}
return subjectAltNames;
}
// The optional argument is only here for testing purposes.
function setTechnicalDetailsOnCertError(
failedCertInfo = document.getFailedCertSecurityInfo()
) {
let technicalInfo = document.getElementById("badCertTechnicalInfo");
technicalInfo.textContent = "";
function addLabel(l10nId, args = null, attrs = null) {
let elem = document.createElement("label");
technicalInfo.appendChild(elem);
let newLines = document.createTextNode("\n \n");
technicalInfo.appendChild(newLines);
if (attrs) {
let link = document.createElement("a");
for (let [attr, value] of Object.entries(attrs)) {
link.setAttribute(attr, value);
}
elem.appendChild(link);
}
document.l10n.setAttributes(elem, l10nId, args);
}
function addErrorCodeLink() {
addLabel(
"cert-error-code-prefix-link",
{ error: failedCertInfo.errorCodeString },
{
title: failedCertInfo.errorCodeString,
id: "errorCode",
"data-l10n-name": "error-code-link",
"data-telemetry-id": "error_code_link",
href: "#certificateErrorDebugInformation",
}
);
// We're attaching the event listener to the parent element and not on
// the errorCodeLink itself because event listeners cannot be attached
// to fluent DOM overlays.
technicalInfo.addEventListener("click", event => {
if (event.target.id === "errorCode") {
event.preventDefault();
toggleCertErrorDebugInfoVisibility();
recordClickTelemetry(event);
}
});
}
let hostname = HOST_NAME;
const { port } = document.location;
if (port && port != 443) {
hostname += ":" + port;
}
switch (failedCertInfo.overridableErrorCategory) {
case "trust-error":
switch (failedCertInfo.errorCodeString) {
case "MOZILLA_PKIX_ERROR_MITM_DETECTED":
addLabel("cert-error-mitm-intro");
addLabel("cert-error-mitm-mozilla");
addLabel("cert-error-mitm-connection");
break;
case "SEC_ERROR_UNKNOWN_ISSUER":
addLabel("cert-error-trust-unknown-issuer-intro");
addLabel("cert-error-trust-unknown-issuer", { hostname });
break;
case "SEC_ERROR_CA_CERT_INVALID":
addLabel("cert-error-intro", { hostname });
addLabel("cert-error-trust-cert-invalid");
break;
case "SEC_ERROR_UNTRUSTED_ISSUER":
addLabel("cert-error-intro", { hostname });
addLabel("cert-error-trust-untrusted-issuer");
break;
case "SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED":
addLabel("cert-error-intro", { hostname });
addLabel("cert-error-trust-signature-algorithm-disabled");
break;
case "SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE":
addLabel("cert-error-intro", { hostname });
addLabel("cert-error-trust-expired-issuer");
break;
case "MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT":
addLabel("cert-error-intro", { hostname });
addLabel("cert-error-trust-self-signed");
break;
case "MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED":
addLabel("cert-error-intro", { hostname });
addLabel("cert-error-trust-symantec");
break;
default:
addLabel("cert-error-intro", { hostname });
addLabel("cert-error-untrusted-default");
}
addErrorCodeLink();
break;
case "expired-or-not-yet-valid": {
const notBefore = failedCertInfo.validNotBefore;
const notAfter = failedCertInfo.validNotAfter;
if (notBefore && Date.now() < notAfter) {
addLabel("cert-error-not-yet-valid-now", {
hostname,
"not-before-local-time": formatter.format(new Date(notBefore)),
});
} else {
addLabel("cert-error-expired-now", {
hostname,
"not-after-local-time": formatter.format(new Date(notAfter)),
});
}
addErrorCodeLink();
break;
}
case "domain-mismatch":
getSubjectAltNames(failedCertInfo).then(subjectAltNames => {
if (!subjectAltNames.length) {
addLabel("cert-error-domain-mismatch", { hostname });
} else if (subjectAltNames.length > 1) {
const names = subjectAltNames.join(", ");
addLabel("cert-error-domain-mismatch-multiple", {
hostname,
"subject-alt-names": names,
});
} else {
const altName = subjectAltNames[0];
// If the alt name is a wildcard domain ("*.example.com")
// let's use "www" instead. "*.example.com" isn't going to
// get anyone anywhere useful. bug 432491
const okHost = altName.replace(/^\*\./, "www.");
// Let's check if we want to make this a link.
const showLink =
/* case #1:
* example.com uses an invalid security certificate.
*
* The certificate is only valid for www.example.com
*
* Make sure to include the "." ahead of thisHost so that a
* MitM attack on paypal.com doesn't hyperlink to "notpaypal.com"
*
* We'd normally just use a RegExp here except that we lack a
* library function to escape them properly (bug 248062), and
* domain names are famous for having '.' characters in them,
* which would allow spurious and possibly hostile matches.
*/
okHost.endsWith("." + HOST_NAME) ||
/* case #2:
* browser.garage.maemo.org uses an invalid security certificate.
*
* The certificate is only valid for garage.maemo.org
*/
HOST_NAME.endsWith("." + okHost);
const l10nArgs = { hostname, "alt-name": altName };
if (showLink) {
// Set the link if we want it.
const proto = document.location.protocol + "//";
addLabel("cert-error-domain-mismatch-single", l10nArgs, {
href: proto + okHost,
"data-l10n-name": "domain-mismatch-link",
id: "cert_domain_link",
});
// If we set a link, meaning there's something helpful for
// the user here, expand the section by default
if (getCSSClass() != "expertBadCert") {
document.getElementById("badCertAdvancedPanel").hidden = false;
// Toggling the advanced panel must ensure that the debugging
// information panel is hidden as well, since it's opened by the
// error code link in the advanced panel.
toggleCertErrorDebugInfoVisibility(false);
}
} else {
addLabel("cert-error-domain-mismatch-single-nolink", l10nArgs);
}
}
addErrorCodeLink();
});
break;
}
getFailedCertificatesAsPEMString().then(pemString => {
const errorText = document.getElementById("certificateErrorText");
errorText.textContent = pemString;
});
}
/* Only focus if we're the toplevel frame; otherwise we
don't want to call attention to ourselves!
*/
function setFocus(selector, position = "afterbegin") {
if (window.top == window) {
var button = document.querySelector(selector);
button.parentNode.insertAdjacentElement(position, button);
// It's possible setFocus was called via the DOMContentLoaded event
// handler and that the button has no frame. Things without a frame cannot
// be focused. We use a requestAnimationFrame to queue up the focus to occur
// once the button has its frame.
requestAnimationFrame(() => {
button.focus({ focusVisible: false });
});
}
}
for (let button of document.querySelectorAll(".try-again")) {
button.addEventListener("click", function() {
retryThis(this);
});
}
initPage();
// Dispatch this event so tests can detect that we finished loading the error page.
document.dispatchEvent(new CustomEvent("AboutNetErrorLoad", { bubbles: true }));