Ticket #3455: 0001-Bug-3455.3-Add-DomainIsolator-for-isolating-circuit-.patch

File 0001-Bug-3455.3-Add-DomainIsolator-for-isolating-circuit-.patch, 7.2 KB (added by arthuredelstein, 5 years ago)
  • src/chrome.manifest

    From 3d07bbe39dc4465787521b38a03cb7097388d33b Mon Sep 17 00:00:00 2001
    From: Arthur Edelstein <arthuredelstein@gmail.com>
    Date: Mon, 14 Jul 2014 00:40:13 -0700
    Subject: [PATCH] Bug #3455.3: Add DomainIsolator, for isolating circuit by
     domain.
    
    An XPCOM component that registers a ProtocolProxyChannelFilter
    which sets the username/password for each web request according to
    url bar domain.
    ---
     src/chrome.manifest               |   5 +-
     src/components/domain-isolator.js | 128 ++++++++++++++++++++++++++++++++++++++
     2 files changed, 132 insertions(+), 1 deletion(-)
     create mode 100644 src/components/domain-isolator.js
    
    diff --git a/src/chrome.manifest b/src/chrome.manifest
    index af44862..d211984 100644
    a b contract @torproject.org/torbutton-torCheckService;1 {5d57312b-5d8c-4169-b4af-e8 
    155155component {f36d72c9-9718-4134-b550-e109638331d7} components/torbutton-logger.js
    156156contract @torproject.org/torbutton-logger;1 {f36d72c9-9718-4134-b550-e109638331d7}
    157157
     158component {e33fd6d4-270f-475f-a96f-ff3140279f68} components/domain-isolator.js
     159contract @torproject.org/domain-isolator;1 {e33fd6d4-270f-475f-a96f-ff3140279f68}
     160
    158161category profile-after-change CookieJarSelector @torproject.org/cookie-jar-selector;1
    159 # category profile-after-change RefSpoofer @torproject.org/torRefSpoofer;1
    160162category profile-after-change TBSessionBlocker @torproject.org/torbutton-ss-blocker;1
    161163category profile-after-change StartupObserver @torproject.org/startup-observer;1
     164category profile-after-change DomainIsolator @torproject.org/domain-isolator;1
     165 No newline at end of file
  • new file src/components/domain-isolator.js

    diff --git a/src/components/domain-isolator.js b/src/components/domain-isolator.js
    new file mode 100644
    index 0000000..e8e6bfa
    - +  
     1// # domain-isolator.js
     2// A component for TorBrowser that puts requests from different
     3// first party domains on separate tor circuits.
     4
     5// This file is written in call stack order (later functions
     6// call earlier functions). The code file can be processed
     7// with docco.js to provide clear documentation.
     8
     9/* jshint moz: true */
     10/* global Components, console, XPCOMUtils */
     11
     12// ### Abbreviations
     13const Cc = Components.classes, Ci = Components.interfaces, Cu = Components.utils;
     14
     15// Make the logger available.
     16let logger = Cc["@torproject.org/torbutton-logger;1"]
     17               .getService(Components.interfaces.nsISupports).wrappedJSObject;
     18
     19// ## mozilla namespace.
     20// Useful functionality for interacting with Mozilla services.
     21let mozilla = mozilla || {};
     22
     23// __mozilla.protocolProxyService__.
     24// Mozilla's protocol proxy service, useful for managing proxy connections made
     25// by the browser.
     26mozilla.protocolProxyService = Cc["@mozilla.org/network/protocol-proxy-service;1"]
     27                                 .getService(Ci.nsIProtocolProxyService);
     28
     29// __mozilla.thirdPartyUtil__.
     30// Mozilla's Thirdy Party Utilities, for figuring out first party domain.
     31mozilla.thirdPartyUtil = Cc["@mozilla.org/thirdpartyutil;1"]
     32                           .getService(Ci.mozIThirdPartyUtil);
     33                           
     34// __mozilla.registerProxyChannelFilter(filterFunction, positionIndex)__.
     35// Registers a proxy channel filter with the Mozilla Protocol Proxy Service,
     36// which will help to decide the proxy to be used for a given channel.
     37// The filterFunction should expect two arguments, (aChannel, aProxy),
     38// where aProxy is the proxy or list of proxies that would be used by default
     39// for the given channel, and should return a new Proxy or list of Proxies.
     40mozilla.registerProxyChannelFilter = function (filterFunction, positionIndex) {
     41  let proxyFilter = {
     42    applyFilter : function (aProxyService, aChannel, aProxy) {
     43      return filterFunction(aChannel, aProxy);
     44    }
     45  };
     46  mozilla.protocolProxyService.registerChannelFilter(proxyFilter, positionIndex);
     47};
     48
     49// ## tor functionality.
     50let tor = tor || {};
     51
     52// __tor.noncesForDomains__.
     53// A mutable map that records what nonce we are using for each domain.
     54tor.noncesForDomains = {};
     55
     56// __tor.socksProxyCredentials(originalProxy, domain)__.
     57// Takes a proxyInfo object (originalProxy) and returns a new proxyInfo
     58// object with the same properties, except the username is set to the
     59// the domain, and the password is a nonce.
     60tor.socksProxyCredentials = function (originalProxy, domain) {
     61  // Check if we already have a nonce. If not, create
     62  // one for this domain.
     63  if (!tor.noncesForDomains.hasOwnProperty(domain)) {
     64    tor.noncesForDomains[domain] = 0;
     65  }
     66  let proxy = originalProxy.QueryInterface(Ci.nsIProxyInfo);
     67  return mozilla.protocolProxyService
     68           .newSOCKSProxyInfo(proxy.host,
     69                              proxy.port,
     70                              domain, // username
     71                              tor.noncesForDomains[domain].toString(), // password
     72                              proxy.flags,
     73                              proxy.failoverTimeout,
     74                              proxy.failoverProxy);
     75};
     76
     77// __tor.isolateCircuitsByDomain()__.
     78// For every HTTPChannel, replaces the default SOCKS proxy with one that authenticates
     79// to the SOCKS server (the tor client process) with a username (the first party domain)
     80// and a nonce password. Tor provides a separate circuit for each username+password
     81// combination.
     82tor.isolateCircuitsByDomain = function () {
     83  mozilla.registerProxyChannelFilter(function (aChannel, aProxy) {
     84    try {
     85      let channel = aChannel.QueryInterface(Ci.nsIHttpChannel),
     86          firstPartyURI = mozilla.thirdPartyUtil.getFirstPartyURIFromChannel(channel, true)
     87                            .QueryInterface(Ci.nsIURI),
     88          firstPartyDomain = mozilla.thirdPartyUtil
     89                               .getFirstPartyHostForIsolation(firstPartyURI),
     90          proxy = aProxy.QueryInterface(Ci.nsIProxyInfo),
     91          replacementProxy = tor.socksProxyCredentials(aProxy, firstPartyDomain);
     92      logger.eclog(3, "tor SOCKS: " + channel.URI.spec + " via " +
     93                      replacementProxy.username + ":" + replacementProxy.password);
     94      return replacementProxy;
     95    } catch (err) {
     96      // If we fail, then just use the default proxyInfo.
     97      return aProxy;
     98    }
     99  }, 0);
     100};
     101
     102// ## XPCOM component construction.
     103// Module specific constants
     104const kMODULE_NAME = "TorBrowser Domain Isolator";
     105const kMODULE_CONTRACTID = "@torproject.org/domain-isolator;1";
     106const kMODULE_CID = Components.ID("e33fd6d4-270f-475f-a96f-ff3140279f68");
     107
     108// Import XPCOMUtils object.
     109Cu.import("resource://gre/modules/XPCOMUtils.jsm");
     110
     111// DomainIsolator object. Constructor does nothing.
     112function DomainIsolator() { }
     113// Firefox component requirements
     114DomainIsolator.prototype = {
     115  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]),
     116  classDescription: kMODULE_NAME,
     117  classID: kMODULE_CID,
     118  contractID: kMODULE_CONTRACTID,
     119  observe: function (subject, topic, data) {
     120    if (topic === "profile-after-change") {
     121      logger.eclog(3, "domain isolator: set up isolating circuits by domain");
     122      tor.isolateCircuitsByDomain();
     123    }
     124  }
     125};
     126
     127// Assign factory to global object.
     128const NSGetFactory = XPCOMUtils.generateNSGetFactory([DomainIsolator]);