michael@0: /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: var security = { michael@0: // Display the server certificate (static) michael@0: viewCert : function () { michael@0: var cert = security._cert; michael@0: viewCertHelper(window, cert); michael@0: }, michael@0: michael@0: _getSecurityInfo : function() { michael@0: const nsIX509Cert = Components.interfaces.nsIX509Cert; michael@0: const nsIX509CertDB = Components.interfaces.nsIX509CertDB; michael@0: const nsX509CertDB = "@mozilla.org/security/x509certdb;1"; michael@0: const nsISSLStatusProvider = Components.interfaces.nsISSLStatusProvider; michael@0: const nsISSLStatus = Components.interfaces.nsISSLStatus; michael@0: michael@0: // We don't have separate info for a frame, return null until further notice michael@0: // (see bug 138479) michael@0: if (gWindow != gWindow.top) michael@0: return null; michael@0: michael@0: var hName = null; michael@0: try { michael@0: hName = gWindow.location.host; michael@0: } michael@0: catch (exception) { } michael@0: michael@0: var ui = security._getSecurityUI(); michael@0: if (!ui) michael@0: return null; michael@0: michael@0: var isBroken = michael@0: (ui.state & Components.interfaces.nsIWebProgressListener.STATE_IS_BROKEN); michael@0: var isInsecure = michael@0: (ui.state & Components.interfaces.nsIWebProgressListener.STATE_IS_INSECURE); michael@0: var isEV = michael@0: (ui.state & Components.interfaces.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL); michael@0: ui.QueryInterface(nsISSLStatusProvider); michael@0: var status = ui.SSLStatus; michael@0: michael@0: if (!isInsecure && status) { michael@0: status.QueryInterface(nsISSLStatus); michael@0: var cert = status.serverCert; michael@0: var issuerName = michael@0: this.mapIssuerOrganization(cert.issuerOrganization) || cert.issuerName; michael@0: michael@0: var retval = { michael@0: hostName : hName, michael@0: cAName : issuerName, michael@0: encryptionAlgorithm : undefined, michael@0: encryptionStrength : undefined, michael@0: isBroken : isBroken, michael@0: isEV : isEV, michael@0: cert : cert, michael@0: fullLocation : gWindow.location michael@0: }; michael@0: michael@0: try { michael@0: retval.encryptionAlgorithm = status.cipherName; michael@0: retval.encryptionStrength = status.secretKeyLength; michael@0: } michael@0: catch (e) { michael@0: } michael@0: michael@0: return retval; michael@0: } else { michael@0: return { michael@0: hostName : hName, michael@0: cAName : "", michael@0: encryptionAlgorithm : "", michael@0: encryptionStrength : 0, michael@0: isBroken : isBroken, michael@0: isEV : isEV, michael@0: cert : null, michael@0: fullLocation : gWindow.location michael@0: }; michael@0: } michael@0: }, michael@0: michael@0: // Find the secureBrowserUI object (if present) michael@0: _getSecurityUI : function() { michael@0: if (window.opener.gBrowser) michael@0: return window.opener.gBrowser.securityUI; michael@0: return null; michael@0: }, michael@0: michael@0: // Interface for mapping a certificate issuer organization to michael@0: // the value to be displayed. michael@0: // Bug 82017 - this implementation should be moved to pipnss C++ code michael@0: mapIssuerOrganization: function(name) { michael@0: if (!name) return null; michael@0: michael@0: if (name == "RSA Data Security, Inc.") return "Verisign, Inc."; michael@0: michael@0: // No mapping required michael@0: return name; michael@0: }, michael@0: michael@0: /** michael@0: * Open the cookie manager window michael@0: */ michael@0: viewCookies : function() michael@0: { michael@0: var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] michael@0: .getService(Components.interfaces.nsIWindowMediator); michael@0: var win = wm.getMostRecentWindow("Browser:Cookies"); michael@0: var eTLDService = Components.classes["@mozilla.org/network/effective-tld-service;1"]. michael@0: getService(Components.interfaces.nsIEffectiveTLDService); michael@0: michael@0: var eTLD; michael@0: var uri = gDocument.documentURIObject; michael@0: try { michael@0: eTLD = eTLDService.getBaseDomain(uri); michael@0: } michael@0: catch (e) { michael@0: // getBaseDomain will fail if the host is an IP address or is empty michael@0: eTLD = uri.asciiHost; michael@0: } michael@0: michael@0: if (win) { michael@0: win.gCookiesWindow.setFilter(eTLD); michael@0: win.focus(); michael@0: } michael@0: else michael@0: window.openDialog("chrome://browser/content/preferences/cookies.xul", michael@0: "Browser:Cookies", "", {filterString : eTLD}); michael@0: }, michael@0: michael@0: /** michael@0: * Open the login manager window michael@0: */ michael@0: viewPasswords : function() michael@0: { michael@0: var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] michael@0: .getService(Components.interfaces.nsIWindowMediator); michael@0: var win = wm.getMostRecentWindow("Toolkit:PasswordManager"); michael@0: if (win) { michael@0: win.setFilter(this._getSecurityInfo().hostName); michael@0: win.focus(); michael@0: } michael@0: else michael@0: window.openDialog("chrome://passwordmgr/content/passwordManager.xul", michael@0: "Toolkit:PasswordManager", "", michael@0: {filterString : this._getSecurityInfo().hostName}); michael@0: }, michael@0: michael@0: _cert : null michael@0: }; michael@0: michael@0: function securityOnLoad() { michael@0: var info = security._getSecurityInfo(); michael@0: if (!info) { michael@0: document.getElementById("securityTab").hidden = true; michael@0: document.getElementById("securityBox").collapsed = true; michael@0: return; michael@0: } michael@0: else { michael@0: document.getElementById("securityTab").hidden = false; michael@0: document.getElementById("securityBox").collapsed = false; michael@0: } michael@0: michael@0: const pageInfoBundle = document.getElementById("pageinfobundle"); michael@0: michael@0: /* Set Identity section text */ michael@0: setText("security-identity-domain-value", info.hostName); michael@0: michael@0: var owner, verifier, generalPageIdentityString; michael@0: if (info.cert && !info.isBroken) { michael@0: // Try to pull out meaningful values. Technically these fields are optional michael@0: // so we'll employ fallbacks where appropriate. The EV spec states that Org michael@0: // fields must be specified for subject and issuer so that case is simpler. michael@0: if (info.isEV) { michael@0: owner = info.cert.organization; michael@0: verifier = security.mapIssuerOrganization(info.cAName); michael@0: generalPageIdentityString = pageInfoBundle.getFormattedString("generalSiteIdentity", michael@0: [owner, verifier]); michael@0: } michael@0: else { michael@0: // Technically, a non-EV cert might specify an owner in the O field or not, michael@0: // depending on the CA's issuing policies. However we don't have any programmatic michael@0: // way to tell those apart, and no policy way to establish which organization michael@0: // vetting standards are good enough (that's what EV is for) so we default to michael@0: // treating these certs as domain-validated only. michael@0: owner = pageInfoBundle.getString("securityNoOwner"); michael@0: verifier = security.mapIssuerOrganization(info.cAName || michael@0: info.cert.issuerCommonName || michael@0: info.cert.issuerName); michael@0: generalPageIdentityString = owner; michael@0: } michael@0: } michael@0: else { michael@0: // We don't have valid identity credentials. michael@0: owner = pageInfoBundle.getString("securityNoOwner"); michael@0: verifier = pageInfoBundle.getString("notset"); michael@0: generalPageIdentityString = owner; michael@0: } michael@0: michael@0: setText("security-identity-owner-value", owner); michael@0: setText("security-identity-verifier-value", verifier); michael@0: setText("general-security-identity", generalPageIdentityString); michael@0: michael@0: /* Manage the View Cert button*/ michael@0: var viewCert = document.getElementById("security-view-cert"); michael@0: if (info.cert) { michael@0: security._cert = info.cert; michael@0: viewCert.collapsed = false; michael@0: } michael@0: else michael@0: viewCert.collapsed = true; michael@0: michael@0: /* Set Privacy & History section text */ michael@0: var yesStr = pageInfoBundle.getString("yes"); michael@0: var noStr = pageInfoBundle.getString("no"); michael@0: michael@0: var uri = gDocument.documentURIObject; michael@0: setText("security-privacy-cookies-value", michael@0: hostHasCookies(uri) ? yesStr : noStr); michael@0: setText("security-privacy-passwords-value", michael@0: realmHasPasswords(uri) ? yesStr : noStr); michael@0: michael@0: var visitCount = previousVisitCount(info.hostName); michael@0: if(visitCount > 1) { michael@0: setText("security-privacy-history-value", michael@0: pageInfoBundle.getFormattedString("securityNVisits", [visitCount.toLocaleString()])); michael@0: } michael@0: else if (visitCount == 1) { michael@0: setText("security-privacy-history-value", michael@0: pageInfoBundle.getString("securityOneVisit")); michael@0: } michael@0: else { michael@0: setText("security-privacy-history-value", noStr); michael@0: } michael@0: michael@0: /* Set the Technical Detail section messages */ michael@0: const pkiBundle = document.getElementById("pkiBundle"); michael@0: var hdr; michael@0: var msg1; michael@0: var msg2; michael@0: michael@0: if (info.isBroken) { michael@0: hdr = pkiBundle.getString("pageInfo_MixedContent"); michael@0: msg1 = pkiBundle.getString("pageInfo_Privacy_Mixed1"); michael@0: msg2 = pkiBundle.getString("pageInfo_Privacy_None2"); michael@0: } michael@0: else if (info.encryptionStrength >= 90) { michael@0: hdr = pkiBundle.getFormattedString("pageInfo_StrongEncryptionWithBits", michael@0: [info.encryptionAlgorithm, info.encryptionStrength + ""]); michael@0: msg1 = pkiBundle.getString("pageInfo_Privacy_Strong1"); michael@0: msg2 = pkiBundle.getString("pageInfo_Privacy_Strong2"); michael@0: security._cert = info.cert; michael@0: } michael@0: else if (info.encryptionStrength > 0) { michael@0: hdr = pkiBundle.getFormattedString("pageInfo_WeakEncryptionWithBits", michael@0: [info.encryptionAlgorithm, info.encryptionStrength + ""]); michael@0: msg1 = pkiBundle.getFormattedString("pageInfo_Privacy_Weak1", [info.hostName]); michael@0: msg2 = pkiBundle.getString("pageInfo_Privacy_Weak2"); michael@0: } michael@0: else { michael@0: hdr = pkiBundle.getString("pageInfo_NoEncryption"); michael@0: if (info.hostName != null) michael@0: msg1 = pkiBundle.getFormattedString("pageInfo_Privacy_None1", [info.hostName]); michael@0: else michael@0: msg1 = pkiBundle.getString("pageInfo_Privacy_None3"); michael@0: msg2 = pkiBundle.getString("pageInfo_Privacy_None2"); michael@0: } michael@0: setText("security-technical-shortform", hdr); michael@0: setText("security-technical-longform1", msg1); michael@0: setText("security-technical-longform2", msg2); michael@0: setText("general-security-privacy", hdr); michael@0: } michael@0: michael@0: function setText(id, value) michael@0: { michael@0: var element = document.getElementById(id); michael@0: if (!element) michael@0: return; michael@0: if (element.localName == "textbox" || element.localName == "label") michael@0: element.value = value; michael@0: else { michael@0: if (element.hasChildNodes()) michael@0: element.removeChild(element.firstChild); michael@0: var textNode = document.createTextNode(value); michael@0: element.appendChild(textNode); michael@0: } michael@0: } michael@0: michael@0: function viewCertHelper(parent, cert) michael@0: { michael@0: if (!cert) michael@0: return; michael@0: michael@0: var cd = Components.classes[CERTIFICATEDIALOGS_CONTRACTID].getService(nsICertificateDialogs); michael@0: cd.viewCert(parent, cert); michael@0: } michael@0: michael@0: /** michael@0: * Return true iff we have cookies for uri michael@0: */ michael@0: function hostHasCookies(uri) { michael@0: var cookieManager = Components.classes["@mozilla.org/cookiemanager;1"] michael@0: .getService(Components.interfaces.nsICookieManager2); michael@0: michael@0: return cookieManager.countCookiesFromHost(uri.asciiHost) > 0; michael@0: } michael@0: michael@0: /** michael@0: * Return true iff realm (proto://host:port) (extracted from uri) has michael@0: * saved passwords michael@0: */ michael@0: function realmHasPasswords(uri) { michael@0: var passwordManager = Components.classes["@mozilla.org/login-manager;1"] michael@0: .getService(Components.interfaces.nsILoginManager); michael@0: return passwordManager.countLogins(uri.prePath, "", "") > 0; michael@0: } michael@0: michael@0: /** michael@0: * Return the number of previous visits recorded for host before today. michael@0: * michael@0: * @param host - the domain name to look for in history michael@0: */ michael@0: function previousVisitCount(host, endTimeReference) { michael@0: if (!host) michael@0: return false; michael@0: michael@0: var historyService = Components.classes["@mozilla.org/browser/nav-history-service;1"] michael@0: .getService(Components.interfaces.nsINavHistoryService); michael@0: michael@0: var options = historyService.getNewQueryOptions(); michael@0: options.resultType = options.RESULTS_AS_VISIT; michael@0: michael@0: // Search for visits to this host before today michael@0: var query = historyService.getNewQuery(); michael@0: query.endTimeReference = query.TIME_RELATIVE_TODAY; michael@0: query.endTime = 0; michael@0: query.domain = host; michael@0: michael@0: var result = historyService.executeQuery(query, options); michael@0: result.root.containerOpen = true; michael@0: var cc = result.root.childCount; michael@0: result.root.containerOpen = false; michael@0: return cc; michael@0: }