[tbb-dev] Tor Browser TorLauncher Proposal
Matthew Finkel
matthew.finkel at gmail.com
Wed Jan 10 15:10:21 UTC 2018
Hi All,
Apologies for the delay in sending this. Attached (or below) is the
proposal for migrating the TorLauncher legacy extension to
WebExtension. The main problem with directly moving TorLauncher to
using WebExtensions is the two Extensions APIs are not 1-to-1. There
was significant functionality previously available that is not available
with WebExtensions. In particular these involve launching a child
process and controlling it. This is a primary objective of TorLauncher,
so we needed an alternative.
As a result, this proposal takes a mixed approach. Part of the
functionality of TorLauncher will remain as an extension and the
remaining functionality will be directly implemented into Tor Browser.
>From the mobile/Android perspective, TorLauncher is a strange
requirement at this moment. On Android, Orbot controls and configures
tor, and external Apps cannot configure tor which is the purpose of
TorLauncher. In the future, we may prefer another design and
integration, providing a better user experience.
Although the proposal is long, it is mostly documenting the extension's
existing functionality.
Thanks,
Matt
-------------- next part --------------
Author: Matthew Finkel
0. Motivation
As of Firefox 57, only extensions developed using WebExtensions are
supported. As a result, the TorLauncher extension must be ported.
The main objectives of TorLauncher are providing the User with an
interactive interface for configuring tor and acting as a tor
controller so tor may be configured as needed for the user.
Although porting TorLauncher so it only uses the WebExtensions API
is mostly possible, integrating some of the current functionality
into Tor Browser may be easier and provide for a better user
experience.
This proposal describes TorLauncher's use case and how we can continue
providing a uniform bootstrapping/loading user experience across all
platforms and projects/products (Tor {Browser,Birdy,Messenger}).
1. Functionality
Currently TorLauncher provides the following functionality:
- Detects operating system platform
- Constructs command line and execute tor as background process
- Sets browser as controlling process of tor
- Shows network settings wizard when networking and/or
configuration issue is detected
- Provides user interface for configuring bridges, proxy, and
informing tor it is behind a fascist firewall
- Shows the user tor's bootstrapping status as a progress bar
- Provides "Copy Tor Log to Clipboard"
- Connects to tor's control socket
- Exports some tor controller functionality as a service within XPCOM
- Retrieves bootstrapping progress via "GETINFO status/bootstrap-phase"
- Buffers tor client log messages via "SETEVENTS STATUS_CLIENT NOTICE WARN ERR"
- Monitors bootstrapping progress via events
- Provides accessor and mutator of tor configuration via getconf/setconf
Some of these points are redundant, but they give insight into how
the extension works from different perspectives.
2. Back End
The TorLauncher extension can be divided into two parts. As the first
part, we can consider the back-end functionality the extension
provides. The tor controller and tor process manager can be
re-implemented in C++. The controller can be written as a network
protocol service under netwerk/protocol/. The tor process can be
managed by a class under security/.
TorLauncher currently provides a XPCOM service for the tor
controller using the contract ID
"@torproject.org/torlauncher-protocol-service;1". Instead, now we
can present the tor controller as a XPCOM service using the
contract ID "@torproject.org/network/protocol/torcontroller;1".
Ideally, this controller can be implemented in a child process and
sandboxed, but that requires additional investigation and design.
3. Front End
The second part of TorLauncher's functionality is providing a
front-end user interface. The TorLauncher extension can be modified
so it continues providing the user interface of the network settings
and wizard using the WebExtension API. This will give us continued
consistency across Windows, OSX, and Unix, but we will need a new UI
for Android.
Although the UI could be implemented directly as a widget for
Tor Browser on desktop, using an extension provides easy code re-use
across projects. Any UI changes directly in Tor Browser will likely
require duplicaating or reimplementing in Mail/Messanger.
On Android, we need a new mobile-friendly UI in any case (POE? [0]).
How we integrate this with Orbot will be extremely important. We will
use an Intent listener, and receive status messages from Orbot, but
any tor configuration changes must be made using Orbot. This is the
current state of implementation in Orfox. Therefore, on Android
TorLauncher is not directly useful.
4. Mobile Questions
Should we propose improvements/changes of Orbot so (trusted) external
Apps can send Controller messages via intent?
Should we launch our own tor service and fully control it rather than
rely on another app?
5. Security Considerations
Is there a way Tor Browser can further restrict access to a XPCOM
service? Firefox's sandboxing makes difficult unprivileged access to
internal services, but this risk remains when Tor Browser runs as a
single process.
As mentioned earlier, sandboxing the controller and process manager
into a sandboxed-child process would provide additional assurance the
tor process would not reveal private information if a vulnerability
is found in the Browser.
What are the implications of the browser having access to the full
circuit information, including the User's guard?
6. Proposed TorController Contract
TorController::GetControlSocket()
- Return an object containing the Control socket information, as
appropriate: Unix Domain Socket file path, hostname/IP address,
and TCP port number.
TorController::GetSOCKSSocket()
- Return an object containing the SOCKS socket information, as
appropriate: Unix Domain Socket file path, hostname/IP address,
and TCP port number.
TorController::GetControlPassword()
- Return the password or, if requested, the hash of the
password, or null if the password is null
TorController::UnescapeString()
- Nearly same implementation as TorUnescapeString() below.
Return an error on failure (malformed string)
Additional abstractions should be added at the public interface. We
can re-use the below Interface, and replace the first five methods
defined below with the four methods above. This new controller can be
implemented within the TorController class and renaming the below
functions by delete the "Tor" namespace prefix.
We should enumerate all GETCONF and SETCONF use cases and limit the
public Interface for only this functionality.
Below there are public JS properties, these should be encapsulated
within getter/setter methods.
7. Existing TorLauncher Contract
The TorLauncher service contract currently provides the following
interfaces, the new implemenation may use this as a reference:
Protocol:
Providing: nsISupports, nsIFactory, nsIObserver, nsIClassInfo
property TorLogHasWarnOrErr
- true if the log messages we have captured contain WARN or ERR
TorGetControlIPCFile()
- Return a copy of the Unix Domain file path if defined,
otherwise return undefined
TorGetControlPort()
- Return the control port number, or null if using IPC file
TorGetPassword()
- Return the password or, if requested, the hash of the
password, or null if the password is null
TorGetSOCKSPortInfo()
- Returns an object containing the SOCKS Port information, or
null if not defined. The object defined keys: ipcFile, host,
and port.
TorUnescapeString()
- Return a string after:
stripping '"' as the first and last characters
reinterpretting '\r', '\n', '\t'
converting hex and octal values into decimal
stripping one '\' before any other character
Throws Error on failure (malformed string)
TorEscapeString()
- Return a string after escaping:
character sequences:
'\' -> '\\'
'\\' -> '\\\\'
'\r' -> '\\r'
'\n' -> '\\n'
'\t' -> '\\t'
UTF-8 characters as a \xHH hex sequence
TorGetConf()
- Send GETCONF command, return original result on failure,
and returns parsed reply object on success.
Result object:
{
statusCode: 0,
lineArray: [],
_parseError: false
}
TorGetConfStr()
- Same as TorGetConf() but set the retVal key in the reply
object as the GETCONF reply status value or the provided
default
TorGetConfBool()
- Same as TorGetConf() but set retVal as boolean true if the
first non-status-ok response line is "1", else return false.
Return the provided default value if Tor is currently using
its default configuration for this config.
TorSetConf()
- Send SETCONF command where the input is an object with keys
defining the config option, and the key's value is the new
configuration. The value may be a string, a string array,
or a boolean value. On failure return null, else return the
reponse object.
TorSetConfWithReply()
- Same as TorSetConf() but return a boolean value indicating
success or failure. On failure, return an object a key named
"details" that is a string with an error message.
TorRetrieveBootstrapStatus()
- Send "GETCONF status/bootstrap-phase" command. Return null.
Send a "TorBootstrapStatus" notification if the command
returns successful.
TorSendCommand()
- Send the provided command, and return the received response
TorCommandSucceeded()
- Return a boolean value of true if the reply is not null and
the status code was 250 (OK).
TorCleanupConnection()
- Call during browser shutdown, it closes the
connections and it terminates event monitoring.
TorStartEventMonitor()
- Begin event monitoring by sending the SETEVENTS commnd
"SETEVENTS STATUS_CLIENT NOTICE WARN ERR"
TorGetLog()
- Return the captured log messages as a text string. Return
the number of log line if a non-null object is passed-in as
a parameter.
TorHaveControlConnection()
- Return boolean true if a control connection is established.
Creates a new control connection is a valid connection does
not exist.
Process:
property TorProcessStatus
- An "enum" defining the current status of the Tor process
One of: Unknkown, Starting, Running, Exited
property TorIsBootstrapDone
- A boolean value notating bootstrapping is complete
property TorBootstrapErrorOccurred
- A boolean value notating an error occurred during bootstrap.
TorStartAndControlTor()
- Start Tor, notice when the process successfully started,
launch the network settings wizard if needed.
TorClearBootstrapError()
- Clear (set as false or null) the state variables indicating
an error occurred during bootstrap.
More information about the tbb-dev
mailing list