123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- diff --git a/README.md b/README.md
- index 902d727..359cc69 100644
- --- a/README.md
- +++ b/README.md
- @@ -1,7 +1,4 @@
- -
- A Java library for controlling a Tor instance via its control port. It is
- used in the Android app Orbot as well as others.
-
- -To add this library to a gradle project:
- -
- - compile 'net.freehaven.tor.control:jtorctl:0.2'
- +This fork includes patches for managing onion services.
- diff --git a/net/freehaven/tor/control/TorControlCommands.java b/net/freehaven/tor/control/TorControlCommands.java
- index 36482d5..14486e3 100644
- --- a/net/freehaven/tor/control/TorControlCommands.java
- +++ b/net/freehaven/tor/control/TorControlCommands.java
- @@ -144,5 +144,8 @@ public interface TorControlCommands {
- "No such OR",
- };
-
- + public static final String HS_ADDRESS = "onionAddress";
- + public static final String HS_PRIVKEY = "onionPrivKey";
- +
- }
-
- diff --git a/net/freehaven/tor/control/TorControlConnection.java b/net/freehaven/tor/control/TorControlConnection.java
- index 9524612..eacdd66 100644
- --- a/net/freehaven/tor/control/TorControlConnection.java
- +++ b/net/freehaven/tor/control/TorControlConnection.java
- @@ -40,10 +40,14 @@ public class TorControlConnection implements TorControlCommands {
- static class Waiter {
-
- List<ReplyLine> response; // Locking: this
- + boolean interrupted;
-
- synchronized List<ReplyLine> getResponse() throws InterruptedException {
- while (response == null) {
- wait();
- + if (interrupted) {
- + throw new InterruptedException();
- + }
- }
- return response;
- }
- @@ -52,6 +56,11 @@ public class TorControlConnection implements TorControlCommands {
- this.response = response;
- notifyAll();
- }
- +
- + synchronized void interrupt() {
- + interrupted = true;
- + notifyAll();
- + }
- }
-
- static class ReplyLine {
- @@ -171,7 +180,7 @@ public class TorControlConnection implements TorControlCommands {
-
- protected synchronized List<ReplyLine> sendAndWaitForResponse(String s,
- String rest) throws IOException {
- - if(parseThreadException != null) throw parseThreadException;
- + if (parseThreadException != null) throw parseThreadException;
- checkThread();
- Waiter w = new Waiter();
- if (debugOutput != null)
- @@ -305,8 +314,15 @@ public class TorControlConnection implements TorControlCommands {
- while (true) {
- ArrayList<ReplyLine> lst = readReply();
- if (lst.isEmpty()) {
- - // connection has been closed remotely! end the loop!
- - return;
- + // interrupted queued waiters, there won't be any response.
- + synchronized (waiters) {
- + if (!waiters.isEmpty()) {
- + for (Waiter w : waiters) {
- + w.interrupt();
- + }
- + }
- + }
- + throw new IOException("Tor is no longer running");
- }
- if ((lst.get(0)).status.startsWith("6"))
- handleEvent(lst);
- @@ -736,11 +752,111 @@ public class TorControlConnection implements TorControlCommands {
- sendAndWaitForResponse("TAKEOWNERSHIP\r\n", null);
- }
-
- + /**
- + * Tells Tor to generate and set up a new onion service using the best
- + * supported algorithm.
- + * <p/>
- + * ADD_ONION was added in Tor 0.2.7.1-alpha.
- + */
- + public Map<String,String> addOnion(Map<Integer,String> portLines)
- + throws IOException {
- + return addOnion("NEW:BEST", portLines, null);
- + }
- +
- + /**
- + * Tells Tor to generate and set up a new onion service using the best
- + * supported algorithm.
- + * <p/>
- + * ADD_ONION was added in Tor 0.2.7.1-alpha.
- + */
- + public Map<String,String> addOnion(Map<Integer,String> portLines,
- + boolean ephemeral, boolean detach)
- + throws IOException {
- + return addOnion("NEW:BEST", portLines, ephemeral, detach);
- + }
- +
- + /**
- + * Tells Tor to set up an onion service using the provided private key.
- + * <p/>
- + * ADD_ONION was added in Tor 0.2.7.1-alpha.
- + */
- + public Map<String,String> addOnion(String privKey,
- + Map<Integer,String> portLines)
- + throws IOException {
- + return addOnion(privKey, portLines, null);
- + }
- +
- + /**
- + * Tells Tor to set up an onion service using the provided private key.
- + * <p/>
- + * ADD_ONION was added in Tor 0.2.7.1-alpha.
- + */
- + public Map<String,String> addOnion(String privKey,
- + Map<Integer,String> portLines,
- + boolean ephemeral, boolean detach)
- + throws IOException {
- + List<String> flags = new ArrayList<String>();
- + if (ephemeral)
- + flags.add("DiscardPK");
- + if (detach)
- + flags.add("Detach");
- + return addOnion(privKey, portLines, flags);
- + }
- +
- + /**
- + * Tells Tor to set up an onion service.
- + * <p/>
- + * ADD_ONION was added in Tor 0.2.7.1-alpha.
- + */
- + public Map<String,String> addOnion(String privKey,
- + Map<Integer,String> portLines,
- + List<String> flags)
- + throws IOException {
- + if (privKey.indexOf(':') < 0)
- + throw new IllegalArgumentException("Invalid privKey");
- + if (portLines == null || portLines.size() < 1)
- + throw new IllegalArgumentException("Must provide at least one port line");
- + StringBuilder b = new StringBuilder();
- + b.append("ADD_ONION ").append(privKey);
- + if (flags != null && flags.size() > 0) {
- + b.append(" Flags=");
- + String separator = "";
- + for (String flag : flags) {
- + b.append(separator).append(flag);
- + separator = ",";
- + }
- + }
- + for (Map.Entry<Integer,String> portLine : portLines.entrySet()) {
- + int virtPort = portLine.getKey();
- + String target = portLine.getValue();
- + b.append(" Port=").append(virtPort);
- + if (target != null && target.length() > 0)
- + b.append(",").append(target);
- + }
- + b.append("\r\n");
- + List<ReplyLine> lst = sendAndWaitForResponse(b.toString(), null);
- + Map<String,String> ret = new HashMap<String,String>();
- + ret.put(HS_ADDRESS, (lst.get(0)).msg.split("=", 2)[1]);
- + if (lst.size() > 2)
- + ret.put(HS_PRIVKEY, (lst.get(1)).msg.split("=", 2)[1]);
- + return ret;
- + }
- +
- + /**
- + * Tells Tor to take down an onion service previously set up with
- + * addOnion(). The hostname excludes the .onion extension.
- + * <p/>
- + * DEL_ONION was added in Tor 0.2.7.1-alpha.
- + */
- + public void delOnion(String hostname) throws IOException {
- + sendAndWaitForResponse("DEL_ONION " + hostname + "\r\n", null);
- + }
- +
- /** Tells Tor to forget any cached client state relating to the hidden
- * service with the given hostname (excluding the .onion extension).
- */
- public void forgetHiddenService(String hostname) throws IOException {
- - sendAndWaitForResponse("FORGETHS " + hostname + "\r\n", null);
- + sendAndWaitForResponse("HSFORGET " + hostname + "\r\n", null);
- }
- }
-
|