Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 let Cc = Components.classes;
6 let Ci = Components.interfaces;
7 let Cu = Components.utils;
9 Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
11 /**
12 A class to add exceptions to override SSL certificate problems. The functionality
13 itself is borrowed from exceptionDialog.js.
14 */
15 function SSLExceptions() {
16 this._overrideService = Cc["@mozilla.org/security/certoverride;1"]
17 .getService(Ci.nsICertOverrideService);
18 }
21 SSLExceptions.prototype = {
22 _overrideService: null,
23 _sslStatus: null,
25 getInterface: function SSLE_getInterface(aIID) {
26 return this.QueryInterface(aIID);
27 },
28 QueryInterface: function SSLE_QueryInterface(aIID) {
29 if (aIID.equals(Ci.nsIBadCertListener2) ||
30 aIID.equals(Ci.nsISupports))
31 return this;
33 throw Components.results.NS_ERROR_NO_INTERFACE;
34 },
36 /**
37 To collect the SSL status we intercept the certificate error here
38 and store the status for later use.
39 */
40 notifyCertProblem: function SSLE_notifyCertProblem(socketInfo, sslStatus, targetHost) {
41 this._sslStatus = sslStatus.QueryInterface(Ci.nsISSLStatus);
42 return true; // suppress error UI
43 },
45 /**
46 Attempt to download the certificate for the location specified to get the SSLState
47 for the certificate and the errors.
48 */
49 _checkCert: function SSLE_checkCert(aURI) {
50 this._sslStatus = null;
52 var req = new XMLHttpRequest();
53 try {
54 if(aURI) {
55 req.open("GET", aURI.prePath, false);
56 req.channel.notificationCallbacks = this;
57 req.send(null);
58 }
59 } catch (e) {
60 // We *expect* exceptions if there are problems with the certificate
61 // presented by the site. Log it, just in case, but we can proceed here,
62 // with appropriate sanity checks
63 Components.utils.reportError("Attempted to connect to a site with a bad certificate in the add exception dialog. " +
64 "This results in a (mostly harmless) exception being thrown. " +
65 "Logged for information purposes only: " + e);
66 }
68 return this._sslStatus;
69 },
71 /**
72 Internal method to create an override.
73 */
74 _addOverride: function SSLE_addOverride(aURI, aWindow, temporary) {
75 var SSLStatus = this._checkCert(aURI);
76 var certificate = SSLStatus.serverCert;
78 var flags = 0;
80 // in private browsing do not store exceptions permanently ever
81 if (PrivateBrowsingUtils.isWindowPrivate(aWindow)) {
82 temporary = true;
83 }
85 if(SSLStatus.isUntrusted)
86 flags |= this._overrideService.ERROR_UNTRUSTED;
87 if(SSLStatus.isDomainMismatch)
88 flags |= this._overrideService.ERROR_MISMATCH;
89 if(SSLStatus.isNotValidAtThisTime)
90 flags |= this._overrideService.ERROR_TIME;
92 this._overrideService.rememberValidityOverride(
93 aURI.asciiHost,
94 aURI.port,
95 certificate,
96 flags,
97 temporary);
98 },
100 /**
101 Creates a permanent exception to override all overridable errors for
102 the given URL.
103 */
104 addPermanentException: function SSLE_addPermanentException(aURI, aWindow) {
105 this._addOverride(aURI, aWindow, false);
106 },
108 /**
109 Creates a temporary exception to override all overridable errors for
110 the given URL.
111 */
112 addTemporaryException: function SSLE_addTemporaryException(aURI, aWindow) {
113 this._addOverride(aURI, aWindow, true);
114 }
115 };