diff --git a/bramble-core/build.gradle b/bramble-core/build.gradle index 63162934221bc3bbed27d3399f97131217b39128..f8bbfcf5ac1c95979ff8e30efc86f1f5c8a0de8a 100644 --- a/bramble-core/build.gradle +++ b/bramble-core/build.gradle @@ -17,6 +17,7 @@ dependencies { implementation 'net.i2p.crypto:eddsa:0.2.0' implementation 'org.whispersystems:curve25519-java:0.5.0' implementation 'org.briarproject:jtorctl:0.5' + implementation 'org.briarproject:socks-socket:0.1' //noinspection GradleDependency implementation "com.squareup.okhttp3:okhttp:$okhttp_version" diff --git a/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksModule.java b/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksModule.java index 5d4d7939c9c5fa27cd0d2a433305ef5586680150..420739e8aaffee7cabe0984585d9f8ad6444d320 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksModule.java @@ -1,6 +1,7 @@ package org.briarproject.bramble.socks; import org.briarproject.bramble.api.plugin.TorSocksPort; +import org.briarproject.socks.SocksSocketFactory; import java.net.InetSocketAddress; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksSocket.java b/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksSocket.java deleted file mode 100644 index e7b15786ee3adba824227d00c8f3c3193f015ca7..0000000000000000000000000000000000000000 --- a/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksSocket.java +++ /dev/null @@ -1,137 +0,0 @@ -package org.briarproject.bramble.socks; - -import org.briarproject.bramble.util.ByteUtils; -import org.briarproject.bramble.util.IoUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketAddress; -import java.util.Arrays; - -class SocksSocket extends Socket { - - private static final String[] ERRORS = { - "Succeeded", - "General SOCKS server failure", - "Connection not allowed by ruleset", - "Network unreachable", - "Host unreachable", - "Connection refused", - "TTL expired", - "Command not supported", - "Address type not supported" - }; - - @SuppressWarnings("MismatchedReadAndWriteOfArray") - private static final byte[] UNSPECIFIED_ADDRESS = new byte[4]; - - private final SocketAddress proxy; - private final int connectToProxyTimeout; - private final int extraConnectTimeout, extraSocketTimeout; - - SocksSocket(SocketAddress proxy, int connectToProxyTimeout, - int extraConnectTimeout, int extraSocketTimeout) { - this.proxy = proxy; - this.connectToProxyTimeout = connectToProxyTimeout; - this.extraConnectTimeout = extraConnectTimeout; - this.extraSocketTimeout = extraSocketTimeout; - } - - @Override - public void connect(SocketAddress endpoint, int timeout) - throws IOException { - - // Validate the endpoint - if (!(endpoint instanceof InetSocketAddress)) - throw new IllegalArgumentException(); - InetSocketAddress inet = (InetSocketAddress) endpoint; - InetAddress address = inet.getAddress(); - if (address != null - && !Arrays.equals(address.getAddress(), UNSPECIFIED_ADDRESS)) { - throw new IllegalArgumentException(); - } - String host = inet.getHostName(); - if (host.length() > 255) throw new IllegalArgumentException(); - int port = inet.getPort(); - - // Connect to the proxy - super.connect(proxy, connectToProxyTimeout); - OutputStream out = IoUtils.getOutputStream(this); - InputStream in = IoUtils.getInputStream(this); - - // Request SOCKS 5 with no authentication - sendMethodRequest(out); - receiveMethodResponse(in); - - // Use the supplied timeout temporarily, plus any configured extra - int oldTimeout = getSoTimeout(); - setSoTimeout(timeout + extraConnectTimeout); - - // Connect to the endpoint via the proxy - sendConnectRequest(out, host, port); - receiveConnectResponse(in); - - // Restore the old timeout, plus any configured extra - setSoTimeout(oldTimeout + extraSocketTimeout); - } - - private void sendMethodRequest(OutputStream out) throws IOException { - byte[] methodRequest = new byte[] { - 5, // SOCKS version is 5 - 1, // Number of methods is 1 - 0 // Method is 0, no authentication - }; - out.write(methodRequest); - out.flush(); - } - - private void receiveMethodResponse(InputStream in) throws IOException { - byte[] methodResponse = new byte[2]; - IoUtils.read(in, methodResponse); - byte version = methodResponse[0]; - byte method = methodResponse[1]; - if (version != 5) - throw new IOException("Unsupported SOCKS version: " + version); - if (method == (byte) 255) - throw new IOException("Proxy requires authentication"); - if (method != 0) - throw new IOException("Unsupported auth method: " + method); - } - - private void sendConnectRequest(OutputStream out, String host, int port) - throws IOException { - byte[] connectRequest = new byte[7 + host.length()]; - connectRequest[0] = 5; // SOCKS version is 5 - connectRequest[1] = 1; // Command is 1, connect - connectRequest[3] = 3; // Address type is 3, domain name - connectRequest[4] = (byte) host.length(); // Length of domain name - for (int i = 0; i < host.length(); i++) - connectRequest[5 + i] = (byte) host.charAt(i); - ByteUtils.writeUint16(port, connectRequest, connectRequest.length - 2); - out.write(connectRequest); - out.flush(); - } - - private void receiveConnectResponse(InputStream in) throws IOException { - byte[] connectResponse = new byte[4]; - IoUtils.read(in, connectResponse); - int version = connectResponse[0] & 0xFF; - int reply = connectResponse[1] & 0xFF; - int addressType = connectResponse[3] & 0xFF; - if (version != 5) - throw new IOException("Unsupported SOCKS version: " + version); - if (reply != 0) { - if (reply < ERRORS.length) - throw new IOException("Connection failed: " + ERRORS[reply]); - else throw new IOException("Connection failed: " + reply); - } - if (addressType == 1) IoUtils.read(in, new byte[4]); // IPv4 - else if (addressType == 4) IoUtils.read(in, new byte[16]); // IPv6 - else throw new IOException("Unsupported address type: " + addressType); - IoUtils.read(in, new byte[2]); // Port number - } -} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksSocketFactory.java b/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksSocketFactory.java deleted file mode 100644 index 6f1edc8a0760f9ec09a0320598ebae8c535de848..0000000000000000000000000000000000000000 --- a/bramble-core/src/main/java/org/briarproject/bramble/socks/SocksSocketFactory.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.briarproject.bramble.socks; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketAddress; - -import javax.net.SocketFactory; - -class SocksSocketFactory extends SocketFactory { - - private final SocketAddress proxy; - private final int connectToProxyTimeout; - private final int extraConnectTimeout, extraSocketTimeout; - - SocksSocketFactory(SocketAddress proxy, int connectToProxyTimeout, - int extraConnectTimeout, int extraSocketTimeout) { - this.proxy = proxy; - this.connectToProxyTimeout = connectToProxyTimeout; - this.extraConnectTimeout = extraConnectTimeout; - this.extraSocketTimeout = extraSocketTimeout; - } - - @Override - public Socket createSocket() { - return new SocksSocket(proxy, connectToProxyTimeout, - extraConnectTimeout, extraSocketTimeout); - } - - @Override - public Socket createSocket(String host, int port) throws IOException { - Socket socket = createSocket(); - socket.connect(InetSocketAddress.createUnresolved(host, port)); - return socket; - } - - @Override - public Socket createSocket(InetAddress host, int port) { - throw new UnsupportedOperationException(); - } - - @Override - public Socket createSocket(String host, int port, InetAddress localHost, - int localPort) { - throw new UnsupportedOperationException(); - } - - @Override - public Socket createSocket(InetAddress address, int port, - InetAddress localAddress, int localPort) throws IOException { - throw new UnsupportedOperationException(); - } -} diff --git a/bramble-core/witness.gradle b/bramble-core/witness.gradle index f1af7ac8fee094f42ba112e739b068649de39c41..99b4a7033052ae3bfe931ee1e5b184caf6f099e5 100644 --- a/bramble-core/witness.gradle +++ b/bramble-core/witness.gradle @@ -36,6 +36,8 @@ dependencyVerification { 'org.bitlet:weupnp:0.1.4:weupnp-0.1.4.jar:88df7e6504929d00bdb832863761385c68ab92af945b04f0770b126270a444fb', 'org.bouncycastle:bcprov-jdk15to18:1.70:bcprov-jdk15to18-1.70.jar:7df4c54f29ce2dd616dc3b198ca4db3dfcc79e3cb397c084a0aff97b85c0bf38', 'org.briarproject:jtorctl:0.5:jtorctl-0.5.jar:43f8c7d390169772b9a2c82ab806c8414c136a2a8636c555e22754bb7260793b', + 'org.briarproject:null-safety:0.1:null-safety-0.1.jar:161760de5e838cb982bafa973df820675d4397098e9a91637a36a306d43ba011', + 'org.briarproject:socks-socket:0.1:socks-socket-0.1.jar:e5898822d10f5390363c5dddb945891648c92cf93ba50709e07f0d173ec0eb4b', 'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d', 'org.checkerframework:checker-qual:2.5.2:checker-qual-2.5.2.jar:64b02691c8b9d4e7700f8ee2e742dce7ea2c6e81e662b7522c9ee3bf568c040a', 'org.codehaus.mojo.signature:java16:1.1:java16-1.1.signature:53799223a2c98dba2d0add810bed76315460df285c69e4f397ae6098f87dd619',