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