[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [torbutton/maint-1.9.3] Revert "remove obsolete files, re Bug 1506 P0"



commit 9f37464b6f446feec96147b32b3e2f2537f93636
Author: Yan Zhu <yan@xxxxxxx>
Date:   Tue Jul 29 17:08:36 2014 -0700

    Revert "remove obsolete files, re Bug 1506 P0"
    
    This reverts commit 80b06cdf422238f5eece38a1974d31e6e7be7a17.
---
 src/chrome.manifest             |   12 +++
 src/components/tor-protocol.js  |  103 ++++++++++++++++++++++
 src/components/torRefSpoofer.js |  125 +++++++++++++++++++++++++++
 src/components/tors-protocol.js |  103 ++++++++++++++++++++++
 src/components/window-mapper.js |  180 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 523 insertions(+)

diff --git a/src/chrome.manifest b/src/chrome.manifest
index 8323e66..ddf582e 100644
--- a/src/chrome.manifest
+++ b/src/chrome.manifest
@@ -159,6 +159,18 @@ contract @torproject.org/torbutton-logger;1 {f36d72c9-9718-4134-b550-e109638331d
 component {e33fd6d4-270f-475f-a96f-ff3140279f68} components/domain-isolator.js
 contract @torproject.org/domain-isolator;1 {e33fd6d4-270f-475f-a96f-ff3140279f68}
 
+# component {b985e49c-12cb-4f29-9d14-b62603332ec4} components/window-mapper.js
+# contract @torproject.org/content-window-mapper;1 {b985e49c-12cb-4f29-9d14-b62603332ec4}
+
+# component {65be2be0-ceb4-44c2-91a5-9c75c53430bf} components/torRefSpoofer.js
+# contract @torproject.org/torRefSpoofer;1 {65be2be0-ceb4-44c2-91a5-9c75c53430bf}
+
+# component {52183e20-4d4b-11de-8a39-0800200c9a66} components/tor-protocol.js
+# contract @mozilla.org/network/protocol;1?name=tor {52183e20-4d4b-11de-8a39-0800200c9a66}
+
+# component {a5a4bc50-5e8d-11de-8a39-0800200c9a66} components/tors-protocol.js
+# contract @mozilla.org/network/protocol;1?name=tors {a5a4bc50-5e8d-11de-8a39-0800200c9a66}
+
 category profile-after-change CookieJarSelector @torproject.org/cookie-jar-selector;1
 category profile-after-change StartupObserver @torproject.org/startup-observer;1
 category profile-after-change DomainIsolator @torproject.org/domain-isolator;1
diff --git a/src/components/tor-protocol.js b/src/components/tor-protocol.js
new file mode 100644
index 0000000..4ba5cf4
--- /dev/null
+++ b/src/components/tor-protocol.js
@@ -0,0 +1,103 @@
+// Bug 1506 P0: This code is toggle-mode code and is unused. Kill it.
+
+// Test protocol related
+const kSCHEME = "tor";
+const kPROTOCOL_NAME = "tor";
+const kPROTOCOL_CONTRACTID = "@mozilla.org/network/protocol;1?name=" + kSCHEME;
+const kPROTOCOL_CID = Components.ID("52183e20-4d4b-11de-8a39-0800200c9a66");
+
+// Mozilla defined
+const kSIMPLEURI_CONTRACTID = "@mozilla.org/network/simple-uri;1";
+const kIOSERVICE_CONTRACTID = "@mozilla.org/network/io-service;1";
+const nsISupports = Components.interfaces.nsISupports;
+const nsIIOService = Components.interfaces.nsIIOService;
+const nsIProtocolHandler = Components.interfaces.nsIProtocolHandler;
+const nsIURI = Components.interfaces.nsIURI;
+
+function Protocol()
+{
+}
+
+Protocol.prototype =
+{
+  QueryInterface: function(iid)
+  {
+    if (!iid.equals(nsIProtocolHandler) &&
+        !iid.equals(nsISupports))
+      throw Components.results.NS_ERROR_NO_INTERFACE;
+    return this;
+  },
+
+  scheme: kSCHEME,
+  defaultPort: -1,
+  protocolFlags: nsIProtocolHandler.URI_NORELATIVE |
+                 nsIProtocolHandler.URI_NOAUTH,
+  
+  allowPort: function(port, scheme)
+  {
+    return false;
+  },
+
+  newURI: function(spec, charset, baseURI)
+  {
+    const nsIStandardURL = Components.interfaces.nsIStandardURL;
+    var uri = Components.classes["@mozilla.org/network/standard-url;1"].createInstance(nsIStandardURL);
+    uri.init(nsIStandardURL.URLTYPE_STANDARD, 80, spec, charset, baseURI);
+
+    return uri.QueryInterface(Components.interfaces.nsIURI);
+
+  },
+
+  newChannel: function(aURI)
+  {
+    var prefs = Components.classes["@mozilla.org/preferences-service;1"]
+        .getService(Components.interfaces.nsIPrefBranch);
+    if (!prefs.getBoolPref("extensions.torbutton.tor_urls")) {
+      throw Components.results.NS_ERROR_UNKNOWN_PROTOCOL;
+    }
+
+    /*The protocol has been called, therefore we want to enable tor, wait for it to activate return the new channel with the scheme of http.*/
+    var ios = Components.classes[kIOSERVICE_CONTRACTID].getService(nsIIOService);
+    var prompt = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+                        .getService(Components.interfaces.nsIPromptService);
+    var tor_enabled = prefs.getBoolPref("extensions.torbutton.tor_enabled");
+    var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+                         .getService(Components.interfaces.nsIWindowMediator);
+    var chrome = wm.getMostRecentWindow("navigator:browser");
+    if (!ios.allowPort(aURI.port, aURI.scheme))
+      throw Components.results.NS_ERROR_FAILURE;
+    
+    if (!tor_enabled)
+    {
+      var result = prompt.confirm(null, "Allow Tor toggle?", "Do you want to enable Tor and navigate to " + aURI.spec + "?");   
+      if (!result)
+        throw Components.results.NS_ERROR_UNEXPECTED;        
+      chrome.torbutton_enable_tor(true);    
+    } 
+    
+    //if tor is turned on then, else we should throw exception of some sort.
+    tor_enabled = prefs.getBoolPref("extensions.torbutton.tor_enabled");
+    if (!tor_enabled)
+        throw Components.results.NS_ERROR_UNEXPECTED;
+    else
+    {
+        aURI.scheme = "http";    
+        return ios.newChannelFromURI(aURI);
+    }      
+  },
+
+  // method of nsIClassInfo
+  classDescription: "Tor protocol handler",
+  classID: kPROTOCOL_CID,
+  contractID: kPROTOCOL_CONTRACTID,
+}
+
+/**
+* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
+* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6).
+*/
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+if (XPCOMUtils.generateNSGetFactory)
+    var NSGetFactory = XPCOMUtils.generateNSGetFactory([Protocol]);
+else
+    var NSGetModule = XPCOMUtils.generateNSGetModule([Protocol]);
diff --git a/src/components/torRefSpoofer.js b/src/components/torRefSpoofer.js
new file mode 100644
index 0000000..8b50075
--- /dev/null
+++ b/src/components/torRefSpoofer.js
@@ -0,0 +1,125 @@
+// Bug 1506 P0: I don't really believe referers matter in the grand scheme.
+// Kill this code.
+
+const kMODULE_CID = Components.ID("65be2be0-ceb4-44c2-91a5-9c75c53430bf");
+const kMODULE_CONTRACTID = "@torproject.org/torRefSpoofer;1";
+
+function RefSpoofer() {
+ this.logger = Components.classes["@torproject.org/torbutton-logger;1"].getService(Components.interfaces.nsISupports).wrappedJSObject;
+ this.logger.log(3, "RefSpoof component created");
+ this.specials = /[-[\]{}()*+?.,\\^$|#\s]/g;
+}
+
+
+RefSpoofer.prototype = {    
+  observe: function(subject, topic, data)
+  {
+    if (topic == "http-on-modify-request") {
+      var prefs = Components.classes["@mozilla.org/preferences-service;1"]
+      .getService(Components.interfaces.nsIPrefBranch);    
+      var tor_enabled = prefs.getBoolPref("extensions.torbutton.tor_enabled");
+      
+      if (!tor_enabled)
+        return;
+        
+      subject.QueryInterface(Components.interfaces.nsIHttpChannel);
+      this.onModifyRequest(subject);
+      return;
+    }
+    if (topic == "profile-after-change") {
+      this.logger.log(3, "RefSpoof got profile-after-change");
+      var os = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
+      os.addObserver(this, "http-on-modify-request", false);
+      return;
+    }
+  },
+  onModifyRequest: function(oHttpChannel)
+  {
+    var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
+    
+    var spoofmode = prefs.getIntPref("extensions.torbutton.refererspoof");
+    
+    var ios = Components.classes["@mozilla.org/network/io-service;1"]
+                    .getService(Components.interfaces.nsIIOService);
+
+    if (spoofmode == 0)
+    try {
+      oHttpChannel.QueryInterface(Components.interfaces.nsIChannel);
+      var referer;
+      try{
+        referer = oHttpChannel.getRequestHeader("Referer");
+        referer = ios.newURI(referer,null,null);//make a nsIURI object for referer
+      }catch(referr) {
+        return;//no referer available or invalid uri
+      }
+      var requestURI = oHttpChannel.URI; //request nsIURI object
+      var destHost = referer.host; //referer host w/o scheme
+      var srcHost = oHttpChannel.URI.host;//request host without scheme
+
+      // match is not what we want, unless we escape dots:
+      var destHostMatch = destHost.replace(this.specials, "\\$&");
+      var srcHostMatch = srcHost.replace(this.specials, "\\$&");
+
+      // FIXME: This isn't exactly bulletproof security here, but it still
+      // may need to be more lenient not to break sites...
+      //
+      // If we suspect issues, we can try doing the following first:
+      // 1. Strip off all TLD suffixes, up to but not including '.'
+      // 2. If more than one domain part is till left, strip off prefix
+
+      //if they're in the same domain(if we can tell) or have the same host, keep the referer
+      if (srcHost.split(".").length >= destHost.split(".").length
+          && srcHost.match(destHostMatch)) // dest is a substring of src
+        return;
+      else if (destHost.split(".").length >= srcHost.split(".").length
+          && destHost.match(srcHostMatch)) // src is a substring of dest
+        return;
+      //if they do not have the same host
+      this.adjustRef(oHttpChannel, requestURI.scheme + "://" + requestURI.host);      
+      this.logger.safe_log(3, "Adjusting Referer, ",
+                          "from " + destHost + " to " + requestURI.host);
+    }
+     catch (ex) {
+      this.logger.log(5, "RefSpoof onModifyRequest: " +ex);
+    }
+    else if (spoofmode == 2)
+      this.adjustRef(oHttpChannel, "");
+  },
+  adjustRef: function(oChannel, sRef)
+  {
+    try {
+      if (oChannel.referrer)
+      {
+        oChannel.referrer.spec = sRef;
+        oChannel.setRequestHeader("Referer", sRef, false);
+      }
+      return true;
+    } 
+    catch (ex) {
+      this.logger.log(5, "RefSpoof adjustRef: " +ex);
+    }
+    return false;
+  },
+  QueryInterface: function(iid)
+  {
+    if (!iid.equals(Components.interfaces.nsISupports) &&
+      !iid.equals(Components.interfaces.nsIObserver) &&
+      !iid.equals(Components.interfaces.nsISupportsWeakReference))
+      throw Components.results.NS_ERROR_NO_INTERFACE;    
+    return this;
+  },
+  _xpcom_categories: [{category:"profile-after-change"}],
+  classID: kMODULE_CID,
+  contractID: kMODULE_CONTRACTID,
+  classDescription: "Tor Ref Spoofer"
+};
+
+/**
+* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
+* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6).
+*/
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+if (XPCOMUtils.generateNSGetFactory)
+    var NSGetFactory = XPCOMUtils.generateNSGetFactory([RefSpoofer]);
+else
+    var NSGetModule = XPCOMUtils.generateNSGetModule([RefSpoofer]);
diff --git a/src/components/tors-protocol.js b/src/components/tors-protocol.js
new file mode 100644
index 0000000..f075e43
--- /dev/null
+++ b/src/components/tors-protocol.js
@@ -0,0 +1,103 @@
+// Bug 1506 P0: This code is toggle-mode code and is unused. Kill it.
+
+// Test protocol related
+const kSCHEME = "tors";
+const kPROTOCOL_NAME = "tors";
+const kPROTOCOL_CONTRACTID = "@mozilla.org/network/protocol;1?name=" + kSCHEME;
+const kPROTOCOL_CID = Components.ID("a5a4bc50-5e8d-11de-8a39-0800200c9a66");
+
+// Mozilla defined
+const kSIMPLEURI_CONTRACTID = "@mozilla.org/network/simple-uri;1";
+const kIOSERVICE_CONTRACTID = "@mozilla.org/network/io-service;1";
+const nsISupports = Components.interfaces.nsISupports;
+const nsIIOService = Components.interfaces.nsIIOService;
+const nsIProtocolHandler = Components.interfaces.nsIProtocolHandler;
+const nsIURI = Components.interfaces.nsIURI;
+
+function Protocol()
+{
+}
+
+Protocol.prototype =
+{
+  QueryInterface: function(iid)
+  {
+    if (!iid.equals(nsIProtocolHandler) &&
+        !iid.equals(nsISupports))
+      throw Components.results.NS_ERROR_NO_INTERFACE;
+    return this;
+  },
+
+  scheme: kSCHEME,
+  defaultPort: -1,
+  protocolFlags: nsIProtocolHandler.URI_NORELATIVE |
+                 nsIProtocolHandler.URI_NOAUTH,
+  
+  allowPort: function(port, scheme)
+  {
+    return false;
+  },
+
+  newURI: function(spec, charset, baseURI)
+  {
+    const nsIStandardURL = Components.interfaces.nsIStandardURL;
+    var uri = Components.classes["@mozilla.org/network/standard-url;1"].createInstance(nsIStandardURL);
+    uri.init(nsIStandardURL.URLTYPE_STANDARD, 433, spec, charset, baseURI);
+
+    return uri.QueryInterface(Components.interfaces.nsIURI);
+
+  },
+
+  newChannel: function(aURI)
+  {
+    var prefs = Components.classes["@mozilla.org/preferences-service;1"]
+        .getService(Components.interfaces.nsIPrefBranch);
+    if (!prefs.getBoolPref("extensions.torbutton.tor_urls")) {
+      throw Components.results.NS_ERROR_UNKNOWN_PROTOCOL;
+    }
+
+    /*The protocol has been called, therefore we want to enable tor, wait for it to activate return the new channel with the scheme of https.*/
+    var ios = Components.classes[kIOSERVICE_CONTRACTID].getService(nsIIOService);
+    var prompt = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+                        .getService(Components.interfaces.nsIPromptService);
+    var tor_enabled = prefs.getBoolPref("extensions.torbutton.tor_enabled");
+    var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+                         .getService(Components.interfaces.nsIWindowMediator);
+    var chrome = wm.getMostRecentWindow("navigator:browser");
+    if (!ios.allowPort(aURI.port, aURI.scheme))
+      throw Components.results.NS_ERROR_FAILURE;
+    
+    if (!tor_enabled)
+    {
+      var result = prompt.confirm(null, "Allow Tor toggle?", "Do you want to enable Tor and navigate to " + aURI.spec + "?");   
+      if (!result)
+        throw Components.results.NS_ERROR_UNEXPECTED;        
+      chrome.torbutton_enable_tor(true);    
+    } 
+    
+    //if tor is turned on then, else we should throw exception of some sort.
+    tor_enabled = prefs.getBoolPref("extensions.torbutton.tor_enabled");
+    if (!tor_enabled)
+        throw Components.results.NS_ERROR_UNEXPECTED;
+    else
+    {
+        aURI.scheme = "https";    
+        return ios.newChannelFromURI(aURI);
+    }      
+  },
+
+  // method of nsIClassInfo
+  classDescription: "Tor protocol handler",
+  classID: kPROTOCOL_CID,
+  contractID: kPROTOCOL_CONTRACTID
+}
+
+/**
+* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
+* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6).
+*/
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+if (XPCOMUtils.generateNSGetFactory)
+    var NSGetFactory = XPCOMUtils.generateNSGetFactory([Protocol]);
+else
+    var NSGetModule = XPCOMUtils.generateNSGetModule([Protocol]);
diff --git a/src/components/window-mapper.js b/src/components/window-mapper.js
new file mode 100644
index 0000000..a04f12b
--- /dev/null
+++ b/src/components/window-mapper.js
@@ -0,0 +1,180 @@
+// Bug 1506 P0: This code is toggle-mode code and is unused. Kill it.
+
+/*************************************************************************
+ * ContentWindowMapper (JavaScript XPCOM component)
+ *
+ * Allows you to find a tabbrowser tab for a top level content window.
+ *
+ *************************************************************************/
+
+// Module specific constants
+const kMODULE_NAME = "Content Window Mapper";
+const kMODULE_CONTRACTID = "@torproject.org/content-window-mapper;1";
+const kMODULE_CID = Components.ID("b985e49c-12cb-4f29-9d14-b62603332ec4");
+
+const Cr = Components.results;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const EXPIRATION_TIME = 60000; // 60 seconds
+
+const nsISupports = Components.interfaces.nsISupports;
+const nsIClassInfo = Components.interfaces.nsIClassInfo;
+const nsIComponentRegistrar = Components.interfaces.nsIComponentRegistrar;
+const nsIObserverService = Components.interfaces.nsIObserverService;
+
+function ContentWindowMapper() {
+    this.cache = {};
+
+    this.logger = Components.classes["@torproject.org/torbutton-logger;1"]
+        .getService(Components.interfaces.nsISupports).wrappedJSObject;
+    this.logger.log(3, "Component Load 2: Content window mapper online: "+kMODULE_CONTRACTID);
+    this.last_expired = Date.now();
+    // This JSObject is exported directly to chrome
+    this.wrappedJSObject = this;
+}
+
+ContentWindowMapper.prototype =
+{
+  QueryInterface: function(iid)
+  {
+    if (!iid.equals(nsIClassInfo) &&
+        !iid.equals(nsISupports)) {
+      Components.returnCode = Cr.NS_ERROR_NO_INTERFACE;
+      return null;
+    }
+    return this;
+  },
+
+  wrappedJSObject: null,  // Initialized by constructor
+
+  // make this an nsIClassInfo object
+  flags: nsIClassInfo.DOM_OBJECT,
+
+  // method of nsIClassInfo
+  classDescription: kMODULE_NAME,
+  classID: kMODULE_CID,
+  contractID: kMODULE_CONTRACTID,
+
+  // method of nsIClassInfo
+  getInterfaces: function(count) {
+    var interfaceList = [nsIClassInfo];
+    count.value = interfaceList.length;
+    return interfaceList;
+  },
+
+  // method of nsIClassInfo
+  getHelperForLanguage: function(count) { return null; },
+
+  checkCache: function(topContentWindow) {
+      if(typeof(topContentWindow.ghetto_guid) != "undefined"
+         && typeof(this.cache[topContentWindow.ghetto_guid]) != "undefined") {
+          return this.cache[topContentWindow.ghetto_guid].browser;
+      }
+
+      return null;
+  },
+
+  addCache: function(topContentWindow, browser) {
+      var insertion = new Object();
+      insertion.browser = browser;
+      insertion.time = Date.now();
+      topContentWindow.ghetto_guid = Math.random().toString()+Math.random().toString();
+      this.cache[topContentWindow.ghetto_guid] = insertion; 
+  },
+
+  expireOldCache: function() {
+      var now = Date.now();
+
+      if((now - this.last_expired) < EXPIRATION_TIME) {
+          this.logger.log(3, "Early mapper check.");
+          return;
+      }
+
+      var delkeys = [];
+      for(var elem in this.cache) {
+          if((now - this.cache[elem].time) > EXPIRATION_TIME) {
+              this.logger.log(2, "Deleting cached element: "+elem.location);
+              delkeys.push(elem);
+          }
+      }
+
+      for(var k in delkeys) {
+        delete this.cache[k];
+      }
+
+      this.last_expired = now;
+  },
+
+  getBrowserForContentWindow: function(topContentWindow) {
+      if(topContentWindow instanceof Components.interfaces.nsIDOMChromeWindow) {
+          if(topContentWindow.browserDOMWindow) {
+              var browser = topContentWindow.getBrowser().selectedTab.linkedBrowser;
+              this.logger.log(3, "Chrome browser at "
+                      +browser.contentWindow.location+" found for: "
+                      +topContentWindow.location);
+              return browser;
+          }
+          // Allow strange chrome to go through..
+          this.logger.log(3, "Odd chome window"+topContentWindow.location);
+          return topContentWindow;
+      }
+
+      var cached = this.checkCache(topContentWindow);
+      if(cached != null) {
+          return cached;
+      }
+
+      try {
+          this.logger.log(3, "Cache failed for: "+topContentWindow.location);
+      } catch(e) {
+          this.logger.log(3, "Cache failed for unknown location?");
+      }
+
+      var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+          .getService(Components.interfaces.nsIWindowMediator);
+      var enumerator = wm.getEnumerator("navigator:browser");
+      while(enumerator.hasMoreElements()) {
+          var win = enumerator.getNext();
+          var browser = win.getBrowser(); 
+          for (var i = 0; i < browser.browsers.length; ++i) {
+              var b = browser.browsers[i];
+              if (b && b.contentWindow == topContentWindow) {
+                  this.addCache(topContentWindow, b);
+                  return b;
+              }
+          }
+      }
+
+      // SpeedDial, google notebook and other extensions can create their 
+      // own "<browser>" tag elements. AFAICT, there is no way to enumerate
+      // these... Just punt and return the most recently used browser
+      try {
+          if(topContentWindow.name != "speedDialLoaderBrowser") {
+              if(topContentWindow && topContentWindow.location)
+                  this.logger.safe_log(4, "No browser found: ", topContentWindow.location);
+              else
+                  this.logger.safe_log(4, "No browser found: ", topContentWindow.name);
+          } else {
+              this.logger.log(3, "SpeedDial browser found: "+topContentWindow.name);
+          }
+      } catch(e) {
+          this.logger.log(4, "No browser found.");
+      }
+
+      // Punt..
+      var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].
+          getService(Components.interfaces.nsIWindowMediator);
+      var recentWindow = wm.getMostRecentWindow("navigator:browser");
+      return recentWindow ? recentWindow.getBrowser().selectedTab.linkedBrowser : null;
+  }
+}
+
+/**
+* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
+* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6).
+*/
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+if (XPCOMUtils.generateNSGetFactory)
+    var NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentWindowMapper]);
+else
+    var NSGetModule = XPCOMUtils.generateNSGetModule([ContentWindowMapper]);



_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits