From eac1f9ed745cdf060ea9c6b12a830b4cdbb613f0 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Tue, 26 Jun 2018 15:48:49 -0300 Subject: [PATCH 1/4] MVP for bridge support --- .../plugin/tor/TorNetworkMetadata.java | 20 ++++++++++++++++++- .../bramble/plugin/tor/TorPlugin.java | 11 ++++++++-- bramble-android/src/main/res/raw/torrc | 5 +++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorNetworkMetadata.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorNetworkMetadata.java index e6151d574..a6b28c19a 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorNetworkMetadata.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorNetworkMetadata.java @@ -6,13 +6,31 @@ import java.util.Set; class TorNetworkMetadata { + /** + * Countries where Tor is blocked, i.e. vanilla Tor connection won't work. + */ + private static final String[] BLOCKED = { "CN", "IR", "EG", "SY", "VE" }; + + /** + * Countries where vanilla bridge connection are likely to work. + * Should be a subset of {@link #BLOCKED}. + */ + private static final String[] BRIDGES = { "SY", "VE" }; + // See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 // and https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki // TODO: get a more complete list private static final Set BLOCKED_IN_COUNTRIES = - new HashSet<>(Arrays.asList("CN", "IR", "SY", "ZZ")); + new HashSet<>(Arrays.asList(BLOCKED)); + private static final Set BRIDGES_WORK_IN_COUNTRIES = + new HashSet<>(Arrays.asList(BRIDGES)); static boolean isTorProbablyBlocked(String countryCode) { return BLOCKED_IN_COUNTRIES.contains(countryCode); } + + static boolean doBridgesWork(String countryCode) { + return BRIDGES_WORK_IN_COUNTRIES.contains(countryCode); + } + } diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java index 015056b49..5851c385a 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java @@ -91,6 +91,7 @@ import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_ import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WIFI; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT; import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION; +import static org.briarproject.bramble.plugin.tor.TorNetworkMetadata.doBridgesWork; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion; @@ -678,8 +679,14 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { LOG.info("Disabling network, device is offline"); enableNetwork(false); } else if (blocked) { - LOG.info("Disabling network, country is blocked"); - enableNetwork(false); + if (doBridgesWork(country)) { + LOG.info("Enabling network, using bridges"); + controlConnection.setConf("UseBridges", "1"); + enableNetwork(true); + } else { + LOG.info("Disabling network, country is blocked"); + enableNetwork(false); + } } else if (network == PREF_TOR_NETWORK_NEVER || (network == PREF_TOR_NETWORK_WIFI && !wifi)) { LOG.info("Disabling network due to data setting"); diff --git a/bramble-android/src/main/res/raw/torrc b/bramble-android/src/main/res/raw/torrc index 3d27a7f20..d1f881dce 100644 --- a/bramble-android/src/main/res/raw/torrc +++ b/bramble-android/src/main/res/raw/torrc @@ -4,3 +4,8 @@ DisableNetwork 1 RunAsDaemon 1 SafeSocks 1 SocksPort 59050 +UseBridges 0 +Bridge 131.252.210.150:8081 0E858AC201BF0F3FA3C462F64844CBFFC7297A42 +Bridge 128.105.214.161:8081 1E326AAFB3FCB515015250D8FCCC8E37F91A153B +Bridge 67.205.189.122:8443 12D64D5D44E20169585E7378580C0D33A872AD98 +Bridge 45.32.148.146:8443 0CE016FB2462D8BF179AE71F7D702D09DEAC3F1D From 7e05a49bdaa9ecc5ee6e56de90cad64daba9e5c5 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Tue, 26 Jun 2018 15:47:19 -0300 Subject: [PATCH 2/4] Add Android integration tests that checks if included bridges work This also changes the way bridges are used. Instead of using the torrc config file, bridges are now activated via Tor's control port. --- bramble-android/build.gradle | 8 ++ .../bramble/IntegrationTestComponent.java | 23 ++++ .../bramble/plugin/tor/BridgeTest.java | 102 ++++++++++++++++++ .../bramble/plugin/tor/TorPluginCallBack.java | 54 ++++++++++ .../bramble/BrambleAndroidModule.java | 12 +++ .../bramble/plugin/tor/BridgeProvider.java | 9 ++ .../plugin/tor/BridgeProviderImpl.java | 20 ++++ .../bramble/plugin/tor/TorPlugin.java | 20 +++- .../bramble/plugin/tor/TorPluginFactory.java | 5 +- bramble-android/src/main/res/raw/torrc | 5 - .../briarproject/briar/android/AppModule.java | 5 +- 11 files changed, 253 insertions(+), 10 deletions(-) create mode 100644 bramble-android/src/androidTest/java/org/briarproject/bramble/IntegrationTestComponent.java create mode 100644 bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java create mode 100644 bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/TorPluginCallBack.java create mode 100644 bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProvider.java create mode 100644 bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProviderImpl.java diff --git a/bramble-android/build.gradle b/bramble-android/build.gradle index f2f2ba5de..fe202931d 100644 --- a/bramble-android/build.gradle +++ b/bramble-android/build.gradle @@ -11,6 +11,8 @@ android { versionCode 10011 versionName "1.0.11" consumerProguardFiles 'proguard-rules.txt' + + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } compileOptions { @@ -31,6 +33,12 @@ dependencies { annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2' compileOnly 'javax.annotation:jsr250-api:1.0' + + androidTestImplementation project(path: ':bramble-api', configuration: 'testOutput') + androidTestImplementation project(path: ':bramble-core', configuration: 'testOutput') + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestAnnotationProcessor 'com.google.dagger:dagger-compiler:2.0.2' + androidTestCompileOnly 'javax.annotation:jsr250-api:1.0' } dependencyVerification { diff --git a/bramble-android/src/androidTest/java/org/briarproject/bramble/IntegrationTestComponent.java b/bramble-android/src/androidTest/java/org/briarproject/bramble/IntegrationTestComponent.java new file mode 100644 index 000000000..bb5875ac3 --- /dev/null +++ b/bramble-android/src/androidTest/java/org/briarproject/bramble/IntegrationTestComponent.java @@ -0,0 +1,23 @@ +package org.briarproject.bramble; + +import org.briarproject.bramble.event.EventModule; +import org.briarproject.bramble.plugin.PluginModule; +import org.briarproject.bramble.plugin.tor.BridgeTest; +import org.briarproject.bramble.system.SystemModule; + +import javax.inject.Singleton; + +import dagger.Component; + +@Singleton +@Component(modules = { + BrambleAndroidModule.class, + PluginModule.class, // needed for BackoffFactory + EventModule.class, + SystemModule.class, +}) +public interface IntegrationTestComponent { + + void inject(BridgeTest init); + +} diff --git a/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java b/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java new file mode 100644 index 000000000..cb8c4bd3f --- /dev/null +++ b/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java @@ -0,0 +1,102 @@ +package org.briarproject.bramble.plugin.tor; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.briarproject.bramble.DaggerIntegrationTestComponent; +import org.briarproject.bramble.IntegrationTestComponent; +import org.briarproject.bramble.api.event.EventBus; +import org.briarproject.bramble.api.plugin.BackoffFactory; +import org.briarproject.bramble.api.system.Clock; +import org.briarproject.bramble.api.system.LocationUtils; +import org.briarproject.bramble.test.BrambleTestCase; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.logging.Logger; + +import javax.inject.Inject; +import javax.net.SocketFactory; + +import static java.util.Collections.singletonList; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.briarproject.bramble.plugin.tor.BridgeProviderImpl.BRIDGES; +import static org.briarproject.bramble.plugin.tor.TorNetworkMetadata.doBridgesWork; +import static org.briarproject.bramble.plugin.tor.TorNetworkMetadata.isTorProbablyBlocked; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + + +@RunWith(AndroidJUnit4.class) +public class BridgeTest extends BrambleTestCase { + + private final static String BRIDGE_COUNTRY = "VE"; + private final static long TIMEOUT = SECONDS.toMillis(23); + + private final static Logger LOG = + Logger.getLogger(BridgeTest.class.getSimpleName()); + + @Inject + EventBus eventBus; + @Inject + BackoffFactory backoffFactory; + @Inject + Clock clock; + + private final TorPluginFactory factory; + private TorPlugin plugin; + private int currentBridge = 0; + + public BridgeTest() { + IntegrationTestComponent component = + DaggerIntegrationTestComponent.builder().build(); + component.inject(this); + + Executor ioExecutor = Executors.newCachedThreadPool(); + ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1); + Context appContext = InstrumentationRegistry.getTargetContext(); + LocationUtils locationUtils = () -> BRIDGE_COUNTRY; + SocketFactory torSocketFactory = SocketFactory.getDefault(); + BridgeProvider bridgeProvider = + () -> singletonList(BRIDGES[currentBridge]); + factory = new TorPluginFactory(ioExecutor, scheduler, appContext, + locationUtils, eventBus, torSocketFactory, + backoffFactory, bridgeProvider, clock); + } + + @Test + public void testBridges() throws Exception { + assertTrue(isTorProbablyBlocked(BRIDGE_COUNTRY)); + assertTrue(doBridgesWork(BRIDGE_COUNTRY)); + assertTrue(BRIDGES.length > 0); + + for (int i = 0; i < BRIDGES.length; i++) { + plugin = (TorPlugin) factory.createPlugin(new TorPluginCallBack()); + testBridge(i); + } + } + + private void testBridge(int bridge) throws Exception { + currentBridge = bridge; + LOG.warning("Testing " + BRIDGES[currentBridge]); + try { + plugin.start(); + long start = clock.currentTimeMillis(); + while (clock.currentTimeMillis() - start < TIMEOUT) { + if (plugin.isRunning()) return; + clock.sleep(500); + } + if (!plugin.isRunning()) { + fail("Could not connect to Tor within timeout."); + } + } finally { + plugin.stop(); + } + } + +} diff --git a/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/TorPluginCallBack.java b/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/TorPluginCallBack.java new file mode 100644 index 000000000..320e8f02f --- /dev/null +++ b/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/TorPluginCallBack.java @@ -0,0 +1,54 @@ +package org.briarproject.bramble.plugin.tor; + +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback; +import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection; +import org.briarproject.bramble.api.properties.TransportProperties; +import org.briarproject.bramble.api.settings.Settings; + +@NotNullByDefault +public class TorPluginCallBack implements DuplexPluginCallback { + + @Override + public void incomingConnectionCreated(DuplexTransportConnection d) { + + } + + @Override + public void outgoingConnectionCreated(ContactId c, + DuplexTransportConnection d) { + + } + + @Override + public Settings getSettings() { + return new Settings(); + } + + @Override + public TransportProperties getLocalProperties() { + return new TransportProperties(); + } + + @Override + public void mergeSettings(Settings s) { + + } + + @Override + public void mergeLocalProperties(TransportProperties p) { + + } + + @Override + public void transportEnabled() { + + } + + @Override + public void transportDisabled() { + + } + +} diff --git a/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java b/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java index 1ec256348..16f2c6c59 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java @@ -1,11 +1,23 @@ package org.briarproject.bramble; +import org.briarproject.bramble.plugin.tor.BridgeProvider; +import org.briarproject.bramble.plugin.tor.BridgeProviderImpl; import org.briarproject.bramble.system.AndroidSystemModule; +import javax.inject.Singleton; + import dagger.Module; +import dagger.Provides; @Module(includes = { AndroidSystemModule.class }) public class BrambleAndroidModule { + + @Provides + @Singleton + BridgeProvider provideBridgeProvider() { + return new BridgeProviderImpl(); + } + } diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProvider.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProvider.java new file mode 100644 index 000000000..a6a74fcb5 --- /dev/null +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProvider.java @@ -0,0 +1,9 @@ +package org.briarproject.bramble.plugin.tor; + +import java.util.List; + +public interface BridgeProvider { + + List getBridges(); + +} diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProviderImpl.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProviderImpl.java new file mode 100644 index 000000000..c66da9c8a --- /dev/null +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProviderImpl.java @@ -0,0 +1,20 @@ +package org.briarproject.bramble.plugin.tor; + +import java.util.Arrays; +import java.util.List; + +public class BridgeProviderImpl implements BridgeProvider { + + final static String[] BRIDGES = { + "Bridge 131.252.210.150:8081 0E858AC201BF0F3FA3C462F64844CBFFC7297A42", +// "Bridge 128.105.214.161:8081 1E326AAFB3FCB515015250D8FCCC8E37F91A153B", + "Bridge 67.205.189.122:8443 12D64D5D44E20169585E7378580C0D33A872AD98", + "Bridge 45.32.148.146:8443 0CE016FB2462D8BF179AE71F7D702D09DEAC3F1D", + }; + + @Override + public List getBridges() { + return Arrays.asList(BRIDGES); + } + +} diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java index 5851c385a..1079d7ffb 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java @@ -50,7 +50,9 @@ import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -120,6 +122,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { private final Backoff backoff; private final DuplexPluginCallback callback; private final String architecture; + private final BridgeProvider bridgeProvider; private final int maxLatency, maxIdleTime, socketTimeout; private final ConnectionStatus connectionStatus; private final File torDirectory, torFile, geoIpFile, configFile; @@ -139,7 +142,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { Context appContext, LocationUtils locationUtils, SocketFactory torSocketFactory, Clock clock, Backoff backoff, DuplexPluginCallback callback, String architecture, - int maxLatency, int maxIdleTime) { + BridgeProvider bridgeProvider, int maxLatency, int maxIdleTime) { this.ioExecutor = ioExecutor; this.scheduler = scheduler; this.appContext = appContext; @@ -149,6 +152,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { this.backoff = backoff; this.callback = callback; this.architecture = architecture; + this.bridgeProvider = bridgeProvider; this.maxLatency = maxLatency; this.maxIdleTime = maxIdleTime; if (maxIdleTime > Integer.MAX_VALUE / 2) @@ -499,6 +503,17 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { } } + private void enableBridges(boolean enable) throws IOException { + if (enable) { + Collection conf = new ArrayList<>(); + conf.add("UseBridges 1"); + conf.addAll(bridgeProvider.getBridges()); + controlConnection.setConf(conf); + } else { + controlConnection.setConf("UseBridges", "0"); + } + } + @Override public void stop() { running = false; @@ -681,7 +696,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { } else if (blocked) { if (doBridgesWork(country)) { LOG.info("Enabling network, using bridges"); - controlConnection.setConf("UseBridges", "1"); + enableBridges(true); enableNetwork(true); } else { LOG.info("Disabling network, country is blocked"); @@ -693,6 +708,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { enableNetwork(false); } else { LOG.info("Enabling network"); + enableBridges(false); enableNetwork(true); } } catch (IOException e) { diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPluginFactory.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPluginFactory.java index c380cbb0c..3472a5cd1 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPluginFactory.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPluginFactory.java @@ -43,12 +43,14 @@ public class TorPluginFactory implements DuplexPluginFactory { private final EventBus eventBus; private final SocketFactory torSocketFactory; private final BackoffFactory backoffFactory; + private final BridgeProvider bridgeProvider; private final Clock clock; public TorPluginFactory(Executor ioExecutor, ScheduledExecutorService scheduler, Context appContext, LocationUtils locationUtils, EventBus eventBus, SocketFactory torSocketFactory, BackoffFactory backoffFactory, + BridgeProvider bridgeProvider, Clock clock) { this.ioExecutor = ioExecutor; this.scheduler = scheduler; @@ -57,6 +59,7 @@ public class TorPluginFactory implements DuplexPluginFactory { this.eventBus = eventBus; this.torSocketFactory = torSocketFactory; this.backoffFactory = backoffFactory; + this.bridgeProvider = bridgeProvider; this.clock = clock; } @@ -95,7 +98,7 @@ public class TorPluginFactory implements DuplexPluginFactory { MAX_POLLING_INTERVAL, BACKOFF_BASE); TorPlugin plugin = new TorPlugin(ioExecutor, scheduler, appContext, locationUtils, torSocketFactory, clock, backoff, callback, - architecture, MAX_LATENCY, MAX_IDLE_TIME); + architecture, bridgeProvider, MAX_LATENCY, MAX_IDLE_TIME); eventBus.addListener(plugin); return plugin; } diff --git a/bramble-android/src/main/res/raw/torrc b/bramble-android/src/main/res/raw/torrc index d1f881dce..3d27a7f20 100644 --- a/bramble-android/src/main/res/raw/torrc +++ b/bramble-android/src/main/res/raw/torrc @@ -4,8 +4,3 @@ DisableNetwork 1 RunAsDaemon 1 SafeSocks 1 SocksPort 59050 -UseBridges 0 -Bridge 131.252.210.150:8081 0E858AC201BF0F3FA3C462F64844CBFFC7297A42 -Bridge 128.105.214.161:8081 1E326AAFB3FCB515015250D8FCCC8E37F91A153B -Bridge 67.205.189.122:8443 12D64D5D44E20169585E7378580C0D33A872AD98 -Bridge 45.32.148.146:8443 0CE016FB2462D8BF179AE71F7D702D09DEAC3F1D diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java index 03470f4f2..3cb866348 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java @@ -25,6 +25,7 @@ import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.api.system.Scheduler; import org.briarproject.bramble.plugin.bluetooth.AndroidBluetoothPluginFactory; import org.briarproject.bramble.plugin.tcp.AndroidLanTcpPluginFactory; +import org.briarproject.bramble.plugin.tor.BridgeProvider; import org.briarproject.bramble.plugin.tor.TorPluginFactory; import org.briarproject.bramble.util.AndroidUtils; import org.briarproject.bramble.util.StringUtils; @@ -99,14 +100,14 @@ public class AppModule { AndroidExecutor androidExecutor, SecureRandom random, SocketFactory torSocketFactory, BackoffFactory backoffFactory, Application app, LocationUtils locationUtils, EventBus eventBus, - Clock clock) { + BridgeProvider bridgeProvider, Clock clock) { Context appContext = app.getApplicationContext(); DuplexPluginFactory bluetooth = new AndroidBluetoothPluginFactory(ioExecutor, androidExecutor, appContext, random, eventBus, backoffFactory); DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, scheduler, appContext, locationUtils, eventBus, torSocketFactory, - backoffFactory, clock); + backoffFactory, bridgeProvider, clock); DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor, scheduler, backoffFactory, appContext); Collection duplex = asList(bluetooth, tor, lan); From 331c09a02a9086995038a11a2eacc524fea72d09 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 4 Jul 2018 16:21:49 -0300 Subject: [PATCH 3/4] Load bridges from file res/raw/bridges --- .../bramble/plugin/tor/BridgeTest.java | 12 +++--- .../bramble/plugin/tor/BridgeProvider.java | 7 +++- .../plugin/tor/BridgeProviderImpl.java | 40 ++++++++++++++----- .../plugin/tor/TorNetworkMetadata.java | 5 ++- .../bramble/plugin/tor/TorPlugin.java | 2 +- bramble-android/src/main/res/raw/bridges | 4 ++ .../bramble/api/lifecycle/IoExecutor.java | 2 +- 7 files changed, 53 insertions(+), 19 deletions(-) create mode 100644 bramble-android/src/main/res/raw/bridges diff --git a/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java b/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java index cb8c4bd3f..52f1490ce 100644 --- a/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java +++ b/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java @@ -14,6 +14,7 @@ import org.briarproject.bramble.test.BrambleTestCase; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -25,7 +26,6 @@ import javax.net.SocketFactory; import static java.util.Collections.singletonList; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.briarproject.bramble.plugin.tor.BridgeProviderImpl.BRIDGES; import static org.briarproject.bramble.plugin.tor.TorNetworkMetadata.doBridgesWork; import static org.briarproject.bramble.plugin.tor.TorNetworkMetadata.isTorProbablyBlocked; import static org.junit.Assert.assertTrue; @@ -50,6 +50,7 @@ public class BridgeTest extends BrambleTestCase { private final TorPluginFactory factory; private TorPlugin plugin; + private final List bridges; private int currentBridge = 0; public BridgeTest() { @@ -62,8 +63,9 @@ public class BridgeTest extends BrambleTestCase { Context appContext = InstrumentationRegistry.getTargetContext(); LocationUtils locationUtils = () -> BRIDGE_COUNTRY; SocketFactory torSocketFactory = SocketFactory.getDefault(); + bridges = new BridgeProviderImpl().getBridges(appContext); BridgeProvider bridgeProvider = - () -> singletonList(BRIDGES[currentBridge]); + context -> singletonList(bridges.get(currentBridge)); factory = new TorPluginFactory(ioExecutor, scheduler, appContext, locationUtils, eventBus, torSocketFactory, backoffFactory, bridgeProvider, clock); @@ -73,9 +75,9 @@ public class BridgeTest extends BrambleTestCase { public void testBridges() throws Exception { assertTrue(isTorProbablyBlocked(BRIDGE_COUNTRY)); assertTrue(doBridgesWork(BRIDGE_COUNTRY)); - assertTrue(BRIDGES.length > 0); + assertTrue(bridges.size() > 0); - for (int i = 0; i < BRIDGES.length; i++) { + for (int i = 0; i < bridges.size(); i++) { plugin = (TorPlugin) factory.createPlugin(new TorPluginCallBack()); testBridge(i); } @@ -83,7 +85,7 @@ public class BridgeTest extends BrambleTestCase { private void testBridge(int bridge) throws Exception { currentBridge = bridge; - LOG.warning("Testing " + BRIDGES[currentBridge]); + LOG.warning("Testing " + bridges.get(currentBridge)); try { plugin.start(); long start = clock.currentTimeMillis(); diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProvider.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProvider.java index a6a74fcb5..00fa5fd94 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProvider.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProvider.java @@ -1,9 +1,14 @@ package org.briarproject.bramble.plugin.tor; +import android.content.Context; + +import org.briarproject.bramble.api.lifecycle.IoExecutor; + import java.util.List; public interface BridgeProvider { - List getBridges(); + @IoExecutor + List getBridges(Context context); } diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProviderImpl.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProviderImpl.java index c66da9c8a..f28dd6978 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProviderImpl.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProviderImpl.java @@ -1,20 +1,42 @@ package org.briarproject.bramble.plugin.tor; -import java.util.Arrays; +import android.content.Context; +import android.content.res.Resources; + +import org.briarproject.bramble.api.lifecycle.IoExecutor; + +import java.io.InputStream; +import java.util.ArrayList; import java.util.List; +import java.util.Scanner; + +import javax.annotation.Nullable; public class BridgeProviderImpl implements BridgeProvider { - final static String[] BRIDGES = { - "Bridge 131.252.210.150:8081 0E858AC201BF0F3FA3C462F64844CBFFC7297A42", -// "Bridge 128.105.214.161:8081 1E326AAFB3FCB515015250D8FCCC8E37F91A153B", - "Bridge 67.205.189.122:8443 12D64D5D44E20169585E7378580C0D33A872AD98", - "Bridge 45.32.148.146:8443 0CE016FB2462D8BF179AE71F7D702D09DEAC3F1D", - }; + private final static String BRIDGE_FILE_NAME = "bridges"; + + @Nullable + private volatile List bridges = null; @Override - public List getBridges() { - return Arrays.asList(BRIDGES); + @IoExecutor + public List getBridges(Context context) { + if (this.bridges != null) return this.bridges; + + Resources res = context.getResources(); + int resId = res.getIdentifier(BRIDGE_FILE_NAME, "raw", + context.getPackageName()); + InputStream is = context.getResources().openRawResource(resId); + Scanner scanner = new Scanner(is); + + List bridges = new ArrayList<>(); + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + if (!line.startsWith("#")) bridges.add(line); + } + this.bridges = bridges; + return bridges; } } diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorNetworkMetadata.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorNetworkMetadata.java index a6b28c19a..f0587c532 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorNetworkMetadata.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorNetworkMetadata.java @@ -9,13 +9,14 @@ class TorNetworkMetadata { /** * Countries where Tor is blocked, i.e. vanilla Tor connection won't work. */ - private static final String[] BLOCKED = { "CN", "IR", "EG", "SY", "VE" }; + private static final String[] BLOCKED = + {"CN", "IR", "EG", "BY", "TR", "SY", "VE"}; /** * Countries where vanilla bridge connection are likely to work. * Should be a subset of {@link #BLOCKED}. */ - private static final String[] BRIDGES = { "SY", "VE" }; + private static final String[] BRIDGES = { "EG", "BY", "TR", "SY", "VE" }; // See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 // and https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java index 1079d7ffb..2370f3e9f 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java @@ -507,7 +507,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { if (enable) { Collection conf = new ArrayList<>(); conf.add("UseBridges 1"); - conf.addAll(bridgeProvider.getBridges()); + conf.addAll(bridgeProvider.getBridges(appContext)); controlConnection.setConf(conf); } else { controlConnection.setConf("UseBridges", "0"); diff --git a/bramble-android/src/main/res/raw/bridges b/bramble-android/src/main/res/raw/bridges new file mode 100644 index 000000000..52d4f44d1 --- /dev/null +++ b/bramble-android/src/main/res/raw/bridges @@ -0,0 +1,4 @@ +Bridge 131.252.210.150:8081 0E858AC201BF0F3FA3C462F64844CBFFC7297A42 +#Bridge 128.105.214.161:8081 1E326AAFB3FCB515015250D8FCCC8E37F91A153B +Bridge 67.205.189.122:8443 12D64D5D44E20169585E7378580C0D33A872AD98 +Bridge 45.32.148.146:8443 0CE016FB2462D8BF179AE71F7D702D09DEAC3F1D \ No newline at end of file diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/IoExecutor.java b/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/IoExecutor.java index c63e6a8c7..6ec68922b 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/IoExecutor.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/IoExecutor.java @@ -12,7 +12,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Annotation for injecting the executor for long-running IO tasks. Also used - * for annotating methods that should run on the UI executor. + * for annotating methods that should run on the IO executor. *

* The contract of this executor is that tasks may be run concurrently, and * submitting a task will never block. Tasks may run indefinitely. Tasks From 7ecac1867e518050ad24c799dcdc4c90988b7f35 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Thu, 5 Jul 2018 10:59:10 -0300 Subject: [PATCH 4/4] Address review comments for Tor bridge support --- .../bramble/plugin/tor/BridgeTest.java | 54 ++++++++++----- .../bramble/BrambleAndroidModule.java | 10 +-- .../bramble/plugin/tor/BridgeProvider.java | 14 ---- .../plugin/tor/BridgeProviderImpl.java | 42 ------------ .../plugin/tor/CircumventionProvider.java | 30 ++++++++ .../plugin/tor/CircumventionProviderImpl.java | 68 +++++++++++++++++++ .../plugin/tor/TorNetworkMetadata.java | 37 ---------- .../bramble/plugin/tor/TorPlugin.java | 23 +++---- .../bramble/plugin/tor/TorPluginFactory.java | 8 +-- bramble-android/src/main/res/raw/bridges | 5 +- .../briarproject/briar/android/AppModule.java | 6 +- 11 files changed, 163 insertions(+), 134 deletions(-) delete mode 100644 bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProvider.java delete mode 100644 bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProviderImpl.java create mode 100644 bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProvider.java create mode 100644 bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProviderImpl.java delete mode 100644 bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorNetworkMetadata.java diff --git a/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java b/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java index 52f1490ce..0cb2d4232 100644 --- a/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java +++ b/bramble-android/src/androidTest/java/org/briarproject/bramble/plugin/tor/BridgeTest.java @@ -1,16 +1,17 @@ package org.briarproject.bramble.plugin.tor; import android.content.Context; -import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import org.briarproject.bramble.DaggerIntegrationTestComponent; import org.briarproject.bramble.IntegrationTestComponent; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.plugin.BackoffFactory; +import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.test.BrambleTestCase; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -24,10 +25,10 @@ import java.util.logging.Logger; import javax.inject.Inject; import javax.net.SocketFactory; +import static android.support.test.InstrumentationRegistry.getTargetContext; import static java.util.Collections.singletonList; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.briarproject.bramble.plugin.tor.TorNetworkMetadata.doBridgesWork; -import static org.briarproject.bramble.plugin.tor.TorNetworkMetadata.isTorProbablyBlocked; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -35,7 +36,6 @@ import static org.junit.Assert.fail; @RunWith(AndroidJUnit4.class) public class BridgeTest extends BrambleTestCase { - private final static String BRIDGE_COUNTRY = "VE"; private final static long TIMEOUT = SECONDS.toMillis(23); private final static Logger LOG = @@ -48,42 +48,64 @@ public class BridgeTest extends BrambleTestCase { @Inject Clock clock; - private final TorPluginFactory factory; - private TorPlugin plugin; + private final Context appContext = getTargetContext(); + private final CircumventionProvider circumventionProvider; private final List bridges; - private int currentBridge = 0; + private TorPluginFactory factory; + private volatile int currentBridge = 0; public BridgeTest() { + super(); + circumventionProvider = new CircumventionProvider() { + @Override + public boolean isTorProbablyBlocked(String countryCode) { + return true; + } + + @Override + public boolean doBridgesWork(String countryCode) { + return true; + } + + @Override + public List getBridges() { + return singletonList(bridges.get(currentBridge)); + } + }; + bridges = new CircumventionProviderImpl(appContext).getBridges(); + } + + @Before + public void setUp() { IntegrationTestComponent component = DaggerIntegrationTestComponent.builder().build(); component.inject(this); Executor ioExecutor = Executors.newCachedThreadPool(); ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1); - Context appContext = InstrumentationRegistry.getTargetContext(); - LocationUtils locationUtils = () -> BRIDGE_COUNTRY; + LocationUtils locationUtils = () -> "US"; SocketFactory torSocketFactory = SocketFactory.getDefault(); - bridges = new BridgeProviderImpl().getBridges(appContext); - BridgeProvider bridgeProvider = - context -> singletonList(bridges.get(currentBridge)); + factory = new TorPluginFactory(ioExecutor, scheduler, appContext, locationUtils, eventBus, torSocketFactory, - backoffFactory, bridgeProvider, clock); + backoffFactory, circumventionProvider, clock); } @Test public void testBridges() throws Exception { - assertTrue(isTorProbablyBlocked(BRIDGE_COUNTRY)); - assertTrue(doBridgesWork(BRIDGE_COUNTRY)); assertTrue(bridges.size() > 0); for (int i = 0; i < bridges.size(); i++) { - plugin = (TorPlugin) factory.createPlugin(new TorPluginCallBack()); testBridge(i); } } private void testBridge(int bridge) throws Exception { + DuplexPlugin duplexPlugin = + factory.createPlugin(new TorPluginCallBack()); + assertNotNull(duplexPlugin); + TorPlugin plugin = (TorPlugin) duplexPlugin; + currentBridge = bridge; LOG.warning("Testing " + bridges.get(currentBridge)); try { diff --git a/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java b/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java index 16f2c6c59..cb563508a 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/BrambleAndroidModule.java @@ -1,7 +1,9 @@ package org.briarproject.bramble; -import org.briarproject.bramble.plugin.tor.BridgeProvider; -import org.briarproject.bramble.plugin.tor.BridgeProviderImpl; +import android.app.Application; + +import org.briarproject.bramble.plugin.tor.CircumventionProvider; +import org.briarproject.bramble.plugin.tor.CircumventionProviderImpl; import org.briarproject.bramble.system.AndroidSystemModule; import javax.inject.Singleton; @@ -16,8 +18,8 @@ public class BrambleAndroidModule { @Provides @Singleton - BridgeProvider provideBridgeProvider() { - return new BridgeProviderImpl(); + CircumventionProvider provideCircumventionProvider(Application app) { + return new CircumventionProviderImpl(app.getApplicationContext()); } } diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProvider.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProvider.java deleted file mode 100644 index 00fa5fd94..000000000 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProvider.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.briarproject.bramble.plugin.tor; - -import android.content.Context; - -import org.briarproject.bramble.api.lifecycle.IoExecutor; - -import java.util.List; - -public interface BridgeProvider { - - @IoExecutor - List getBridges(Context context); - -} diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProviderImpl.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProviderImpl.java deleted file mode 100644 index f28dd6978..000000000 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/BridgeProviderImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.briarproject.bramble.plugin.tor; - -import android.content.Context; -import android.content.res.Resources; - -import org.briarproject.bramble.api.lifecycle.IoExecutor; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Scanner; - -import javax.annotation.Nullable; - -public class BridgeProviderImpl implements BridgeProvider { - - private final static String BRIDGE_FILE_NAME = "bridges"; - - @Nullable - private volatile List bridges = null; - - @Override - @IoExecutor - public List getBridges(Context context) { - if (this.bridges != null) return this.bridges; - - Resources res = context.getResources(); - int resId = res.getIdentifier(BRIDGE_FILE_NAME, "raw", - context.getPackageName()); - InputStream is = context.getResources().openRawResource(resId); - Scanner scanner = new Scanner(is); - - List bridges = new ArrayList<>(); - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - if (!line.startsWith("#")) bridges.add(line); - } - this.bridges = bridges; - return bridges; - } - -} diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProvider.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProvider.java new file mode 100644 index 000000000..c1acfff7e --- /dev/null +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProvider.java @@ -0,0 +1,30 @@ +package org.briarproject.bramble.plugin.tor; + +import org.briarproject.bramble.api.lifecycle.IoExecutor; + +import java.util.List; + +public interface CircumventionProvider { + + /** + * Countries where Tor is blocked, i.e. vanilla Tor connection won't work. + * + * See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 + * and https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki + */ + String[] BLOCKED = {"CN", "IR", "EG", "BY", "TR", "SY", "VE"}; + + /** + * Countries where vanilla bridge connection are likely to work. + * Should be a subset of {@link #BLOCKED}. + */ + String[] BRIDGES = { "EG", "BY", "TR", "SY", "VE" }; + + boolean isTorProbablyBlocked(String countryCode); + + boolean doBridgesWork(String countryCode); + + @IoExecutor + List getBridges(); + +} diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProviderImpl.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProviderImpl.java new file mode 100644 index 000000000..6a9999b9c --- /dev/null +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProviderImpl.java @@ -0,0 +1,68 @@ +package org.briarproject.bramble.plugin.tor; + +import android.content.Context; +import android.content.res.Resources; + +import org.briarproject.bramble.api.lifecycle.IoExecutor; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Scanner; +import java.util.Set; + +import javax.annotation.Nullable; +import javax.inject.Inject; + +public class CircumventionProviderImpl implements CircumventionProvider { + + private final static String BRIDGE_FILE_NAME = "bridges"; + + private final Context ctx; + @Nullable + private volatile List bridges = null; + + @Inject + public CircumventionProviderImpl(Context ctx) { + this.ctx = ctx; + } + + private static final Set BLOCKED_IN_COUNTRIES = + new HashSet<>(Arrays.asList(BLOCKED)); + private static final Set BRIDGES_WORK_IN_COUNTRIES = + new HashSet<>(Arrays.asList(BRIDGES)); + + @Override + public boolean isTorProbablyBlocked(String countryCode) { + return BLOCKED_IN_COUNTRIES.contains(countryCode); + } + + @Override + public boolean doBridgesWork(String countryCode) { + return BRIDGES_WORK_IN_COUNTRIES.contains(countryCode); + } + + @Override + @IoExecutor + public List getBridges() { + if (this.bridges != null) return this.bridges; + + Resources res = ctx.getResources(); + int resId = res.getIdentifier(BRIDGE_FILE_NAME, "raw", + ctx.getPackageName()); + InputStream is = ctx.getResources().openRawResource(resId); + Scanner scanner = new Scanner(is); + + List bridges = new ArrayList<>(); + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + if (!line.startsWith("#")) bridges.add(line); + } + scanner.close(); + this.bridges = bridges; + return bridges; + } + +} diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorNetworkMetadata.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorNetworkMetadata.java deleted file mode 100644 index f0587c532..000000000 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorNetworkMetadata.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.briarproject.bramble.plugin.tor; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -class TorNetworkMetadata { - - /** - * Countries where Tor is blocked, i.e. vanilla Tor connection won't work. - */ - private static final String[] BLOCKED = - {"CN", "IR", "EG", "BY", "TR", "SY", "VE"}; - - /** - * Countries where vanilla bridge connection are likely to work. - * Should be a subset of {@link #BLOCKED}. - */ - private static final String[] BRIDGES = { "EG", "BY", "TR", "SY", "VE" }; - - // See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 - // and https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki - // TODO: get a more complete list - private static final Set BLOCKED_IN_COUNTRIES = - new HashSet<>(Arrays.asList(BLOCKED)); - private static final Set BRIDGES_WORK_IN_COUNTRIES = - new HashSet<>(Arrays.asList(BRIDGES)); - - static boolean isTorProbablyBlocked(String countryCode) { - return BLOCKED_IN_COUNTRIES.contains(countryCode); - } - - static boolean doBridgesWork(String countryCode) { - return BRIDGES_WORK_IN_COUNTRIES.contains(countryCode); - } - -} diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java index 2370f3e9f..03e9bf1f2 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java @@ -93,7 +93,6 @@ import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_ import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WIFI; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_PORT; import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION; -import static org.briarproject.bramble.plugin.tor.TorNetworkMetadata.doBridgesWork; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion; @@ -122,7 +121,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { private final Backoff backoff; private final DuplexPluginCallback callback; private final String architecture; - private final BridgeProvider bridgeProvider; + private final CircumventionProvider circumventionProvider; private final int maxLatency, maxIdleTime, socketTimeout; private final ConnectionStatus connectionStatus; private final File torDirectory, torFile, geoIpFile, configFile; @@ -142,7 +141,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { Context appContext, LocationUtils locationUtils, SocketFactory torSocketFactory, Clock clock, Backoff backoff, DuplexPluginCallback callback, String architecture, - BridgeProvider bridgeProvider, int maxLatency, int maxIdleTime) { + CircumventionProvider circumventionProvider, int maxLatency, int maxIdleTime) { this.ioExecutor = ioExecutor; this.scheduler = scheduler; this.appContext = appContext; @@ -152,7 +151,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { this.backoff = backoff; this.callback = callback; this.architecture = architecture; - this.bridgeProvider = bridgeProvider; + this.circumventionProvider = circumventionProvider; this.maxLatency = maxLatency; this.maxIdleTime = maxIdleTime; if (maxIdleTime > Integer.MAX_VALUE / 2) @@ -507,7 +506,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { if (enable) { Collection conf = new ArrayList<>(); conf.add("UseBridges 1"); - conf.addAll(bridgeProvider.getBridges(appContext)); + conf.addAll(circumventionProvider.getBridges()); controlConnection.setConf(conf); } else { controlConnection.setConf("UseBridges", "0"); @@ -678,8 +677,8 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { boolean online = net != null && net.isConnected(); boolean wifi = online && net.getType() == TYPE_WIFI; String country = locationUtils.getCurrentCountry(); - boolean blocked = TorNetworkMetadata.isTorProbablyBlocked( - country); + boolean blocked = + circumventionProvider.isTorProbablyBlocked(country); Settings s = callback.getSettings(); int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS); @@ -693,8 +692,12 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { if (!online) { LOG.info("Disabling network, device is offline"); enableNetwork(false); + } else if (network == PREF_TOR_NETWORK_NEVER + || (network == PREF_TOR_NETWORK_WIFI && !wifi)) { + LOG.info("Disabling network due to data setting"); + enableNetwork(false); } else if (blocked) { - if (doBridgesWork(country)) { + if (circumventionProvider.doBridgesWork(country)) { LOG.info("Enabling network, using bridges"); enableBridges(true); enableNetwork(true); @@ -702,10 +705,6 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { LOG.info("Disabling network, country is blocked"); enableNetwork(false); } - } else if (network == PREF_TOR_NETWORK_NEVER - || (network == PREF_TOR_NETWORK_WIFI && !wifi)) { - LOG.info("Disabling network due to data setting"); - enableNetwork(false); } else { LOG.info("Enabling network"); enableBridges(false); diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPluginFactory.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPluginFactory.java index 3472a5cd1..a7feb2372 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPluginFactory.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPluginFactory.java @@ -43,14 +43,14 @@ public class TorPluginFactory implements DuplexPluginFactory { private final EventBus eventBus; private final SocketFactory torSocketFactory; private final BackoffFactory backoffFactory; - private final BridgeProvider bridgeProvider; + private final CircumventionProvider circumventionProvider; private final Clock clock; public TorPluginFactory(Executor ioExecutor, ScheduledExecutorService scheduler, Context appContext, LocationUtils locationUtils, EventBus eventBus, SocketFactory torSocketFactory, BackoffFactory backoffFactory, - BridgeProvider bridgeProvider, + CircumventionProvider circumventionProvider, Clock clock) { this.ioExecutor = ioExecutor; this.scheduler = scheduler; @@ -59,7 +59,7 @@ public class TorPluginFactory implements DuplexPluginFactory { this.eventBus = eventBus; this.torSocketFactory = torSocketFactory; this.backoffFactory = backoffFactory; - this.bridgeProvider = bridgeProvider; + this.circumventionProvider = circumventionProvider; this.clock = clock; } @@ -98,7 +98,7 @@ public class TorPluginFactory implements DuplexPluginFactory { MAX_POLLING_INTERVAL, BACKOFF_BASE); TorPlugin plugin = new TorPlugin(ioExecutor, scheduler, appContext, locationUtils, torSocketFactory, clock, backoff, callback, - architecture, bridgeProvider, MAX_LATENCY, MAX_IDLE_TIME); + architecture, circumventionProvider, MAX_LATENCY, MAX_IDLE_TIME); eventBus.addListener(plugin); return plugin; } diff --git a/bramble-android/src/main/res/raw/bridges b/bramble-android/src/main/res/raw/bridges index 52d4f44d1..dc3d6a581 100644 --- a/bramble-android/src/main/res/raw/bridges +++ b/bramble-android/src/main/res/raw/bridges @@ -1,4 +1,5 @@ Bridge 131.252.210.150:8081 0E858AC201BF0F3FA3C462F64844CBFFC7297A42 -#Bridge 128.105.214.161:8081 1E326AAFB3FCB515015250D8FCCC8E37F91A153B Bridge 67.205.189.122:8443 12D64D5D44E20169585E7378580C0D33A872AD98 -Bridge 45.32.148.146:8443 0CE016FB2462D8BF179AE71F7D702D09DEAC3F1D \ No newline at end of file +Bridge 45.32.148.146:8443 0CE016FB2462D8BF179AE71F7D702D09DEAC3F1D +Bridge 148.251.90.59:7510 019F727CA6DCA6CA5C90B55E477B7D87981E75BC +#Bridge 128.105.214.161:8081 1E326AAFB3FCB515015250D8FCCC8E37F91A153B \ No newline at end of file diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java index 3cb866348..565a2c6d3 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java @@ -25,7 +25,7 @@ import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.bramble.api.system.Scheduler; import org.briarproject.bramble.plugin.bluetooth.AndroidBluetoothPluginFactory; import org.briarproject.bramble.plugin.tcp.AndroidLanTcpPluginFactory; -import org.briarproject.bramble.plugin.tor.BridgeProvider; +import org.briarproject.bramble.plugin.tor.CircumventionProvider; import org.briarproject.bramble.plugin.tor.TorPluginFactory; import org.briarproject.bramble.util.AndroidUtils; import org.briarproject.bramble.util.StringUtils; @@ -100,14 +100,14 @@ public class AppModule { AndroidExecutor androidExecutor, SecureRandom random, SocketFactory torSocketFactory, BackoffFactory backoffFactory, Application app, LocationUtils locationUtils, EventBus eventBus, - BridgeProvider bridgeProvider, Clock clock) { + CircumventionProvider circumventionProvider, Clock clock) { Context appContext = app.getApplicationContext(); DuplexPluginFactory bluetooth = new AndroidBluetoothPluginFactory(ioExecutor, androidExecutor, appContext, random, eventBus, backoffFactory); DuplexPluginFactory tor = new TorPluginFactory(ioExecutor, scheduler, appContext, locationUtils, eventBus, torSocketFactory, - backoffFactory, bridgeProvider, clock); + backoffFactory, circumventionProvider, clock); DuplexPluginFactory lan = new AndroidLanTcpPluginFactory(ioExecutor, scheduler, backoffFactory, appContext); Collection duplex = asList(bluetooth, tor, lan);