Class TorControlConnection

java.lang.Object
net.freehaven.tor.control.TorControlConnection
All Implemented Interfaces:
TorControlCommands

public class TorControlConnection extends Object implements TorControlCommands
A connection to a running Tor process as specified in control-spec.txt.
  • Constructor Details

    • TorControlConnection

      public TorControlConnection(Socket connection) throws IOException
      Create a new TorControlConnection to communicate with Tor over a given socket. After calling this constructor, it is typical to call launchThread and authenticate.
      Throws:
      IOException
    • TorControlConnection

      public TorControlConnection(InputStream i, OutputStream o)
      Create a new TorControlConnection to communicate with Tor over an arbitrary pair of data streams.
    • TorControlConnection

      public TorControlConnection(Reader i, Writer o)
  • Method Details

    • writeEscaped

      protected final void writeEscaped(String s) throws IOException
      Throws:
      IOException
    • quote

      protected static String quote(String s)
    • readReply

      protected final ArrayList<net.freehaven.tor.control.TorControlConnection.ReplyLine> readReply() throws IOException
      Throws:
      IOException
    • sendAndWaitForResponse

      protected List<net.freehaven.tor.control.TorControlConnection.ReplyLine> sendAndWaitForResponse(String s, String rest) throws IOException
      Throws:
      IOException
    • handleEvent

      protected void handleEvent(ArrayList<net.freehaven.tor.control.TorControlConnection.ReplyLine> events)
      Helper: decode a CMD_EVENT command and dispatch it to our EventHandler (if any).
    • setDebugging

      public void setDebugging(PrintWriter w)
      Sets w as the PrintWriter for debugging output, which writes out all messages passed between Tor and the controller. Outgoing messages are preceded by "\>\>" and incoming messages are preceded by "\<\<"
    • setDebugging

      public void setDebugging(PrintStream s)
      Sets s as the PrintStream for debugging output, which writes out all messages passed between Tor and the controller. Outgoing messages are preceded by "\>\>" and incoming messages are preceded by "\<\<"
    • setEventHandler

      public void setEventHandler(EventHandler handler)
      Set the EventHandler object that will be notified of any events Tor delivers to this connection. To make Tor send us events, call setEvents().
    • launchThread

      public Thread launchThread(boolean daemon)
      Start a thread to react to Tor's responses in the background. This is necessary to handle asynchronous events and synchronous responses that arrive independantly over the same socket.
    • checkThread

      protected void checkThread()
    • react

      protected void react() throws IOException
      helper: implement the main background loop.
      Throws:
      IOException
    • setConf

      public void setConf(String key, String value) throws IOException
      Change the value of the configuration option 'key' to 'val'.
      Throws:
      IOException
    • setConf

      public void setConf(Map<String,String> kvMap) throws IOException
      Change the values of the configuration options stored in kvMap.
      Throws:
      IOException
    • setConf

      public void setConf(Collection<String> kvList) throws IOException
      Changes the values of the configuration options stored in kvList. Each list element in kvList is expected to be String of the format "key value".

      Tor behaves as though it had just read each of the key-value pairs from its configuration file. Keywords with no corresponding values have their configuration values reset to their defaults. setConf is all-or-nothing: if there is an error in any of the configuration settings, Tor sets none of them.

      When a configuration option takes multiple values, or when multiple configuration keys form a context-sensitive group (see getConf 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 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), include a String in kvList containing the key and no value.

      Throws:
      IOException
    • resetConf

      public void resetConf(Collection<String> keys) throws IOException
      Try to reset the values listed in the collection 'keys' to their default values.
      Throws:
      IOException
    • getConf

      public List<ConfigEntry> getConf(String key) throws IOException
      Return the value of the configuration option 'key'
      Throws:
      IOException
    • getConf

      public List<ConfigEntry> getConf(Collection<String> keys) throws IOException
      Requests the values of the configuration variables listed in keys. Results are returned as a list of ConfigEntry objects.

      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.

      Throws:
      IOException
    • setEvents

      public void setEvents(List<String> events) throws IOException
      Request that the server inform the client about interesting events. Each element of events is one of the following Strings: ["CIRC" | "STREAM" | "ORCONN" | "BW" | "DEBUG" | "INFO" | "NOTICE" | "WARN" | "ERR" | "NEWDESC" | "ADDRMAP"] .

      Any events not listed in the events are turned off; thus, calling setEvents with an empty events argument turns off all event reporting.

      Throws:
      IOException
    • authenticate

      public void authenticate(byte[] auth) throws IOException
      Authenticates the controller to the Tor server.

      By default, the current Tor implementation trusts all local users, and the controller can authenticate itself by calling authenticate(new byte[0]).

      If the 'CookieAuthentication' option is true, Tor writes a "magic cookie" file named "control_auth_cookie" into its data directory. To authenticate, the controller must send the contents of this file in auth.

      If the 'HashedControlPassword' option is set, auth must contain the salted hash of a secret password. The salted hash is computed according to the S2K algorithm in RFC 2440 (OpenPGP), and prefixed with the s2k specifier. This is then encoded in hexadecimal, prefixed by the indicator sequence "16:".

      You can generate the salt of a password by calling 'tor --hash-password ' or by using the provided PasswordDigest class. To authenticate under this scheme, the controller sends Tor the original secret that was used to generate the password.

      Throws:
      IOException
    • saveConf

      public void saveConf() throws IOException
      Instructs the server to write out its configuration options into its torrc.
      Throws:
      IOException
    • signal

      public void signal(String signal) throws IOException
      Sends a signal from the controller to the Tor server. signal is one of the following Strings:
      • "RELOAD" or "HUP" : Reload config items, refetch directory
      • "SHUTDOWN" or "INT" : Controlled shutdown: if server is an OP, exit immediately. If it's an OR, close listeners and exit after 30 seconds
      • "DUMP" or "USR1" : Dump stats: log information about open connections and circuits
      • "DEBUG" or "USR2" : Debug: switch all open logs to loglevel debug
      • "HALT" or "TERM" : Immediate shutdown: clean up and exit now
      Throws:
      IOException
    • shutdownTor

      public void shutdownTor(String signal) throws IOException
      Send a signal to the Tor process to shut it down or halt it. Does not wait for a response.
      Throws:
      IOException
    • mapAddresses

      public Map<String,String> mapAddresses(Collection<String> kvLines) throws IOException
      Tells the Tor server that future SOCKS requests for connections to a set of original addresses should be replaced with connections to the specified replacement addresses. Each element of kvLines is a String of the form "old-address new-address". This function returns the new address mapping.

      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), signifying that the server should choose the original address itself, and return that address in the reply. The server should ensure that it returns 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.

      Mappings set by the controller last until the Tor process exits: they never expire. If the controller wants the mapping to last only a certain time, then it must explicitly un-map the address when that time has elapsed.

      Throws:
      IOException
    • mapAddresses

      public Map<String,String> mapAddresses(Map<String,String> addresses) throws IOException
      Throws:
      IOException
    • mapAddress

      public String mapAddress(String fromAddr, String toAddr) throws IOException
      Throws:
      IOException
    • getInfo

      public Map<String,String> getInfo(Collection<String> keys) throws IOException
      Queries the Tor server for keyed values that are not stored in the torrc configuration file. Returns a map of keys to values.

      Recognized keys include:

      • "version" : The version of the server's software, including the name of the software. (example: "Tor 0.0.9.4")
      • "desc/id/" or "desc/name/" : the latest server descriptor for a given OR, NUL-terminated. If no such OR is known, the corresponding value is an empty string.
      • "network-status" : a space-separated list of all known OR identities. This is in the same format as the router-status line in directories; see tor-spec.txt for details.
      • "addr-mappings/all"
      • "addr-mappings/config"
      • "addr-mappings/cache"
      • "addr-mappings/control" : a space-separated list of address mappings, each in the form of "from-address=to-address". The 'config' key returns those address mappings set in the configuration; the 'cache' key returns the mappings in the client-side DNS cache; the 'control' key returns the mappings set via the control interface; the 'all' target returns the mappings set through any mechanism.
      • "circuit-status" : A series of lines as for a circuit status event. Each line is of the form: "CircuitID CircStatus Path"
      • "stream-status" : A series of lines as for a stream status event. Each is of the form: "StreamID StreamStatus CircID Target"
      • "orconn-status" : A series of lines as for an OR connection status event. Each is of the form: "ServerID ORStatus"
      Throws:
      IOException
    • getInfo

      public String getInfo(String key) throws IOException
      Return the value of the information field 'key'
      Throws:
      IOException
    • extendCircuit

      public String extendCircuit(String circID, String path) throws IOException
      An extendCircuit request takes one of two forms: either the circID is zero, in which case it is a request for the server to build a new circuit according to the specified path, or the circID 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 successful, returns the Circuit ID of the (maybe newly created) circuit.

      Throws:
      IOException
    • attachStream

      public void attachStream(String streamID, String circID) throws IOException
      Informs the Tor server that the stream specified by streamID should be associated with the circuit specified by circID.

      Each stream may be associated with at most one circuit, and multiple streams may share the same circuit. Streams can only be attached to completed circuits (that is, circuits that have sent a circuit status "BUILT" event or are listed as built in a getInfo circuit-status request).

      If circID is 0, responsibility for attaching the given stream is returned to Tor.

      By default, Tor automatically attaches streams to circuits itself, unless the configuration variable "__LeaveStreamsUnattached" is set to "1". Attempting to attach streams via TC when "__LeaveStreamsUnattached" is false may cause a race between Tor and the controller, as both attempt to attach streams to circuits.

      Throws:
      IOException
    • postDescriptor

      public String postDescriptor(String desc) throws IOException
      Tells Tor about the server descriptor in desc.

      The descriptor, when parsed, must contain a number of well-specified fields, including fields for its nickname and identity.

      Throws:
      IOException
    • redirectStream

      public void redirectStream(String streamID, String address) throws IOException
      Tells Tor to change the exit address of the stream identified by streamID to address. No remapping is performed on the new provided address.

      To be sure that the modified address will be used, this event must be sent after a new stream event is received, and before attaching this stream to a circuit.

      Throws:
      IOException
    • closeStream

      public void closeStream(String streamID, byte reason) throws IOException
      Tells Tor to close the stream identified by streamID. reason should be one of the Tor RELAY_END reasons given in tor-spec.txt, as a decimal:
      • 1 -- REASON_MISC (catch-all for unlisted reasons)
      • 2 -- REASON_RESOLVEFAILED (couldn't look up hostname)
      • 3 -- REASON_CONNECTREFUSED (remote host refused connection)
      • 4 -- REASON_EXITPOLICY (OR refuses to connect to host or port)
      • 5 -- REASON_DESTROY (Circuit is being destroyed)
      • 6 -- REASON_DONE (Anonymized TCP connection was closed)
      • 7 -- REASON_TIMEOUT (Connection timed out, or OR timed out while connecting)
      • 8 -- (unallocated)
      • 9 -- REASON_HIBERNATING (OR is temporarily hibernating)
      • 10 -- REASON_INTERNAL (Internal error at the OR)
      • 11 -- REASON_RESOURCELIMIT (OR has no resources to fulfill request)
      • 12 -- REASON_CONNRESET (Connection was unexpectedly reset)
      • 13 -- REASON_TORPROTOCOL (Sent when closing connection because of Tor protocol violations)

      Tor may hold the stream open for a while to flush any data that is pending.

      Throws:
      IOException
    • closeCircuit

      public void closeCircuit(String circID, boolean ifUnused) throws IOException
      Tells Tor to close the circuit identified by circID. If ifUnused is true, do not close the circuit unless it is unused.
      Throws:
      IOException
    • takeOwnership

      public void takeOwnership() throws IOException
      Tells Tor to exit when this control connection is closed. This command was added in Tor 0.2.2.28-beta.
      Throws:
      IOException
    • addOnion

      public Map<String,String> addOnion(Map<Integer,String> portLines) throws IOException
      Tells Tor to generate and set up a new onion service using the best supported algorithm.

      ADD_ONION was added in Tor 0.2.7.1-alpha.

      Throws:
      IOException
    • addOnion

      public Map<String,String> addOnion(Map<Integer,String> portLines, boolean ephemeral, boolean detach) throws IOException
      Tells Tor to generate and set up a new onion service using the best supported algorithm.

      ADD_ONION was added in Tor 0.2.7.1-alpha.

      Throws:
      IOException
    • addOnion

      public Map<String,String> addOnion(String privKey, Map<Integer,String> portLines) throws IOException
      Tells Tor to set up an onion service using the provided private key.

      ADD_ONION was added in Tor 0.2.7.1-alpha.

      Throws:
      IOException
    • addOnion

      public Map<String,String> addOnion(String privKey, Map<Integer,String> portLines, boolean ephemeral, boolean detach) throws IOException
      Tells Tor to set up an onion service using the provided private key.

      ADD_ONION was added in Tor 0.2.7.1-alpha.

      Throws:
      IOException
    • addOnion

      public Map<String,String> addOnion(String privKey, Map<Integer,String> portLines, List<String> flags) throws IOException
      Tells Tor to set up an onion service.

      ADD_ONION was added in Tor 0.2.7.1-alpha.

      Throws:
      IOException
    • delOnion

      public void delOnion(String hostname) throws IOException
      Tells Tor to take down an onion service previously set up with addOnion(). The hostname excludes the .onion extension.

      DEL_ONION was added in Tor 0.2.7.1-alpha.

      Throws:
      IOException