[or-cvs] r14656: Sink a ton of effort into fixing cert jaring performance and (in torbutton/trunk/src: chrome/content chrome/locale/en-US components defaults/preferences)

mikeperry at seul.org mikeperry at seul.org
Sun May 18 00:04:50 UTC 2008


Author: mikeperry
Date: 2008-05-17 20:04:50 -0400 (Sat, 17 May 2008)
New Revision: 14656

Added:
   torbutton/trunk/src/components/certDialogsOverride.js
Modified:
   torbutton/trunk/src/chrome/content/preferences.js
   torbutton/trunk/src/chrome/content/preferences.xul
   torbutton/trunk/src/chrome/content/torbutton.js
   torbutton/trunk/src/chrome/locale/en-US/torbutton.dtd
   torbutton/trunk/src/defaults/preferences/preferences.js
Log:

Sink a ton of effort into fixing cert jaring performance and general 
behavior, only to discover that a Firefox race condition
prevents us from doing this properly if the user toggles Tor
quickly. Add code, but remove pref :(



Modified: torbutton/trunk/src/chrome/content/preferences.js
===================================================================
--- torbutton/trunk/src/chrome/content/preferences.js	2008-05-17 13:44:17 UTC (rev 14655)
+++ torbutton/trunk/src/chrome/content/preferences.js	2008-05-18 00:04:50 UTC (rev 14656)
@@ -215,9 +215,10 @@
     doc.getElementById('torbutton_clearHttpAuth').checked = o_torprefs.getBoolPref('clear_http_auth');
     doc.getElementById('torbutton_blockJSHistory').checked = o_torprefs.getBoolPref('block_js_history');
     doc.getElementById('torbutton_blockFileNet').checked = o_torprefs.getBoolPref('block_file_net');
+    /*
     doc.getElementById('torbutton_jarCerts').checked = o_torprefs.getBoolPref('jar_certs');
-    // XXX: Grey this out if jar_certs is false
     doc.getElementById('torbutton_jarCACerts').checked = o_torprefs.getBoolPref('jar_ca_certs');
+    */
 
     torbutton_prefs_set_field_attributes(doc);
 }
@@ -312,10 +313,12 @@
     o_torprefs.setBoolPref('set_uagent', doc.getElementById('torbutton_setUagent').checked);
     o_torprefs.setBoolPref('disable_referer', doc.getElementById('torbutton_noReferer').checked);
     o_torprefs.setBoolPref('spoof_english', doc.getElementById('torbutton_spoofEnglish').checked);
+    /*
     o_torprefs.setBoolPref('jar_certs', doc.getElementById('torbutton_jarCerts').checked);
     o_torprefs.setBoolPref('jar_ca_certs',
             o_torprefs.getBoolPref('jar_certs') &&
             doc.getElementById('torbutton_jarCACerts').checked);
+    */
 
     // if tor settings were initially active, update the active settings to reflect any changes
     if (tor_enabled) torbutton_activate_tor_settings();

Modified: torbutton/trunk/src/chrome/content/preferences.xul
===================================================================
--- torbutton/trunk/src/chrome/content/preferences.xul	2008-05-17 13:44:17 UTC (rev 14655)
+++ torbutton/trunk/src/chrome/content/preferences.xul	2008-05-18 00:04:50 UTC (rev 14656)
@@ -240,10 +240,12 @@
                   oncommand="torbutton_prefs_set_field_attributes(document)"/>
           <checkbox id="torbutton_spoofEnglish" label="&torbutton.prefs.spoof_english;" 
                    oncommand="torbutton_prefs_set_field_attributes(document)"/>
+<!--
           <checkbox id="torbutton_jarCerts" label="&torbutton.prefs.jar_certs;" 
                    oncommand="torbutton_prefs_set_field_attributes(document)"/>
           <checkbox id="torbutton_jarCACerts" label="&torbutton.prefs.jar_ca_certs;" 
                    oncommand="torbutton_prefs_set_field_attributes(document)"/>
+-->
           <checkbox id="torbutton_noReferer" label="&torbutton.prefs.disable_referer;" 
                    oncommand="torbutton_prefs_set_field_attributes(document)"/>
            </vbox>

Modified: torbutton/trunk/src/chrome/content/torbutton.js
===================================================================
--- torbutton/trunk/src/chrome/content/torbutton.js	2008-05-17 13:44:17 UTC (rev 14655)
+++ torbutton/trunk/src/chrome/content/torbutton.js	2008-05-18 00:04:50 UTC (rev 14656)
@@ -942,11 +942,29 @@
     
     torbutton_log(2, "Jaring "+name+" certificates: "+mode);
 
+    if(type == Components.interfaces.nsIX509Cert.CA_CERT) {
+        try {
+            var bundles = Components.classes["@mozilla.org/intl/stringbundle;1"]
+                .getService(Components.interfaces.nsIStringBundleService);
+            var pipnss_bundle = bundles.createBundle("chrome://pipnss/locale/pipnss.properties");
+            var internalToken = pipnss_bundle.GetStringFromName("InternalToken");
+        } catch(err) {
+            torbutton_log(5, "No String bundle for NSS: "+err);
+        }
+    }
+
     for(var i = 0; i < treeView.rowCount; i++) {
-        if(!treeView.getCert(i)) {
+        var cert = treeView.getCert(i);
+        // HACK alert
+        // There is no real way to differentiate user added 
+        // CA certificates from builtin ones, aside from the 
+        // token name string (which is localized) 
+        if(!cert || (type == Components.interfaces.nsIX509Cert.CA_CERT
+                && cert.tokenName != internalToken)) {
             continue;
         }
-        outList.push(treeView.getCert(i));
+
+        outList.push(cert);
     }
 
     // Write current certs to certjar-tor
@@ -986,20 +1004,29 @@
         bstream.setOutputStream(stream);
 
         var binaryCerts = [];
+        var bitList = [];
 
         for(var i = 0; i< outList.length; i++) {
             if(outList[i]) {
                 var len = new Object();
                 var data = outList[i].getRawDER(len);
                 //torbutton_log(2, "Delete: "+certdb.deleteCertificate(outList[i]));
+                torbutton_log(2, "Delete: "+outList[i].organization+" "+outList[i].tokenName);
+                // Need to save trustbits somehow.. They are not saved.
+                var bits = 0;
+                if(certdb.isCertTrusted(outList[i], type, certdb.TRUSTED_SSL)) {
+                    bits |= certdb.TRUSTED_SSL;
+                }
+                if(certdb.isCertTrusted(outList[i], type, certdb.TRUSTED_EMAIL)) {
+                    bits |= certdb.TRUSTED_EMAIL;
+                }
+                if(certdb.isCertTrusted(outList[i], type, certdb.TRUSTED_OBJSIGN)) {
+                    bits |= certdb.TRUSTED_OBJSIGN;
+                }
+
                 certdb.deleteCertificate(outList[i]);
-                /* Doesn't work.. db isn't updated right away..
-                 * if(outList[i].equals(
-                            certdb.findCertByDBKey(outList[i].dbKey, null))) {
-                    torbutton_log(2, "Not writing cert: "+outList[i].organization);
-                } else {
-                    binaryCerts.push(data);
-                }*/
+
+                bitList.push(bits); 
                 binaryCerts.push(data);
             }
         }
@@ -1007,6 +1034,7 @@
         bstream.write32(binaryCerts.length);
         for(var i = 0; i < binaryCerts.length; i++) {
             bstream.write32(binaryCerts[i].length);
+            bstream.write32(bitList[i]);
             bstream.writeByteArray(binaryCerts[i], binaryCerts[i].length);
         }
 
@@ -1063,45 +1091,52 @@
 
     if(bstream.available()) {
         var certs = bstream.read32();
+
+        if(type == Components.interfaces.nsIX509Cert.CA_CERT) {
+            m_tb_prefs.setBoolPref("extensions.torbutton.block_cert_dialogs", 
+                    true);
+        }
+
         for(var i = 0; i < certs; i++) {
             var len = bstream.read32();
+            var trustBits = bstream.read32();
             var bytes = bstream.readByteArray(len);
-            switch(type) {
-                case Components.interfaces.nsIX509Cert.EMAIL_CERT:
-                    unjared_certs++;
-                    certdb.importEmailCertificate(bytes, bytes.length, null);
-                    break;
-                case Components.interfaces.nsIX509Cert.SERVER_CERT:
-                    unjared_certs++;
-                    certdb.importServerCertificate(bytes, bytes.length, null);
-                    break;
-                case Components.interfaces.nsIX509Cert.USER_CERT:
-                    unjared_certs++;
-                    certdb.importUserCertificate(bytes, bytes.length, null);
-                    break;
-                case Components.interfaces.nsIX509Cert.CA_CERT:
-                    try {
-                        // System-wide CA certs aren't deletable and can't be 
-                        // distinguished from user-added ones. Need to check
-                        // to see if they are still present before trying
-                        // to re-insert them. (We can't check deletable status
-                        // above because they don't get deleted immediately).
-                        var base64 = window.btoa(torbutton_bytearray_to_string(bytes));
-                        var checkCert = certdb.constructX509FromBase64(base64);
-                        torbutton_log(2, "Made Cert: "+checkCert.organization);
 
-                        if(checkCert.equals(certdb.findCertByDBKey(checkCert.dbKey, null))) {
-                            torbutton_log(2, "Skipping cert: "+checkCert.organization);
-                        } else {
-                            unjared_certs++;
-                            certdb.importCertificates(bytes, bytes.length, type, null);
-                        }
-                    } catch(e) {
-                        torbutton_log(2, "Falied to make Cert: ");
-                    }
-                    break;
+            // This just for the trustBits, which seem to be lost 
+            // in the BER translation. sucks..
+            var base64 = window.btoa(torbutton_bytearray_to_string(bytes));
+            var checkCert = certdb.constructX509FromBase64(base64);
+            torbutton_log(2, "Made Cert: "+checkCert.organization);
+
+            try {
+                switch(type) {
+                    case Components.interfaces.nsIX509Cert.EMAIL_CERT:
+                        certdb.importEmailCertificate(bytes, bytes.length, null);
+                        break;
+                    case Components.interfaces.nsIX509Cert.SERVER_CERT:
+                        certdb.importServerCertificate(bytes, bytes.length, null);
+                        break;
+                    case Components.interfaces.nsIX509Cert.USER_CERT:
+                        certdb.importUserCertificate(bytes, bytes.length, null);
+                        break;
+                    case Components.interfaces.nsIX509Cert.CA_CERT:
+                        certdb.importCertificates(bytes, bytes.length, type, null);
+                        break;
+                }
+            
+                certdb.setCertTrust(checkCert, type, trustBits);
+
+            } catch(e) {
+                torbutton_log(5, "Failed to import cert: "+checkCert.organization+": "+e);
             }
+
+            unjared_certs++;
         }
+        if(type == Components.interfaces.nsIX509Cert.CA_CERT) {
+            m_tb_prefs.setBoolPref("extensions.torbutton.block_cert_dialogs", 
+                    false);
+        }
+
         torbutton_log(2, "Read "+unjared_certs+" "+name+" certificates from "+inFile.path);
     }
 
@@ -1196,34 +1231,31 @@
                     .getService(Components.interfaces.nsIX509CertDB2);
     certdb.QueryInterface(Components.interfaces.nsIX509CertDB);
 
-    // This is done because a couple of rogue system-wide certs
-    // end up in the server cert pane somehow after the above. This 
-    // doesn't actually get rid of them, but hey, here's 
-    // hoping.. maybe someday :)
-    for(var i = 0; i < serverTreeView.rowCount; i++) {
-        if(serverTreeView.getCert(i)) {
-            torbutton_log(2, 
-                    "Killing cert: "+serverTreeView.getCert(i).organization);
-            certdb.deleteCertificate(serverTreeView.getCert(i));
-        }
-    }
+    certCache.cacheAllCerts();
+    serverTreeView.loadCertsFromCache(certCache, 
+            Components.interfaces.nsIX509Cert.SERVER_CERT);
+    if(serverTreeView.selection)
+        serverTreeView.selection.clearSelection();
+    
+    emailTreeView.loadCertsFromCache(certCache, 
+            Components.interfaces.nsIX509Cert.EMAIL_CERT);
+    if(emailTreeView.selection)
+        emailTreeView.selection.clearSelection();
+    
+    userTreeView.loadCertsFromCache(certCache, 
+            Components.interfaces.nsIX509Cert.USER_CERT);
+    if(userTreeView.selection)
+        userTreeView.selection.clearSelection();
+    
+    caTreeView.loadCertsFromCache(certCache, 
+            Components.interfaces.nsIX509Cert.CA_CERT);
+    if(caTreeView.selection)
+        caTreeView.selection.clearSelection();
 
+
     if(m_tb_prefs.getBoolPref("extensions.torbutton.jar_ca_certs")) {
         if(torbutton_unjar_cert_type(mode, caTreeView, "ca", 
                 Components.interfaces.nsIX509Cert.CA_CERT) == 0) {
-            /*
-            if(!m_tb_prefs.getBoolPref("extensions.torbutton.asked_ca_disable")) {
-                var o_stringbundle = torbutton_get_stringbundle();
-                var warning = o_stringbundle.GetStringFromName("torbutton.popup.confirm_ca_certs");
-                var val = window.confirm(warning);
-                torbutton_log(3, "Got response: "+val);
-                if(val) {
-                    m_tb_prefs.setBoolPref("extensions.torbutton.jar_ca_certs",
-                            false);
-                }
-                m_tb_prefs.setBoolPref("extensions.torbutton.asked_ca_disable", 
-                        true);
-            }*/
             // arma thinks this not worth even asking. He is probably right.
             m_tb_prefs.setBoolPref("extensions.torbutton.jar_ca_certs",
                     false);
@@ -1237,7 +1269,6 @@
             Components.interfaces.nsIX509Cert.SERVER_CERT);
 
 
-
     certCache.cacheAllCerts();
     serverTreeView.loadCertsFromCache(certCache, 
             Components.interfaces.nsIX509Cert.SERVER_CERT);
@@ -2015,6 +2046,7 @@
                         var browser = wm.getBrowserForContentWindow(DOMWindow.opener);
                         torbutton_eclog(3, 'Got browser for request: ' + (browser != null));
 
+                        // XXX: This may block ssl popups in the first tab
                         if(browser && browser.__tb_tor_fetched != m_tb_prefs.getBoolPref("extensions.torbutton.tor_enabled")) {
                             try {
                                 torbutton_eclog(3, 'Stopping document: '+DOMWindow.location);

Modified: torbutton/trunk/src/chrome/locale/en-US/torbutton.dtd
===================================================================
--- torbutton/trunk/src/chrome/locale/en-US/torbutton.dtd	2008-05-17 13:44:17 UTC (rev 14655)
+++ torbutton/trunk/src/chrome/locale/en-US/torbutton.dtd	2008-05-18 00:04:50 UTC (rev 14656)
@@ -74,4 +74,4 @@
 <!ENTITY torbutton.prefs.block_file_net     "Block access to network from file:// urls (recommended)">
 <!ENTITY torbutton.prefs.block_links        "Block link clicks and page reloads from different Tor states (optional)">
 <!ENTITY torbutton.prefs.jar_certs        "Store SSL certs in seperate jars for Tor/Non-Tor (recommended)">
-<!ENTITY torbutton.prefs.jar_ca_certs        "Store CA certs in seperate jars for Tor/Non-Tor (recommended, slow)">
+<!ENTITY torbutton.prefs.jar_ca_certs        "Store CA certs in seperate jars for Tor/Non-Tor (recommended)">

Added: torbutton/trunk/src/components/certDialogsOverride.js
===================================================================
--- torbutton/trunk/src/components/certDialogsOverride.js	                        (rev 0)
+++ torbutton/trunk/src/components/certDialogsOverride.js	2008-05-18 00:04:50 UTC (rev 14656)
@@ -0,0 +1,166 @@
+/*************************************************************************
+ * Hack to disable CA cert trust dialog popup during CA cert import
+ * during Tor toggle (since we save the trust bits to disk).
+ *
+ *************************************************************************/
+
+// Module specific constants
+const kMODULE_NAME = "CA Cert Dialogs";
+const kMODULE_CONTRACTID = "@mozilla.org/nsCertificateDialogs;1";
+const kMODULE_CID = Components.ID("6AB9E86E-2459-11DD-AEBC-679A55D89593");
+
+/* Mozilla defined interfaces for FF3.0 and 2.0 */
+const kREAL_CERTDIALOG_CID = "{518e071f-1dd2-11b2-937e-c45f14def778}";
+
+const kCertDialogsInterfaces2 = [ "nsIBadCertListener", "nsIClientAuthDialogs", 
+                             "nsIDOMCryptoDialogs", 
+                             "nsICertificateDialogs", "nsITokenPasswordDialogs",
+                             "nsITokenDialogs", "nsICertPickDialogs",
+                             "nsIGeneratingKeypairInfoDialogs"];
+
+const kCertDialogsInterfaces3 = 
+                             [ "nsIClientAuthDialogs", "nsIDOMCryptoDialogs", 
+                             "nsICertificateDialogs", "nsITokenPasswordDialogs",
+                             "nsITokenDialogs", "nsICertPickDialogs",
+                             "nsIGeneratingKeypairInfoDialogs"];
+
+const Cr = Components.results;
+
+function CertDialogsWrapper() {
+  // assuming we're running under Firefox
+  var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
+      .getService(Components.interfaces.nsIXULAppInfo);
+  var versionChecker = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
+      .getService(Components.interfaces.nsIVersionComparator);
+
+  this._real_certdlg = Components.classesByID[kREAL_CERTDIALOG_CID];
+  if(versionChecker.compare(appInfo.version, "3.0a1") >= 0) {
+    this._interfaces = kCertDialogsInterfaces3;
+  } else {
+    this._interfaces = kCertDialogsInterfaces2;
+  }
+ 
+  this._prefs = Components.classes["@mozilla.org/preferences-service;1"]
+      .getService(Components.interfaces.nsIPrefBranch);
+  this.logger = Components.classes["@torproject.org/torbutton-logger;1"]
+      .getService(Components.interfaces.nsISupports).wrappedJSObject;
+
+  this._certdlg = function() {
+    var certdlg = this._real_certdlg.getService();
+    for (var i = 0; i < this._interfaces.length; i++) {
+      certdlg.QueryInterface(Components.interfaces[this._interfaces[i]]);
+    }
+    return certdlg;
+  };
+
+  this.copyMethods(this._certdlg());
+}
+
+CertDialogsWrapper.prototype =
+{
+  QueryInterface: function(iid) {
+    if (/*iid.equals(Components.interfaces.nsIClassInfo)
+        || */iid.equals(Components.interfaces.nsISupports)) {
+      return this;
+    }
+
+    var certdlg = this._certdlg().QueryInterface(iid);
+    this.copyMethods(certdlg);
+    return this;
+  },
+
+  /* 
+   * Copies methods from the true history object we are wrapping
+   */
+  copyMethods: function(wrapped) {
+    var mimic = function(newObj, method) {
+      if(typeof(wrapped[method]) == "function") {
+          // Code courtesy of timeless: 
+          // http://www.webwizardry.net/~timeless/windowStubs.js
+          var params = [];
+          params.length = wrapped[method].length;
+          var x = 0;
+          var call;
+          if(params.length) call = "("+params.join().replace(/(?:)/g,function(){return "p"+(++x)})+")";
+          else call = "()";
+          var fun = "function "+call+"{if (arguments.length < "+wrapped[method].length+") throw Components.results.NS_ERROR_XPC_NOT_ENOUGH_ARGS; return wrapped."+method+".apply(wrapped, arguments);}";
+          // already in scope
+          //var Components = this.Components;
+          newObj[method] = eval(fun);
+          //dump("wrapped: "+method+": "+fun+"\n");
+      } else {
+          newObj.__defineGetter__(method, function() { return wrapped[method]; });
+          newObj.__defineSetter__(method, function(val) { wrapped[method] = val; });
+      }
+    };
+    for (var method in wrapped) {
+      if(typeof(this[method]) == "undefined") mimic(this, method);
+    }
+  },
+
+  confirmDownloadCACert: function(ctx, cert, trust) { 
+    if(this._prefs.getBoolPref("extensions.torbutton.block_cert_dialogs")) {
+      this.logger.log(3, "Blocking cert window");
+      return true;
+    }
+    return this._certdlg().confirmDownloadCACert(ctx, cert, trust);
+  }
+
+};
+ 
+var CertDialogsWrapperSingleton = null;
+var CertDialogsWrapperFactory = new Object();
+
+CertDialogsWrapperFactory.createInstance = function (outer, iid)
+{
+  if (outer != null) {
+    Components.returnCode = Cr.NS_ERROR_NO_AGGREGATION;
+    return null;
+  }
+
+  if(!CertDialogsWrapperSingleton)
+    CertDialogsWrapperSingleton = new CertDialogsWrapper();
+
+  return CertDialogsWrapperSingleton;
+};
+
+
+/**
+ * JS XPCOM component registration goop:
+ *
+ * Everything below is boring boilerplate and can probably be ignored.
+ */
+
+var CertDialogsWrapperModule = new Object();
+
+CertDialogsWrapperModule.registerSelf = 
+function (compMgr, fileSpec, location, type) {
+  var nsIComponentRegistrar = Components.interfaces.nsIComponentRegistrar;
+  compMgr = compMgr.QueryInterface(nsIComponentRegistrar);
+  compMgr.registerFactoryLocation(kMODULE_CID,
+                                  kMODULE_NAME,
+                                  kMODULE_CONTRACTID,
+                                  fileSpec, 
+                                  location, 
+                                  type);
+};
+
+CertDialogsWrapperModule.getClassObject = function (compMgr, cid, iid)
+{
+  if (cid.equals(kMODULE_CID))
+    return CertDialogsWrapperFactory;
+
+  Components.returnCode = Cr.NS_ERROR_NOT_REGISTERED;
+  return null;
+};
+
+CertDialogsWrapperModule.canUnload = function (compMgr)
+{
+  return true;
+};
+
+function NSGetModule(compMgr, fileSpec)
+{
+  return CertDialogsWrapperModule;
+}
+

Modified: torbutton/trunk/src/defaults/preferences/preferences.js
===================================================================
--- torbutton/trunk/src/defaults/preferences/preferences.js	2008-05-17 13:44:17 UTC (rev 14655)
+++ torbutton/trunk/src/defaults/preferences/preferences.js	2008-05-18 00:04:50 UTC (rev 14656)
@@ -88,6 +88,7 @@
 pref("extensions.torbutton.useragent_vendorSub","");
 pref("extensions.torbutton.banned_ports","8118,8123,9050,9051");
 pref("extensions.torbutton.block_file_net",true);
-pref("extensions.torbutton.jar_certs",true);
-pref("extensions.torbutton.jar_ca_certs",true);
+pref("extensions.torbutton.jar_certs",false);
+pref("extensions.torbutton.jar_ca_certs",false);
 pref("extensions.torbutton.asked_ca_disable",false);
+pref("extensions.torbutton.block_cert_dialogs",false);



More information about the tor-commits mailing list