browser/base/content/pageinfo/security.js

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

     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 }

mercurial