mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-01 08:03:31 +01:00
f309168301
svn:r3635
395 lines
15 KiB
Plaintext
395 lines
15 KiB
Plaintext
$Id$
|
|
|
|
TC: A Tor control protocol
|
|
|
|
0. Scope
|
|
|
|
This document describes an implementation-specific protocol that is used
|
|
for other programs (such as frontend user-interfaces) to communicate
|
|
with a locally running Tor process. It is not part of the Tor onion
|
|
routing protocol.
|
|
|
|
We're trying to be pretty extensible here, but not infinitely
|
|
forward-compatible.
|
|
|
|
1. Protocol outline
|
|
|
|
TC is a bidirectional message-based protocol. It assumes an underlying
|
|
stream for communication between a controlling process (the "client") and
|
|
a Tor process (the "server"). The stream may be implemented via TCP,
|
|
TLS-over-TCP, a Unix-domain socket, or so on, but it must provide
|
|
reliable in-order delivery. For security, the stream should not be
|
|
accessible by untrusted parties.
|
|
|
|
In TC, the client and server send typed variable-length messages to each
|
|
other over the underlying stream. By default, all messages from the server
|
|
are in response to messages from the client. Some client requests, however,
|
|
will cause the server to send messages to the client indefinitely far into
|
|
the future.
|
|
|
|
Servers respond to messages in the order they're received.
|
|
|
|
2. Message format
|
|
|
|
The messages take the following format:
|
|
|
|
Length [2 octets; big-endian]
|
|
Type [2 octets; big-endian]
|
|
Body [Length octets]
|
|
|
|
Upon encountering a recognized Type, implementations behave as described in
|
|
section 3 below. If the type is not recognized, servers respond with a
|
|
"STAT" message (code UNRECOGNIZED; see 3.1 below), and clients simply ignore
|
|
the message.
|
|
|
|
2.1. Types and encodings
|
|
|
|
All numbers are given in big-endian (network) order.
|
|
|
|
OR identities are given in hexadecimal, in the same format as identity key
|
|
fingerprints, but without spaces; see tor-spec.txt for more information.
|
|
|
|
3. Message types
|
|
|
|
3.1. ERROR (Type 0x0000)
|
|
|
|
Sent in response to a message that could not be processed as requested.
|
|
|
|
The body of the message begins with a 2-byte error code. The following
|
|
values are defined:
|
|
|
|
0x0000 Unspecified error
|
|
[]
|
|
|
|
0x0001 Internal error
|
|
[Something went wrong inside Tor, so that the client's
|
|
request couldn't be fulfilled.]
|
|
|
|
0x0002 Unrecognized message type
|
|
[The client sent a message type we don't understand.]
|
|
|
|
0x0003 Syntax error
|
|
[The client sent a message body in a format we can't parse.]
|
|
|
|
0x0004 Unrecognized configuration key
|
|
[The client tried to get or set a configuration option we don't
|
|
recognize.]
|
|
|
|
0x0005 Invalid configuration value
|
|
[The client tried to set a configuration option to an
|
|
incorrect, ill-formed, or impossible value.]
|
|
|
|
0x0006 Unrecognized byte code
|
|
[The client tried to set a byte code (in the body) that
|
|
we don't recognize.]
|
|
|
|
0x0007 Unauthorized.
|
|
[The client tried to send a command that requires
|
|
authorization, but it hasn't sent a valid AUTHENTICATE
|
|
message.]
|
|
|
|
0x0008 Failed authentication attempt
|
|
[The client sent a well-formed authorization message.]
|
|
|
|
0x0009 Resource exhausted
|
|
[The server didn't have enough of a given resource to
|
|
fulfill a given request.]
|
|
|
|
The rest of the body should be a human-readable description of the error.
|
|
|
|
In general, new error codes should only be added when they don't fall under
|
|
one of the existing error codes.
|
|
|
|
3.2. DONE (Type 0x0001)
|
|
|
|
Sent from server to client in response to a request that was successfully
|
|
completed, with no more information needed. The body is usually empty but
|
|
may contain a message.
|
|
|
|
3.3. SETCONF (Type 0x0002)
|
|
|
|
Change the value of a configuration variable. The body contains a list of
|
|
newline-terminated key-value configuration lines.
|
|
The server behaves as though it had just read the key-value pair in its
|
|
configuration file.
|
|
|
|
The server responds with a DONE message on success, or an ERROR message on
|
|
failure.
|
|
|
|
When a configuration options takes multiple values, or when multiple
|
|
configuration keys form a context-sensitive group (see below), then
|
|
setting _any_ of the options in a SETCONF command is taken to reset all of
|
|
the others. For example, if two ORBindAddress values are configured,
|
|
and a SETCONF command arrives containing a single ORBindAddress value, the
|
|
new command's value replaces the two old values.
|
|
|
|
To _remove_ all settings for a given option entirely (and go back to its
|
|
default value), send a single line containing the key and no value.
|
|
|
|
3.4. GETCONF (Type 0x0003)
|
|
|
|
Request the value of a configuration variable. The body contains one or
|
|
more NL-terminated strings for configuration keys. The server replies
|
|
with a CONFVALUE message.
|
|
|
|
If an option appears multiple times in the configuration, all of its
|
|
key-value pairs are returned in order.
|
|
|
|
Some options are context-sensitive, and depend on other options with
|
|
different keywords. These cannot be fetched directly. Currently there
|
|
is only one such option: clients should use the "HiddenServiceOptions"
|
|
virtual keyword to get all HiddenServiceDir, HiddenServicePort,
|
|
HiddenServiceNodes, and HiddenServiceExcludeNodes option settings.
|
|
|
|
3.5. CONFVALUE (Type 0x0004)
|
|
|
|
Sent in response to a GETCONF message; contains a list of "Key Value\n"
|
|
(A non-whitespace keyword, a single space, a non-NL value, a NL)
|
|
strings.
|
|
|
|
3.6. SETEVENTS (Type 0x0005)
|
|
|
|
Request the server to inform the client about interesting events.
|
|
The body contains a list of 2-byte event codes (see "event" below).
|
|
Sending SETEVENTS with an empty body turns off all event reporting.
|
|
|
|
The server responds with a DONE message on success, and an ERROR message
|
|
if one of the event codes isn't recognized. (On error, the list of active
|
|
event codes isn't changed.)
|
|
|
|
3.7. EVENT (Type 0x0006)
|
|
|
|
Sent from the server to the client when an event has occurred and the
|
|
client has requested that kind of event. The body contains a 2-byte
|
|
event code followed by additional event-dependent information. Event
|
|
codes are:
|
|
0x0001 -- Circuit status changed
|
|
|
|
Status [1 octet]
|
|
(Launched=0,Built=1,Extended=2,Failed=3,Closed=4)
|
|
Circuit ID [4 octets]
|
|
(Must be unique to Tor process/time)
|
|
Path [NUL-terminated comma-separated string]
|
|
(For extended/failed, is the portion of the path that is
|
|
built)
|
|
|
|
0x0002 -- Stream status changed
|
|
|
|
Status [1 octet]
|
|
(Sent connect=0,sent resolve=1,succeeded=2,failed=3,
|
|
closed=4, new=5)
|
|
Stream ID [4 octets]
|
|
(Must be unique to Tor process/time)
|
|
Target (NUL-terminated address-port string]
|
|
|
|
0x0003 -- OR Connection status changed
|
|
|
|
Status [1 octet]
|
|
(Launched=0,connected=1,failed=2,closed=3)
|
|
OR nickname/identity [NUL-terminated]
|
|
|
|
0x0004 -- Bandwidth used in the last second
|
|
|
|
Bytes read [4 octets]
|
|
Bytes written [4 octets]
|
|
|
|
0x0005 -- Notice/warning/error occurred
|
|
|
|
Message [NUL-terminated]
|
|
|
|
0x0006 -- New descriptors available
|
|
|
|
OR List [NUL-terminated, comma-delimited list of
|
|
OR identity]
|
|
|
|
3.8. AUTHENTICATE (Type 0x0007)
|
|
|
|
Sent from the client to the server. Contains a 'magic cookie' to prove
|
|
that client is really the admin for this Tor process. The server responds
|
|
with DONE or ERROR.
|
|
|
|
3.9. SAVECONF (Type 0x0008)
|
|
|
|
Sent from the client to the server. Instructs the server to write out
|
|
its config options into its torrc. Server returns DONE if successful, or
|
|
ERROR if it can't write the file or some other error occurs.
|
|
|
|
3.10. SIGNAL (Type 0x0009)
|
|
|
|
Sent from the client to the server. The body contains one byte that
|
|
indicates the action the client wishes the server to take.
|
|
|
|
1 (0x01) -- Reload: reload config items, refetch directory.
|
|
2 (0x02) -- Controlled shutdown: if server is an OP, exit immediately.
|
|
If it's an OR, close listeners and exit after 30 seconds.
|
|
10 (0x0A) -- Dump stats: log information about open connections and
|
|
circuits.
|
|
12 (0x0C) -- Debug: switch all open logs to loglevel debug.
|
|
15 (0x0F) -- Immediate shutdown: clean up and exit now.
|
|
|
|
The server responds with DONE if the signal is recognized (or simply
|
|
closes the socket if it was asked to close immediately), else ERROR.
|
|
|
|
3.11. MAPADDRESS (Type 0x000A)
|
|
|
|
[Proposal; not finalized]
|
|
|
|
Sent from the client to the server. The body contains a sequence of
|
|
address mappings, each consisting of the address to be mapped, a single
|
|
space, the replacement address, and a NL character.
|
|
|
|
Addresses may be IPv4 addresses, IPv6 addresses, or hostnames.
|
|
|
|
The client sends this message to the server in order to tell it that future
|
|
SOCKS requests for connections to the original address should be replaced
|
|
with connections to the specified replacement address. If the addresses
|
|
are well-formed, and the server is able to fulfill the request, the server
|
|
replies with a single DONE message containing the source and destination
|
|
addresses. If request is malformed, the server replies with a syntax error
|
|
message. The server can't fulfill the request, it replies with an internal
|
|
ERROR message.
|
|
|
|
The client may decline to provide a body for the original address, and
|
|
instead send a special null address (0.0.0.0 for IPv4, ::0 for IPv6, or "."
|
|
for hostname). This signifies that the server should choose the original
|
|
address itself, and return that address in the DONE message. The server
|
|
should ensure that an element of address space that is unlikely to be in
|
|
actual use. If there is already an address mapped to the destination
|
|
address, the server may reuse that mapping.
|
|
|
|
If the original address is already mapped to a different address, the old
|
|
mapping is removed. If the original address and the destination address
|
|
are the same, the server removes any mapping in place for the original
|
|
address.
|
|
|
|
{Note: This feature is designed to be used to help Tor-ify applications
|
|
that need to use SOCKS4 or hostname-less SOCKS5. There are three
|
|
approaches to doing this:
|
|
1. Somehow make them use SOCKS4a or SOCKS5-with-hostnames instead.
|
|
2. Use tor-resolve (or another interface to Tor's resolve-over-SOCKS
|
|
feature) to resolve the hostname remotely. This doesn't work
|
|
with special addresses like x.onion or x.y.exit.
|
|
3. Use MAPADDRESS to map an IP address to the desired hostname, and then
|
|
arrange to fool the application into thinking that the hostname
|
|
has resolved to that IP.
|
|
This functionality is designed to help implement the 3rd approach.}
|
|
|
|
[XXXX When, if ever, can mappings expire? Should they expire?]
|
|
[XXXX What addresses, if any, are safe to use?]
|
|
|
|
3.12 GETINFO (Type 0x000B)
|
|
|
|
[Proposal; not finalized]
|
|
|
|
Sent from the client to the server. The message body is as for GETCONF:
|
|
one or more NL-terminated strings. The server replies with an INFOVALUE
|
|
message.
|
|
|
|
Unlike GETCONF, this message is used for data that are not stored in the
|
|
Tor configuration file, but instead.
|
|
|
|
Recognized key and their values include:
|
|
|
|
"version" -- The version of the server's software, including the name
|
|
of the software. (example: "Tor 0.0.9.4")
|
|
|
|
"desc/id/<OR identity>" or "desc/name/<OR nickname>" -- the latest server
|
|
descriptor for a given OR, NUL-terminated. If no such OR is known, the
|
|
corresponding value is an empty string.
|
|
|
|
"desc/all-ids" -- a comma-separated list of all known OR identities.
|
|
|
|
"addr-mappings" -- a NL-terminated list of address mappings, each in
|
|
the form of "from-address" SP "to-address".
|
|
|
|
3.13 INFOVALUE (Type 0x000C)
|
|
|
|
[Proposal; not finalized]
|
|
|
|
Sent from the server to the client in response to a GETINFO message.
|
|
Contains one or more items of the format:
|
|
|
|
Key [(NUL-terminated string)]
|
|
Value [(NUL-terminated string)]
|
|
|
|
The keys match those given in the GETINFO message.
|
|
|
|
3.14 EXTENDCIRCUIT (Type 0x000D)
|
|
|
|
[Proposal; not finalized]
|
|
|
|
Sent from the client to the server. The message body contains two fields:
|
|
Circuit ID [4 octets]
|
|
Path [NUL-terminated, comma-delimited string of OR nickname/identity]
|
|
|
|
This request takes one of two forms: either the Circuit ID is zero, in
|
|
which case it is a request for the server to build a new circuit according
|
|
to the specified path, or the Circuit ID is nonzero, in which case it is a
|
|
request for the server to extend an existing circuit with that ID according
|
|
to the specified path.
|
|
|
|
If the request for a NEW circuit is successful, then the resultant DONE
|
|
message will contain a message body consisting of the four-octet Circuit ID
|
|
of the newly created circuit.
|
|
|
|
3.15 ATTACHSTREAM (Type 0x000E)
|
|
|
|
[Proposal; not finalized]
|
|
|
|
Sent from the client to the server. The message body contains two fields:
|
|
Stream ID [4 octets]
|
|
Circuit ID [4 octets]
|
|
|
|
This message informs the server that the specified stream should be
|
|
associated with the specified circuit. Each stream may be associated with
|
|
at most one circuit, and multiple streams may share the same circuit.
|
|
|
|
3.16 POSTDESCRIPTOR (Type 0x000F)
|
|
|
|
[Proposal; not finalized]
|
|
|
|
Sent from the client to the server. The message body contains one field:
|
|
Descriptor [NUL-terminated string]
|
|
|
|
This message informs the server about a new descriptor.
|
|
|
|
The descriptor, when parsed, must contain a number of well-specified
|
|
fields, including fields for its nickname and identity.
|
|
|
|
If there is an error in parsing the descriptor, or if the server rejects
|
|
the descriptor for any reason, the server must send an appropriate error
|
|
message.
|
|
|
|
4. Implementation notes
|
|
|
|
4.1. There are four ways we could authenticate, for now:
|
|
|
|
1) Listen on 127.0.0.1; trust all local users.
|
|
|
|
2) Write a named socket in tor's data-directory or in some other location;
|
|
rely on the OS to ensure that only authorized users can open it. (NOTE:
|
|
the Linux unix(7) man page suggests that some BSDs don't enforce
|
|
authorization.) If the OS has named sockets, and implements
|
|
authentication, trust all users who can read Tor's data directory.
|
|
|
|
3) Write a random magic cookie to the FS in Tor's data-directory; use that
|
|
magic cookie for authentication. Trust all users who can read Tor's data
|
|
directory.
|
|
|
|
4) Store a salted-and-hashed passphrase in Tor's configuration. Use the
|
|
passphrase for authentication. Trust all users who know the passphrase.
|
|
|
|
On Win32, our only options are 1, 3, and 4. Since the semantics for 2
|
|
and 3 are so similar, we chose to not support 2, and just always bind
|
|
on 127.0.0.1. We've implemented 1, 3, and 4.
|
|
|
|
By default, the Tor client accepts authentication approach #1. If
|
|
the controller wants Tor to demand more authentication, it should use
|
|
setconf and saveconf to configure Tor to demand more next time.
|
|
|
|
4.2. Don't let the buffer get too big.
|
|
|
|
If you ask for lots of events, and 16MB of them queue up on the buffer,
|
|
the Tor process will close the socket.
|
|
|