package com.msopentech.thali.java.toronionproxy; import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy; import com.runjva.sourceforge.jsocks.protocol.SocksSocket; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.nio.ByteBuffer; public class Utilities { private static final int READ_TIMEOUT_MILLISECONDS = 30000; private static final int CONNECT_TIMEOUT_MILLISECONDS = 60000; private static final Logger LOG = LoggerFactory.getLogger(Utilities.class); private Utilities() { } public static Socket socks4aSocketConnection(String networkHost, int networkPort, String socksHost, int socksPort) throws IOException { Socket socket = new Socket(); socket.setSoTimeout(READ_TIMEOUT_MILLISECONDS); SocketAddress socksAddress = new InetSocketAddress(socksHost, socksPort); socket.connect(socksAddress, CONNECT_TIMEOUT_MILLISECONDS); DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream()); outputStream.write((byte) 0x04); outputStream.write((byte) 0x01); outputStream.writeShort((short) networkPort); outputStream.writeInt(0x01); outputStream.write((byte) 0x00); outputStream.write(networkHost.getBytes()); outputStream.write((byte) 0x00); DataInputStream inputStream = new DataInputStream(socket.getInputStream()); byte firstByte = inputStream.readByte(); byte secondByte = inputStream.readByte(); if (firstByte != (byte) 0x00 || secondByte != (byte) 0x5a) { socket.close(); throw new IOException("SOCKS4a connect failed, got " + firstByte + " - " + secondByte + ", but expected 0x00 - 0x5a"); } inputStream.readShort(); inputStream.readInt(); return socket; } public static Socket socks5rawSocketConnection(String networkHost, int networkPort, String socksHost, int socksPort) throws IOException { int bytesRead = 0; boolean end = false; String messageString = ""; final byte[] messageByte = new byte[1000]; Socket socket = new Socket(); socket.setSoTimeout(READ_TIMEOUT_MILLISECONDS); SocketAddress socksAddress = new InetSocketAddress(socksHost, socksPort); socket.connect(socksAddress, CONNECT_TIMEOUT_MILLISECONDS); DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream()); outputStream.write((byte) 0x05); outputStream.write((byte) 0x01); outputStream.write((byte) 0x00); outputStream.write((byte) 0x01); outputStream.write(networkHost.getBytes()); outputStream.writeShort((short) networkPort); DataInputStream inputStream = new DataInputStream(socket.getInputStream()); messageByte[0] = inputStream.readByte(); messageByte[1] = inputStream.readByte(); if (messageByte[0] != (byte) 0x05 || messageByte[1] != (byte) 0x00) { socket.close(); throw new IOException("SOCKS4a connect failed, got " + messageByte[0] + " - " + messageByte[1] + ", but expected 0x00 - 0x5a"); } ByteBuffer byteBuffer = ByteBuffer.wrap(messageByte, 0, 2); int bytesToRead = byteBuffer.getShort(); LOG.info("About to read " + bytesToRead + " octets"); while (!end) { bytesRead = inputStream.read(messageByte); messageString += new String(messageByte, 0, bytesRead); if (messageString.length() == bytesToRead) { end = true; } } return socket; } public static Socket Socks5connection(Socks5Proxy proxy, String onionUrl, int HiddenServicePort) throws IOException { Socket ssock = new SocksSocket(proxy, onionUrl, HiddenServicePort); ssock.setTcpNoDelay(true); return ssock; } }