Ticket #11414: jtorctl-1.patch

File jtorctl-1.patch, 12.5 KB (added by akwizgran, 5 years ago)
  • net/freehaven/tor/control/examples/DebuggingEventHandler.java

    diff -wur jtorctl/net/freehaven/tor/control/examples/DebuggingEventHandler.java jtorctl-briar/net/freehaven/tor/control/examples/DebuggingEventHandler.java
    old new  
    88
    99public class DebuggingEventHandler implements EventHandler {
    1010
    11     protected PrintWriter out;
     11    private final PrintWriter out;
    1212
    1313    public DebuggingEventHandler(PrintWriter p) {
    1414        out = p;
  • net/freehaven/tor/control/examples/Main.java

    diff -wur jtorctl/net/freehaven/tor/control/examples/Main.java jtorctl-briar/net/freehaven/tor/control/examples/Main.java
    old new  
    33package net.freehaven.tor.control.examples;
    44
    55import net.freehaven.tor.control.*;
    6 import java.io.PrintWriter;
     6import java.io.EOFException;
    77import java.io.IOException;
     8import java.io.PrintWriter;
     9import java.net.Socket;
    810import java.util.ArrayList;
    911import java.util.List;
    1012import java.util.Arrays;
     
    3436            } else {
    3537                System.err.println("Unrecognized command: "+args[0]);
    3638            }
    37         } catch (java.io.EOFException ex) {
     39        } catch (EOFException ex) {
    3840            System.out.println("Control socket closed by Tor.");
    3941        } catch (IOException ex) {
    4042            System.err.println("IO exception when talking to Tor process: "+
     
    4749    }
    4850
    4951    private static TorControlConnection getConnection(String[] args,
    50                                                       boolean daemon)
    51         throws IOException {
    52         TorControlConnection conn = TorControlConnection.getConnection(
    53                                     new java.net.Socket("127.0.0.1", 9100));
    54         //if (conn instanceof TorControlConnection1) {
    55         //    System.err.println("Debugging");
    56         //    ((TorControlConnection1)conn).setDebugging(System.err);
    57         //}
     52        boolean daemon) throws IOException {
     53        Socket s = new Socket("127.0.0.1", 9100);
     54        TorControlConnection conn = new TorControlConnection(s);
    5855        conn.launchThread(daemon);
    5956        conn.authenticate(new byte[0]);
    6057        return conn;
     
    132129    public static void authDemo(String[] args) throws IOException {
    133130
    134131        PasswordDigest pwd = PasswordDigest.generateDigest();
    135         java.net.Socket s = new java.net.Socket("127.0.0.1", 9100);
    136         TorControlConnection conn = TorControlConnection.getConnection(s);
     132        Socket s = new Socket("127.0.0.1", 9100);
     133        TorControlConnection conn = new TorControlConnection(s);
    137134        conn.launchThread(true);
    138135        conn.authenticate(new byte[0]);
    139136
    140137        conn.setConf("HashedControlPassword", pwd.getHashedPassword());
    141138
    142         conn = TorControlConnection.getConnection(
    143                                     new java.net.Socket("127.0.0.1", 9100));
     139        s = new Socket("127.0.0.1", 9100);
     140        conn = new TorControlConnection(s);
    144141        conn.launchThread(true);
    145142        conn.authenticate(pwd.getSecret());
    146143    }
  • net/freehaven/tor/control/PasswordDigest.java

    diff -wur jtorctl/net/freehaven/tor/control/PasswordDigest.java jtorctl-briar/net/freehaven/tor/control/PasswordDigest.java
    old new  
    22// See LICENSE file for copying information
    33package net.freehaven.tor.control;
    44
    5 import java.security.SecureRandom;
    65import java.security.MessageDigest;
     6import java.security.NoSuchAlgorithmException;
     7import java.security.SecureRandom;
    78
    89/**
    910 * A hashed digest of a secret password (used to set control connection
     
    1314 */
    1415public class PasswordDigest {
    1516
    16     byte[] secret;
    17     String hashedKey;
     17    private final byte[] secret;
     18    private final String hashedKey;
    1819
    1920    /** Return a new password digest with a random secret and salt. */
    2021    public static PasswordDigest generateDigest() {
     
    6364        MessageDigest d;
    6465        try {
    6566            d = MessageDigest.getInstance("SHA-1");
    66         } catch (java.security.NoSuchAlgorithmException ex) {
     67        } catch (NoSuchAlgorithmException ex) {
    6768            throw new RuntimeException("Can't run without sha-1.");
    6869        }
    6970        int c = (specifier[8])&0xff;
  • net/freehaven/tor/control/TorControlConnection.java

    diff -wur jtorctl/net/freehaven/tor/control/TorControlConnection.java jtorctl-briar/net/freehaven/tor/control/TorControlConnection.java
    old new  
    22// See LICENSE file for copying information
    33package net.freehaven.tor.control;
    44
     5import java.io.BufferedReader;
    56import java.io.IOException;
     7import java.io.InputStream;
     8import java.io.InputStreamReader;
     9import java.io.OutputStream;
     10import java.io.OutputStreamWriter;
     11import java.io.PrintStream;
     12import java.io.PrintWriter;
     13import java.io.Reader;
     14import java.io.Writer;
     15import java.net.Socket;
    616import java.net.SocketException;
    717import java.util.ArrayList;
    818import java.util.Collection;
     
    1525import java.util.concurrent.CancellationException;
    1626
    1727/** A connection to a running Tor process as specified in control-spec.txt. */
    18 public class TorControlConnection implements TorControlCommands
    19 {
    20 
    21     protected EventHandler handler;
     28public class TorControlConnection implements TorControlCommands {
    2229
    23     protected LinkedList<Waiter> waiters;
     30    private final LinkedList<Waiter> waiters;
     31    private final BufferedReader input;
     32    private final Writer output;
    2433
    25     protected ControlParseThread thread;
     34    private ControlParseThread thread; // Locking: this
    2635
    27     protected java.io.BufferedReader input;
     36    private volatile EventHandler handler;
     37    private volatile PrintWriter debugOutput;
     38    private volatile IOException parseThreadException;
    2839   
    29     protected java.io.Writer output;
     40    static class Waiter {
    3041   
    31     protected java.io.PrintWriter debugOutput;
     42        List<ReplyLine> response; // Locking: this
    3243   
    33     static class Waiter {
    34         List<ReplyLine> response;
    35         public synchronized List<ReplyLine> getResponse() {
    36             try {
     44        synchronized List<ReplyLine> getResponse() throws InterruptedException {
    3745                while (response == null) {
    3846                    wait();
    3947                }
    40             } catch (InterruptedException ex) {
    41                 throw new CancellationException(
    42                     "Please don't interrupt library calls.");
    43             }
    4448            return response;
    4549        }
    46         public synchronized void setResponse(List<ReplyLine> response) {
     50
     51        synchronized void setResponse(List<ReplyLine> response) {
    4752            this.response = response;
    4853            notifyAll();
    4954        }
    5055    }
    5156
    5257    static class ReplyLine {
    53         public String status;
    54         public String msg;
    55         public String rest;
     58
     59        final String status;
     60        final String msg;
     61        final String rest;
    5662
    5763        ReplyLine(String status, String msg, String rest) {
    5864            this.status = status; this.msg = msg; this.rest = rest;
    5965        }
    6066    }
    6167   
    62     public static TorControlConnection getConnection(java.net.Socket sock)
    63         throws IOException
    64     {
    65         return new TorControlConnection(sock);
    66     }
    67 
    6868    /** Create a new TorControlConnection to communicate with Tor over
    6969     * a given socket.  After calling this constructor, it is typical to
    7070     * call launchThread and authenticate. */
    71     public TorControlConnection(java.net.Socket connection)
    72         throws IOException {
     71    public TorControlConnection(Socket connection) throws IOException {
    7372        this(connection.getInputStream(), connection.getOutputStream());
    7473    }
    7574
    7675    /** Create a new TorControlConnection to communicate with Tor over
    7776     * an arbitrary pair of data streams.
    7877     */
    79     public TorControlConnection(java.io.InputStream i, java.io.OutputStream o) {
    80         this(new java.io.InputStreamReader(i),
    81              new java.io.OutputStreamWriter(o));
     78    public TorControlConnection(InputStream i, OutputStream o) {
     79        this(new InputStreamReader(i), new OutputStreamWriter(o));
    8280    }
    8381
    84     public TorControlConnection(java.io.Reader i, java.io.Writer o) {
     82    public TorControlConnection(Reader i, Writer o) {
    8583        this.output = o;
    86         if (i instanceof java.io.BufferedReader)
    87             this.input = (java.io.BufferedReader) i;
     84        if (i instanceof BufferedReader)
     85            this.input = (BufferedReader) i;
    8886        else
    89             this.input = new java.io.BufferedReader(i);
    90 
     87            this.input = new BufferedReader(i);
    9188        this.waiters = new LinkedList<Waiter>();
    9289    }
    9390
     
    172169        return reply;
    173170    }
    174171
    175     protected synchronized List<ReplyLine> sendAndWaitForResponse(String s,String rest)
    176         throws IOException {
     172    protected synchronized List<ReplyLine> sendAndWaitForResponse(String s,
     173        String rest) throws IOException {
     174        if(parseThreadException != null) throw parseThreadException;
    177175        checkThread();
    178176        Waiter w = new Waiter();
    179177        if (debugOutput != null)
     
    185183            output.flush();
    186184            waiters.addLast(w);
    187185        }
    188         List<ReplyLine> lst = w.getResponse();
     186        List<ReplyLine> lst;
     187        try {
     188            lst = w.getResponse();
     189        } catch (InterruptedException ex) {
     190            throw new IOException("Interrupted");
     191        }
    189192        for (Iterator<ReplyLine> i = lst.iterator(); i.hasNext(); ) {
    190193            ReplyLine c = i.next();
    191194            if (! c.status.startsWith("2"))
     
    210213                handler.circuitStatus(lst.get(1),
    211214                                      lst.get(0),
    212215                                      lst.get(1).equals("LAUNCHED")
    213                                           || lst.size() < 2 ? ""
     216                                          || lst.size() < 3 ? ""
    214217                                          : lst.get(2));
    215218            } else if (tp.equals("STREAM")) {
    216219                List<String> lst = Bytes.splitStr(null, rest);
     
    246249    * Outgoing messages are preceded by "\>\>" and incoming messages are preceded
    247250    * by "\<\<"
    248251    */
    249     public void setDebugging(java.io.PrintWriter w) {
     252    public void setDebugging(PrintWriter w) {
    250253        debugOutput = w;
    251254    }
    252255   
     
    255258    * Outgoing messages are preceded by "\>\>" and incoming messages are preceded
    256259    * by "\<\<"
    257260    */
    258     public void setDebugging(java.io.PrintStream s) {
    259         debugOutput = new java.io.PrintWriter(s, true);
     261    public void setDebugging(PrintStream s) {
     262        debugOutput = new PrintWriter(s, true);
    260263    }
    261264
    262265    /** Set the EventHandler object that will be notified of any
     
    271274     * This is necessary to handle asynchronous events and synchronous
    272275     * responses that arrive independantly over the same socket.
    273276     */
    274     public Thread launchThread(boolean daemon) {
     277    public synchronized Thread launchThread(boolean daemon) {
    275278        ControlParseThread th = new ControlParseThread();
    276279        if (daemon)
    277280            th.setDaemon(true);
     
    281284    }
    282285
    283286    protected class ControlParseThread extends Thread {
    284         boolean stopped = false;
     287
    285288        @Override
    286289        public void run() {
    287290            try {
    288291                react();
    289             } catch (SocketException ex) {
    290                 if (stopped) // we expected this exception
    291                     return;
    292                 throw new RuntimeException(ex);
    293292            } catch (IOException ex) {
    294                 throw new RuntimeException(ex);
     293                parseThreadException = ex;
    295294            }
    296295        }
    297         public void stopListening() {
    298             this.stopped = true;
    299         }
    300296    }
    301297
    302     protected final void checkThread() {
     298    protected synchronized void checkThread() {
    303299        if (thread == null)
    304300            launchThread(true);
    305301    }
     
    505501        Waiter w = new Waiter();
    506502        if (debugOutput != null)
    507503            debugOutput.print(">> "+s);
    508         if (this.thread != null) {
    509             this.thread.stopListening();
    510         }
    511504        synchronized (waiters) {
    512505            output.write(s);
    513506            output.flush();
    514             waiters.addLast(w); // Prevent react() from finding the list empty
    515507        }
    516508    }
    517509