/** * Request that the server inform the client about interesting events. Each element of * <b>events</b> is one of the following Strings: ["CIRC" | "STREAM" | "ORCONN" | "BW" | "DEBUG" | * "INFO" | "NOTICE" | "WARN" | "ERR" | "NEWDESC" | "ADDRMAP"] . * * <p>Any events not listed in the <b>events</b> are turned off; thus, calling setEvents with an * empty <b>events</b> argument turns off all event reporting. */ public void setEvents(List<String> events) throws IOException { StringBuffer sb = new StringBuffer("SETEVENTS"); for (Iterator<String> it = events.iterator(); it.hasNext(); ) { sb.append(" ").append(it.next()); } sb.append("\r\n"); sendAndWaitForResponse(sb.toString(), null); }
/** Try to reset the values listed in the collection 'keys' to their default values. */ public void resetConf(Collection<String> keys) throws IOException { if (keys.size() == 0) return; StringBuffer b = new StringBuffer("RESETCONF"); for (Iterator<String> it = keys.iterator(); it.hasNext(); ) { String key = it.next(); b.append(" ").append(key); } b.append("\r\n"); sendAndWaitForResponse(b.toString(), null); }
/** * Changes the values of the configuration options stored in <b>kvList</b>. Each list element in * <b>kvList</b> is expected to be String of the format "key value". * * <p>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. * * <p>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. * * <p>To remove all settings for a given option entirely (and go back to its default value), * include a String in <b>kvList</b> containing the key and no value. */ public void setConf(Collection<String> kvList) throws IOException { if (kvList.size() == 0) return; StringBuffer b = new StringBuffer("SETCONF"); for (Iterator<String> it = kvList.iterator(); it.hasNext(); ) { String kv = it.next(); int i = kv.indexOf(' '); if (i == -1) b.append(" ").append(kv); b.append(" ").append(kv.substring(0, i)).append("=").append(quote(kv.substring(i + 1))); } b.append("\r\n"); sendAndWaitForResponse(b.toString(), null); }
/** * Tells Tor to close the circuit identified by <b>circID</b>. If <b>ifUnused</b> is true, do not * close the circuit unless it is unused. */ public void closeCircuit(String circID, boolean ifUnused) throws IOException { sendAndWaitForResponse("CLOSECIRCUIT " + circID + (ifUnused ? " IFUNUSED" : "") + "\r\n", null); }
/** * Tells Tor to close the stream identified by <b>streamID</b>. <b>reason</b> should be one of the * Tor RELAY_END reasons given in tor-spec.txt, as a decimal: * * <ul> * <li>1 -- REASON_MISC (catch-all for unlisted reasons) * <li>2 -- REASON_RESOLVEFAILED (couldn't look up hostname) * <li>3 -- REASON_CONNECTREFUSED (remote host refused connection) * <li>4 -- REASON_EXITPOLICY (OR refuses to connect to host or port) * <li>5 -- REASON_DESTROY (Circuit is being destroyed) * <li>6 -- REASON_DONE (Anonymized TCP connection was closed) * <li>7 -- REASON_TIMEOUT (Connection timed out, or OR timed out while connecting) * <li>8 -- (unallocated) * <li>9 -- REASON_HIBERNATING (OR is temporarily hibernating) * <li>10 -- REASON_INTERNAL (Internal error at the OR) * <li>11 -- REASON_RESOURCELIMIT (OR has no resources to fulfill request) * <li>12 -- REASON_CONNRESET (Connection was unexpectedly reset) * <li>13 -- REASON_TORPROTOCOL (Sent when closing connection because of Tor protocol * violations) * </ul> * * Tor may hold the stream open for a while to flush any data that is pending. */ public void closeStream(String streamID, byte reason) throws IOException { sendAndWaitForResponse("CLOSESTREAM " + streamID + " " + reason + "\r\n", null); }
/** * Tells Tor to change the exit address of the stream identified by <b>streamID</b> to * <b>address</b>. No remapping is performed on the new provided address. * * <p>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. */ public void redirectStream(String streamID, String address) throws IOException { sendAndWaitForResponse("REDIRECTSTREAM " + streamID + " " + address + "\r\n", null); }
/** * Informs the Tor server that the stream specified by <b>streamID</b> should be associated with * the circuit specified by <b>circID</b>. * * <p>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). * * <p>If <b>circID</b> is 0, responsibility for attaching the given stream is returned to Tor. * * <p>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. */ public void attachStream(String streamID, String circID) throws IOException { sendAndWaitForResponse("ATTACHSTREAM " + streamID + " " + circID + "\r\n", null); }
/** * Sends a signal from the controller to the Tor server. <b>signal</b> is one of the following * Strings: * * <ul> * <li>"RELOAD" or "HUP" : Reload config items, refetch directory * <li>"SHUTDOWN" or "INT" : Controlled shutdown: if server is an OP, exit immediately. If it's * an OR, close listeners and exit after 30 seconds * <li>"DUMP" or "USR1" : Dump stats: log information about open connections and circuits * <li>"DEBUG" or "USR2" : Debug: switch all open logs to loglevel debug * <li>"HALT" or "TERM" : Immediate shutdown: clean up and exit now * </ul> */ public void signal(String signal) throws IOException { String cmd = "SIGNAL " + signal + "\r\n"; sendAndWaitForResponse(cmd, null); }
/** Instructs the server to write out its configuration options into its torrc. */ public void saveConf() throws IOException { sendAndWaitForResponse("SAVECONF\r\n", null); }
/** * Authenticates the controller to the Tor server. * * <p>By default, the current Tor implementation trusts all local users, and the controller can * authenticate itself by calling authenticate(new byte[0]). * * <p>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 <b>auth</b>. * * <p>If the 'HashedControlPassword' option is set, <b>auth</b> 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:". * * <p>You can generate the salt of a password by calling 'tor --hash-password <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. */ public void authenticate(byte[] auth) throws IOException { String cmd = "AUTHENTICATE " + Bytes.hex(auth) + "\r\n"; sendAndWaitForResponse(cmd, null); }