summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap/bitmaskclient
diff options
context:
space:
mode:
authorcyBerta <cyberta@riseup.net>2021-07-11 19:25:50 +0200
committercyBerta <cyberta@riseup.net>2021-07-21 22:02:28 +0200
commit8dc39ff8e4684cbd9235824c58a5deb70fb818ee (patch)
treee0582dd14a3a8e5a2023dbebd0a5bb3b5a04eeff /app/src/main/java/se/leap/bitmaskclient
parent02d09ff48aed5374e331f2609d27879cd801b9c3 (diff)
implement ClientTransportPluginInterface to start / stop snowflake client for tor
Diffstat (limited to 'app/src/main/java/se/leap/bitmaskclient')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java4
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java93
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyInterface.java72
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyWrapper.java40
4 files changed, 94 insertions, 115 deletions
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<String, String> mFronts;
+ private final WeakReference<Context> 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 &#34;$TMPDIR/pt_state&#34;.
- */
- void setStateLocation(String v);
-
- /**
- * StateLocation - Override TOR_PT_STATE_LOCATION, which defaults to &#34;$TMPDIR/pt_state&#34;.
- */
- 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&#39;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();
- }
-}