|
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 |
|
5 let Cc = Components.classes; |
|
6 let Ci = Components.interfaces; |
|
7 let Cu = Components.utils; |
|
8 |
|
9 Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); |
|
10 |
|
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 } |
|
19 |
|
20 |
|
21 SSLExceptions.prototype = { |
|
22 _overrideService: null, |
|
23 _sslStatus: null, |
|
24 |
|
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; |
|
32 |
|
33 throw Components.results.NS_ERROR_NO_INTERFACE; |
|
34 }, |
|
35 |
|
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 }, |
|
44 |
|
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; |
|
51 |
|
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 } |
|
67 |
|
68 return this._sslStatus; |
|
69 }, |
|
70 |
|
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; |
|
77 |
|
78 var flags = 0; |
|
79 |
|
80 // in private browsing do not store exceptions permanently ever |
|
81 if (PrivateBrowsingUtils.isWindowPrivate(aWindow)) { |
|
82 temporary = true; |
|
83 } |
|
84 |
|
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; |
|
91 |
|
92 this._overrideService.rememberValidityOverride( |
|
93 aURI.asciiHost, |
|
94 aURI.port, |
|
95 certificate, |
|
96 flags, |
|
97 temporary); |
|
98 }, |
|
99 |
|
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 }, |
|
107 |
|
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 }; |