commit d99650b338f23d824cbd9d3cc91559ba607a465e
Author: Kathy Brade <brade(a)pearlcrescent.com>
Date: Tue Jan 10 12:03:41 2017 -0500
Bug 20951: Back out Unix domain socket related patches for Tor Browser 6.5
Revert the following commits, preserving the _strUnescape() fixes that
were made as part of Bug 20111:
8871259c966755233b134a5ddb2b4926539d25c6
Bug 14272: Make Tor Launcher work with Unix Domain Socket option
32ddac7015be571c336be686b4f901103d0d36f6
Fix typo
fa4e114a20067810af0c5cc6a57aa6e849386418
fixup! Bug 14272: Make Tor Launcher work with Unix Domain Socket option
8ca52414916c3d8bc2a2974017d759901ddc1736
Bug 20111: use Unix domain sockets for SOCKS port by default
4dd8f6130f931616cf014e0ded444c30e04c8bad
Bug 20185: Avoid using Unix domain socket paths that are too long
---
src/components/tl-process.js | 290 +++++++++++++++++++++-----
src/components/tl-protocol.js | 222 ++------------------
src/defaults/preferences/prefs.js | 25 +--
src/modules/tl-util.jsm | 415 +-------------------------------------
4 files changed, 254 insertions(+), 698 deletions(-)
diff --git a/src/components/tl-process.js b/src/components/tl-process.js
index 717c338..48be93d 100644
--- a/src/components/tl-process.js
+++ b/src/components/tl-process.js
@@ -16,6 +16,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "TorLauncherUtil",
"resource://torlauncher/modules/tl-util.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TorLauncherLogger",
"resource://torlauncher/modules/tl-logger.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
+ "resource://gre/modules/FileUtils.jsm");
function TorProcessService()
{
@@ -29,6 +31,8 @@ TorProcessService.prototype =
{
kContractID : "@torproject.org/torlauncher-process-service;1",
kServiceName : "Tor Launcher Process Service",
+ kThunderbirdID: "{3550f703-e582-4d05-9a08-453d09bdfdc6}",
+ kInstantbirdID: "{33cb9019-c295-46dd-be21-8c4936574bee}",
kClassID: Components.ID("{FE7B4CAF-BCF4-4848-8BFF-EFA66C9AFDA1}"),
kTorLauncherExtPath: "tor-launcher(a)torproject.org", // This could vary.
@@ -142,11 +146,7 @@ TorProcessService.prototype =
this.mObsSvc.notifyObservers(null, "TorProcessExited", null);
- if (this.mIsQuitting)
- {
- TorLauncherUtil.cleanupTempDirectories();
- }
- else
+ if (!this.mIsQuitting)
{
this.mProtocolSvc.TorCleanupConnection();
@@ -311,6 +311,11 @@ TorProcessService.prototype =
mProtocolSvc: null,
mTorProcess: null, // nsIProcess
mTorProcessStartTime: null, // JS Date.now()
+ // mIsUserDataOutsideOfAppDir is true when TorBrowser-Data is used.
+ // (cached; access via this._isUserDataOutsideOfAppDir)
+ mIsUserDataOutsideOfAppDir: undefined,
+ mAppDir: null, // nsIFile (cached; access via this._appDir)
+ mDataDir: null, // nsIFile (cached; access via this._dataDir)
mControlConnTimer: null,
mControlConnDelayMS: 0,
mQuitSoon: false, // Quit was requested by the user; do so soon.
@@ -332,15 +337,11 @@ TorProcessService.prototype =
// Get the Tor data directory first so it is created before we try to
// construct paths to files that will be inside it.
- var dataDir = TorLauncherUtil.getTorFile("tordatadir", true);
- var exeFile = TorLauncherUtil.getTorFile("tor", false);
- var torrcFile = TorLauncherUtil.getTorFile("torrc", true);
- var torrcDefaultsFile =
- TorLauncherUtil.getTorFile("torrc-defaults", false);
+ var dataDir = this._getTorFile("tordatadir", true);
+ var exeFile = this._getTorFile("tor", false);
+ var torrcFile = this._getTorFile("torrc", true);
+ var torrcDefaultsFile = this._getTorFile("torrc-defaults", false);
var hashedPassword = this.mProtocolSvc.TorGetPassword(true);
- var controlIPCFile = this.mProtocolSvc.TorGetControlIPCFile();
- var controlPort = this.mProtocolSvc.TorGetControlPort();
- var socksPortInfo = this.mProtocolSvc.TorGetSOCKSPortInfo();
var detailsKey;
if (!exeFile)
@@ -362,6 +363,7 @@ TorProcessService.prototype =
return;
}
+
// The geoip and geoip6 files are in the same directory as torrc-defaults.
var geoipFile = torrcDefaultsFile.clone();
geoipFile.leafName = "geoip";
@@ -386,40 +388,6 @@ TorProcessService.prototype =
args.push("HashedControlPassword");
args.push(hashedPassword);
- // Include a ControlPort argument to support switching between
- // a TCP port and an IPC port (e.g., a Unix domain socket).
- let controlPortArg;
- if (controlIPCFile)
- controlPortArg = this._ipcPortArg(controlIPCFile);
- else if (controlPort)
- controlPortArg = "" + controlPort;
- if (controlPortArg)
- {
- args.push("ControlPort");
- args.push(controlPortArg);
- }
-
- // Include a SocksPort argument to support switching between
- // a TCP port and an IPC port (e.g., a Unix domain socket).
- if (socksPortInfo)
- {
- let socksPortArg;
- if (socksPortInfo.ipcFile)
- socksPortArg = this._ipcPortArg(socksPortInfo.ipcFile)
- else if (socksPortInfo.host && (socksPortInfo.port != 0))
- socksPortArg = socksPortInfo.host + ':' + socksPortInfo.port;
-
- if (socksPortArg)
- {
- let socksPortFlags = TorLauncherUtil.getCharPref(
- "extensions.torlauncher.socks_port_flags");
- if (socksPortFlags)
- socksPortArg += ' ' + socksPortFlags;
- args.push("SocksPort");
- args.push(socksPortArg);
- }
- }
-
var pid = this._getpid();
if (0 != pid)
{
@@ -489,13 +457,6 @@ TorProcessService.prototype =
}
}, // _startTor()
- // Return a ControlPort or SocksPort argument for aIPCFile (an nsIFile).
- // The result is unix:/path or unix:"/path with spaces" with appropriate
- // C-style escaping within the path portion.
- _ipcPortArg: function(aIPCFile)
- {
- return "unix:" + this.mProtocolSvc.TorEscapeString(aIPCFile.path);
- },
_controlTor: function()
{
@@ -715,6 +676,227 @@ TorProcessService.prototype =
return argsArray;
},
+ // Returns an nsIFile.
+ // If aCreate is true and the file doesn't exist, it is created.
+ _getTorFile: function(aTorFileType, aCreate)
+ {
+ if (!aTorFileType)
+ return null;
+
+ let isRelativePath = true;
+ let isUserData = (aTorFileType != "tor") &&
+ (aTorFileType != "torrc-defaults");
+ let prefName = "extensions.torlauncher." + aTorFileType + "_path";
+ let path = TorLauncherUtil.getCharPref(prefName);
+ if (path)
+ {
+ let re = (TorLauncherUtil.isWindows) ? /^[A-Za-z]:\\/ : /^\//;
+ isRelativePath = !re.test(path);
+ }
+ else
+ {
+ // Get default path.
+ if (this._isUserDataOutsideOfAppDir)
+ {
+ // This block is used for the TorBrowser-Data/ case.
+ if (TorLauncherUtil.isWindows)
+ {
+ if ("tor" == aTorFileType)
+ path = "TorBrowser\\Tor\\tor.exe";
+ else if ("torrc-defaults" == aTorFileType)
+ path = "TorBrowser\\Tor\\torrc-defaults";
+ else if ("torrc" == aTorFileType)
+ path = "Tor\\torrc";
+ else if ("tordatadir" == aTorFileType)
+ path = "Tor";
+ }
+ else if (TorLauncherUtil.isMac)
+ {
+ if ("tor" == aTorFileType)
+ path = "Contents/Resources/TorBrowser/Tor/tor";
+ else if ("torrc-defaults" == aTorFileType)
+ path = "Contents/Resources/TorBrowser/Tor/torrc-defaults";
+ else if ("torrc" == aTorFileType)
+ path = "Tor/torrc";
+ else if ("tordatadir" == aTorFileType)
+ path = "Tor";
+ }
+ else // Linux and others.
+ {
+ if ("tor" == aTorFileType)
+ path = "TorBrowser/Tor/tor";
+ else if ("torrc-defaults" == aTorFileType)
+ path = "TorBrowser/Tor/torrc-defaults";
+ else if ("torrc" == aTorFileType)
+ path = "Tor/torrc";
+ else if ("tordatadir" == aTorFileType)
+ path = "Tor";
+ }
+ }
+ else if (TorLauncherUtil.isWindows)
+ {
+ // This block is used for the non-TorBrowser-Data/ case.
+ if ("tor" == aTorFileType)
+ path = "Tor\\tor.exe";
+ else if ("torrc-defaults" == aTorFileType)
+ path = "Data\\Tor\\torrc-defaults";
+ else if ("torrc" == aTorFileType)
+ path = "Data\\Tor\\torrc";
+ else if ("tordatadir" == aTorFileType)
+ path = "Data\\Tor";
+ }
+ else // Linux, Mac OS and others.
+ {
+ // This block is also used for the non-TorBrowser-Data/ case.
+ if ("tor" == aTorFileType)
+ path = "Tor/tor";
+ else if ("torrc-defaults" == aTorFileType)
+ path = "Data/Tor/torrc-defaults";
+ else if ("torrc" == aTorFileType)
+ path = "Data/Tor/torrc";
+ else if ("tordatadir" == aTorFileType)
+ path = "Data/Tor";
+ }
+ }
+
+ if (!path)
+ return null;
+
+ try
+ {
+ let f;
+ if (isRelativePath)
+ {
+ // Turn 'path' into an absolute path.
+ if (this._isUserDataOutsideOfAppDir)
+ {
+ let baseDir = isUserData ? this._dataDir : this._appDir;
+ f = baseDir.clone();
+ }
+ else
+ {
+ f = this._appDir.clone();
+ f.append("TorBrowser");
+ }
+ f.appendRelativePath(path);
+ }
+ else
+ {
+ f = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
+ f.initWithPath(path);
+ }
+
+ if (!f.exists() && aCreate)
+ {
+ try
+ {
+ if ("tordatadir" == aTorFileType)
+ f.create(f.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
+ else
+ f.create(f.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
+ }
+ catch (e)
+ {
+ TorLauncherLogger.safelog(4, "unable to create " + f.path + ": ", e);
+ return null;
+ }
+ }
+
+ if (f.exists())
+ {
+ try { f.normalize(); } catch(e) {}
+
+ return f;
+ }
+
+ TorLauncherLogger.log(4, aTorFileType + " file not found: " + f.path);
+ }
+ catch(e)
+ {
+ TorLauncherLogger.safelog(4, "_getTorFile " + aTorFileType +
+ " failed for " + path + ": ", e);
+ }
+
+ return null; // File not found or error (logged above).
+ }, // _getTorFile()
+
+ get _isUserDataOutsideOfAppDir()
+ {
+ if (this.mIsUserDataOutsideOfAppDir == undefined)
+ {
+ // Determine if we are using a "side-by-side" data model by checking
+ // whether the user profile is outside of the app directory.
+ try
+ {
+ let ds = Cc["@mozilla.org/file/directory_service;1"]
+ .getService(Ci.nsIProperties);
+ let profDir = ds.get("ProfD", Ci.nsIFile);
+ this.mIsUserDataOutsideOfAppDir = !this._appDir.contains(profDir);
+ }
+ catch (e)
+ {
+ this.mIsUserDataOutsideOfAppDir = false;
+ }
+ }
+
+ return this.mIsUserDataOutsideOfAppDir;
+ }, // get _isUserDataOutsideOfAppDir
+
+ // Returns an nsIFile that points to the application directory.
+ // May throw.
+ get _appDir()
+ {
+ if (!this.mAppDir)
+ {
+ let topDir = Cc["@mozilla.org/file/directory_service;1"]
+ .getService(Ci.nsIProperties).get("CurProcD", Ci.nsIFile);
+ let appInfo = Cc["@mozilla.org/xre/app-info;1"]
+ .getService(Ci.nsIXULAppInfo);
+ // On Linux and Windows, we want to return the Browser/ directory.
+ // Because topDir ("CurProcD") points to Browser/browser on those
+ // platforms, we need to go up one level.
+ // On Mac OS, we want to return the TorBrowser.app/ directory.
+ // Because topDir points to Contents/Resources/browser on Mac OS,
+ // we need to go up 3 levels.
+ let tbbBrowserDepth = (TorLauncherUtil.isMac) ? 3 : 1;
+ if ((appInfo.ID == this.kThunderbirdID) ||
+ (appInfo.ID == this.kInstantbirdID))
+ {
+ // On Thunderbird/Instantbird, the topDir is the root dir and not
+ // browser/, so we need to iterate one level less than Firefox.
+ --tbbBrowserDepth;
+ }
+
+ while (tbbBrowserDepth > 0)
+ {
+ let didRemove = (topDir.leafName != ".");
+ topDir = topDir.parent;
+ if (didRemove)
+ tbbBrowserDepth--;
+ }
+
+ this.mAppDir = topDir;
+ }
+
+ return this.mAppDir;
+ }, // get _appDir
+
+ // Returns an nsIFile that points to the TorBrowser-Data/ directory.
+ // This function is only used when this._isUserDataOutsideOfAppDir == true.
+ // May throw.
+ get _dataDir()
+ {
+ if (!this.mDataDir)
+ {
+ let ds = Cc["@mozilla.org/file/directory_service;1"]
+ .getService(Ci.nsIProperties);
+ let profDir = ds.get("ProfD", Ci.nsIFile);
+ this.mDataDir = profDir.parent.parent;
+ }
+
+ return this.mDataDir;
+ }, // get _dataDir
+
_getpid: function()
{
// Use nsIXULRuntime.processID if it is available.
diff --git a/src/components/tl-protocol.js b/src/components/tl-protocol.js
index 12f3910..581327e 100644
--- a/src/components/tl-protocol.js
+++ b/src/components/tl-protocol.js
@@ -17,8 +17,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "TorLauncherUtil",
"resource://torlauncher/modules/tl-util.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TorLauncherLogger",
"resource://torlauncher/modules/tl-logger.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
- "resource://gre/modules/FileUtils.jsm");
function TorProtocolService()
@@ -33,48 +31,28 @@ function TorProtocolService()
try
{
- let isWindows = TorLauncherUtil.isWindows;
- let env = Cc["@mozilla.org/process/environment;1"]
+ var env = Cc["@mozilla.org/process/environment;1"]
.getService(Ci.nsIEnvironment);
- // Determine how Tor Launcher will connect to the Tor control port.
- // Environment variables get top priority followed by preferences.
- if (!isWindows && env.exists("TOR_CONTROL_IPC_PATH"))
+
+ if (env.exists("TOR_CONTROL_HOST"))
+ this.mControlHost = env.get("TOR_CONTROL_HOST");
+ else
{
- let ipcPath = env.get("TOR_CONTROL_IPC_PATH");
- this.mControlIPCFile = new FileUtils.File(ipcPath);
+ this.mControlHost = TorLauncherUtil.getCharPref(
+ "extensions.torlauncher.control_host", "127.0.0.1");
}
+
+ if (env.exists("TOR_CONTROL_PORT"))
+ this.mControlPort = parseInt(env.get("TOR_CONTROL_PORT"), 10);
else
{
- // Check for TCP host and port environment variables.
- if (env.exists("TOR_CONTROL_HOST"))
- this.mControlHost = env.get("TOR_CONTROL_HOST");
- if (env.exists("TOR_CONTROL_PORT"))
- this.mControlPort = parseInt(env.get("TOR_CONTROL_PORT"), 10);
-
- let useIPC = !isWindows && TorLauncherUtil.getBoolPref(
- "extensions.torlauncher.control_port_use_ipc", true);
- if (!this.mControlHost && !this.mControlPort && useIPC)
- this.mControlIPCFile = TorLauncherUtil.getTorFile("control_ipc", false);
- else
- {
- if (!this.mControlHost)
- {
- this.mControlHost = TorLauncherUtil.getCharPref(
- "extensions.torlauncher.control_host", "127.0.0.1");
- }
- if (!this.mControlPort)
- {
- this.mControlPort = TorLauncherUtil.getIntPref(
+ this.mControlPort = TorLauncherUtil.getIntPref(
"extensions.torlauncher.control_port", 9151);
- }
- }
}
// Populate mControlPassword so it is available when starting tor.
if (env.exists("TOR_CONTROL_PASSWD"))
- {
this.mControlPassword = env.get("TOR_CONTROL_PASSWD");
- }
else if (env.exists("TOR_CONTROL_COOKIE_AUTH_FILE"))
{
// TODO: test this code path (TOR_CONTROL_COOKIE_AUTH_FILE).
@@ -85,117 +63,6 @@ function TorProtocolService()
if (!this.mControlPassword)
this.mControlPassword = this._generateRandomPassword();
-
- // Determine what kind of SOCKS port Tor and the browser will use.
- // On Windows (where Unix domain sockets are not supported), TCP is
- // always used.
- //
- // The following environment variables are supported and take
- // precedence over preferences:
- // TOR_SOCKS_IPC_PATH (file system path; ignored on Windows)
- // TOR_SOCKS_HOST
- // TOR_SOCKS_PORT
- //
- // The following preferences are consulted:
- // network.proxy.socks
- // network.proxy.socks_port
- // extensions.torlauncher.socks_port_use_ipc (Boolean)
- // extensions.torlauncher.socks_ipc_path (file system path)
- // If extensions.torlauncher.socks_ipc_path is empty, a default
- // path is used (<tor-data-directory>/socks.socket).
- //
- // When using TCP, if a value is not defined via an env variable it is
- // taken from the corresponding browser preference if possible. The
- // exceptions are:
- // If network.proxy.socks contains a file: URL, a default value of
- // "127.0.0.1" is used instead.
- // If the network.proxy.socks_port value is 0, a default value of
- // 9150 is used instead.
- //
- // Supported scenarios:
- // 1. By default, an IPC object at a default path is used.
- // 2. If extensions.torlauncher.socks_port_use_ipc is set to false,
- // a TCP socket at 127.0.0.1:9150 is used, unless different values
- // are set in network.proxy.socks and network.proxy.socks_port.
- // 3. If the TOR_SOCKS_IPC_PATH env var is set, an IPC object at that
- // path is used (e.g., a Unix domain socket).
- // 4. If the TOR_SOCKS_HOST and/or TOR_SOCKS_PORT env vars are set, TCP
- // is used. Values not set via env vars will be taken from the
- // network.proxy.socks and network.proxy.socks_port prefs as described
- // above.
- // 5. If extensions.torlauncher.socks_port_use_ipc is true and
- // extensions.torlauncher.socks_ipc_path is set, an IPC object at
- // the specified path is used.
- // 6. Tor Launcher is disabled. Torbutton will respect the env vars if
- // present; if not, the values in network.proxy.socks and
- // network.proxy.socks_port are used without modification.
-
- let useIPC;
- this.mSOCKSPortInfo = { ipcFile: undefined, host: undefined, port: 0 };
- if (!isWindows && env.exists("TOR_SOCKS_IPC_PATH"))
- {
- let ipcPath = env.get("TOR_SOCKS_IPC_PATH");
- this.mSOCKSPortInfo.ipcFile = new FileUtils.File(ipcPath);
- useIPC = true;
- }
- else
- {
- // Check for TCP host and port environment variables.
- if (env.exists("TOR_SOCKS_HOST"))
- {
- this.mSOCKSPortInfo.host = env.get("TOR_SOCKS_HOST");
- useIPC = false;
- }
- if (env.exists("TOR_SOCKS_PORT"))
- {
- this.mSOCKSPortInfo.port = parseInt(env.get("TOR_SOCKS_PORT"), 10);
- useIPC = false;
- }
- }
-
- if (useIPC === undefined)
- {
- useIPC = !isWindows && TorLauncherUtil.getBoolPref(
- "extensions.torlauncher.socks_port_use_ipc", true);
- }
-
- // Fill in missing SOCKS info from prefs.
- if (useIPC)
- {
- if (!this.mSOCKSPortInfo.ipcFile)
- {
- this.mSOCKSPortInfo.ipcFile =
- TorLauncherUtil.getTorFile("socks_ipc", false);
- }
- }
- else
- {
- if (!this.mSOCKSPortInfo.host)
- {
- let socksAddr = TorLauncherUtil.getCharPref("network.proxy.socks",
- "127.0.0.1");
- let socksAddrHasHost = (socksAddr && !socksAddr.startsWith("file:"));
- this.mSOCKSPortInfo.host = socksAddrHasHost ? socksAddr : "127.0.0.1";
- }
-
- if (!this.mSOCKSPortInfo.port)
- {
- let socksPort = TorLauncherUtil.getIntPref("network.proxy.socks_port",
- 0);
- this.mSOCKSPortInfo.port = (socksPort != 0) ? socksPort : 9150;
- }
- }
-
- TorLauncherLogger.log(3, "SOCKS port type: " + (useIPC ? "IPC" : "TCP"));
- if (useIPC)
- {
- TorLauncherLogger.log(3, "ipcFile: " + this.mSOCKSPortInfo.ipcFile.path);
- }
- else
- {
- TorLauncherLogger.log(3, "SOCKS host: " + this.mSOCKSPortInfo.host);
- TorLauncherLogger.log(3, "SOCKS port: " + this.mSOCKSPortInfo.port);
- }
}
catch(e)
{
@@ -274,19 +141,6 @@ TorProtocolService.prototype =
kCmdStatusOK: 250,
kCmdStatusEventNotification: 650,
- TorGetControlIPCFile: function()
- {
- if (!this.mControlIPCFile)
- return undefined;
-
- return this.mControlIPCFile.clone();
- },
-
- TorGetControlPort: function()
- {
- return this.mControlPort;
- },
-
// Returns Tor password string or null if an error occurs.
TorGetPassword: function(aPleaseHash)
{
@@ -294,18 +148,6 @@ TorProtocolService.prototype =
return (aPleaseHash) ? this._hashPassword(pw) : pw;
},
- TorGetSOCKSPortInfo: function()
- {
- return this.mSOCKSPortInfo;
- },
-
- // Escape non-ASCII characters for use within the Tor Control protocol.
- // Returns a string.
- TorEscapeString: function(aStr)
- {
- return this._strEscape(aStr);
- },
-
// NOTE: Many Tor protocol functions return a reply object, which is a
// a JavaScript object that has the following fields:
// reply.statusCode -- integer, e.g., 250
@@ -672,9 +514,7 @@ TorProtocolService.prototype =
mConsoleSvc: null,
mControlPort: null,
mControlHost: null,
- mControlIPCFile: null, // An nsIFile if using IPC for control port.
mControlPassword: null, // JS string that contains hex-encoded password.
- mSOCKSPortInfo: null, // An object that contains ipcFile, host, port.
mControlConnection: null, // This is cached and reused.
mEventMonitorConnection: null,
mEventMonitorBuffer: null,
@@ -722,44 +562,12 @@ TorProtocolService.prototype =
var conn;
try
{
- let sts = Cc["@mozilla.org/network/socket-transport-service;1"]
+ var sts = Cc["@mozilla.org/network/socket-transport-service;1"]
.getService(Ci.nsISocketTransportService);
- let socket;
- if (this.mControlIPCFile)
- {
- let exists = this.mControlIPCFile.exists();
- if (!exists)
- {
- TorLauncherLogger.log(5, "Control port IPC object does not exist: " +
- this.mControlIPCFile.path);
- }
- else
- {
- let isSpecial = this.mControlIPCFile.isSpecial();
- if (!isSpecial)
- {
- TorLauncherLogger.log(5,
- "Control port IPC object is not a special file: " +
- this.mControlIPCFile.path);
- }
- else
- {
- TorLauncherLogger.log(2, "Opening control connection to " +
- this.mControlIPCFile.path);
- socket = sts.createUnixDomainTransport(this.mControlIPCFile);
- }
- }
- }
- else
- {
- TorLauncherLogger.log(2, "Opening control connection to " +
+ TorLauncherLogger.log(2, "Opening control connection to " +
this.mControlHost + ":" + this.mControlPort);
- socket = sts.createTransport(null, 0, this.mControlHost,
- this.mControlPort, null);
- }
-
- if (!socket)
- return null;
+ var socket = sts.createTransport(null, 0, this.mControlHost,
+ this.mControlPort, null);
// Our event monitor connection is non-blocking and unbuffered (an
// asyncWait() call is used so we only read data when we know that
diff --git a/src/defaults/preferences/prefs.js b/src/defaults/preferences/prefs.js
index ea5ea80..ac1af21 100644
--- a/src/defaults/preferences/prefs.js
+++ b/src/defaults/preferences/prefs.js
@@ -1,33 +1,12 @@
-pref("extensions.torlauncher.start_tor", true);
-pref("extensions.torlauncher.prompt_at_startup", true);
-
pref("extensions.torlauncher.loglevel", 4); // 1=verbose, 2=debug, 3=info, 4=note, 5=warn
pref("extensions.torlauncher.logmethod", 1); // 0=stdout, 1=errorconsole, 2=debuglog
pref("extensions.torlauncher.max_tor_log_entries", 1000);
-// By default, an IPC object (e.g., a Unix domain socket) at a default
-// location is used for the Tor control port.
-// Change control_port_use_ipc to false to use a TCP connection instead, as
-// defined by control_host and control_port.
-// Modify control_ipc_path to override the default IPC object location. If a
-// relative path is used, it is handled like torrc_path (see below).
-pref("extensions.torlauncher.control_port_use_ipc", true);
-pref("extensions.torlauncher.control_ipc_path", "");
pref("extensions.torlauncher.control_host", "127.0.0.1");
pref("extensions.torlauncher.control_port", 9151);
-// By default, an IPC object (e.g., a Unix domain socket) at a default
-// location is used for the Tor SOCKS port.
-// Change socks_port_use_ipc to false to use a TCP connection. When a
-// TCP connection is used, the host is taken from the network.proxy.socks
-// pref and the port is taken from the network.proxy.socks_port pref.
-// Modify socks_ipc_path to override the default IPC object location. If a
-// relative path is used, it is handled like torrc_path (see below).
-// Modify socks_port_flags to use a different set of SocksPort flags (but be
-// careful).
-pref("extensions.torlauncher.socks_port_use_ipc", true);
-pref("extensions.torlauncher.socks_ipc_path", "");
-pref("extensions.torlauncher.socks_port_flags", "IPv6Traffic PreferIPv6 KeepAliveIsolateSOCKSAuth");
+pref("extensions.torlauncher.start_tor", true);
+pref("extensions.torlauncher.prompt_at_startup", true);
// The tor_path is relative to the application directory. On Linux and
// Windows this is the Browser/ directory that contains the firefox
diff --git a/src/modules/tl-util.jsm b/src/modules/tl-util.jsm
index 313a51b..3c7d80b 100644
--- a/src/modules/tl-util.jsm
+++ b/src/modules/tl-util.jsm
@@ -11,19 +11,14 @@ let EXPORTED_SYMBOLS = [ "TorLauncherUtil" ];
const Cc = Components.classes;
const Ci = Components.interfaces;
-const Cu = Components.utils;
const kPropBundleURI = "chrome://torlauncher/locale/torlauncher.properties";
const kPropNamePrefix = "torlauncher.";
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "TorLauncherLogger",
- "resource://torlauncher/modules/tl-logger.jsm");
-
let TorLauncherUtil = // Public
{
get isMac()
{
- return TLUtilInternal._isMac;
+ return ("Darwin" == TLUtilInternal._OS);
},
get isWindows()
@@ -247,14 +242,6 @@ let TorLauncherUtil = // Public
} catch (e) {}
},
- clearUserPref: function(aPrefName)
- {
- try
- {
- TLUtilInternal.mPrefsSvc.clearUserPref(aPrefName);
- } catch (e) {}
- },
-
// Currently, this returns a random permutation of an array, bridgeArray.
// Later, we might want to change this function to weight based on the
// bridges' bandwidths.
@@ -374,281 +361,6 @@ let TorLauncherUtil = // Public
return undefined;
},
-
- // Returns an nsIFile.
- // If aTorFileType is "control_ipc" or "socks_ipc", aCreate is ignored
- // and there is no requirement that the IPC object exists.
- // For all other file types, null is returned if the file does not exist
- // and it cannot be created (it will be created if aCreate is true).
- getTorFile: function(aTorFileType, aCreate)
- {
- if (!aTorFileType)
- return null;
-
- let torFile; // an nsIFile to be returned
- let path; // a relative or absolute path that will determine torFile
-
- let isRelativePath = false;
- let isUserData = (aTorFileType != "tor") &&
- (aTorFileType != "torrc-defaults");
- let isControlIPC = ("control_ipc" == aTorFileType);
- let isSOCKSIPC = ("socks_ipc" == aTorFileType);
- let isIPC = isControlIPC || isSOCKSIPC;
- let checkIPCPathLen = true;
-
- const kControlIPCFileName = "control.socket";
- const kSOCKSIPCFileName = "socks.socket";
- let extraIPCPathLen = (isSOCKSIPC) ? 2 : 0;
- let ipcFileName;
- if (isControlIPC)
- ipcFileName = kControlIPCFileName;
- else if (isSOCKSIPC)
- ipcFileName = kSOCKSIPCFileName;
-
- // If this is the first request for an IPC path during this browser
- // session, remove the old temporary directory. This helps to keep /tmp
- // clean if the browser crashes or is killed.
- let ipcDirPath;
- if (isIPC && TLUtilInternal.mIsFirstIPCPathRequest)
- {
- this.cleanupTempDirectories();
- TLUtilInternal.mIsFirstIPCPathRequest = false;
- }
- else
- {
- // Retrieve path for IPC objects (it may have already been determined).
- ipcDirPath = this.getCharPref(TLUtilInternal.kIPCDirPrefName);
- }
-
- // First, check the _path preference for this file type.
- let prefName = "extensions.torlauncher." + aTorFileType + "_path";
- path = this.getCharPref(prefName);
- if (path)
- {
- let re = (this.isWindows) ? /^[A-Za-z]:\\/ : /^\//;
- isRelativePath = !re.test(path);
- checkIPCPathLen = false; // always try to use path if provided in pref
- }
- else if (isIPC)
- {
- if (ipcDirPath)
- {
- // We have already determined where IPC objects will be placed.
- torFile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
- torFile.initWithPath(ipcDirPath);
- torFile.append(ipcFileName);
- checkIPCPathLen = false; // already checked.
- }
- else
- {
- // If XDG_RUNTIME_DIR is set, use it as the base directory for IPC
- // objects (e.g., Unix domain sockets) -- assuming it is not too long.
- let env = Cc["@mozilla.org/process/environment;1"]
- .getService(Ci.nsIEnvironment);
- if (env.exists("XDG_RUNTIME_DIR"))
- {
- let ipcDir = TLUtilInternal._createUniqueIPCDir(
- env.get("XDG_RUNTIME_DIR"));
- if (ipcDir)
- {
- let f = ipcDir.clone();
- f.append(ipcFileName);
- if (TLUtilInternal._isIPCPathLengthOK(f.path, extraIPCPathLen))
- {
- torFile = f;
- checkIPCPathLen = false; // no need to check again.
-
- // Store directory path so it can be reused for other IPC objects
- // and so it can be removed during exit.
- this.setCharPref(TLUtilInternal.kIPCDirPrefName, ipcDir.path);
- }
- else
- {
- // too long; remove the directory that we just created.
- ipcDir.remove(false);
- }
- }
- }
- }
- }
-
- if (!path && !torFile)
- {
- // No preference and no pre-determined IPC path: use a default path.
- isRelativePath = true;
- if (TLUtilInternal._isUserDataOutsideOfAppDir)
- {
- // This block is used for the TorBrowser-Data/ case.
- if (this.isWindows)
- {
- if ("tor" == aTorFileType)
- path = "TorBrowser\\Tor\\tor.exe";
- else if ("torrc-defaults" == aTorFileType)
- path = "TorBrowser\\Tor\\torrc-defaults";
- else if ("torrc" == aTorFileType)
- path = "Tor\\torrc";
- else if ("tordatadir" == aTorFileType)
- path = "Tor";
- }
- else if (this.isMac)
- {
- if ("tor" == aTorFileType)
- path = "Contents/Resources/TorBrowser/Tor/tor";
- else if ("torrc-defaults" == aTorFileType)
- path = "Contents/Resources/TorBrowser/Tor/torrc-defaults";
- else if ("torrc" == aTorFileType)
- path = "Tor/torrc";
- else if ("tordatadir" == aTorFileType)
- path = "Tor";
- else if (isIPC)
- path = "Tor/" + ipcFileName;
- }
- else // Linux and others.
- {
- if ("tor" == aTorFileType)
- path = "TorBrowser/Tor/tor";
- else if ("torrc-defaults" == aTorFileType)
- path = "TorBrowser/Tor/torrc-defaults";
- else if ("torrc" == aTorFileType)
- path = "Tor/torrc";
- else if ("tordatadir" == aTorFileType)
- path = "Tor";
- else if (isIPC)
- path = "Tor/" + ipcFileName;
- }
- }
- else if (this.isWindows)
- {
- // This block is used for the non-TorBrowser-Data/ case.
- if ("tor" == aTorFileType)
- path = "Tor\\tor.exe";
- else if ("torrc-defaults" == aTorFileType)
- path = "Data\\Tor\\torrc-defaults";
- else if ("torrc" == aTorFileType)
- path = "Data\\Tor\\torrc";
- else if ("tordatadir" == aTorFileType)
- path = "Data\\Tor";
- }
- else // Linux, Mac OS and others.
- {
- // This block is also used for the non-TorBrowser-Data/ case.
- if ("tor" == aTorFileType)
- path = "Tor/tor";
- else if ("torrc-defaults" == aTorFileType)
- path = "Data/Tor/torrc-defaults";
- else if ("torrc" == aTorFileType)
- path = "Data/Tor/torrc";
- else if ("tordatadir" == aTorFileType)
- path = "Data/Tor";
- else if (isIPC)
- path = "Data/Tor/" + ipcFileName;
- }
-
- if (!path)
- return null;
- }
-
- try
- {
- if (path)
- {
- if (isRelativePath)
- {
- // Turn 'path' into an absolute path.
- if (TLUtilInternal._isUserDataOutsideOfAppDir)
- {
- let baseDir = isUserData ? TLUtilInternal._dataDir
- : TLUtilInternal._appDir;
- torFile = baseDir.clone();
- }
- else
- {
- torFile = TLUtilInternal._appDir.clone();
- torFile.append("TorBrowser");
- }
- torFile.appendRelativePath(path);
- }
- else
- {
- torFile = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
- torFile.initWithPath(path);
- }
-
- if (!torFile.exists() && !isIPC && aCreate)
- {
- try
- {
- if ("tordatadir" == aTorFileType)
- torFile.create(torFile.DIRECTORY_TYPE, 0700);
- else
- torFile.create(torFile.NORMAL_FILE_TYPE, 0600);
- }
- catch (e)
- {
- TorLauncherLogger.safelog(4,
- "unable to create " + torFile.path + ": ", e);
- return null;
- }
- }
- }
-
- // If the file exists or an IPC object was requested, normalize the path
- // and return a file object. The control and SOCKS IPC objects will be
- // created by tor.
- if (torFile.exists() || isIPC)
- {
- try { torFile.normalize(); } catch(e) {}
-
- // Ensure that the IPC path length is short enough for use by the
- // operating system. If not, create and use a unique directory under
- // /tmp for all IPC objects. The created directory path is stored in
- // a preference so it can be reused for other IPC objects and so it
- // can be removed during exit.
- if (isIPC && checkIPCPathLen &&
- !TLUtilInternal._isIPCPathLengthOK(torFile.path, extraIPCPathLen))
- {
- torFile = TLUtilInternal._createUniqueIPCDir("/tmp");
- if (!torFile)
- {
- TorLauncherLogger.log(4,
- "failed to create unique directory under /tmp");
- return null;
- }
-
- this.setCharPref(TLUtilInternal.kIPCDirPrefName, torFile.path);
- torFile.append(ipcFileName);
- }
-
- return torFile;
- }
-
- TorLauncherLogger.log(4, aTorFileType + " file not found: "
- + torFile.path);
- }
- catch(e)
- {
- TorLauncherLogger.safelog(4, "getTorFile " + aTorFileType +
- " failed for " + path + ": ", e);
- }
-
- return null; // File not found or error (logged above).
- }, // getTorFile()
-
- cleanupTempDirectories: function()
- {
- try
- {
- let dirPath = this.getCharPref(TLUtilInternal.kIPCDirPrefName);
- this.clearUserPref(TLUtilInternal.kIPCDirPrefName);
- if (dirPath)
- {
- let f = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
- f.initWithPath(dirPath);
- if (f.exists())
- f.remove(false); // Remove directory if it is empty
- }
- } catch(e) {}
- },
};
@@ -657,19 +369,9 @@ Object.freeze(TorLauncherUtil);
let TLUtilInternal = // Private
{
- kThunderbirdID: "{3550f703-e582-4d05-9a08-453d09bdfdc6}",
- kInstantbirdID: "{33cb9019-c295-46dd-be21-8c4936574bee}",
- kIPCDirPrefName: "extensions.torlauncher.tmp_ipc_dir",
-
mPrefsSvc : null,
mStringBundle : null,
mOS : "",
- // mIsUserDataOutsideOfAppDir is true when TorBrowser-Data is used.
- mIsUserDataOutsideOfAppDir: undefined, // Boolean (cached; access via
- // this._isUserDataOutsideOfAppDir)
- mAppDir: null, // nsIFile (cached; access via this._appDir)
- mDataDir: null, // nsIFile (cached; access via this._dataDir)
- mIsFirstIPCPathRequest : true,
_init: function()
{
@@ -699,121 +401,6 @@ let TLUtilInternal = // Private
return this.mOS;
},
-
- get _isMac()
- {
- return ("Darwin" == this._OS);
- },
-
- get _isUserDataOutsideOfAppDir()
- {
- if (this.mIsUserDataOutsideOfAppDir == undefined)
- {
- // Determine if we are using a "side-by-side" data model by checking
- // whether the user profile is outside of the app directory.
- try
- {
- let ds = Cc["@mozilla.org/file/directory_service;1"]
- .getService(Ci.nsIProperties);
- let profDir = ds.get("ProfD", Ci.nsIFile);
- this.mIsUserDataOutsideOfAppDir = !this._appDir.contains(profDir);
- }
- catch (e)
- {
- this.mIsUserDataOutsideOfAppDir = false;
- }
- }
-
- return this.mIsUserDataOutsideOfAppDir;
- }, // get _isUserDataOutsideOfAppDir
-
- // Returns an nsIFile that points to the application directory.
- // May throw.
- get _appDir()
- {
- if (!this.mAppDir)
- {
- let topDir = Cc["@mozilla.org/file/directory_service;1"]
- .getService(Ci.nsIProperties).get("CurProcD", Ci.nsIFile);
- let appInfo = Cc["@mozilla.org/xre/app-info;1"]
- .getService(Ci.nsIXULAppInfo);
- // On Linux and Windows, we want to return the Browser/ directory.
- // Because topDir ("CurProcD") points to Browser/browser on those
- // platforms, we need to go up one level.
- // On Mac OS, we want to return the TorBrowser.app/ directory.
- // Because topDir points to Contents/Resources/browser on Mac OS,
- // we need to go up 3 levels.
- let tbbBrowserDepth = (this._isMac) ? 3 : 1;
- if ((appInfo.ID == this.kThunderbirdID) ||
- (appInfo.ID == this.kInstantbirdID))
- {
- // On Thunderbird/Instantbird, the topDir is the root dir and not
- // browser/, so we need to iterate one level less than Firefox.
- --tbbBrowserDepth;
- }
-
- while (tbbBrowserDepth > 0)
- {
- let didRemove = (topDir.leafName != ".");
- topDir = topDir.parent;
- if (didRemove)
- tbbBrowserDepth--;
- }
-
- this.mAppDir = topDir;
- }
-
- return this.mAppDir;
- }, // get _appDir
-
- // Returns an nsIFile that points to the TorBrowser-Data/ directory.
- // This function is only used when this._isUserDataOutsideOfAppDir == true.
- // May throw.
- get _dataDir()
- {
- if (!this.mDataDir)
- {
- let ds = Cc["@mozilla.org/file/directory_service;1"]
- .getService(Ci.nsIProperties);
- let profDir = ds.get("ProfD", Ci.nsIFile);
- this.mDataDir = profDir.parent.parent;
- }
-
- return this.mDataDir;
- }, // get _dataDir
-
- // Return true if aPath is short enough to be used as an IPC object path,
- // e.g., for a Unix domain socket path. aExtraLen is the "delta" necessary
- // to accommodate other IPC objects that have longer names; it is used to
- // account for "control.socket" vs. "socks.socket" (we want to ensure that
- // all IPC objects are placed in the same parent directory unless the user
- // has set prefs or env vars to explicitly specify the path for an object).
- // We enforce a maximum length of 100 because all operating systems allow
- // at least 100 characters for Unix domain socket paths.
- _isIPCPathLengthOK: function(aPath, aExtraLen)
- {
- const kMaxIPCPathLen = 100;
- return aPath && ((aPath.length + aExtraLen) <= kMaxIPCPathLen);
- },
-
- // Returns an nsIFile or null if a unique directory could not be created.
- _createUniqueIPCDir: function(aBasePath)
- {
- try
- {
- let d = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
- d.initWithPath(aBasePath);
- d.append("Tor");
- d.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0700);
- return d;
- }
- catch (e)
- {
- TorLauncherLogger.safelog(4, "_createUniqueIPCDir failed for "
- + aBasePath + ": ", e);
- return null;
- }
- },
};