Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 var security = {
7 // Display the server certificate (static)
8 viewCert : function () {
9 var cert = security._cert;
10 viewCertHelper(window, cert);
11 },
13 _getSecurityInfo : function() {
14 const nsIX509Cert = Components.interfaces.nsIX509Cert;
15 const nsIX509CertDB = Components.interfaces.nsIX509CertDB;
16 const nsX509CertDB = "@mozilla.org/security/x509certdb;1";
17 const nsISSLStatusProvider = Components.interfaces.nsISSLStatusProvider;
18 const nsISSLStatus = Components.interfaces.nsISSLStatus;
20 // We don't have separate info for a frame, return null until further notice
21 // (see bug 138479)
22 if (gWindow != gWindow.top)
23 return null;
25 var hName = null;
26 try {
27 hName = gWindow.location.host;
28 }
29 catch (exception) { }
31 var ui = security._getSecurityUI();
32 if (!ui)
33 return null;
35 var isBroken =
36 (ui.state & Components.interfaces.nsIWebProgressListener.STATE_IS_BROKEN);
37 var isInsecure =
38 (ui.state & Components.interfaces.nsIWebProgressListener.STATE_IS_INSECURE);
39 var isEV =
40 (ui.state & Components.interfaces.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL);
41 ui.QueryInterface(nsISSLStatusProvider);
42 var status = ui.SSLStatus;
44 if (!isInsecure && status) {
45 status.QueryInterface(nsISSLStatus);
46 var cert = status.serverCert;
47 var issuerName =
48 this.mapIssuerOrganization(cert.issuerOrganization) || cert.issuerName;
50 var retval = {
51 hostName : hName,
52 cAName : issuerName,
53 encryptionAlgorithm : undefined,
54 encryptionStrength : undefined,
55 isBroken : isBroken,
56 isEV : isEV,
57 cert : cert,
58 fullLocation : gWindow.location
59 };
61 try {
62 retval.encryptionAlgorithm = status.cipherName;
63 retval.encryptionStrength = status.secretKeyLength;
64 }
65 catch (e) {
66 }
68 return retval;
69 } else {
70 return {
71 hostName : hName,
72 cAName : "",
73 encryptionAlgorithm : "",
74 encryptionStrength : 0,
75 isBroken : isBroken,
76 isEV : isEV,
77 cert : null,
78 fullLocation : gWindow.location
79 };
80 }
81 },
83 // Find the secureBrowserUI object (if present)
84 _getSecurityUI : function() {
85 if (window.opener.gBrowser)
86 return window.opener.gBrowser.securityUI;
87 return null;
88 },
90 // Interface for mapping a certificate issuer organization to
91 // the value to be displayed.
92 // Bug 82017 - this implementation should be moved to pipnss C++ code
93 mapIssuerOrganization: function(name) {
94 if (!name) return null;
96 if (name == "RSA Data Security, Inc.") return "Verisign, Inc.";
98 // No mapping required
99 return name;
100 },
102 /**
103 * Open the cookie manager window
104 */
105 viewCookies : function()
106 {
107 var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
108 .getService(Components.interfaces.nsIWindowMediator);
109 var win = wm.getMostRecentWindow("Browser:Cookies");
110 var eTLDService = Components.classes["@mozilla.org/network/effective-tld-service;1"].
111 getService(Components.interfaces.nsIEffectiveTLDService);
113 var eTLD;
114 var uri = gDocument.documentURIObject;
115 try {
116 eTLD = eTLDService.getBaseDomain(uri);
117 }
118 catch (e) {
119 // getBaseDomain will fail if the host is an IP address or is empty
120 eTLD = uri.asciiHost;
121 }
123 if (win) {
124 win.gCookiesWindow.setFilter(eTLD);
125 win.focus();
126 }
127 else
128 window.openDialog("chrome://browser/content/preferences/cookies.xul",
129 "Browser:Cookies", "", {filterString : eTLD});
130 },
132 /**
133 * Open the login manager window
134 */
135 viewPasswords : function()
136 {
137 var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
138 .getService(Components.interfaces.nsIWindowMediator);
139 var win = wm.getMostRecentWindow("Toolkit:PasswordManager");
140 if (win) {
141 win.setFilter(this._getSecurityInfo().hostName);
142 win.focus();
143 }
144 else
145 window.openDialog("chrome://passwordmgr/content/passwordManager.xul",
146 "Toolkit:PasswordManager", "",
147 {filterString : this._getSecurityInfo().hostName});
148 },
150 _cert : null
151 };
153 function securityOnLoad() {
154 var info = security._getSecurityInfo();
155 if (!info) {
156 document.getElementById("securityTab").hidden = true;
157 document.getElementById("securityBox").collapsed = true;
158 return;
159 }
160 else {
161 document.getElementById("securityTab").hidden = false;
162 document.getElementById("securityBox").collapsed = false;
163 }
165 const pageInfoBundle = document.getElementById("pageinfobundle");
167 /* Set Identity section text */
168 setText("security-identity-domain-value", info.hostName);
170 var owner, verifier, generalPageIdentityString;
171 if (info.cert && !info.isBroken) {
172 // Try to pull out meaningful values. Technically these fields are optional
173 // so we'll employ fallbacks where appropriate. The EV spec states that Org
174 // fields must be specified for subject and issuer so that case is simpler.
175 if (info.isEV) {
176 owner = info.cert.organization;
177 verifier = security.mapIssuerOrganization(info.cAName);
178 generalPageIdentityString = pageInfoBundle.getFormattedString("generalSiteIdentity",
179 [owner, verifier]);
180 }
181 else {
182 // Technically, a non-EV cert might specify an owner in the O field or not,
183 // depending on the CA's issuing policies. However we don't have any programmatic
184 // way to tell those apart, and no policy way to establish which organization
185 // vetting standards are good enough (that's what EV is for) so we default to
186 // treating these certs as domain-validated only.
187 owner = pageInfoBundle.getString("securityNoOwner");
188 verifier = security.mapIssuerOrganization(info.cAName ||
189 info.cert.issuerCommonName ||
190 info.cert.issuerName);
191 generalPageIdentityString = owner;
192 }
193 }
194 else {
195 // We don't have valid identity credentials.
196 owner = pageInfoBundle.getString("securityNoOwner");
197 verifier = pageInfoBundle.getString("notset");
198 generalPageIdentityString = owner;
199 }
201 setText("security-identity-owner-value", owner);
202 setText("security-identity-verifier-value", verifier);
203 setText("general-security-identity", generalPageIdentityString);
205 /* Manage the View Cert button*/
206 var viewCert = document.getElementById("security-view-cert");
207 if (info.cert) {
208 security._cert = info.cert;
209 viewCert.collapsed = false;
210 }
211 else
212 viewCert.collapsed = true;
214 /* Set Privacy & History section text */
215 var yesStr = pageInfoBundle.getString("yes");
216 var noStr = pageInfoBundle.getString("no");
218 var uri = gDocument.documentURIObject;
219 setText("security-privacy-cookies-value",
220 hostHasCookies(uri) ? yesStr : noStr);
221 setText("security-privacy-passwords-value",
222 realmHasPasswords(uri) ? yesStr : noStr);
224 var visitCount = previousVisitCount(info.hostName);
225 if(visitCount > 1) {
226 setText("security-privacy-history-value",
227 pageInfoBundle.getFormattedString("securityNVisits", [visitCount.toLocaleString()]));
228 }
229 else if (visitCount == 1) {
230 setText("security-privacy-history-value",
231 pageInfoBundle.getString("securityOneVisit"));
232 }
233 else {
234 setText("security-privacy-history-value", noStr);
235 }
237 /* Set the Technical Detail section messages */
238 const pkiBundle = document.getElementById("pkiBundle");
239 var hdr;
240 var msg1;
241 var msg2;
243 if (info.isBroken) {
244 hdr = pkiBundle.getString("pageInfo_MixedContent");
245 msg1 = pkiBundle.getString("pageInfo_Privacy_Mixed1");
246 msg2 = pkiBundle.getString("pageInfo_Privacy_None2");
247 }
248 else if (info.encryptionStrength >= 90) {
249 hdr = pkiBundle.getFormattedString("pageInfo_StrongEncryptionWithBits",
250 [info.encryptionAlgorithm, info.encryptionStrength + ""]);
251 msg1 = pkiBundle.getString("pageInfo_Privacy_Strong1");
252 msg2 = pkiBundle.getString("pageInfo_Privacy_Strong2");
253 security._cert = info.cert;
254 }
255 else if (info.encryptionStrength > 0) {
256 hdr = pkiBundle.getFormattedString("pageInfo_WeakEncryptionWithBits",
257 [info.encryptionAlgorithm, info.encryptionStrength + ""]);
258 msg1 = pkiBundle.getFormattedString("pageInfo_Privacy_Weak1", [info.hostName]);
259 msg2 = pkiBundle.getString("pageInfo_Privacy_Weak2");
260 }
261 else {
262 hdr = pkiBundle.getString("pageInfo_NoEncryption");
263 if (info.hostName != null)
264 msg1 = pkiBundle.getFormattedString("pageInfo_Privacy_None1", [info.hostName]);
265 else
266 msg1 = pkiBundle.getString("pageInfo_Privacy_None3");
267 msg2 = pkiBundle.getString("pageInfo_Privacy_None2");
268 }
269 setText("security-technical-shortform", hdr);
270 setText("security-technical-longform1", msg1);
271 setText("security-technical-longform2", msg2);
272 setText("general-security-privacy", hdr);
273 }
275 function setText(id, value)
276 {
277 var element = document.getElementById(id);
278 if (!element)
279 return;
280 if (element.localName == "textbox" || element.localName == "label")
281 element.value = value;
282 else {
283 if (element.hasChildNodes())
284 element.removeChild(element.firstChild);
285 var textNode = document.createTextNode(value);
286 element.appendChild(textNode);
287 }
288 }
290 function viewCertHelper(parent, cert)
291 {
292 if (!cert)
293 return;
295 var cd = Components.classes[CERTIFICATEDIALOGS_CONTRACTID].getService(nsICertificateDialogs);
296 cd.viewCert(parent, cert);
297 }
299 /**
300 * Return true iff we have cookies for uri
301 */
302 function hostHasCookies(uri) {
303 var cookieManager = Components.classes["@mozilla.org/cookiemanager;1"]
304 .getService(Components.interfaces.nsICookieManager2);
306 return cookieManager.countCookiesFromHost(uri.asciiHost) > 0;
307 }
309 /**
310 * Return true iff realm (proto://host:port) (extracted from uri) has
311 * saved passwords
312 */
313 function realmHasPasswords(uri) {
314 var passwordManager = Components.classes["@mozilla.org/login-manager;1"]
315 .getService(Components.interfaces.nsILoginManager);
316 return passwordManager.countLogins(uri.prePath, "", "") > 0;
317 }
319 /**
320 * Return the number of previous visits recorded for host before today.
321 *
322 * @param host - the domain name to look for in history
323 */
324 function previousVisitCount(host, endTimeReference) {
325 if (!host)
326 return false;
328 var historyService = Components.classes["@mozilla.org/browser/nav-history-service;1"]
329 .getService(Components.interfaces.nsINavHistoryService);
331 var options = historyService.getNewQueryOptions();
332 options.resultType = options.RESULTS_AS_VISIT;
334 // Search for visits to this host before today
335 var query = historyService.getNewQuery();
336 query.endTimeReference = query.TIME_RELATIVE_TODAY;
337 query.endTime = 0;
338 query.domain = host;
340 var result = historyService.executeQuery(query, options);
341 result.root.containerOpen = true;
342 var cc = result.root.childCount;
343 result.root.containerOpen = false;
344 return cc;
345 }