summaryrefslogtreecommitdiffstats
path: root/toolkit/components/securityreporter
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/securityreporter')
-rw-r--r--toolkit/components/securityreporter/SecurityReporter.js112
-rw-r--r--toolkit/components/securityreporter/SecurityReporter.manifest2
-rw-r--r--toolkit/components/securityreporter/moz.build16
-rw-r--r--toolkit/components/securityreporter/nsISecurityReporter.idl14
4 files changed, 144 insertions, 0 deletions
diff --git a/toolkit/components/securityreporter/SecurityReporter.js b/toolkit/components/securityreporter/SecurityReporter.js
new file mode 100644
index 000000000..9ca1e5546
--- /dev/null
+++ b/toolkit/components/securityreporter/SecurityReporter.js
@@ -0,0 +1,112 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+const { classes: Cc, interfaces: Ci, utils: Cu} = Components;
+
+Cu.importGlobalProperties(['fetch']);
+
+const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
+const protocolHandler = Cc["@mozilla.org/network/protocol;1?name=http"]
+ .getService(Ci.nsIHttpProtocolHandler);
+const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
+
+const TLS_ERROR_REPORT_TELEMETRY_SUCCESS = 6;
+const TLS_ERROR_REPORT_TELEMETRY_FAILURE = 7;
+const HISTOGRAM_ID = "TLS_ERROR_REPORT_UI";
+
+
+XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
+ "resource://gre/modules/UpdateUtils.jsm");
+
+function getDERString(cert)
+{
+ var length = {};
+ var derArray = cert.getRawDER(length);
+ var derString = '';
+ for (var i = 0; i < derArray.length; i++) {
+ derString += String.fromCharCode(derArray[i]);
+ }
+ return derString;
+}
+
+function SecurityReporter() { }
+
+SecurityReporter.prototype = {
+ classDescription: "Security reporter component",
+ classID: Components.ID("{8a997c9a-bea1-11e5-a1fa-be6aBc8e7f8b}"),
+ contractID: "@mozilla.org/securityreporter;1",
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsISecurityReporter]),
+ reportTLSError: function(transportSecurityInfo, hostname, port) {
+ // don't send if there's no transportSecurityInfo (since the report cannot
+ // contain anything of interest)
+ if (!transportSecurityInfo) {
+ return;
+ }
+
+ // don't send a report if the pref is not enabled
+ if (!Services.prefs.getBoolPref("security.ssl.errorReporting.enabled")) {
+ return;
+ }
+
+ // Don't send a report if the host we're connecting to is the report
+ // server (otherwise we'll get loops when this fails)
+ let endpoint =
+ Services.prefs.getCharPref("security.ssl.errorReporting.url");
+ let reportURI = Services.io.newURI(endpoint, null, null);
+
+ if (reportURI.host == hostname) {
+ return;
+ }
+
+ // Convert the nsIX509CertList into a format that can be parsed into
+ // JSON
+ let asciiCertChain = [];
+
+ if (transportSecurityInfo.failedCertChain) {
+ let certs = transportSecurityInfo.failedCertChain.getEnumerator();
+ while (certs.hasMoreElements()) {
+ let cert = certs.getNext();
+ cert.QueryInterface(Ci.nsIX509Cert);
+ asciiCertChain.push(btoa(getDERString(cert)));
+ }
+ }
+
+ let report = {
+ hostname: hostname,
+ port: port,
+ timestamp: Math.round(Date.now() / 1000),
+ errorCode: transportSecurityInfo.errorCode,
+ failedCertChain: asciiCertChain,
+ userAgent: protocolHandler.userAgent,
+ version: 1,
+ build: Services.appinfo.appBuildID,
+ product: Services.appinfo.name,
+ channel: UpdateUtils.UpdateChannel
+ }
+
+ fetch(endpoint, {
+ method: "POST",
+ body: JSON.stringify(report),
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ }).then(function (aResponse) {
+ if (!aResponse.ok) {
+ // request returned non-success status
+ Services.telemetry.getHistogramById(HISTOGRAM_ID)
+ .add(TLS_ERROR_REPORT_TELEMETRY_FAILURE);
+ } else {
+ Services.telemetry.getHistogramById(HISTOGRAM_ID)
+ .add(TLS_ERROR_REPORT_TELEMETRY_SUCCESS);
+ }
+ }).catch(function (e) {
+ // error making request to reportURL
+ Services.telemetry.getHistogramById(HISTOGRAM_ID)
+ .add(TLS_ERROR_REPORT_TELEMETRY_FAILURE);
+ });
+ }
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SecurityReporter]);
diff --git a/toolkit/components/securityreporter/SecurityReporter.manifest b/toolkit/components/securityreporter/SecurityReporter.manifest
new file mode 100644
index 000000000..d4e080dc7
--- /dev/null
+++ b/toolkit/components/securityreporter/SecurityReporter.manifest
@@ -0,0 +1,2 @@
+component {8a997c9a-bea1-11e5-a1fa-be6aBc8e7f8b} SecurityReporter.js
+contract @mozilla.org/securityreporter;1 {8a997c9a-bea1-11e5-a1fa-be6aBc8e7f8b}
diff --git a/toolkit/components/securityreporter/moz.build b/toolkit/components/securityreporter/moz.build
new file mode 100644
index 000000000..7ef56a115
--- /dev/null
+++ b/toolkit/components/securityreporter/moz.build
@@ -0,0 +1,16 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+XPIDL_MODULE = 'toolkit_securityreporter'
+
+XPIDL_SOURCES += [
+ 'nsISecurityReporter.idl',
+]
+
+EXTRA_COMPONENTS += [
+ 'SecurityReporter.js',
+ 'SecurityReporter.manifest',
+]
diff --git a/toolkit/components/securityreporter/nsISecurityReporter.idl b/toolkit/components/securityreporter/nsISecurityReporter.idl
new file mode 100644
index 000000000..462dd1e48
--- /dev/null
+++ b/toolkit/components/securityreporter/nsISecurityReporter.idl
@@ -0,0 +1,14 @@
+/* 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/. */
+
+#include "nsISupports.idl"
+#include "nsITransportSecurityInfo.idl"
+
+[scriptable, uuid(8a997c9a-bea1-11e5-a1fa-be6aBc8e7f8b)]
+interface nsISecurityReporter : nsISupports
+{
+ void reportTLSError(in nsITransportSecurityInfo aSecurityInfo,
+ in AUTF8String aHostname,
+ in long aPort);
+};