Skip to content
Snippets Groups Projects
Verified Commit 9722ca26 authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame :jack_o_lantern:
Browse files

fixup! Bug 10760: Integrate TorButton to TorBrowser core

Removed torbutton.js, tor-control-port.js and utils.js.
parent 57b25177
Branches
Tags
1 merge request!709Bug 41926: Reimplement the control port
......@@ -130,17 +130,11 @@
Services.scriptloader.loadSubScript("chrome://browser/content/search/autocomplete-popup.js", this);
Services.scriptloader.loadSubScript("chrome://browser/content/search/searchbar.js", this);
Services.scriptloader.loadSubScript("chrome://browser/content/languageNotification.js", this);
Services.scriptloader.loadSubScript("chrome://torbutton/content/torbutton.js", this);
window.onload = gBrowserInit.onLoad.bind(gBrowserInit);
window.onunload = gBrowserInit.onUnload.bind(gBrowserInit);
window.onclose = WindowIsClosing;
//onLoad Handler
try {
window.addEventListener("load", torbutton_init);
} catch (e) {}
window.addEventListener("MozBeforeInitialXULLayout",
gBrowserInit.onBeforeInitialXULLayout.bind(gBrowserInit), { once: true });
......
// window globals
var torbutton_init;
(() => {
// Bug 1506 P1-P5: This is the main Torbutton overlay file. Much needs to be
// preserved here, but in an ideal world, most of this code should perhaps be
// moved into an XPCOM service, and much can also be tossed. See also
// individual 1506 comments for details.
// TODO: check for leaks: http://www.mozilla.org/scriptable/avoiding-leaks.html
// TODO: Double-check there are no strange exploits to defeat:
// http://kb.mozillazine.org/Links_to_local_pages_don%27t_work
/* global gBrowser, Services, AppConstants */
let { torbutton_log } = ChromeUtils.import(
"resource://torbutton/modules/utils.js"
);
let { configureControlPortModule } = ChromeUtils.import(
"resource://torbutton/modules/tor-control-port.js"
);
const { TorProtocolService } = ChromeUtils.import(
"resource://gre/modules/TorProtocolService.jsm"
);
var m_tb_prefs = Services.prefs;
// status
var m_tb_wasinited = false;
var m_tb_control_ipc_file = null; // Set if using IPC (UNIX domain socket).
var m_tb_control_port = null; // Set if using TCP.
var m_tb_control_host = null; // Set if using TCP.
var m_tb_control_pass = null;
// Bug 1506 P2-P4: This code sets some version variables that are irrelevant.
// It does read out some important environment variables, though. It is
// called once per browser window.. This might belong in a component.
torbutton_init = function () {
torbutton_log(3, "called init()");
if (m_tb_wasinited) {
return;
}
m_tb_wasinited = true;
// Bug 1506 P4: These vars are very important for New Identity
if (Services.env.exists("TOR_CONTROL_PASSWD")) {
m_tb_control_pass = Services.env.get("TOR_CONTROL_PASSWD");
} else if (Services.env.exists("TOR_CONTROL_COOKIE_AUTH_FILE")) {
var cookie_path = Services.env.get("TOR_CONTROL_COOKIE_AUTH_FILE");
try {
if ("" != cookie_path) {
m_tb_control_pass = torbutton_read_authentication_cookie(cookie_path);
}
} catch (e) {
torbutton_log(4, "unable to read authentication cookie");
}
} else {
try {
// Try to get password from Tor Launcher.
m_tb_control_pass = TorProtocolService.torGetPassword();
} catch (e) {}
}
// Try to get the control port IPC file (an nsIFile) from Tor Launcher,
// since Tor Launcher knows how to handle its own preferences and how to
// resolve relative paths.
try {
m_tb_control_ipc_file = TorProtocolService.torGetControlIPCFile();
} catch (e) {}
if (!m_tb_control_ipc_file) {
if (Services.env.exists("TOR_CONTROL_PORT")) {
m_tb_control_port = Services.env.get("TOR_CONTROL_PORT");
} else {
try {
const kTLControlPortPref = "extensions.torlauncher.control_port";
m_tb_control_port = m_tb_prefs.getIntPref(kTLControlPortPref);
} catch (e) {
// Since we want to disable some features when Tor Launcher is
// not installed (e.g., New Identity), we do not set a default
// port value here.
}
}
if (Services.env.exists("TOR_CONTROL_HOST")) {
m_tb_control_host = Services.env.get("TOR_CONTROL_HOST");
} else {
try {
const kTLControlHostPref = "extensions.torlauncher.control_host";
m_tb_control_host = m_tb_prefs.getCharPref(kTLControlHostPref);
} catch (e) {
m_tb_control_host = "127.0.0.1";
}
}
}
configureControlPortModule(
m_tb_control_ipc_file,
m_tb_control_host,
m_tb_control_port,
m_tb_control_pass
);
torbutton_log(3, "init completed");
};
// Bug 1506 P4: Control port interaction. Needed for New Identity.
function torbutton_read_authentication_cookie(path) {
var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(path);
var fileStream = Cc[
"@mozilla.org/network/file-input-stream;1"
].createInstance(Ci.nsIFileInputStream);
fileStream.init(file, 1, 0, false);
var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
Ci.nsIBinaryInputStream
);
binaryStream.setInputStream(fileStream);
var array = binaryStream.readByteArray(fileStream.available());
binaryStream.close();
fileStream.close();
return torbutton_array_to_hexdigits(array);
}
// Bug 1506 P4: Control port interaction. Needed for New Identity.
function torbutton_array_to_hexdigits(array) {
return array
.map(function (c) {
return String("0" + c.toString(16)).slice(-2);
})
.join("");
}
// ---------------------- Event handlers -----------------
// Bug 1506 P3: This is needed pretty much only for the window resizing.
// See comments for individual functions for details
function torbutton_new_window(event) {
torbutton_log(3, "New window");
if (!m_tb_wasinited) {
torbutton_init();
}
}
window.addEventListener("load", torbutton_new_window);
})();
Classes = [
{
"cid": "{f36d72c9-9718-4134-b550-e109638331d7}",
"contract_ids": [
"@torproject.org/torbutton-logger;1"
],
"jsm": "resource://torbutton/modules/TorbuttonLogger.jsm",
"constructor": "TorbuttonLogger",
},
]
#filter substitution
torbutton.jar:
% content torbutton %content/
content/torbutton.js (chrome/content/torbutton.js)
modules/ (modules/*)
% resource torbutton %
% category l10n-registry torbutton resource://torbutton/locale/{locale}/
# browser branding
% override chrome://branding/locale/brand.dtd chrome://torbutton/locale/brand.dtd
% override chrome://branding/locale/brand.properties chrome://torbutton/locale/brand.properties
% category l10n-registry torbutton resource://torbutton/locale/{locale}/
# Strings for the about:tbupdate page
% override chrome://browser/locale/aboutTBUpdate.dtd chrome://torbutton/locale/aboutTBUpdate.dtd
......
// Bug 1506 P1: This is just a handy logger. If you have a better one, toss
// this in the trash.
/*************************************************************************
* TBLogger (JavaScript XPCOM component)
*
* Allows loglevel-based logging to different logging mechanisms.
*
*************************************************************************/
var EXPORTED_SYMBOLS = ["TorbuttonLogger"];
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
function TorbuttonLogger() {
// Register observer
Services.prefs.addObserver("extensions.torbutton", this);
this.loglevel = Services.prefs.getIntPref("extensions.torbutton.loglevel", 4);
this.logmethod = Services.prefs.getIntPref(
"extensions.torbutton.logmethod",
1
);
try {
var logMngr = Cc["@mozmonkey.com/debuglogger/manager;1"].getService(
Ci.nsIDebugLoggerManager
);
this._debuglog = logMngr.registerLogger("torbutton");
} catch (exErr) {
this._debuglog = false;
}
this._console = Services.console;
// This JSObject is exported directly to chrome
this.wrappedJSObject = this;
this.log(3, "Torbutton debug output ready");
}
/**
* JS XPCOM component registration goop:
*
* Everything below is boring boilerplate and can probably be ignored.
*/
TorbuttonLogger.prototype = {
QueryInterface: ChromeUtils.generateQI([Ci.nsIClassInfo]),
wrappedJSObject: null, // Initialized by constructor
formatLog(str, level) {
const padInt = n => String(n).padStart(2, "0");
const logString = { 1: "VERB", 2: "DBUG", 3: "INFO", 4: "NOTE", 5: "WARN" };
const d = new Date();
const now =
padInt(d.getUTCMonth() + 1) +
"-" +
padInt(d.getUTCDate()) +
" " +
padInt(d.getUTCHours()) +
":" +
padInt(d.getUTCMinutes()) +
":" +
padInt(d.getUTCSeconds());
return `${now} Torbutton ${logString[level]}: ${str}`;
},
// error console log
eclog(level, str) {
switch (this.logmethod) {
case 0: // stderr
if (this.loglevel <= level) {
dump(this.formatLog(str, level) + "\n");
}
break;
default:
// errorconsole
if (this.loglevel <= level) {
this._console.logStringMessage(this.formatLog(str, level));
}
break;
}
},
safe_log(level, str, scrub) {
if (this.loglevel < 4) {
this.eclog(level, str + scrub);
} else {
this.eclog(level, str + " [scrubbed]");
}
},
log(level, str) {
switch (this.logmethod) {
case 2: // debuglogger
if (this._debuglog) {
this._debuglog.log(6 - level, this.formatLog(str, level));
break;
}
// fallthrough
case 0: // stderr
if (this.loglevel <= level) {
dump(this.formatLog(str, level) + "\n");
}
break;
case 1: // errorconsole
if (this.loglevel <= level) {
this._console.logStringMessage(this.formatLog(str, level));
}
break;
default:
dump("Bad log method: " + this.logmethod);
}
},
// Pref observer interface implementation
// topic: what event occurred
// subject: what nsIPrefBranch we're observing
// data: which pref has been changed (relative to subject)
observe(subject, topic, data) {
if (topic != "nsPref:changed") {
return;
}
switch (data) {
case "extensions.torbutton.logmethod":
this.logmethod = Services.prefs.getIntPref(
"extensions.torbutton.logmethod"
);
if (this.logmethod === 0) {
Services.prefs.setBoolPref("browser.dom.window.dump.enabled", true);
} else if (
Services.prefs.getIntPref("extensions.torlauncher.logmethod", 3) !== 0
) {
// If Tor Launcher is not available or its log method is not 0
// then let's reset the dump pref.
Services.prefs.setBoolPref("browser.dom.window.dump.enabled", false);
}
break;
case "extensions.torbutton.loglevel":
this.loglevel = Services.prefs.getIntPref(
"extensions.torbutton.loglevel"
);
break;
}
},
};
This diff is collapsed.
// # Utils.js
// Various helpful utility functions.
// ### Import Mozilla Services
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
// ## Pref utils
// __prefs__. A shortcut to Mozilla Services.prefs.
let prefs = Services.prefs;
// __getPrefValue(prefName)__
// Returns the current value of a preference, regardless of its type.
var getPrefValue = function (prefName) {
switch (prefs.getPrefType(prefName)) {
case prefs.PREF_BOOL:
return prefs.getBoolPref(prefName);
case prefs.PREF_INT:
return prefs.getIntPref(prefName);
case prefs.PREF_STRING:
return prefs.getCharPref(prefName);
default:
return null;
}
};
// __bindPref(prefName, prefHandler, init)__
// Applies prefHandler whenever the value of the pref changes.
// If init is true, applies prefHandler to the current value.
// Returns a zero-arg function that unbinds the pref.
var bindPref = function (prefName, prefHandler, init = false) {
let update = () => {
prefHandler(getPrefValue(prefName));
},
observer = {
observe(subject, topic, data) {
if (data === prefName) {
update();
}
},
};
prefs.addObserver(prefName, observer);
if (init) {
update();
}
return () => {
prefs.removeObserver(prefName, observer);
};
};
// __bindPrefAndInit(prefName, prefHandler)__
// Applies prefHandler to the current value of pref specified by prefName.
// Re-applies prefHandler whenever the value of the pref changes.
// Returns a zero-arg function that unbinds the pref.
var bindPrefAndInit = (prefName, prefHandler) =>
bindPref(prefName, prefHandler, true);
// ## Observers
// __observe(topic, callback)__.
// Observe the given topic. When notification of that topic
// occurs, calls callback(subject, data). Returns a zero-arg
// function that stops observing.
var observe = function (topic, callback) {
let observer = {
observe(aSubject, aTopic, aData) {
if (topic === aTopic) {
callback(aSubject, aData);
}
},
};
Services.obs.addObserver(observer, topic);
return () => Services.obs.removeObserver(observer, topic);
};
// ## Environment variables
// __getEnv(name)__.
// Reads the environment variable of the given name.
var getEnv = function (name) {
return Services.env.exists(name) ? Services.env.get(name) : undefined;
};
// __getLocale
// Returns the app locale to be used in tor-related urls.
var getLocale = function () {
const locale = Services.locale.appLocaleAsBCP47;
if (locale === "ja-JP-macos") {
// We don't want to distinguish the mac locale.
return "ja";
}
return locale;
};
// ## Windows
// __dialogsByName__.
// Map of window names to dialogs.
let dialogsByName = {};
// __showDialog(parent, url, name, features, arg1, arg2, ...)__.
// Like window.openDialog, but if the window is already
// open, just focuses it instead of opening a new one.
var showDialog = function (parent, url, name, features) {
let existingDialog = dialogsByName[name];
if (existingDialog && !existingDialog.closed) {
existingDialog.focus();
return existingDialog;
}
let newDialog = parent.openDialog.apply(parent, Array.slice(arguments, 1));
dialogsByName[name] = newDialog;
return newDialog;
};
// ## Tor control protocol utility functions
let _torControl = {
// Unescape Tor Control string aStr (removing surrounding "" and \ escapes).
// Based on Vidalia's src/common/stringutil.cpp:string_unescape().
// Returns the unescaped string. Throws upon failure.
// Within Tor Launcher, the file components/tl-protocol.js also contains a
// copy of _strUnescape().
_strUnescape(aStr) {
if (!aStr) {
return aStr;
}
var len = aStr.length;
if (len < 2 || '"' != aStr.charAt(0) || '"' != aStr.charAt(len - 1)) {
return aStr;
}
const kHexRE = /[0-9A-Fa-f]{2}/;
const kOctalRE = /[0-7]{3}/;
var rv = "";
var i = 1;
var lastCharIndex = len - 2;
while (i <= lastCharIndex) {
var c = aStr.charAt(i);
if ("\\" == c) {
if (++i > lastCharIndex) {
throw new Error("missing character after \\");
}
c = aStr.charAt(i);
if ("n" == c) {
rv += "\n";
} else if ("r" == c) {
rv += "\r";
} else if ("t" == c) {
rv += "\t";
} else if ("x" == c) {
if (i + 2 > lastCharIndex) {
throw new Error("not enough hex characters");
}
let s = aStr.substr(i + 1, 2);
if (!kHexRE.test(s)) {
throw new Error("invalid hex characters");
}
let val = parseInt(s, 16);
rv += String.fromCharCode(val);
i += 3;
} else if (this._isDigit(c)) {
let s = aStr.substr(i, 3);
if (i + 2 > lastCharIndex) {
throw new Error("not enough octal characters");
}
if (!kOctalRE.test(s)) {
throw new Error("invalid octal characters");
}
let val = parseInt(s, 8);
rv += String.fromCharCode(val);
i += 3;
} // "\\" and others
else {
rv += c;
++i;
}
} else if ('"' == c) {
throw new Error('unescaped " within string');
} else {
rv += c;
++i;
}
}
// Convert from UTF-8 to Unicode. TODO: is UTF-8 always used in protocol?
return decodeURIComponent(escape(rv));
}, // _strUnescape()
// Within Tor Launcher, the file components/tl-protocol.js also contains a
// copy of _isDigit().
_isDigit(aChar) {
const kRE = /^\d$/;
return aChar && kRE.test(aChar);
},
}; // _torControl
// __unescapeTorString(str, resultObj)__.
// Unescape Tor Control string str (removing surrounding "" and \ escapes).
// Returns the unescaped string. Throws upon failure.
var unescapeTorString = function (str) {
return _torControl._strUnescape(str);
};
var m_tb_torlog = Cc["@torproject.org/torbutton-logger;1"].getService(
Ci.nsISupports
).wrappedJSObject;
var m_tb_string_bundle = torbutton_get_stringbundle();
function torbutton_safelog(nLevel, sMsg, scrub) {
m_tb_torlog.safe_log(nLevel, sMsg, scrub);
return true;
}
function torbutton_log(nLevel, sMsg) {
m_tb_torlog.log(nLevel, sMsg);
// So we can use it in boolean expressions to determine where the
// short-circuit is..
return true;
}
// load localization strings
function torbutton_get_stringbundle() {
var o_stringbundle = false;
try {
var oBundle = Services.strings;
o_stringbundle = oBundle.createBundle(
"chrome://torbutton/locale/torbutton.properties"
);
} catch (err) {
o_stringbundle = false;
}
if (!o_stringbundle) {
torbutton_log(5, "ERROR (init): failed to find torbutton-bundle");
}
return o_stringbundle;
}
function torbutton_get_property_string(propertyname) {
try {
if (!m_tb_string_bundle) {
m_tb_string_bundle = torbutton_get_stringbundle();
}
return m_tb_string_bundle.GetStringFromName(propertyname);
} catch (e) {
torbutton_log(4, "Unlocalized string " + propertyname);
}
return propertyname;
}
// Export utility functions for external use.
let EXPORTED_SYMBOLS = [
"bindPref",
"bindPrefAndInit",
"getEnv",
"getLocale",
"getPrefValue",
"observe",
"showDialog",
"show_torbrowser_manual",
"unescapeTorString",
"torbutton_safelog",
"torbutton_log",
"torbutton_get_property_string",
];
......@@ -3,8 +3,4 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
JAR_MANIFESTS += ['jar.mn']
XPCOM_MANIFESTS += [
"components.conf",
]
JAR_MANIFESTS += ["jar.mn"]
......@@ -90,11 +90,7 @@ function getGlobalScriptIncludes(scriptPath) {
"browser/components/screenshots/content/"
)
.replace("chrome://browser/content/", "browser/base/content/")
.replace("chrome://global/content/", "toolkit/content/")
.replace(
"chrome://torbutton/content/",
"toolkit/torbutton/chrome/content/"
);
.replace("chrome://global/content/", "toolkit/content/");
for (let mapping of Object.getOwnPropertyNames(MAPPINGS)) {
if (sourceFile.includes(mapping)) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment