2

I want to use Java Socket with SOCKS proxy to connect on Tor (I am using Orbot and Tor service is running on port 9050 ).

I got the error :

I/System.out: java.net.UnknownHostException: Host is unresolved: 3g2upl4pq6kufc4m.onion

My code is as follow :

// setup proxy
address = new InetSocketAddress('localhost', 9050);
proxy = new java.net.Proxy(java.net.Proxy.Type.SOCKS,address);
// setup socket
client = new Socket(proxy);
inet = new InetSocketAddress("3g2upl4pq6kufc4m.onion", 80);
// connect
client.connect(inet);

This is legitimate, as Android will probably perform DNS resolution via DNS server specified in network configuration and the resolution of onion address will not work.

How do I specify to let Tor service to perform the DNS resolution (Tor will normally handle the hostname from the TCP packet) ?

Am_I_Helpful
  • 18,735
  • 7
  • 49
  • 73
Duke Nukem
  • 319
  • 4
  • 15
  • Good Luck doing some intensive search and exercise! – Am_I_Helpful Sep 03 '16 at 17:30
  • @Am_I_Helpful Do you have more information? I was thinking about reimplementing the java dns resolution function, but well I hope there is a simpler solution :) – Duke Nukem Sep 03 '16 at 17:34
  • For achieving this, you may have to probably re-implement the dns-resolution in java! I don't think there is any API which would come to rescue. Good Luck... – Am_I_Helpful Sep 03 '16 at 17:39
  • @Am_I_Helpful Ok. My idea, rather than touching java DNS resolution function, is to modify the java.net.Proxy in order to drop the DNS request and continue (as it's useless for Tor). I think the problem is here, and not specially into the java DNS resolution function (the proxy will perform DNS resolution and fail as Tor service will not handle this. It will then return an exception). What do you think about this? – Duke Nukem Sep 03 '16 at 18:01
  • I have no idea about Tor, and what you're trying to convey. I can't help further, SORRY! – Am_I_Helpful Sep 03 '16 at 18:03
  • Have you found a solution to this? – palindrom Jan 12 '17 at 19:08
  • Not yet. Also, I didn't have the time to test Jehy's answer. But a very possible solution may be to modify InetSocketAddress in order to not perform DNS resolution. – Duke Nukem Jan 12 '17 at 22:53

2 Answers2

1

The correct way of doing this is to use InetSocketAddress.createUnresolved(...) method but this throws an exception on Android.

As a work around we need to implement Socks ourselves like here: http://www.mit.edu/~foley/TinFoil/src/tinfoil/TorLib.java

An explanation is here: https://github.com/acomminos/OnionKit/blob/master/libnetcipher/src/info/guardianproject/onionkit/proxy/SocksProxyClientConnOperator.java

Basically:

        socket = new Socket();
        socket.setSoTimeout(READ_TIMEOUT_MILLISECONDS);
        socket.connect(new InetSocketAddress(mProxyHost, mProxyPort), CONNECT_TIMEOUT_MILLISECONDS);

        DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
        outputStream.write((byte)0x04);
        outputStream.write((byte)0x01);
        outputStream.writeShort((short)port);
        outputStream.writeInt(0x01);
        outputStream.write((byte)0x00);
        outputStream.write(host.getBytes());
        outputStream.write((byte)0x00);

        DataInputStream inputStream = new DataInputStream(socket.getInputStream());
        if (inputStream.readByte() != (byte)0x00 || inputStream.readByte() != (byte)0x5a) {
            throw new IOException("SOCKS4a connect failed");
        }
        inputStream.readShort();
        inputStream.readInt();
        //socket is ready to use
palindrom
  • 18,033
  • 1
  • 21
  • 37
0

You should pass unresolved socket to Orbot library. It should be created like this:

InetSocketAddress unresolvedRemote = InetSocketAddress.
createUnresolved(host.getHostName(), remoteAddress.getPort());

By the way, if you use apache's httpClient, you can find a sample here.

Jehy
  • 4,729
  • 1
  • 38
  • 55