commit 9fe9cdfe816ed030e615643e35b9e0dcaa5a8635 Author: Yan Zhu yan@mit.edu 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]);