From 8dc39ff8e4684cbd9235824c58a5deb70fb818ee Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sun, 11 Jul 2021 19:25:50 +0200 Subject: implement ClientTransportPluginInterface to start / stop snowflake client for tor --- .../bitmaskclient/providersetup/ProviderAPI.java | 4 +- .../bitmaskclient/tor/ClientTransportPlugin.java | 93 +++++++++++++++++++++- .../leap/bitmaskclient/tor/IPtProxyInterface.java | 72 ----------------- .../se/leap/bitmaskclient/tor/IPtProxyWrapper.java | 40 ---------- 4 files changed, 94 insertions(+), 115 deletions(-) delete mode 100644 app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyInterface.java delete mode 100644 app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyWrapper.java (limited to 'app/src') diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java index 9ba64b31..f2376568 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java @@ -39,7 +39,7 @@ import java.util.concurrent.LinkedBlockingQueue; import se.leap.bitmaskclient.base.utils.PreferenceHelper; import se.leap.bitmaskclient.providersetup.connectivity.OkHttpClientGenerator; -import se.leap.bitmaskclient.tor.IPtProxyWrapper; +import se.leap.bitmaskclient.tor.ClientTransportPlugin; import se.leap.bitmaskclient.tor.TorNotificationManager; import se.leap.bitmaskclient.tor.TorStatusObservable; @@ -203,7 +203,7 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB try { if (torServiceConnection == null) { Log.d(TAG, "serviceConnection is still null"); - TorService.setIPtProxy(new IPtProxyWrapper()); + TorService.setClientTransportPlugin(new ClientTransportPlugin(context.getApplicationContext())); torServiceConnection = new TorServiceConnection(context); } } catch (InterruptedException | IllegalStateException e) { diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java b/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java index 9ed805e4..9e3828de 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java @@ -1,4 +1,95 @@ package se.leap.bitmaskclient.tor; -public class ClientTransportPlugin { +import android.content.Context; +import android.util.Log; + +import androidx.annotation.Nullable; + +import org.torproject.jni.ClientTransportPluginInterface; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.ref.WeakReference; +import java.util.HashMap; + +import IPtProxy.IPtProxy; + +public class ClientTransportPlugin implements ClientTransportPluginInterface { + public static String TAG = ClientTransportPlugin.class.getSimpleName(); + + private HashMap mFronts; + private final WeakReference contextRef; + private long snowflakePort = -1; + + public ClientTransportPlugin(Context context) { + this.contextRef = new WeakReference<>(context); + loadCdnFronts(context); + } + + @Override + public void start() { + Context context = contextRef.get(); + if (context == null) { + return; + } + File logfile = new File(context.getApplicationContext().getCacheDir(), "snowflake.log"); + Log.d(TAG, "logfile at " + logfile.getAbsolutePath()); + if (!logfile.exists()) { + try { + logfile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + //this is using the current, default Tor snowflake infrastructure + String target = getCdnFront("snowflake-target"); + String front = getCdnFront("snowflake-front"); + String stunServer = getCdnFront("snowflake-stun"); + Log.d(TAG, "startSnowflake. target: " + target + ", front:" + front + ", stunServer" + stunServer); + snowflakePort = IPtProxy.startSnowflake( stunServer, target, front, logfile.getAbsolutePath(), false, false, true, 1); + Log.d(TAG, "startSnowflake running on port: " + snowflakePort); + } + + @Override + public void stop() { + IPtProxy.stopSnowflake(); + snowflakePort = -1; + } + + @Override + public String getTorrc() { + return "UseBridges 1\n" + + "ClientTransportPlugin snowflake socks5 127.0.0.1:" + snowflakePort + "\n" + + "Bridge snowflake 192.0.2.3:1"; + } + + private void loadCdnFronts(Context context) { + if (mFronts == null) { + mFronts = new HashMap<>(); + } + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(context.getAssets().open("fronts"))); + String line; + while (true) { + line = reader.readLine(); + if (line == null) break; + String[] front = line.split(" "); + mFronts.put(front[0], front[1]); + Log.d(TAG, "front: " + front[0] + ", " + front[1]); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Nullable + private String getCdnFront(String service) { + if (mFronts != null) { + return mFronts.get(service); + } + return null; + } } diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyInterface.java b/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyInterface.java deleted file mode 100644 index 0203e082..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyInterface.java +++ /dev/null @@ -1,72 +0,0 @@ -package se.leap.bitmaskclient.tor; - -public interface IPtProxyInterface { - - /** - * StateLocation - Override TOR_PT_STATE_LOCATION, which defaults to "$TMPDIR/pt_state". - */ - void setStateLocation(String v); - - /** - * StateLocation - Override TOR_PT_STATE_LOCATION, which defaults to "$TMPDIR/pt_state". - */ - String getStateLocation(); - - /** - * SnowflakePort - Port where Snowflake will provide its service. - Only use this property after calling StartSnowflake! It might have changed after that! - */ - long snowflakePort(); - - /** - * StartSnowflake - Start the Snowflake client. - - @param ice Comma-separated list of ICE servers. - - @param url URL of signaling broker. - - @param front Front domain. - - @param logFile Name of log file. OPTIONAL - - @param logToStateDir Resolve the log file relative to Tor's PT state dir. - - @param keepLocalAddresses Keep local LAN address ICE candidates. - - @param unsafeLogging Prevent logs from being scrubbed. - - @param maxPeers Capacity for number of multiplexed WebRTC peers. DEFAULTs to 1 if less than that. - - @return Port number where Snowflake will listen on, if no error happens during start up. - */ - long startSnowflake(String ice, String url, String front, String logFile, boolean logToStateDir, boolean keepLocalAddresses, boolean unsafeLogging, long maxPeers); - - /** - * StartSnowflakeProxy - Start the Snowflake proxy. - - @param capacity Maximum concurrent clients. OPTIONAL. Defaults to 10, if 0. - - @param broker Broker URL. OPTIONAL. Defaults to https://snowflake-broker.bamsoftware.com/, if empty. - - @param relay WebSocket relay URL. OPTIONAL. Defaults to wss://snowflake.bamsoftware.com/, if empty. - - @param stun STUN URL. OPTIONAL. Defaults to stun:stun.stunprotocol.org:3478, if empty. - - @param logFile Name of log file. OPTIONAL - - @param keepLocalAddresses Keep local LAN address ICE candidates. - - @param unsafeLogging Prevent logs from being scrubbed. - */ - void startSnowflakeProxy(long capacity, String broker, String relay, String stun, String logFile, boolean keepLocalAddresses, boolean unsafeLogging); - - /** - * StopSnowflake - Stop the Snowflake client. - */ - void stopSnowflake(); - - /** - * StopSnowflakeProxy - Stop the Snowflake proxy. - */ - void stopSnowflakeProxy(); -} diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyWrapper.java b/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyWrapper.java deleted file mode 100644 index c7ca165e..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyWrapper.java +++ /dev/null @@ -1,40 +0,0 @@ -package se.leap.bitmaskclient.tor; - -import IPtProxy.IPtProxy; - -public class IPtProxyWrapper implements IPtProxyInterface { - @Override - public void setStateLocation(String location) { - IPtProxy.setStateLocation(location); - } - - @Override - public String getStateLocation() { - return IPtProxy.getStateLocation(); - } - - @Override - public long snowflakePort() { - return IPtProxy.snowflakePort(); - } - - @Override - public long startSnowflake(String ice, String url, String front, String logFile, boolean logToStateDir, boolean keepLocalAddresses, boolean unsafeLogging, long maxPeers) { - return IPtProxy.startSnowflake(ice, url, front, logFile, logToStateDir, keepLocalAddresses, unsafeLogging, maxPeers); - } - - @Override - public void startSnowflakeProxy(long capacity, String broker, String relay, String stun, String logFile, boolean keepLocalAddresses, boolean unsafeLogging) { - IPtProxy.startSnowflakeProxy(capacity, broker, relay, stun, logFile, keepLocalAddresses, unsafeLogging); - } - - @Override - public void stopSnowflake() { - IPtProxy.stopSnowflake(); - } - - @Override - public void stopSnowflakeProxy() { - IPtProxy.stopSnowflakeProxy(); - } -} -- cgit v1.2.3