diff --git a/tor-android-binary/src/main/assets/bridges.txt b/tor-android-binary/src/main/assets/common/bridges.txt similarity index 100% rename from tor-android-binary/src/main/assets/bridges.txt rename to tor-android-binary/src/main/assets/common/bridges.txt diff --git a/tor-android-binary/src/main/res/raw/geoip.mp3 b/tor-android-binary/src/main/assets/common/geoip.mp3 similarity index 100% rename from tor-android-binary/src/main/res/raw/geoip.mp3 rename to tor-android-binary/src/main/assets/common/geoip.mp3 diff --git a/tor-android-binary/src/main/assets/common/geoip6.mp3 b/tor-android-binary/src/main/assets/common/geoip6.mp3 new file mode 100644 index 00000000..e69de29b diff --git a/tor-android-binary/src/main/res/raw/torpolipo.conf b/tor-android-binary/src/main/assets/common/torpolipo.conf similarity index 100% rename from tor-android-binary/src/main/res/raw/torpolipo.conf rename to tor-android-binary/src/main/assets/common/torpolipo.conf diff --git a/tor-android-binary/src/main/res/raw/torrc b/tor-android-binary/src/main/assets/common/torrc similarity index 100% rename from tor-android-binary/src/main/res/raw/torrc rename to tor-android-binary/src/main/assets/common/torrc diff --git a/tor-android-binary/src/main/java/net/freehaven/tor/control/.cvsignore b/tor-android-binary/src/main/java/net/freehaven/tor/control/.cvsignore deleted file mode 100644 index 6b468b62..00000000 --- a/tor-android-binary/src/main/java/net/freehaven/tor/control/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.class diff --git a/tor-android-binary/src/main/java/net/freehaven/tor/control/Bytes.java b/tor-android-binary/src/main/java/net/freehaven/tor/control/Bytes.java deleted file mode 100644 index e754d907..00000000 --- a/tor-android-binary/src/main/java/net/freehaven/tor/control/Bytes.java +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -import java.util.Arrays; -import java.util.List; - -/** - * Static class to do bytewise structure manipulation in Java. - */ -/* XXXX There must be a better way to do most of this. - * XXXX The string logic here uses default encoding, which is stupid. - */ -final class Bytes { - - /** Write the two-byte value in 's' into the byte array 'ba', starting at - * the index 'pos'. */ - public static void setU16(byte[] ba, int pos, short s) { - ba[pos] = (byte)((s >> 8) & 0xff); - ba[pos+1] = (byte)((s ) & 0xff); - } - - /** Write the four-byte value in 'i' into the byte array 'ba', starting at - * the index 'pos'. */ - public static void setU32(byte[] ba, int pos, int i) { - ba[pos] = (byte)((i >> 24) & 0xff); - ba[pos+1] = (byte)((i >> 16) & 0xff); - ba[pos+2] = (byte)((i >> 8) & 0xff); - ba[pos+3] = (byte)((i ) & 0xff); - } - - /** Return the four-byte value starting at index 'pos' within 'ba' */ - public static int getU32(byte[] ba, int pos) { - return - ((ba[pos ]&0xff)<<24) | - ((ba[pos+1]&0xff)<<16) | - ((ba[pos+2]&0xff)<< 8) | - ((ba[pos+3]&0xff)); - } - - public static String getU32S(byte[] ba, int pos) { - return String.valueOf( (getU32(ba,pos))&0xffffffffL ); - } - - /** Return the two-byte value starting at index 'pos' within 'ba' */ - public static int getU16(byte[] ba, int pos) { - return - ((ba[pos ]&0xff)<<8) | - ((ba[pos+1]&0xff)); - } - - /** Return the string starting at position 'pos' of ba and extending - * until a zero byte or the end of the string. */ - public static String getNulTerminatedStr(byte[] ba, int pos) { - int len, maxlen = ba.length-pos; - for (len=0; len lst, byte[] ba, int pos, byte split) { - while (pos < ba.length && ba[pos] != 0) { - int len; - for (len=0; pos+len < ba.length; ++len) { - if (ba[pos+len] == 0 || ba[pos+len] == split) - break; - } - if (len>0) - lst.add(new String(ba, pos, len)); - pos += len; - if (ba[pos] == split) - ++pos; - } - } - - /** - * Read bytes from 'ba' starting at 'pos', dividing them into strings - * along the character in 'split' and writing them into 'lst' - */ - public static List splitStr(List lst, String str) { - // split string on spaces, include trailing/leading - String[] tokenArray = str.split(" ", -1); - if (lst == null) { - lst = Arrays.asList( tokenArray ); - } else { - lst.addAll( Arrays.asList( tokenArray ) ); - } - return lst; - } - - private static final char[] NYBBLES = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' - }; - - public static final String hex(byte[] ba) { - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < ba.length; ++i) { - int b = (ba[i]) & 0xff; - buf.append(NYBBLES[b >> 4]); - buf.append(NYBBLES[b&0x0f]); - } - return buf.toString(); - } - - private Bytes() {}; -} - diff --git a/tor-android-binary/src/main/java/net/freehaven/tor/control/ConfigEntry.java b/tor-android-binary/src/main/java/net/freehaven/tor/control/ConfigEntry.java deleted file mode 100644 index 31eb4b8e..00000000 --- a/tor-android-binary/src/main/java/net/freehaven/tor/control/ConfigEntry.java +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -/** A single key-value pair from Tor's configuration. */ -public class ConfigEntry { - public ConfigEntry(String k, String v) { - key = k; - value = v; - is_default = false; - } - public ConfigEntry(String k) { - key = k; - value = ""; - is_default = true; - } - public final String key; - public final String value; - public final boolean is_default; -} diff --git a/tor-android-binary/src/main/java/net/freehaven/tor/control/EventHandler.java b/tor-android-binary/src/main/java/net/freehaven/tor/control/EventHandler.java deleted file mode 100644 index 5a4e2b5b..00000000 --- a/tor-android-binary/src/main/java/net/freehaven/tor/control/EventHandler.java +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -/** - * Abstract interface whose methods are invoked when Tor sends us an event. - * - * @see TorControlConnection#setEventHandler - * @see TorControlConnection#setEvents - */ -public interface EventHandler { - /** - * Invoked when a circuit's status has changed. - * Possible values for status are: - *
    - *
  • "LAUNCHED" : circuit ID assigned to new circuit
  • - *
  • "BUILT" : all hops finished, can now accept streams
  • - *
  • "EXTENDED" : one more hop has been completed
  • - *
  • "FAILED" : circuit closed (was not built)
  • - *
  • "CLOSED" : circuit closed (was built)
  • - *
- * - * circID is the alphanumeric identifier of the affected circuit, - * and path is a comma-separated list of alphanumeric ServerIDs. - */ - public void circuitStatus(String status, String circID, String path); - /** - * Invoked when a stream's status has changed. - * Possible values for status are: - *
    - *
  • "NEW" : New request to connect
  • - *
  • "NEWRESOLVE" : New request to resolve an address
  • - *
  • "SENTCONNECT" : Sent a connect cell along a circuit
  • - *
  • "SENTRESOLVE" : Sent a resolve cell along a circuit
  • - *
  • "SUCCEEDED" : Received a reply; stream established
  • - *
  • "FAILED" : Stream failed and not retriable.
  • - *
  • "CLOSED" : Stream closed
  • - *
  • "DETACHED" : Detached from circuit; still retriable.
  • - *
- * - * streamID is the alphanumeric identifier of the affected stream, - * and its target is specified as address:port. - */ - public void streamStatus(String status, String streamID, String target); - /** - * Invoked when the status of a connection to an OR has changed. - * Possible values for status are ["LAUNCHED" | "CONNECTED" | "FAILED" | "CLOSED"]. - * orName is the alphanumeric identifier of the OR affected. - */ - public void orConnStatus(String status, String orName); - /** - * Invoked once per second. read and written are - * the number of bytes read and written, respectively, in - * the last second. - */ - public void bandwidthUsed(long read, long written); - /** - * Invoked whenever Tor learns about new ORs. The orList object - * contains the alphanumeric ServerIDs associated with the new ORs. - */ - public void newDescriptors(java.util.List orList); - /** - * Invoked when Tor logs a message. - * severity is one of ["DEBUG" | "INFO" | "NOTICE" | "WARN" | "ERR"], - * and msg is the message string. - */ - public void message(String severity, String msg); - /** - * Invoked when an unspecified message is received. - * is the message type, and is the message string. - */ - public void unrecognized(String type, String msg); - -} - diff --git a/tor-android-binary/src/main/java/net/freehaven/tor/control/NullEventHandler.java b/tor-android-binary/src/main/java/net/freehaven/tor/control/NullEventHandler.java deleted file mode 100644 index a2390e68..00000000 --- a/tor-android-binary/src/main/java/net/freehaven/tor/control/NullEventHandler.java +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -/** - * Implementation of EventHandler that ignores all events. Useful - * when you only want to override one method. - */ -public class NullEventHandler implements EventHandler { - public void circuitStatus(String status, String circID, String path) {} - public void streamStatus(String status, String streamID, String target) {} - public void orConnStatus(String status, String orName) {} - public void bandwidthUsed(long read, long written) {} - public void newDescriptors(java.util.List orList) {} - public void message(String severity, String msg) {} - public void unrecognized(String type, String msg) {} -} - diff --git a/tor-android-binary/src/main/java/net/freehaven/tor/control/PasswordDigest.java b/tor-android-binary/src/main/java/net/freehaven/tor/control/PasswordDigest.java deleted file mode 100644 index 03d0a98e..00000000 --- a/tor-android-binary/src/main/java/net/freehaven/tor/control/PasswordDigest.java +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; - -/** - * A hashed digest of a secret password (used to set control connection - * security.) - * - * For the actual hashing algorithm, see RFC2440's secret-to-key conversion. - */ -public class PasswordDigest { - - private final byte[] secret; - private final String hashedKey; - - /** Return a new password digest with a random secret and salt. */ - public static PasswordDigest generateDigest() { - byte[] secret = new byte[20]; - SecureRandom rng = new SecureRandom(); - rng.nextBytes(secret); - return new PasswordDigest(secret); - } - - /** Construct a new password digest with a given secret and random salt */ - public PasswordDigest(byte[] secret) { - this(secret, null); - } - - /** Construct a new password digest with a given secret and random salt. - * Note that the 9th byte of the specifier determines the number of hash - * iterations as in RFC2440. - */ - public PasswordDigest(byte[] secret, byte[] specifier) { - this.secret = secret.clone(); - if (specifier == null) { - specifier = new byte[9]; - SecureRandom rng = new SecureRandom(); - rng.nextBytes(specifier); - specifier[8] = 96; - } - hashedKey = "16:"+encodeBytes(secretToKey(secret, specifier)); - } - - /** Return the secret used to generate this password hash. - */ - public byte[] getSecret() { - return secret.clone(); - } - - /** Return the hashed password in the format used by Tor. */ - public String getHashedPassword() { - return hashedKey; - } - - /** Parameter used by RFC2440's s2k algorithm. */ - private static final int EXPBIAS = 6; - - /** Implement rfc2440 s2k */ - public static byte[] secretToKey(byte[] secret, byte[] specifier) { - MessageDigest d; - try { - d = MessageDigest.getInstance("SHA-1"); - } catch (NoSuchAlgorithmException ex) { - throw new RuntimeException("Can't run without sha-1."); - } - int c = (specifier[8])&0xff; - int count = (16 + (c&15)) << ((c>>4) + EXPBIAS); - - byte[] tmp = new byte[8+secret.length]; - System.arraycopy(specifier, 0, tmp, 0, 8); - System.arraycopy(secret, 0, tmp, 8, secret.length); - while (count > 0) { - if (count >= tmp.length) { - d.update(tmp); - count -= tmp.length; - } else { - d.update(tmp, 0, count); - count = 0; - } - } - byte[] key = new byte[20+9]; - System.arraycopy(d.digest(), 0, key, 9, 20); - System.arraycopy(specifier, 0, key, 0, 9); - return key; - } - - /** Return a hexadecimal encoding of a byte array. */ - // XXX There must be a better way to do this in Java. - private static final String encodeBytes(byte[] ba) { - return Bytes.hex(ba); - } - -} - diff --git a/tor-android-binary/src/main/java/net/freehaven/tor/control/README b/tor-android-binary/src/main/java/net/freehaven/tor/control/README deleted file mode 100644 index b310c7d5..00000000 --- a/tor-android-binary/src/main/java/net/freehaven/tor/control/README +++ /dev/null @@ -1,4 +0,0 @@ -We broke the version detection stuff in Tor 0.1.2.16 / 0.2.0.4-alpha. -Somebody should rip out the v0 control protocol stuff from here, and -it should start working again. -RD - diff --git a/tor-android-binary/src/main/java/net/freehaven/tor/control/TorControlCommands.java b/tor-android-binary/src/main/java/net/freehaven/tor/control/TorControlCommands.java deleted file mode 100644 index c98a1c48..00000000 --- a/tor-android-binary/src/main/java/net/freehaven/tor/control/TorControlCommands.java +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -/** Interface defining constants used by the Tor controller protocol. - */ -// XXXX Take documentation for these from control-spec.txt -public interface TorControlCommands { - - public static final short CMD_ERROR = 0x0000; - public static final short CMD_DONE = 0x0001; - public static final short CMD_SETCONF = 0x0002; - public static final short CMD_GETCONF = 0x0003; - public static final short CMD_CONFVALUE = 0x0004; - public static final short CMD_SETEVENTS = 0x0005; - public static final short CMD_EVENT = 0x0006; - public static final short CMD_AUTH = 0x0007; - public static final short CMD_SAVECONF = 0x0008; - public static final short CMD_SIGNAL = 0x0009; - public static final short CMD_MAPADDRESS = 0x000A; - public static final short CMD_GETINFO = 0x000B; - public static final short CMD_INFOVALUE = 0x000C; - public static final short CMD_EXTENDCIRCUIT = 0x000D; - public static final short CMD_ATTACHSTREAM = 0x000E; - public static final short CMD_POSTDESCRIPTOR = 0x000F; - public static final short CMD_FRAGMENTHEADER = 0x0010; - public static final short CMD_FRAGMENT = 0x0011; - public static final short CMD_REDIRECTSTREAM = 0x0012; - public static final short CMD_CLOSESTREAM = 0x0013; - public static final short CMD_CLOSECIRCUIT = 0x0014; - - public static final String[] CMD_NAMES = { - "ERROR", - "DONE", - "SETCONF", - "GETCONF", - "CONFVALUE", - "SETEVENTS", - "EVENT", - "AUTH", - "SAVECONF", - "SIGNAL", - "MAPADDRESS", - "GETINFO", - "INFOVALUE", - "EXTENDCIRCUIT", - "ATTACHSTREAM", - "POSTDESCRIPTOR", - "FRAGMENTHEADER", - "FRAGMENT", - "REDIRECTSTREAM", - "CLOSESTREAM", - "CLOSECIRCUIT", - }; - - public static final short EVENT_CIRCSTATUS = 0x0001; - public static final short EVENT_STREAMSTATUS = 0x0002; - public static final short EVENT_ORCONNSTATUS = 0x0003; - public static final short EVENT_BANDWIDTH = 0x0004; - public static final short EVENT_NEWDESCRIPTOR = 0x0006; - public static final short EVENT_MSG_DEBUG = 0x0007; - public static final short EVENT_MSG_INFO = 0x0008; - public static final short EVENT_MSG_NOTICE = 0x0009; - public static final short EVENT_MSG_WARN = 0x000A; - public static final short EVENT_MSG_ERROR = 0x000B; - - public static final String[] EVENT_NAMES = { - "(0)", - "CIRC", - "STREAM", - "ORCONN", - "BW", - "OLDLOG", - "NEWDESC", - "DEBUG", - "INFO", - "NOTICE", - "WARN", - "ERR", - }; - - public static final byte CIRC_STATUS_LAUNCHED = 0x01; - public static final byte CIRC_STATUS_BUILT = 0x02; - public static final byte CIRC_STATUS_EXTENDED = 0x03; - public static final byte CIRC_STATUS_FAILED = 0x04; - public static final byte CIRC_STATUS_CLOSED = 0x05; - - public static final String[] CIRC_STATUS_NAMES = { - "LAUNCHED", - "BUILT", - "EXTENDED", - "FAILED", - "CLOSED", - }; - - public static final byte STREAM_STATUS_SENT_CONNECT = 0x00; - public static final byte STREAM_STATUS_SENT_RESOLVE = 0x01; - public static final byte STREAM_STATUS_SUCCEEDED = 0x02; - public static final byte STREAM_STATUS_FAILED = 0x03; - public static final byte STREAM_STATUS_CLOSED = 0x04; - public static final byte STREAM_STATUS_NEW_CONNECT = 0x05; - public static final byte STREAM_STATUS_NEW_RESOLVE = 0x06; - public static final byte STREAM_STATUS_DETACHED = 0x07; - - public static final String[] STREAM_STATUS_NAMES = { - "SENT_CONNECT", - "SENT_RESOLVE", - "SUCCEEDED", - "FAILED", - "CLOSED", - "NEW_CONNECT", - "NEW_RESOLVE", - "DETACHED" - }; - - public static final byte OR_CONN_STATUS_LAUNCHED = 0x00; - public static final byte OR_CONN_STATUS_CONNECTED = 0x01; - public static final byte OR_CONN_STATUS_FAILED = 0x02; - public static final byte OR_CONN_STATUS_CLOSED = 0x03; - - public static final String[] OR_CONN_STATUS_NAMES = { - "LAUNCHED","CONNECTED","FAILED","CLOSED" - }; - - public static final byte SIGNAL_HUP = 0x01; - public static final byte SIGNAL_INT = 0x02; - public static final byte SIGNAL_USR1 = 0x0A; - public static final byte SIGNAL_USR2 = 0x0C; - public static final byte SIGNAL_TERM = 0x0F; - - public static final String ERROR_MSGS[] = { - "Unspecified error", - "Internal error", - "Unrecognized message type", - "Syntax error", - "Unrecognized configuration key", - "Invalid configuration value", - "Unrecognized byte code", - "Unauthorized", - "Failed authentication attempt", - "Resource exhausted", - "No such stream", - "No such circuit", - "No such OR", - }; - -} - diff --git a/tor-android-binary/src/main/java/net/freehaven/tor/control/TorControlConnection.java b/tor-android-binary/src/main/java/net/freehaven/tor/control/TorControlConnection.java deleted file mode 100644 index 05ed8c3c..00000000 --- a/tor-android-binary/src/main/java/net/freehaven/tor/control/TorControlConnection.java +++ /dev/null @@ -1,732 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.Reader; -import java.io.Writer; -import java.net.Socket; -import java.net.SocketException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; -import java.util.concurrent.CancellationException; - -/** A connection to a running Tor process as specified in control-spec.txt. */ -public class TorControlConnection implements TorControlCommands { - - private final LinkedList waiters; - private final BufferedReader input; - private final Writer output; - - private ControlParseThread thread; // Locking: this - - private volatile EventHandler handler; - private volatile PrintWriter debugOutput; - private volatile IOException parseThreadException; - - static class Waiter { - - List response; // Locking: this - - synchronized List getResponse() throws InterruptedException { - while (response == null) { - wait(); - } - return response; - } - - synchronized void setResponse(List response) { - this.response = response; - notifyAll(); - } - } - - static class ReplyLine { - - final String status; - final String msg; - final String rest; - - ReplyLine(String status, String msg, String rest) { - this.status = status; this.msg = msg; this.rest = rest; - } - } - - /** Create a new TorControlConnection to communicate with Tor over - * a given socket. After calling this constructor, it is typical to - * call launchThread and authenticate. */ - public TorControlConnection(Socket connection) throws IOException { - this(connection.getInputStream(), connection.getOutputStream()); - } - - /** Create a new TorControlConnection to communicate with Tor over - * an arbitrary pair of data streams. - */ - public TorControlConnection(InputStream i, OutputStream o) { - this(new InputStreamReader(i), new OutputStreamWriter(o)); - } - - public TorControlConnection(Reader i, Writer o) { - this.output = o; - if (i instanceof BufferedReader) - this.input = (BufferedReader) i; - else - this.input = new BufferedReader(i); - this.waiters = new LinkedList(); - } - - protected final void writeEscaped(String s) throws IOException { - StringTokenizer st = new StringTokenizer(s, "\n"); - while (st.hasMoreTokens()) { - String line = st.nextToken(); - if (line.startsWith(".")) - line = "."+line; - if (line.endsWith("\r")) - line += "\n"; - else - line += "\r\n"; - if (debugOutput != null) - debugOutput.print(">> "+line); - output.write(line); - } - output.write(".\r\n"); - if (debugOutput != null) - debugOutput.print(">> .\n"); - } - - protected static final String quote(String s) { - StringBuffer sb = new StringBuffer("\""); - for (int i = 0; i < s.length(); ++i) { - char c = s.charAt(i); - switch (c) - { - case '\r': - case '\n': - case '\\': - case '\"': - sb.append('\\'); - } - sb.append(c); - } - sb.append('\"'); - return sb.toString(); - } - - protected final ArrayList readReply() throws IOException { - ArrayList reply = new ArrayList(); - char c; - do { - String line = input.readLine(); - if (line == null) { - // if line is null, the end of the stream has been reached, i.e. - // the connection to Tor has been closed! - if (reply.isEmpty()) { - // nothing received so far, can exit cleanly - return reply; - } - // received half of a reply before the connection broke down - throw new TorControlSyntaxError("Connection to Tor " + - " broke down while receiving reply!"); - } - if (debugOutput != null) - debugOutput.println("<< "+line); - if (line.length() < 4) - throw new TorControlSyntaxError("Line (\""+line+"\") too short"); - String status = line.substring(0,3); - c = line.charAt(3); - String msg = line.substring(4); - String rest = null; - if (c == '+') { - StringBuffer data = new StringBuffer(); - while (true) { - line = input.readLine(); - if (debugOutput != null) - debugOutput.print("<< "+line); - if (line.equals(".")) - break; - else if (line.startsWith(".")) - line = line.substring(1); - data.append(line).append('\n'); - } - rest = data.toString(); - } - reply.add(new ReplyLine(status, msg, rest)); - } while (c != ' '); - - return reply; - } - - protected synchronized List sendAndWaitForResponse(String s, - String rest) throws IOException { - if(parseThreadException != null) throw parseThreadException; - checkThread(); - Waiter w = new Waiter(); - if (debugOutput != null) - debugOutput.print(">> "+s); - synchronized (waiters) { - output.write(s); - if (rest != null) - writeEscaped(rest); - output.flush(); - waiters.addLast(w); - } - List lst; - try { - lst = w.getResponse(); - } catch (InterruptedException ex) { - throw new IOException("Interrupted"); - } - for (Iterator i = lst.iterator(); i.hasNext(); ) { - ReplyLine c = i.next(); - if (! c.status.startsWith("2")) - throw new TorControlError("Error reply: "+c.msg); - } - return lst; - } - - /** Helper: decode a CMD_EVENT command and dispatch it to our - * EventHandler (if any). */ - protected void handleEvent(ArrayList events) { - if (handler == null) - return; - - for (Iterator i = events.iterator(); i.hasNext(); ) { - ReplyLine line = i.next(); - int idx = line.msg.indexOf(' '); - String tp = line.msg.substring(0, idx).toUpperCase(); - String rest = line.msg.substring(idx+1); - if (tp.equals("CIRC")) { - List lst = Bytes.splitStr(null, rest); - handler.circuitStatus(lst.get(1), - lst.get(0), - lst.get(1).equals("LAUNCHED") - || lst.size() < 3 ? "" - : lst.get(2)); - } else if (tp.equals("STREAM")) { - List lst = Bytes.splitStr(null, rest); - handler.streamStatus(lst.get(1), - lst.get(0), - lst.get(3)); - // XXXX circID. - } else if (tp.equals("ORCONN")) { - List lst = Bytes.splitStr(null, rest); - handler.orConnStatus(lst.get(1), lst.get(0)); - } else if (tp.equals("BW")) { - List lst = Bytes.splitStr(null, rest); - handler.bandwidthUsed(Integer.parseInt(lst.get(0)), - Integer.parseInt(lst.get(1))); - } else if (tp.equals("NEWDESC")) { - List lst = Bytes.splitStr(null, rest); - handler.newDescriptors(lst); - } else if (tp.equals("DEBUG") || - tp.equals("INFO") || - tp.equals("NOTICE") || - tp.equals("WARN") || - tp.equals("ERR")) { - handler.message(tp, rest); - } else { - handler.unrecognized(tp, rest); - } - } - } - - - /** 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 "\<\<" - */ - public void setDebugging(PrintWriter w) { - debugOutput = w; - } - - /** 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 "\<\<" - */ - public void setDebugging(PrintStream s) { - debugOutput = new PrintWriter(s, true); - } - - /** Set the EventHandler object that will be notified of any - * events Tor delivers to this connection. To make Tor send us - * events, call setEvents(). */ - public void setEventHandler(EventHandler handler) { - this.handler = handler; - } - - /** - * 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. - */ - public synchronized Thread launchThread(boolean daemon) { - ControlParseThread th = new ControlParseThread(); - if (daemon) - th.setDaemon(true); - th.start(); - this.thread = th; - return th; - } - - protected class ControlParseThread extends Thread { - - @Override - public void run() { - try { - react(); - } catch (IOException ex) { - parseThreadException = ex; - } - } - } - - protected synchronized void checkThread() { - if (thread == null) - launchThread(true); - } - - /** helper: implement the main background loop. */ - protected void react() throws IOException { - while (true) { - ArrayList lst = readReply(); - if (lst.isEmpty()) { - // connection has been closed remotely! end the loop! - return; - } - if ((lst.get(0)).status.startsWith("6")) - handleEvent(lst); - else { - synchronized (waiters) { - if (!waiters.isEmpty()) - { - Waiter w; - w = waiters.removeFirst(); - w.setResponse(lst); - } - } - - } - } - } - - /** Change the value of the configuration option 'key' to 'val'. - */ - public void setConf(String key, String value) throws IOException { - List lst = new ArrayList(); - lst.add(key+" "+value); - setConf(lst); - } - - /** Change the values of the configuration options stored in kvMap. */ - public void setConf(Map kvMap) throws IOException { - List lst = new ArrayList(); - for (Iterator> it = kvMap.entrySet().iterator(); it.hasNext(); ) { - Map.Entry ent = it.next(); - lst.add(ent.getKey()+" "+ent.getValue()+"\n"); - } - setConf(lst); - } - - /** 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. - */ - public void setConf(Collection kvList) throws IOException { - if (kvList.size() == 0) - return; - StringBuffer b = new StringBuffer("SETCONF"); - for (Iterator 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); - } - - /** Try to reset the values listed in the collection 'keys' to their - * default values. - **/ - public void resetConf(Collection keys) throws IOException { - if (keys.size() == 0) - return; - StringBuffer b = new StringBuffer("RESETCONF"); - for (Iterator it = keys.iterator(); it.hasNext(); ) { - String key = it.next(); - b.append(" ").append(key); - } - b.append("\r\n"); - sendAndWaitForResponse(b.toString(), null); - } - - /** Return the value of the configuration option 'key' */ - public List getConf(String key) throws IOException { - List lst = new ArrayList(); - lst.add(key); - return getConf(lst); - } - - /** 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. - */ - public List getConf(Collection keys) throws IOException { - StringBuffer sb = new StringBuffer("GETCONF"); - for (Iterator it = keys.iterator(); it.hasNext(); ) { - String key = it.next(); - sb.append(" ").append(key); - } - sb.append("\r\n"); - List lst = sendAndWaitForResponse(sb.toString(), null); - List result = new ArrayList(); - for (Iterator it = lst.iterator(); it.hasNext(); ) { - String kv = (it.next()).msg; - int idx = kv.indexOf('='); - if (idx >= 0) - result.add(new ConfigEntry(kv.substring(0, idx), - kv.substring(idx+1))); - else - result.add(new ConfigEntry(kv)); - } - return result; - } - - /** 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. - */ - public void setEvents(List events) throws IOException { - StringBuffer sb = new StringBuffer("SETEVENTS"); - for (Iterator it = events.iterator(); it.hasNext(); ) { - sb.append(" ").append(it.next()); - } - sb.append("\r\n"); - sendAndWaitForResponse(sb.toString(), null); - } - - /** 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. - */ - public void authenticate(byte[] auth) throws IOException { - String cmd = "AUTHENTICATE " + Bytes.hex(auth) + "\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); - } - - /** 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
  • - *
- */ - public void signal(String signal) throws IOException { - String cmd = "SIGNAL " + signal + "\r\n"; - sendAndWaitForResponse(cmd, null); - } - - /** Send a signal to the Tor process to shut it down or halt it. - * Does not wait for a response. */ - public void shutdownTor(String signal) throws IOException { - String s = "SIGNAL " + signal + "\r\n"; - Waiter w = new Waiter(); - if (debugOutput != null) - debugOutput.print(">> "+s); - synchronized (waiters) { - output.write(s); - output.flush(); - } - } - - /** 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. - */ - public Map mapAddresses(Collection kvLines) throws IOException { - StringBuffer sb = new StringBuffer("MAPADDRESS"); - for (Iterator it = kvLines.iterator(); it.hasNext(); ) { - String kv = it.next(); - int i = kv.indexOf(' '); - sb.append(" ").append(kv.substring(0,i)).append("=") - .append(quote(kv.substring(i+1))); - } - sb.append("\r\n"); - List lst = sendAndWaitForResponse(sb.toString(), null); - Map result = new HashMap(); - for (Iterator it = lst.iterator(); it.hasNext(); ) { - String kv = (it.next()).msg; - int idx = kv.indexOf('='); - result.put(kv.substring(0, idx), - kv.substring(idx+1)); - } - return result; - } - - public Map mapAddresses(Map addresses) throws IOException { - List kvList = new ArrayList(); - for (Iterator> it = addresses.entrySet().iterator(); it.hasNext(); ) { - Map.Entry e = it.next(); - kvList.add(e.getKey()+" "+e.getValue()); - } - return mapAddresses(kvList); - } - - public String mapAddress(String fromAddr, String toAddr) throws IOException { - List lst = new ArrayList(); - lst.add(fromAddr+" "+toAddr+"\n"); - Map m = mapAddresses(lst); - return m.get(fromAddr); - } - - /** 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"
  • - *
- */ - public Map getInfo(Collection keys) throws IOException { - StringBuffer sb = new StringBuffer("GETINFO"); - for (Iterator it = keys.iterator(); it.hasNext(); ) { - sb.append(" ").append(it.next()); - } - sb.append("\r\n"); - List lst = sendAndWaitForResponse(sb.toString(), null); - Map m = new HashMap(); - for (Iterator it = lst.iterator(); it.hasNext(); ) { - ReplyLine line = it.next(); - int idx = line.msg.indexOf('='); - if (idx<0) - break; - String k = line.msg.substring(0,idx); - String v; - if (line.rest != null) { - v = line.rest; - } else { - v = line.msg.substring(idx+1); - } - m.put(k, v); - } - return m; - } - - - - /** Return the value of the information field 'key' */ - public String getInfo(String key) throws IOException { - List lst = new ArrayList(); - lst.add(key); - Map m = getInfo(lst); - return m.get(key); - } - - /** 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. - */ - public String extendCircuit(String circID, String path) throws IOException { - List lst = sendAndWaitForResponse( - "EXTENDCIRCUIT "+circID+" "+path+"\r\n", null); - return (lst.get(0)).msg; - } - - /** 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. - */ - public void attachStream(String streamID, String circID) - throws IOException { - sendAndWaitForResponse("ATTACHSTREAM "+streamID+" "+circID+"\r\n", null); - } - - /** 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. - */ - // More documentation here on format of desc? - // No need for return value? control-spec.txt says reply is merely "250 OK" on success... - public String postDescriptor(String desc) throws IOException { - List lst = sendAndWaitForResponse("+POSTDESCRIPTOR\r\n", desc); - return (lst.get(0)).msg; - } - - /** 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. - */ - public void redirectStream(String streamID, String address) throws IOException { - sendAndWaitForResponse("REDIRECTSTREAM "+streamID+" "+address+"\r\n", - null); - } - - /** 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. - */ - public void closeStream(String streamID, byte reason) - throws IOException { - sendAndWaitForResponse("CLOSESTREAM "+streamID+" "+reason+"\r\n",null); - } - - /** Tells Tor to close the circuit identified by circID. - * If ifUnused 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); - } -} - diff --git a/tor-android-binary/src/main/java/net/freehaven/tor/control/TorControlError.java b/tor-android-binary/src/main/java/net/freehaven/tor/control/TorControlError.java deleted file mode 100644 index d07ee514..00000000 --- a/tor-android-binary/src/main/java/net/freehaven/tor/control/TorControlError.java +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -import java.io.IOException; - -/** - * An exception raised when Tor tells us about an error. - */ -public class TorControlError extends IOException { - - static final long serialVersionUID = 3; - - private final int errorType; - - public TorControlError(int type, String s) { - super(s); - errorType = type; - } - - public TorControlError(String s) { - this(-1, s); - } - - public int getErrorType() { - return errorType; - } - - public String getErrorMsg() { - try { - if (errorType == -1) - return null; - return TorControlCommands.ERROR_MSGS[errorType]; - } catch (ArrayIndexOutOfBoundsException ex) { - return "Unrecongized error #"+errorType; - } - } -} - diff --git a/tor-android-binary/src/main/java/net/freehaven/tor/control/TorControlSyntaxError.java b/tor-android-binary/src/main/java/net/freehaven/tor/control/TorControlSyntaxError.java deleted file mode 100644 index dba4f44b..00000000 --- a/tor-android-binary/src/main/java/net/freehaven/tor/control/TorControlSyntaxError.java +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -import java.io.IOException; - -/** - * An exception raised when Tor behaves in an unexpected way. - */ -public class TorControlSyntaxError extends IOException { - - static final long serialVersionUID = 3; - - public TorControlSyntaxError(String s) { super(s); } -} - diff --git a/tor-android-binary/src/main/java/net/freehaven/tor/control/examples/.cvsignore b/tor-android-binary/src/main/java/net/freehaven/tor/control/examples/.cvsignore deleted file mode 100644 index 6b468b62..00000000 --- a/tor-android-binary/src/main/java/net/freehaven/tor/control/examples/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.class diff --git a/tor-android-binary/src/main/java/net/freehaven/tor/control/examples/DebuggingEventHandler.java b/tor-android-binary/src/main/java/net/freehaven/tor/control/examples/DebuggingEventHandler.java deleted file mode 100644 index 48c49a28..00000000 --- a/tor-android-binary/src/main/java/net/freehaven/tor/control/examples/DebuggingEventHandler.java +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control.examples; - -import java.io.PrintWriter; -import java.util.Iterator; -import org.torproject.android.control.EventHandler; - -public class DebuggingEventHandler implements EventHandler { - - private final PrintWriter out; - - public DebuggingEventHandler(PrintWriter p) { - out = p; - } - - public void circuitStatus(String status, String circID, String path) { - out.println("Circuit "+circID+" is now "+status+" (path="+path+")"); - } - public void streamStatus(String status, String streamID, String target) { - out.println("Stream "+streamID+" is now "+status+" (target="+target+")"); - } - public void orConnStatus(String status, String orName) { - out.println("OR connection to "+orName+" is now "+status); - } - public void bandwidthUsed(long read, long written) { - out.println("Bandwidth usage: "+read+" bytes read; "+ - written+" bytes written."); - } - public void newDescriptors(java.util.List orList) { - out.println("New descriptors for routers:"); - for (Iterator i = orList.iterator(); i.hasNext(); ) - out.println(" "+i.next()); - } - public void message(String type, String msg) { - out.println("["+type+"] "+msg.trim()); - } - - public void unrecognized(String type, String msg) { - out.println("unrecognized event ["+type+"] "+msg.trim()); - } - -} - diff --git a/tor-android-binary/src/main/java/net/freehaven/tor/control/examples/Main.java b/tor-android-binary/src/main/java/net/freehaven/tor/control/examples/Main.java deleted file mode 100644 index b0e0a3c0..00000000 --- a/tor-android-binary/src/main/java/net/freehaven/tor/control/examples/Main.java +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control.examples; - -import org.torproject.android.control.*; -import java.io.EOFException; -import java.io.IOException; -import java.io.PrintWriter; -import java.net.Socket; -import java.util.ArrayList; -import java.util.List; -import java.util.Arrays; -import java.util.Map; -import java.util.Iterator; - -public class Main implements TorControlCommands { - - public static void main(String args[]) { - if (args.length < 1) { - System.err.println("No command given."); - return; - } - try { - if (args[0].equals("set-config")) { - setConfig(args); - } else if (args[0].equals("get-config")) { - getConfig(args); - } else if (args[0].equals("get-info")) { - getInfo(args); - } else if (args[0].equals("listen")) { - listenForEvents(args); - } else if (args[0].equals("signal")) { - signal(args); - } else if (args[0].equals("auth")) { - authDemo(args); - } else { - System.err.println("Unrecognized command: "+args[0]); - } - } catch (EOFException ex) { - System.out.println("Control socket closed by Tor."); - } catch (TorControlError ex) { - System.err.println("Error from Tor process: "+ - ex+" ["+ex.getErrorMsg()+"]"); - } catch (IOException ex) { - System.err.println("IO exception when talking to Tor process: "+ - ex); - ex.printStackTrace(System.err); - } - } - - private static TorControlConnection getConnection(String[] args, - boolean daemon) throws IOException { - Socket s = new Socket("127.0.0.1", 9100); - TorControlConnection conn = new TorControlConnection(s); - conn.launchThread(daemon); - conn.authenticate(new byte[0]); - return conn; - } - - private static TorControlConnection getConnection(String[] args) - throws IOException { - return getConnection(args, true); - } - - public static void setConfig(String[] args) throws IOException { - // Usage: "set-config [-save] key value key value key value" - TorControlConnection conn = getConnection(args); - ArrayList lst = new ArrayList(); - int i = 1; - boolean save = false; - if (args[i].equals("-save")) { - save = true; - ++i; - } - for (; i < args.length; i +=2) { - lst.add(args[i]+" "+args[i+1]); - } - conn.setConf(lst); - if (save) { - conn.saveConf(); - } - } - - public static void getConfig(String[] args) throws IOException { - // Usage: get-config key key key - TorControlConnection conn = getConnection(args); - List lst = conn.getConf(Arrays.asList(args).subList(1,args.length)); - for (Iterator i = lst.iterator(); i.hasNext(); ) { - ConfigEntry e = i.next(); - System.out.println("KEY: "+e.key); - System.out.println("VAL: "+e.value); - } - } - - public static void getInfo(String[] args) throws IOException { - TorControlConnection conn = getConnection(args); - Map m = conn.getInfo(Arrays.asList(args).subList(1,args.length)); - for (Iterator> i = m.entrySet().iterator(); i.hasNext(); ) { - Map.Entry e = i.next(); - System.out.println("KEY: "+e.getKey()); - System.out.println("VAL: "+e.getValue()); - } - } - - public static void listenForEvents(String[] args) throws IOException { - // Usage: listen [circ|stream|orconn|bw|newdesc|info|notice|warn|error]* - TorControlConnection conn = getConnection(args, false); - ArrayList lst = new ArrayList(); - for (int i = 1; i < args.length; ++i) { - lst.add(args[i]); - } - conn.setEventHandler( - new DebuggingEventHandler(new PrintWriter(System.out, true))); - conn.setEvents(lst); - } - - public static void signal(String[] args) throws IOException { - // Usage signal [reload|shutdown|dump|debug|halt] - TorControlConnection conn = getConnection(args, false); - // distinguish shutdown signal from other signals - if ("SHUTDOWN".equalsIgnoreCase(args[1]) - || "HALT".equalsIgnoreCase(args[1])) { - conn.shutdownTor(args[1].toUpperCase()); - } else { - conn.signal(args[1].toUpperCase()); - } - } - - public static void authDemo(String[] args) throws IOException { - - PasswordDigest pwd = PasswordDigest.generateDigest(); - Socket s = new Socket("127.0.0.1", 9100); - TorControlConnection conn = new TorControlConnection(s); - conn.launchThread(true); - conn.authenticate(new byte[0]); - - conn.setConf("HashedControlPassword", pwd.getHashedPassword()); - - s = new Socket("127.0.0.1", 9100); - conn = new TorControlConnection(s); - conn.launchThread(true); - conn.authenticate(pwd.getSecret()); - } - -} - diff --git a/tor-android-binary/src/main/java/org/torproject/android/binary/TorResourceInstaller.java b/tor-android-binary/src/main/java/org/torproject/android/binary/TorResourceInstaller.java index 5b571682..093860f9 100644 --- a/tor-android-binary/src/main/java/org/torproject/android/binary/TorResourceInstaller.java +++ b/tor-android-binary/src/main/java/org/torproject/android/binary/TorResourceInstaller.java @@ -21,7 +21,6 @@ import android.content.Context; import android.os.Build; import android.util.Log; -import org.torproject.android.service.R; public class TorResourceInstaller implements TorServiceConstants { @@ -67,7 +66,7 @@ public class TorResourceInstaller implements TorServiceConstants { File outFile; String cpuPath = "armeabi"; - + if (Build.CPU_ABI.contains("x86")) cpuPath = "x86"; @@ -75,19 +74,14 @@ public class TorResourceInstaller implements TorServiceConstants { installFolder.mkdirs(); - is = context.getResources().openRawResource(R.raw.torrc); + is = context.getAssets().open(COMMON_ASSET_KEY + TORRC_ASSET_KEY); outFile = new File(installFolder, TORRC_ASSET_KEY); streamToFile(is,outFile, false, false); - - is = context.getResources().openRawResource(R.raw.torpolipo); + + is = context.getAssets().open(COMMON_ASSET_KEY + POLIPOCONFIG_ASSET_KEY); outFile = new File(installFolder, POLIPOCONFIG_ASSET_KEY); streamToFile(is,outFile, false, false); - is = context.getAssets().open(cpuPath + '/' + OBFSCLIENT_ASSET_KEY + MP3_EXT); - outFile = new File(installFolder, OBFSCLIENT_ASSET_KEY); - streamToFile(is,outFile, false, true); - setExecutable(outFile); - is = context.getAssets().open(cpuPath + '/' + TOR_ASSET_KEY + MP3_EXT); outFile = new File(installFolder, TOR_ASSET_KEY); streamToFile(is,outFile, false, true); @@ -97,12 +91,7 @@ public class TorResourceInstaller implements TorServiceConstants { outFile = new File(installFolder, POLIPO_ASSET_KEY); streamToFile(is,outFile, false, true); setExecutable(outFile); - - is = context.getAssets().open(cpuPath + '/' + PDNSD_ASSET_KEY + MP3_EXT); - outFile = new File(installFolder, PDNSD_ASSET_KEY); - streamToFile(is,outFile, false, true); - setExecutable(outFile); - + installGeoIP(); return true; @@ -130,9 +119,8 @@ public class TorResourceInstaller implements TorServiceConstants { { InputStream is; - - is = context.getResources().openRawResource(R.raw.torpolipo); + is = context.getAssets().open(COMMON_ASSET_KEY + POLIPOCONFIG_ASSET_KEY); streamToFile(is,filePolipo, false, false); if (extraLines != null && extraLines.length() > 0) @@ -150,9 +138,8 @@ public class TorResourceInstaller implements TorServiceConstants { InputStream is; File outFile; - - is = context.getResources().openRawResource(R.raw.torpolipo); + is = context.getAssets().open(COMMON_ASSET_KEY + POLIPOCONFIG_ASSET_KEY); outFile = new File(installFolder, POLIPOCONFIG_ASSET_KEY); streamToFile(is,outFile, false, false); @@ -170,32 +157,17 @@ public class TorResourceInstaller implements TorServiceConstants { File outFile; outFile = new File(installFolder, GEOIP_ASSET_KEY); - is = context.getResources().openRawResource(R.raw.geoip); + is = context.getAssets().open(COMMON_ASSET_KEY + GEOIP_ASSET_KEY + MP3_EXT); streamToFile(is, outFile, false, true); - - is = context.getResources().openRawResource(R.raw.geoip6); + + is = context.getAssets().open(COMMON_ASSET_KEY + GEOIP6_ASSET_KEY + MP3_EXT); outFile = new File(installFolder, GEOIP6_ASSET_KEY); streamToFile(is, outFile, false, true); return true; } - /* - private static void copyAssetFile(Context ctx, String asset, File file) throws IOException, InterruptedException - { - - DataOutputStream out = new DataOutputStream(new FileOutputStream(file)); - InputStream is = new GZIPInputStream(ctx.getAssets().open(asset)); - - byte buf[] = new byte[8172]; - int len; - while ((len = is.read(buf)) > 0) { - out.write(buf, 0, len); - } - out.close(); - is.close(); - }*/ - + /* * Write the inputstream contents to the file */ @@ -234,81 +206,8 @@ public class TorResourceInstaller implements TorServiceConstants { return true; } - - //copy the file from inputstream to File output - alternative impl - public static boolean copyFile (InputStream is, File outputFile) - { - - try { - if (outputFile.exists()) - outputFile.delete(); - - boolean newFile = outputFile.createNewFile(); - DataOutputStream out = new DataOutputStream(new FileOutputStream(outputFile)); - DataInputStream in = new DataInputStream(is); - - int b = -1; - byte[] data = new byte[1024]; - - while ((b = in.read(data)) != -1) { - out.write(data); - } - - if (b == -1); //rejoice - - // - out.flush(); - out.close(); - in.close(); - // chmod? - - return newFile; - - - } catch (IOException ex) { - Log.e(TAG, "error copying binary", ex); - return false; - } - } - - - - /** - * Copies a raw resource file, given its ID to the given location - * @param ctx context - * @param resid resource id - * @param file destination file - * @param mode file permissions (E.g.: "755") - * @throws IOException on error - * @throws InterruptedException when interrupted - */ - public static void copyRawFile(Context ctx, int resid, File file, String mode, boolean isZipd) throws IOException, InterruptedException - { - final String abspath = file.getAbsolutePath(); - // Write the iptables binary - final FileOutputStream out = new FileOutputStream(file); - InputStream is = ctx.getResources().openRawResource(resid); - - if (isZipd) - { - ZipInputStream zis = new ZipInputStream(is); - ZipEntry ze = zis.getNextEntry(); - is = zis; - } - - byte buf[] = new byte[1024]; - int len; - while ((len = is.read(buf)) > 0) { - out.write(buf, 0, len); - } - out.close(); - is.close(); - // Change the permissions - Runtime.getRuntime().exec("chmod "+mode+" "+abspath).waitFor(); - } - private void setExecutable(File fileBin) { fileBin.setReadable(true); diff --git a/tor-android-binary/src/main/java/org/torproject/android/binary/TorServiceConstants.java b/tor-android-binary/src/main/java/org/torproject/android/binary/TorServiceConstants.java index 531041cc..2eef513a 100644 --- a/tor-android-binary/src/main/java/org/torproject/android/binary/TorServiceConstants.java +++ b/tor-android-binary/src/main/java/org/torproject/android/binary/TorServiceConstants.java @@ -3,24 +3,17 @@ package org.torproject.android.binary; -import android.content.Intent; - public interface TorServiceConstants { String TAG = "TorBinary"; - String DIRECTORY_TOR_BINARY = "bin"; - String DIRECTORY_TOR_DATA = "data"; - //name of the tor C binary String TOR_ASSET_KEY = "tor"; //torrc (tor config file) String TORRC_ASSET_KEY = "torrc"; - String TORRCDIAG_ASSET_KEY = "torrcdiag"; - String TORRC_TETHER_KEY = "torrctether"; - - String TOR_CONTROL_COOKIE = "control_auth_cookie"; - + + String COMMON_ASSET_KEY = "common/"; + //privoxy String POLIPO_ASSET_KEY = "polipo"; @@ -31,17 +24,8 @@ public interface TorServiceConstants { String GEOIP_ASSET_KEY = "geoip"; String GEOIP6_ASSET_KEY = "geoip6"; - String SHELL_CMD_PS = "toolbox ps"; - int FILE_WRITE_BUFFER_SIZE = 1024; - //obfsproxy - String OBFSCLIENT_ASSET_KEY = "obfs4proxy"; - - //DNS daemon for TCP DNS over TOr - String PDNSD_ASSET_KEY = "pdnsd"; - - } diff --git a/tor-android-binary/src/main/libs/armeabi/libtun2socks.so b/tor-android-binary/src/main/libs/armeabi/libtun2socks.so deleted file mode 100755 index 6e9ea8a7..00000000 Binary files a/tor-android-binary/src/main/libs/armeabi/libtun2socks.so and /dev/null differ diff --git a/tor-android-binary/src/main/libs/armeabi/pdnsd b/tor-android-binary/src/main/libs/armeabi/pdnsd deleted file mode 100755 index 5b629ca6..00000000 Binary files a/tor-android-binary/src/main/libs/armeabi/pdnsd and /dev/null differ diff --git a/tor-android-binary/src/main/libs/x86/libtun2socks.so b/tor-android-binary/src/main/libs/x86/libtun2socks.so deleted file mode 100755 index 7e37a7e0..00000000 Binary files a/tor-android-binary/src/main/libs/x86/libtun2socks.so and /dev/null differ diff --git a/tor-android-binary/src/main/res/raw/geoip6.mp3 b/tor-android-binary/src/main/res/raw/geoip6.mp3 deleted file mode 100644 index 0e439b90..00000000 --- a/tor-android-binary/src/main/res/raw/geoip6.mp3 +++ /dev/null @@ -1,1663 +0,0 @@ - - - - - - - - - - - - - orbot/geoip6.mp3 at master · n8fr8/orbot - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Skip to content -
- - - - - - - - - - - - - -
-
-
- -
-
-
- -
    - -
  • -
    - -
    - - - - - Unwatch - - - -
    - -
    -
    - -
    -
  • - -
  • - -
    - -
    - - -
    -
    - - -
    - -
  • - - -
  • - - - Fork - - -
  • - -
- -

- - /orbot - - - - - -

-
-
- -
-
-
- - - -
- - -
-

HTTPS clone URL

-
- - - - -
-
- - -
-

SSH clone URL

-
- - - - -
-
- - -
-

Subversion checkout URL

-
- - - - -
-
- - -

You can clone with - HTTPS, - SSH, - or Subversion. - - - -

- - - - - - Download ZIP - -
-
- -
- - - - - - -
- -
- - - branch: - master - - - -
- -
- - - - -
- - -
- - -
- Fetching contributors… -
- -
-

-

Cannot retrieve contributors at this time

-
-
-
-
-
-
- 81.42 kb -
-
-
- Raw - History -
- - - - - - -
-
- - -
-
- View Raw -
-
- -
-
- -Jump to Line - - -
- -
- -
-
- - -
- -
- -
- - -
-
-
- -
-
- -
- - - -
- - - Something went wrong with that request. Please try again. -
- - - - - - - - - diff --git a/tor-android-binary/src/main/res/raw/pluto.properties b/tor-android-binary/src/main/res/raw/pluto.properties deleted file mode 100644 index 74c03077..00000000 --- a/tor-android-binary/src/main/res/raw/pluto.properties +++ /dev/null @@ -1,3 +0,0 @@ -obfs2=obfsclient -obfs3=obfsclient -scramblesuit=obfsclient diff --git a/tor-android-binary/src/main/res/values/pdnsd.xml b/tor-android-binary/src/main/res/values/pdnsd.xml deleted file mode 100644 index a9ba34d7..00000000 --- a/tor-android-binary/src/main/res/values/pdnsd.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - -global { - perm_cache=0; - cache_dir="/data/data/org.torproject.android/app_bin"; - server_port = 8091; - server_ip = 0.0.0.0; - query_method=udp_only; - min_ttl=15m; - max_ttl=1w; - timeout=10; - daemon=on; - pid_file="/data/data/org.torproject.android/app_bin/pdnsd.pid"; - -} - -server { - label= "upstream"; - ip = %1$s; - port = %2$d; - uptest = none; -} - -rr { - name=localhost; - reverse=on; - a=127.0.0.1; - owner=localhost; - soa=localhost,root.localhost,42,86400,900,86400,86400; -} - - diff --git a/tor-android-binary/src/test/java/org/torproject/android/control/.cvsignore b/tor-android-binary/src/test/java/org/torproject/android/control/.cvsignore deleted file mode 100644 index 6b468b62..00000000 --- a/tor-android-binary/src/test/java/org/torproject/android/control/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.class diff --git a/tor-android-binary/src/test/java/org/torproject/android/control/Bytes.java b/tor-android-binary/src/test/java/org/torproject/android/control/Bytes.java deleted file mode 100644 index e754d907..00000000 --- a/tor-android-binary/src/test/java/org/torproject/android/control/Bytes.java +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -import java.util.Arrays; -import java.util.List; - -/** - * Static class to do bytewise structure manipulation in Java. - */ -/* XXXX There must be a better way to do most of this. - * XXXX The string logic here uses default encoding, which is stupid. - */ -final class Bytes { - - /** Write the two-byte value in 's' into the byte array 'ba', starting at - * the index 'pos'. */ - public static void setU16(byte[] ba, int pos, short s) { - ba[pos] = (byte)((s >> 8) & 0xff); - ba[pos+1] = (byte)((s ) & 0xff); - } - - /** Write the four-byte value in 'i' into the byte array 'ba', starting at - * the index 'pos'. */ - public static void setU32(byte[] ba, int pos, int i) { - ba[pos] = (byte)((i >> 24) & 0xff); - ba[pos+1] = (byte)((i >> 16) & 0xff); - ba[pos+2] = (byte)((i >> 8) & 0xff); - ba[pos+3] = (byte)((i ) & 0xff); - } - - /** Return the four-byte value starting at index 'pos' within 'ba' */ - public static int getU32(byte[] ba, int pos) { - return - ((ba[pos ]&0xff)<<24) | - ((ba[pos+1]&0xff)<<16) | - ((ba[pos+2]&0xff)<< 8) | - ((ba[pos+3]&0xff)); - } - - public static String getU32S(byte[] ba, int pos) { - return String.valueOf( (getU32(ba,pos))&0xffffffffL ); - } - - /** Return the two-byte value starting at index 'pos' within 'ba' */ - public static int getU16(byte[] ba, int pos) { - return - ((ba[pos ]&0xff)<<8) | - ((ba[pos+1]&0xff)); - } - - /** Return the string starting at position 'pos' of ba and extending - * until a zero byte or the end of the string. */ - public static String getNulTerminatedStr(byte[] ba, int pos) { - int len, maxlen = ba.length-pos; - for (len=0; len lst, byte[] ba, int pos, byte split) { - while (pos < ba.length && ba[pos] != 0) { - int len; - for (len=0; pos+len < ba.length; ++len) { - if (ba[pos+len] == 0 || ba[pos+len] == split) - break; - } - if (len>0) - lst.add(new String(ba, pos, len)); - pos += len; - if (ba[pos] == split) - ++pos; - } - } - - /** - * Read bytes from 'ba' starting at 'pos', dividing them into strings - * along the character in 'split' and writing them into 'lst' - */ - public static List splitStr(List lst, String str) { - // split string on spaces, include trailing/leading - String[] tokenArray = str.split(" ", -1); - if (lst == null) { - lst = Arrays.asList( tokenArray ); - } else { - lst.addAll( Arrays.asList( tokenArray ) ); - } - return lst; - } - - private static final char[] NYBBLES = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' - }; - - public static final String hex(byte[] ba) { - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < ba.length; ++i) { - int b = (ba[i]) & 0xff; - buf.append(NYBBLES[b >> 4]); - buf.append(NYBBLES[b&0x0f]); - } - return buf.toString(); - } - - private Bytes() {}; -} - diff --git a/tor-android-binary/src/test/java/org/torproject/android/control/ConfigEntry.java b/tor-android-binary/src/test/java/org/torproject/android/control/ConfigEntry.java deleted file mode 100644 index 31eb4b8e..00000000 --- a/tor-android-binary/src/test/java/org/torproject/android/control/ConfigEntry.java +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -/** A single key-value pair from Tor's configuration. */ -public class ConfigEntry { - public ConfigEntry(String k, String v) { - key = k; - value = v; - is_default = false; - } - public ConfigEntry(String k) { - key = k; - value = ""; - is_default = true; - } - public final String key; - public final String value; - public final boolean is_default; -} diff --git a/tor-android-binary/src/test/java/org/torproject/android/control/EventHandler.java b/tor-android-binary/src/test/java/org/torproject/android/control/EventHandler.java deleted file mode 100644 index 5a4e2b5b..00000000 --- a/tor-android-binary/src/test/java/org/torproject/android/control/EventHandler.java +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -/** - * Abstract interface whose methods are invoked when Tor sends us an event. - * - * @see TorControlConnection#setEventHandler - * @see TorControlConnection#setEvents - */ -public interface EventHandler { - /** - * Invoked when a circuit's status has changed. - * Possible values for status are: - *
    - *
  • "LAUNCHED" : circuit ID assigned to new circuit
  • - *
  • "BUILT" : all hops finished, can now accept streams
  • - *
  • "EXTENDED" : one more hop has been completed
  • - *
  • "FAILED" : circuit closed (was not built)
  • - *
  • "CLOSED" : circuit closed (was built)
  • - *
- * - * circID is the alphanumeric identifier of the affected circuit, - * and path is a comma-separated list of alphanumeric ServerIDs. - */ - public void circuitStatus(String status, String circID, String path); - /** - * Invoked when a stream's status has changed. - * Possible values for status are: - *
    - *
  • "NEW" : New request to connect
  • - *
  • "NEWRESOLVE" : New request to resolve an address
  • - *
  • "SENTCONNECT" : Sent a connect cell along a circuit
  • - *
  • "SENTRESOLVE" : Sent a resolve cell along a circuit
  • - *
  • "SUCCEEDED" : Received a reply; stream established
  • - *
  • "FAILED" : Stream failed and not retriable.
  • - *
  • "CLOSED" : Stream closed
  • - *
  • "DETACHED" : Detached from circuit; still retriable.
  • - *
- * - * streamID is the alphanumeric identifier of the affected stream, - * and its target is specified as address:port. - */ - public void streamStatus(String status, String streamID, String target); - /** - * Invoked when the status of a connection to an OR has changed. - * Possible values for status are ["LAUNCHED" | "CONNECTED" | "FAILED" | "CLOSED"]. - * orName is the alphanumeric identifier of the OR affected. - */ - public void orConnStatus(String status, String orName); - /** - * Invoked once per second. read and written are - * the number of bytes read and written, respectively, in - * the last second. - */ - public void bandwidthUsed(long read, long written); - /** - * Invoked whenever Tor learns about new ORs. The orList object - * contains the alphanumeric ServerIDs associated with the new ORs. - */ - public void newDescriptors(java.util.List orList); - /** - * Invoked when Tor logs a message. - * severity is one of ["DEBUG" | "INFO" | "NOTICE" | "WARN" | "ERR"], - * and msg is the message string. - */ - public void message(String severity, String msg); - /** - * Invoked when an unspecified message is received. - * is the message type, and is the message string. - */ - public void unrecognized(String type, String msg); - -} - diff --git a/tor-android-binary/src/test/java/org/torproject/android/control/NullEventHandler.java b/tor-android-binary/src/test/java/org/torproject/android/control/NullEventHandler.java deleted file mode 100644 index a2390e68..00000000 --- a/tor-android-binary/src/test/java/org/torproject/android/control/NullEventHandler.java +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -/** - * Implementation of EventHandler that ignores all events. Useful - * when you only want to override one method. - */ -public class NullEventHandler implements EventHandler { - public void circuitStatus(String status, String circID, String path) {} - public void streamStatus(String status, String streamID, String target) {} - public void orConnStatus(String status, String orName) {} - public void bandwidthUsed(long read, long written) {} - public void newDescriptors(java.util.List orList) {} - public void message(String severity, String msg) {} - public void unrecognized(String type, String msg) {} -} - diff --git a/tor-android-binary/src/test/java/org/torproject/android/control/PasswordDigest.java b/tor-android-binary/src/test/java/org/torproject/android/control/PasswordDigest.java deleted file mode 100644 index 03d0a98e..00000000 --- a/tor-android-binary/src/test/java/org/torproject/android/control/PasswordDigest.java +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; - -/** - * A hashed digest of a secret password (used to set control connection - * security.) - * - * For the actual hashing algorithm, see RFC2440's secret-to-key conversion. - */ -public class PasswordDigest { - - private final byte[] secret; - private final String hashedKey; - - /** Return a new password digest with a random secret and salt. */ - public static PasswordDigest generateDigest() { - byte[] secret = new byte[20]; - SecureRandom rng = new SecureRandom(); - rng.nextBytes(secret); - return new PasswordDigest(secret); - } - - /** Construct a new password digest with a given secret and random salt */ - public PasswordDigest(byte[] secret) { - this(secret, null); - } - - /** Construct a new password digest with a given secret and random salt. - * Note that the 9th byte of the specifier determines the number of hash - * iterations as in RFC2440. - */ - public PasswordDigest(byte[] secret, byte[] specifier) { - this.secret = secret.clone(); - if (specifier == null) { - specifier = new byte[9]; - SecureRandom rng = new SecureRandom(); - rng.nextBytes(specifier); - specifier[8] = 96; - } - hashedKey = "16:"+encodeBytes(secretToKey(secret, specifier)); - } - - /** Return the secret used to generate this password hash. - */ - public byte[] getSecret() { - return secret.clone(); - } - - /** Return the hashed password in the format used by Tor. */ - public String getHashedPassword() { - return hashedKey; - } - - /** Parameter used by RFC2440's s2k algorithm. */ - private static final int EXPBIAS = 6; - - /** Implement rfc2440 s2k */ - public static byte[] secretToKey(byte[] secret, byte[] specifier) { - MessageDigest d; - try { - d = MessageDigest.getInstance("SHA-1"); - } catch (NoSuchAlgorithmException ex) { - throw new RuntimeException("Can't run without sha-1."); - } - int c = (specifier[8])&0xff; - int count = (16 + (c&15)) << ((c>>4) + EXPBIAS); - - byte[] tmp = new byte[8+secret.length]; - System.arraycopy(specifier, 0, tmp, 0, 8); - System.arraycopy(secret, 0, tmp, 8, secret.length); - while (count > 0) { - if (count >= tmp.length) { - d.update(tmp); - count -= tmp.length; - } else { - d.update(tmp, 0, count); - count = 0; - } - } - byte[] key = new byte[20+9]; - System.arraycopy(d.digest(), 0, key, 9, 20); - System.arraycopy(specifier, 0, key, 0, 9); - return key; - } - - /** Return a hexadecimal encoding of a byte array. */ - // XXX There must be a better way to do this in Java. - private static final String encodeBytes(byte[] ba) { - return Bytes.hex(ba); - } - -} - diff --git a/tor-android-binary/src/test/java/org/torproject/android/control/README b/tor-android-binary/src/test/java/org/torproject/android/control/README deleted file mode 100644 index b310c7d5..00000000 --- a/tor-android-binary/src/test/java/org/torproject/android/control/README +++ /dev/null @@ -1,4 +0,0 @@ -We broke the version detection stuff in Tor 0.1.2.16 / 0.2.0.4-alpha. -Somebody should rip out the v0 control protocol stuff from here, and -it should start working again. -RD - diff --git a/tor-android-binary/src/test/java/org/torproject/android/control/TorControlCommands.java b/tor-android-binary/src/test/java/org/torproject/android/control/TorControlCommands.java deleted file mode 100644 index c98a1c48..00000000 --- a/tor-android-binary/src/test/java/org/torproject/android/control/TorControlCommands.java +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -/** Interface defining constants used by the Tor controller protocol. - */ -// XXXX Take documentation for these from control-spec.txt -public interface TorControlCommands { - - public static final short CMD_ERROR = 0x0000; - public static final short CMD_DONE = 0x0001; - public static final short CMD_SETCONF = 0x0002; - public static final short CMD_GETCONF = 0x0003; - public static final short CMD_CONFVALUE = 0x0004; - public static final short CMD_SETEVENTS = 0x0005; - public static final short CMD_EVENT = 0x0006; - public static final short CMD_AUTH = 0x0007; - public static final short CMD_SAVECONF = 0x0008; - public static final short CMD_SIGNAL = 0x0009; - public static final short CMD_MAPADDRESS = 0x000A; - public static final short CMD_GETINFO = 0x000B; - public static final short CMD_INFOVALUE = 0x000C; - public static final short CMD_EXTENDCIRCUIT = 0x000D; - public static final short CMD_ATTACHSTREAM = 0x000E; - public static final short CMD_POSTDESCRIPTOR = 0x000F; - public static final short CMD_FRAGMENTHEADER = 0x0010; - public static final short CMD_FRAGMENT = 0x0011; - public static final short CMD_REDIRECTSTREAM = 0x0012; - public static final short CMD_CLOSESTREAM = 0x0013; - public static final short CMD_CLOSECIRCUIT = 0x0014; - - public static final String[] CMD_NAMES = { - "ERROR", - "DONE", - "SETCONF", - "GETCONF", - "CONFVALUE", - "SETEVENTS", - "EVENT", - "AUTH", - "SAVECONF", - "SIGNAL", - "MAPADDRESS", - "GETINFO", - "INFOVALUE", - "EXTENDCIRCUIT", - "ATTACHSTREAM", - "POSTDESCRIPTOR", - "FRAGMENTHEADER", - "FRAGMENT", - "REDIRECTSTREAM", - "CLOSESTREAM", - "CLOSECIRCUIT", - }; - - public static final short EVENT_CIRCSTATUS = 0x0001; - public static final short EVENT_STREAMSTATUS = 0x0002; - public static final short EVENT_ORCONNSTATUS = 0x0003; - public static final short EVENT_BANDWIDTH = 0x0004; - public static final short EVENT_NEWDESCRIPTOR = 0x0006; - public static final short EVENT_MSG_DEBUG = 0x0007; - public static final short EVENT_MSG_INFO = 0x0008; - public static final short EVENT_MSG_NOTICE = 0x0009; - public static final short EVENT_MSG_WARN = 0x000A; - public static final short EVENT_MSG_ERROR = 0x000B; - - public static final String[] EVENT_NAMES = { - "(0)", - "CIRC", - "STREAM", - "ORCONN", - "BW", - "OLDLOG", - "NEWDESC", - "DEBUG", - "INFO", - "NOTICE", - "WARN", - "ERR", - }; - - public static final byte CIRC_STATUS_LAUNCHED = 0x01; - public static final byte CIRC_STATUS_BUILT = 0x02; - public static final byte CIRC_STATUS_EXTENDED = 0x03; - public static final byte CIRC_STATUS_FAILED = 0x04; - public static final byte CIRC_STATUS_CLOSED = 0x05; - - public static final String[] CIRC_STATUS_NAMES = { - "LAUNCHED", - "BUILT", - "EXTENDED", - "FAILED", - "CLOSED", - }; - - public static final byte STREAM_STATUS_SENT_CONNECT = 0x00; - public static final byte STREAM_STATUS_SENT_RESOLVE = 0x01; - public static final byte STREAM_STATUS_SUCCEEDED = 0x02; - public static final byte STREAM_STATUS_FAILED = 0x03; - public static final byte STREAM_STATUS_CLOSED = 0x04; - public static final byte STREAM_STATUS_NEW_CONNECT = 0x05; - public static final byte STREAM_STATUS_NEW_RESOLVE = 0x06; - public static final byte STREAM_STATUS_DETACHED = 0x07; - - public static final String[] STREAM_STATUS_NAMES = { - "SENT_CONNECT", - "SENT_RESOLVE", - "SUCCEEDED", - "FAILED", - "CLOSED", - "NEW_CONNECT", - "NEW_RESOLVE", - "DETACHED" - }; - - public static final byte OR_CONN_STATUS_LAUNCHED = 0x00; - public static final byte OR_CONN_STATUS_CONNECTED = 0x01; - public static final byte OR_CONN_STATUS_FAILED = 0x02; - public static final byte OR_CONN_STATUS_CLOSED = 0x03; - - public static final String[] OR_CONN_STATUS_NAMES = { - "LAUNCHED","CONNECTED","FAILED","CLOSED" - }; - - public static final byte SIGNAL_HUP = 0x01; - public static final byte SIGNAL_INT = 0x02; - public static final byte SIGNAL_USR1 = 0x0A; - public static final byte SIGNAL_USR2 = 0x0C; - public static final byte SIGNAL_TERM = 0x0F; - - public static final String ERROR_MSGS[] = { - "Unspecified error", - "Internal error", - "Unrecognized message type", - "Syntax error", - "Unrecognized configuration key", - "Invalid configuration value", - "Unrecognized byte code", - "Unauthorized", - "Failed authentication attempt", - "Resource exhausted", - "No such stream", - "No such circuit", - "No such OR", - }; - -} - diff --git a/tor-android-binary/src/test/java/org/torproject/android/control/TorControlConnection.java b/tor-android-binary/src/test/java/org/torproject/android/control/TorControlConnection.java deleted file mode 100644 index 204dbc06..00000000 --- a/tor-android-binary/src/test/java/org/torproject/android/control/TorControlConnection.java +++ /dev/null @@ -1,730 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.Reader; -import java.io.Writer; -import java.net.Socket; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; - -/** A connection to a running Tor process as specified in control-spec.txt. */ -public class TorControlConnection implements TorControlCommands { - - private final LinkedList waiters; - private final BufferedReader input; - private final Writer output; - - private ControlParseThread thread; // Locking: this - - private volatile EventHandler handler; - private volatile PrintWriter debugOutput; - private volatile IOException parseThreadException; - - static class Waiter { - - List response; // Locking: this - - synchronized List getResponse() throws InterruptedException { - while (response == null) { - wait(); - } - return response; - } - - synchronized void setResponse(List response) { - this.response = response; - notifyAll(); - } - } - - static class ReplyLine { - - final String status; - final String msg; - final String rest; - - ReplyLine(String status, String msg, String rest) { - this.status = status; this.msg = msg; this.rest = rest; - } - } - - /** Create a new TorControlConnection to communicate with Tor over - * a given socket. After calling this constructor, it is typical to - * call launchThread and authenticate. */ - public TorControlConnection(Socket connection) throws IOException { - this(connection.getInputStream(), connection.getOutputStream()); - } - - /** Create a new TorControlConnection to communicate with Tor over - * an arbitrary pair of data streams. - */ - public TorControlConnection(InputStream i, OutputStream o) { - this(new InputStreamReader(i), new OutputStreamWriter(o)); - } - - public TorControlConnection(Reader i, Writer o) { - this.output = o; - if (i instanceof BufferedReader) - this.input = (BufferedReader) i; - else - this.input = new BufferedReader(i); - this.waiters = new LinkedList(); - } - - protected final void writeEscaped(String s) throws IOException { - StringTokenizer st = new StringTokenizer(s, "\n"); - while (st.hasMoreTokens()) { - String line = st.nextToken(); - if (line.startsWith(".")) - line = "."+line; - if (line.endsWith("\r")) - line += "\n"; - else - line += "\r\n"; - if (debugOutput != null) - debugOutput.print(">> "+line); - output.write(line); - } - output.write(".\r\n"); - if (debugOutput != null) - debugOutput.print(">> .\n"); - } - - protected static final String quote(String s) { - StringBuffer sb = new StringBuffer("\""); - for (int i = 0; i < s.length(); ++i) { - char c = s.charAt(i); - switch (c) - { - case '\r': - case '\n': - case '\\': - case '\"': - sb.append('\\'); - } - sb.append(c); - } - sb.append('\"'); - return sb.toString(); - } - - protected final ArrayList readReply() throws IOException { - ArrayList reply = new ArrayList(); - char c; - do { - String line = input.readLine(); - if (line == null) { - // if line is null, the end of the stream has been reached, i.e. - // the connection to Tor has been closed! - if (reply.isEmpty()) { - // nothing received so far, can exit cleanly - return reply; - } - // received half of a reply before the connection broke down - throw new TorControlSyntaxError("Connection to Tor " + - " broke down while receiving reply!"); - } - if (debugOutput != null) - debugOutput.println("<< "+line); - if (line.length() < 4) - throw new TorControlSyntaxError("Line (\""+line+"\") too short"); - String status = line.substring(0,3); - c = line.charAt(3); - String msg = line.substring(4); - String rest = null; - if (c == '+') { - StringBuffer data = new StringBuffer(); - while (true) { - line = input.readLine(); - if (debugOutput != null) - debugOutput.print("<< "+line); - if (line.equals(".")) - break; - else if (line.startsWith(".")) - line = line.substring(1); - data.append(line).append('\n'); - } - rest = data.toString(); - } - reply.add(new ReplyLine(status, msg, rest)); - } while (c != ' '); - - return reply; - } - - protected synchronized List sendAndWaitForResponse(String s, - String rest) throws IOException { - if(parseThreadException != null) throw parseThreadException; - checkThread(); - Waiter w = new Waiter(); - if (debugOutput != null) - debugOutput.print(">> "+s); - synchronized (waiters) { - output.write(s); - if (rest != null) - writeEscaped(rest); - output.flush(); - waiters.addLast(w); - } - List lst; - try { - lst = w.getResponse(); - } catch (InterruptedException ex) { - throw new IOException("Interrupted"); - } - for (Iterator i = lst.iterator(); i.hasNext(); ) { - ReplyLine c = i.next(); - if (! c.status.startsWith("2")) - throw new TorControlError("Error reply: "+c.msg); - } - return lst; - } - - /** Helper: decode a CMD_EVENT command and dispatch it to our - * EventHandler (if any). */ - protected void handleEvent(ArrayList events) { - if (handler == null) - return; - - for (Iterator i = events.iterator(); i.hasNext(); ) { - ReplyLine line = i.next(); - int idx = line.msg.indexOf(' '); - String tp = line.msg.substring(0, idx).toUpperCase(); - String rest = line.msg.substring(idx+1); - if (tp.equals("CIRC")) { - List lst = Bytes.splitStr(null, rest); - handler.circuitStatus(lst.get(1), - lst.get(0), - lst.get(1).equals("LAUNCHED") - || lst.size() < 3 ? "" - : lst.get(2)); - } else if (tp.equals("STREAM")) { - List lst = Bytes.splitStr(null, rest); - handler.streamStatus(lst.get(1), - lst.get(0), - lst.get(3)); - // XXXX circID. - } else if (tp.equals("ORCONN")) { - List lst = Bytes.splitStr(null, rest); - handler.orConnStatus(lst.get(1), lst.get(0)); - } else if (tp.equals("BW")) { - List lst = Bytes.splitStr(null, rest); - handler.bandwidthUsed(Integer.parseInt(lst.get(0)), - Integer.parseInt(lst.get(1))); - } else if (tp.equals("NEWDESC")) { - List lst = Bytes.splitStr(null, rest); - handler.newDescriptors(lst); - } else if (tp.equals("DEBUG") || - tp.equals("INFO") || - tp.equals("NOTICE") || - tp.equals("WARN") || - tp.equals("ERR")) { - handler.message(tp, rest); - } else { - handler.unrecognized(tp, rest); - } - } - } - - - /** 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 "\<\<" - */ - public void setDebugging(PrintWriter w) { - debugOutput = w; - } - - /** 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 "\<\<" - */ - public void setDebugging(PrintStream s) { - debugOutput = new PrintWriter(s, true); - } - - /** Set the EventHandler object that will be notified of any - * events Tor delivers to this connection. To make Tor send us - * events, call setEvents(). */ - public void setEventHandler(EventHandler handler) { - this.handler = handler; - } - - /** - * 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. - */ - public synchronized Thread launchThread(boolean daemon) { - ControlParseThread th = new ControlParseThread(); - if (daemon) - th.setDaemon(true); - th.start(); - this.thread = th; - return th; - } - - protected class ControlParseThread extends Thread { - - @Override - public void run() { - try { - react(); - } catch (IOException ex) { - parseThreadException = ex; - } - } - } - - protected synchronized void checkThread() { - if (thread == null) - launchThread(true); - } - - /** helper: implement the main background loop. */ - protected void react() throws IOException { - while (true) { - ArrayList lst = readReply(); - if (lst.isEmpty()) { - // connection has been closed remotely! end the loop! - return; - } - if ((lst.get(0)).status.startsWith("6")) - handleEvent(lst); - else { - synchronized (waiters) { - if (!waiters.isEmpty()) - { - Waiter w; - w = waiters.removeFirst(); - w.setResponse(lst); - } - } - - } - } - } - - /** Change the value of the configuration option 'key' to 'val'. - */ - public void setConf(String key, String value) throws IOException { - List lst = new ArrayList(); - lst.add(key+" "+value); - setConf(lst); - } - - /** Change the values of the configuration options stored in kvMap. */ - public void setConf(Map kvMap) throws IOException { - List lst = new ArrayList(); - for (Iterator> it = kvMap.entrySet().iterator(); it.hasNext(); ) { - Map.Entry ent = it.next(); - lst.add(ent.getKey()+" "+ent.getValue()+"\n"); - } - setConf(lst); - } - - /** 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. - */ - public void setConf(Collection kvList) throws IOException { - if (kvList.size() == 0) - return; - StringBuffer b = new StringBuffer("SETCONF"); - for (Iterator 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); - } - - /** Try to reset the values listed in the collection 'keys' to their - * default values. - **/ - public void resetConf(Collection keys) throws IOException { - if (keys.size() == 0) - return; - StringBuffer b = new StringBuffer("RESETCONF"); - for (Iterator it = keys.iterator(); it.hasNext(); ) { - String key = it.next(); - b.append(" ").append(key); - } - b.append("\r\n"); - sendAndWaitForResponse(b.toString(), null); - } - - /** Return the value of the configuration option 'key' */ - public List getConf(String key) throws IOException { - List lst = new ArrayList(); - lst.add(key); - return getConf(lst); - } - - /** 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. - */ - public List getConf(Collection keys) throws IOException { - StringBuffer sb = new StringBuffer("GETCONF"); - for (Iterator it = keys.iterator(); it.hasNext(); ) { - String key = it.next(); - sb.append(" ").append(key); - } - sb.append("\r\n"); - List lst = sendAndWaitForResponse(sb.toString(), null); - List result = new ArrayList(); - for (Iterator it = lst.iterator(); it.hasNext(); ) { - String kv = (it.next()).msg; - int idx = kv.indexOf('='); - if (idx >= 0) - result.add(new ConfigEntry(kv.substring(0, idx), - kv.substring(idx+1))); - else - result.add(new ConfigEntry(kv)); - } - return result; - } - - /** 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. - */ - public void setEvents(List events) throws IOException { - StringBuffer sb = new StringBuffer("SETEVENTS"); - for (Iterator it = events.iterator(); it.hasNext(); ) { - sb.append(" ").append(it.next()); - } - sb.append("\r\n"); - sendAndWaitForResponse(sb.toString(), null); - } - - /** 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. - */ - public void authenticate(byte[] auth) throws IOException { - String cmd = "AUTHENTICATE " + Bytes.hex(auth) + "\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); - } - - /** 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
  • - *
- */ - public void signal(String signal) throws IOException { - String cmd = "SIGNAL " + signal + "\r\n"; - sendAndWaitForResponse(cmd, null); - } - - /** Send a signal to the Tor process to shut it down or halt it. - * Does not wait for a response. */ - public void shutdownTor(String signal) throws IOException { - String s = "SIGNAL " + signal + "\r\n"; - Waiter w = new Waiter(); - if (debugOutput != null) - debugOutput.print(">> "+s); - synchronized (waiters) { - output.write(s); - output.flush(); - } - } - - /** 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. - */ - public Map mapAddresses(Collection kvLines) throws IOException { - StringBuffer sb = new StringBuffer("MAPADDRESS"); - for (Iterator it = kvLines.iterator(); it.hasNext(); ) { - String kv = it.next(); - int i = kv.indexOf(' '); - sb.append(" ").append(kv.substring(0,i)).append("=") - .append(quote(kv.substring(i+1))); - } - sb.append("\r\n"); - List lst = sendAndWaitForResponse(sb.toString(), null); - Map result = new HashMap(); - for (Iterator it = lst.iterator(); it.hasNext(); ) { - String kv = (it.next()).msg; - int idx = kv.indexOf('='); - result.put(kv.substring(0, idx), - kv.substring(idx+1)); - } - return result; - } - - public Map mapAddresses(Map addresses) throws IOException { - List kvList = new ArrayList(); - for (Iterator> it = addresses.entrySet().iterator(); it.hasNext(); ) { - Map.Entry e = it.next(); - kvList.add(e.getKey()+" "+e.getValue()); - } - return mapAddresses(kvList); - } - - public String mapAddress(String fromAddr, String toAddr) throws IOException { - List lst = new ArrayList(); - lst.add(fromAddr+" "+toAddr+"\n"); - Map m = mapAddresses(lst); - return m.get(fromAddr); - } - - /** 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"
  • - *
- */ - public Map getInfo(Collection keys) throws IOException { - StringBuffer sb = new StringBuffer("GETINFO"); - for (Iterator it = keys.iterator(); it.hasNext(); ) { - sb.append(" ").append(it.next()); - } - sb.append("\r\n"); - List lst = sendAndWaitForResponse(sb.toString(), null); - Map m = new HashMap(); - for (Iterator it = lst.iterator(); it.hasNext(); ) { - ReplyLine line = it.next(); - int idx = line.msg.indexOf('='); - if (idx<0) - break; - String k = line.msg.substring(0,idx); - String v; - if (line.rest != null) { - v = line.rest; - } else { - v = line.msg.substring(idx+1); - } - m.put(k, v); - } - return m; - } - - - - /** Return the value of the information field 'key' */ - public String getInfo(String key) throws IOException { - List lst = new ArrayList(); - lst.add(key); - Map m = getInfo(lst); - return m.get(key); - } - - /** 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. - */ - public String extendCircuit(String circID, String path) throws IOException { - List lst = sendAndWaitForResponse( - "EXTENDCIRCUIT "+circID+" "+path+"\r\n", null); - return (lst.get(0)).msg; - } - - /** 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. - */ - public void attachStream(String streamID, String circID) - throws IOException { - sendAndWaitForResponse("ATTACHSTREAM "+streamID+" "+circID+"\r\n", null); - } - - /** 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. - */ - // More documentation here on format of desc? - // No need for return value? control-spec.txt says reply is merely "250 OK" on success... - public String postDescriptor(String desc) throws IOException { - List lst = sendAndWaitForResponse("+POSTDESCRIPTOR\r\n", desc); - return (lst.get(0)).msg; - } - - /** 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. - */ - public void redirectStream(String streamID, String address) throws IOException { - sendAndWaitForResponse("REDIRECTSTREAM "+streamID+" "+address+"\r\n", - null); - } - - /** 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. - */ - public void closeStream(String streamID, byte reason) - throws IOException { - sendAndWaitForResponse("CLOSESTREAM "+streamID+" "+reason+"\r\n",null); - } - - /** Tells Tor to close the circuit identified by circID. - * If ifUnused 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); - } -} - diff --git a/tor-android-binary/src/test/java/org/torproject/android/control/TorControlError.java b/tor-android-binary/src/test/java/org/torproject/android/control/TorControlError.java deleted file mode 100644 index d07ee514..00000000 --- a/tor-android-binary/src/test/java/org/torproject/android/control/TorControlError.java +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -import java.io.IOException; - -/** - * An exception raised when Tor tells us about an error. - */ -public class TorControlError extends IOException { - - static final long serialVersionUID = 3; - - private final int errorType; - - public TorControlError(int type, String s) { - super(s); - errorType = type; - } - - public TorControlError(String s) { - this(-1, s); - } - - public int getErrorType() { - return errorType; - } - - public String getErrorMsg() { - try { - if (errorType == -1) - return null; - return TorControlCommands.ERROR_MSGS[errorType]; - } catch (ArrayIndexOutOfBoundsException ex) { - return "Unrecongized error #"+errorType; - } - } -} - diff --git a/tor-android-binary/src/test/java/org/torproject/android/control/TorControlSyntaxError.java b/tor-android-binary/src/test/java/org/torproject/android/control/TorControlSyntaxError.java deleted file mode 100644 index dba4f44b..00000000 --- a/tor-android-binary/src/test/java/org/torproject/android/control/TorControlSyntaxError.java +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control; - -import java.io.IOException; - -/** - * An exception raised when Tor behaves in an unexpected way. - */ -public class TorControlSyntaxError extends IOException { - - static final long serialVersionUID = 3; - - public TorControlSyntaxError(String s) { super(s); } -} - diff --git a/tor-android-binary/src/test/java/org/torproject/android/control/examples/.cvsignore b/tor-android-binary/src/test/java/org/torproject/android/control/examples/.cvsignore deleted file mode 100644 index 6b468b62..00000000 --- a/tor-android-binary/src/test/java/org/torproject/android/control/examples/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.class diff --git a/tor-android-binary/src/test/java/org/torproject/android/control/examples/DebuggingEventHandler.java b/tor-android-binary/src/test/java/org/torproject/android/control/examples/DebuggingEventHandler.java deleted file mode 100644 index 48c49a28..00000000 --- a/tor-android-binary/src/test/java/org/torproject/android/control/examples/DebuggingEventHandler.java +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control.examples; - -import java.io.PrintWriter; -import java.util.Iterator; -import org.torproject.android.control.EventHandler; - -public class DebuggingEventHandler implements EventHandler { - - private final PrintWriter out; - - public DebuggingEventHandler(PrintWriter p) { - out = p; - } - - public void circuitStatus(String status, String circID, String path) { - out.println("Circuit "+circID+" is now "+status+" (path="+path+")"); - } - public void streamStatus(String status, String streamID, String target) { - out.println("Stream "+streamID+" is now "+status+" (target="+target+")"); - } - public void orConnStatus(String status, String orName) { - out.println("OR connection to "+orName+" is now "+status); - } - public void bandwidthUsed(long read, long written) { - out.println("Bandwidth usage: "+read+" bytes read; "+ - written+" bytes written."); - } - public void newDescriptors(java.util.List orList) { - out.println("New descriptors for routers:"); - for (Iterator i = orList.iterator(); i.hasNext(); ) - out.println(" "+i.next()); - } - public void message(String type, String msg) { - out.println("["+type+"] "+msg.trim()); - } - - public void unrecognized(String type, String msg) { - out.println("unrecognized event ["+type+"] "+msg.trim()); - } - -} - diff --git a/tor-android-binary/src/test/java/org/torproject/android/control/examples/Main.java b/tor-android-binary/src/test/java/org/torproject/android/control/examples/Main.java deleted file mode 100644 index b0e0a3c0..00000000 --- a/tor-android-binary/src/test/java/org/torproject/android/control/examples/Main.java +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2005 Nick Mathewson, Roger Dingledine -// See LICENSE file for copying information -package org.torproject.android.control.examples; - -import org.torproject.android.control.*; -import java.io.EOFException; -import java.io.IOException; -import java.io.PrintWriter; -import java.net.Socket; -import java.util.ArrayList; -import java.util.List; -import java.util.Arrays; -import java.util.Map; -import java.util.Iterator; - -public class Main implements TorControlCommands { - - public static void main(String args[]) { - if (args.length < 1) { - System.err.println("No command given."); - return; - } - try { - if (args[0].equals("set-config")) { - setConfig(args); - } else if (args[0].equals("get-config")) { - getConfig(args); - } else if (args[0].equals("get-info")) { - getInfo(args); - } else if (args[0].equals("listen")) { - listenForEvents(args); - } else if (args[0].equals("signal")) { - signal(args); - } else if (args[0].equals("auth")) { - authDemo(args); - } else { - System.err.println("Unrecognized command: "+args[0]); - } - } catch (EOFException ex) { - System.out.println("Control socket closed by Tor."); - } catch (TorControlError ex) { - System.err.println("Error from Tor process: "+ - ex+" ["+ex.getErrorMsg()+"]"); - } catch (IOException ex) { - System.err.println("IO exception when talking to Tor process: "+ - ex); - ex.printStackTrace(System.err); - } - } - - private static TorControlConnection getConnection(String[] args, - boolean daemon) throws IOException { - Socket s = new Socket("127.0.0.1", 9100); - TorControlConnection conn = new TorControlConnection(s); - conn.launchThread(daemon); - conn.authenticate(new byte[0]); - return conn; - } - - private static TorControlConnection getConnection(String[] args) - throws IOException { - return getConnection(args, true); - } - - public static void setConfig(String[] args) throws IOException { - // Usage: "set-config [-save] key value key value key value" - TorControlConnection conn = getConnection(args); - ArrayList lst = new ArrayList(); - int i = 1; - boolean save = false; - if (args[i].equals("-save")) { - save = true; - ++i; - } - for (; i < args.length; i +=2) { - lst.add(args[i]+" "+args[i+1]); - } - conn.setConf(lst); - if (save) { - conn.saveConf(); - } - } - - public static void getConfig(String[] args) throws IOException { - // Usage: get-config key key key - TorControlConnection conn = getConnection(args); - List lst = conn.getConf(Arrays.asList(args).subList(1,args.length)); - for (Iterator i = lst.iterator(); i.hasNext(); ) { - ConfigEntry e = i.next(); - System.out.println("KEY: "+e.key); - System.out.println("VAL: "+e.value); - } - } - - public static void getInfo(String[] args) throws IOException { - TorControlConnection conn = getConnection(args); - Map m = conn.getInfo(Arrays.asList(args).subList(1,args.length)); - for (Iterator> i = m.entrySet().iterator(); i.hasNext(); ) { - Map.Entry e = i.next(); - System.out.println("KEY: "+e.getKey()); - System.out.println("VAL: "+e.getValue()); - } - } - - public static void listenForEvents(String[] args) throws IOException { - // Usage: listen [circ|stream|orconn|bw|newdesc|info|notice|warn|error]* - TorControlConnection conn = getConnection(args, false); - ArrayList lst = new ArrayList(); - for (int i = 1; i < args.length; ++i) { - lst.add(args[i]); - } - conn.setEventHandler( - new DebuggingEventHandler(new PrintWriter(System.out, true))); - conn.setEvents(lst); - } - - public static void signal(String[] args) throws IOException { - // Usage signal [reload|shutdown|dump|debug|halt] - TorControlConnection conn = getConnection(args, false); - // distinguish shutdown signal from other signals - if ("SHUTDOWN".equalsIgnoreCase(args[1]) - || "HALT".equalsIgnoreCase(args[1])) { - conn.shutdownTor(args[1].toUpperCase()); - } else { - conn.signal(args[1].toUpperCase()); - } - } - - public static void authDemo(String[] args) throws IOException { - - PasswordDigest pwd = PasswordDigest.generateDigest(); - Socket s = new Socket("127.0.0.1", 9100); - TorControlConnection conn = new TorControlConnection(s); - conn.launchThread(true); - conn.authenticate(new byte[0]); - - conn.setConf("HashedControlPassword", pwd.getHashedPassword()); - - s = new Socket("127.0.0.1", 9100); - conn = new TorControlConnection(s); - conn.launchThread(true); - conn.authenticate(pwd.getSecret()); - } - -} - diff --git a/tor-android-binary/src/test/java/org/torproject/android/service/ExampleUnitTest.java b/tor-android-binary/src/test/java/org/torproject/android/service/ExampleUnitTest.java deleted file mode 100644 index 578fa4b9..00000000 --- a/tor-android-binary/src/test/java/org/torproject/android/service/ExampleUnitTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.torproject.android.service; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * To work on unit tests, switch the Test Artifact in the Build Variants view. - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() throws Exception { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file