Merge branch '1355-disable-tor-setting' into 'master'

Add a setting to override location-based disabling of Tor

Closes #1355

See merge request briar/briar!871
This commit is contained in:
Torsten Grote
2018-08-03 13:35:33 +00:00
5 changed files with 71 additions and 34 deletions

View File

@@ -76,6 +76,7 @@ import static net.freehaven.tor.control.TorControlCommands.HS_ADDRESS;
import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY; import static net.freehaven.tor.control.TorControlCommands.HS_PRIVKEY;
import static org.briarproject.bramble.api.plugin.TorConstants.CONTROL_PORT; import static org.briarproject.bramble.api.plugin.TorConstants.CONTROL_PORT;
import static org.briarproject.bramble.api.plugin.TorConstants.ID; import static org.briarproject.bramble.api.plugin.TorConstants.ID;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_DISABLE_BLOCKED;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_ALWAYS; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_ALWAYS;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_NEVER; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_NEVER;
@@ -128,8 +129,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
LocationUtils locationUtils, SocketFactory torSocketFactory, LocationUtils locationUtils, SocketFactory torSocketFactory,
Clock clock, CircumventionProvider circumventionProvider, Clock clock, CircumventionProvider circumventionProvider,
Backoff backoff, DuplexPluginCallback callback, Backoff backoff, DuplexPluginCallback callback,
String architecture, String architecture, int maxLatency, int maxIdleTime) {
int maxLatency, int maxIdleTime) {
this.ioExecutor = ioExecutor; this.ioExecutor = ioExecutor;
this.appContext = appContext; this.appContext = appContext;
this.networkManager = networkManager; this.networkManager = networkManager;
@@ -661,6 +661,8 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
circumventionProvider.isTorProbablyBlocked(country); circumventionProvider.isTorProbablyBlocked(country);
Settings s = callback.getSettings(); Settings s = callback.getSettings();
int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS); int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS);
boolean disableWhenBlocked =
s.getBoolean(PREF_TOR_DISABLE_BLOCKED, true);
if (LOG.isLoggable(INFO)) { if (LOG.isLoggable(INFO)) {
LOG.info("Online: " + online + ", wifi: " + wifi); LOG.info("Online: " + online + ", wifi: " + wifi);
@@ -681,9 +683,13 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
LOG.info("Enabling network, using bridges"); LOG.info("Enabling network, using bridges");
enableBridges(true); enableBridges(true);
enableNetwork(true); enableNetwork(true);
} else { } else if (disableWhenBlocked) {
LOG.info("Disabling network, country is blocked"); LOG.info("Disabling network, country is blocked");
enableNetwork(false); enableNetwork(false);
} else {
LOG.info("Enabling network but country is blocked");
enableBridges(false);
enableNetwork(true);
} }
} else { } else {
LOG.info("Enabling network"); LOG.info("Enabling network");

View File

@@ -14,6 +14,7 @@ public interface TorConstants {
String PREF_TOR_NETWORK = "network"; String PREF_TOR_NETWORK = "network";
String PREF_TOR_PORT = "port"; String PREF_TOR_PORT = "port";
String PREF_TOR_DISABLE_BLOCKED = "disableWhenBlocked";
int PREF_TOR_NETWORK_NEVER = 0; int PREF_TOR_NETWORK_NEVER = 0;
int PREF_TOR_NETWORK_WIFI = 1; int PREF_TOR_NETWORK_WIFI = 1;

View File

@@ -43,6 +43,7 @@ import org.briarproject.briar.android.util.UiUtils;
import org.briarproject.briar.android.util.UserFeedback; import org.briarproject.briar.android.util.UserFeedback;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -67,14 +68,19 @@ import static android.provider.Settings.EXTRA_CHANNEL_ID;
import static android.provider.Settings.System.DEFAULT_NOTIFICATION_URI; import static android.provider.Settings.System.DEFAULT_NOTIFICATION_URI;
import static android.support.v4.view.ViewCompat.LAYOUT_DIRECTION_LTR; import static android.support.v4.view.ViewCompat.LAYOUT_DIRECTION_LTR;
import static android.widget.Toast.LENGTH_SHORT; import static android.widget.Toast.LENGTH_SHORT;
import static java.util.Arrays.asList;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENABLE; import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENABLE;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_DISABLE_BLOCKED;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_ALWAYS; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_ALWAYS;
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BLOCKED;
import static org.briarproject.bramble.plugin.tor.CircumventionProvider.BRIDGES;
import static org.briarproject.bramble.util.LogUtils.logDuration; import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now; import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.bramble.util.StringUtils.join;
import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_DARK_THEME; import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_DARK_THEME;
import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_SIGN_IN_REMINDER; import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_SIGN_IN_REMINDER;
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD; import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
@@ -104,6 +110,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
public static final String TOR_NAMESPACE = TorConstants.ID.getString(); public static final String TOR_NAMESPACE = TorConstants.ID.getString();
public static final String LANGUAGE = "pref_key_language"; public static final String LANGUAGE = "pref_key_language";
public static final String NOTIFY_SIGN_IN = "pref_key_notify_sign_in"; public static final String NOTIFY_SIGN_IN = "pref_key_notify_sign_in";
public static final String TOR_LOCATION = "pref_key_tor_location";
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(SettingsFragment.class.getName()); Logger.getLogger(SettingsFragment.class.getName());
@@ -112,6 +119,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
private ListPreference language; private ListPreference language;
private ListPreference enableBluetooth; private ListPreference enableBluetooth;
private ListPreference torNetwork; private ListPreference torNetwork;
private CheckBoxPreference torBlocked;
private CheckBoxPreference notifyPrivateMessages; private CheckBoxPreference notifyPrivateMessages;
private CheckBoxPreference notifyGroupMessages; private CheckBoxPreference notifyGroupMessages;
private CheckBoxPreference notifyForumPosts; private CheckBoxPreference notifyForumPosts;
@@ -150,6 +158,8 @@ public class SettingsFragment extends PreferenceFragmentCompat
(ListPreference) findPreference("pref_key_theme"); (ListPreference) findPreference("pref_key_theme");
enableBluetooth = (ListPreference) findPreference("pref_key_bluetooth"); enableBluetooth = (ListPreference) findPreference("pref_key_bluetooth");
torNetwork = (ListPreference) findPreference("pref_key_tor_network"); torNetwork = (ListPreference) findPreference("pref_key_tor_network");
torBlocked = (CheckBoxPreference) findPreference(TOR_LOCATION);
setBlockedCountries();
CheckBoxPreference notifySignIn = CheckBoxPreference notifySignIn =
(CheckBoxPreference) findPreference(NOTIFY_SIGN_IN); (CheckBoxPreference) findPreference(NOTIFY_SIGN_IN);
notifyPrivateMessages = (CheckBoxPreference) findPreference( notifyPrivateMessages = (CheckBoxPreference) findPreference(
@@ -189,6 +199,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
}); });
enableBluetooth.setOnPreferenceChangeListener(this); enableBluetooth.setOnPreferenceChangeListener(this);
torNetwork.setOnPreferenceChangeListener(this); torNetwork.setOnPreferenceChangeListener(this);
torBlocked.setOnPreferenceChangeListener(this);
if (SDK_INT >= 21) { if (SDK_INT >= 21) {
notifyLockscreen.setVisible(true); notifyLockscreen.setVisible(true);
notifyLockscreen.setOnPreferenceChangeListener(this); notifyLockscreen.setOnPreferenceChangeListener(this);
@@ -288,6 +299,14 @@ public class SettingsFragment extends PreferenceFragmentCompat
return direction == LAYOUT_DIRECTION_LTR; return direction == LAYOUT_DIRECTION_LTR;
} }
private void setBlockedCountries() {
List<String> countries = new ArrayList<>(asList(BLOCKED));
countries.removeAll(asList(BRIDGES));
Collections.sort(countries);
String format = getString(R.string.tor_location_setting_hint_format);
torBlocked.setSummary(String.format(format, join(countries, ", ")));
}
private void loadSettings() { private void loadSettings() {
listener.runOnDbThread(() -> { listener.runOnDbThread(() -> {
try { try {
@@ -299,19 +318,24 @@ public class SettingsFragment extends PreferenceFragmentCompat
logDuration(LOG, "Loading settings", start); logDuration(LOG, "Loading settings", start);
boolean btSetting = boolean btSetting =
btSettings.getBoolean(PREF_BT_ENABLE, false); btSettings.getBoolean(PREF_BT_ENABLE, false);
int torSetting = torSettings.getInt(PREF_TOR_NETWORK, int torNetworkSetting = torSettings.getInt(PREF_TOR_NETWORK,
PREF_TOR_NETWORK_ALWAYS); PREF_TOR_NETWORK_ALWAYS);
displaySettings(btSetting, torSetting); boolean torBlockedSetting =
torSettings.getBoolean(PREF_TOR_DISABLE_BLOCKED, true);
displaySettings(btSetting, torNetworkSetting,
torBlockedSetting);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); logException(LOG, WARNING, e);
} }
}); });
} }
private void displaySettings(boolean btSetting, int torSetting) { private void displaySettings(boolean btSetting, int torNetworkSetting,
boolean torBlockedSetting) {
listener.runOnUiThreadUnlessDestroyed(() -> { listener.runOnUiThreadUnlessDestroyed(() -> {
enableBluetooth.setValue(Boolean.toString(btSetting)); enableBluetooth.setValue(Boolean.toString(btSetting));
torNetwork.setValue(Integer.toString(torSetting)); torNetwork.setValue(Integer.toString(torNetworkSetting));
torBlocked.setChecked(torBlockedSetting);
if (SDK_INT < 26) { if (SDK_INT < 26) {
notifyPrivateMessages.setChecked(settings.getBoolean( notifyPrivateMessages.setChecked(settings.getBoolean(
@@ -371,6 +395,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
// - pref_key_notify_sign_in // - pref_key_notify_sign_in
enableBluetooth.setEnabled(enabled); enableBluetooth.setEnabled(enabled);
torNetwork.setEnabled(enabled); torNetwork.setEnabled(enabled);
torBlocked.setEnabled(enabled);
notifyPrivateMessages.setEnabled(enabled); notifyPrivateMessages.setEnabled(enabled);
notifyGroupMessages.setEnabled(enabled); notifyGroupMessages.setEnabled(enabled);
notifyForumPosts.setEnabled(enabled); notifyForumPosts.setEnabled(enabled);
@@ -430,8 +455,11 @@ public class SettingsFragment extends PreferenceFragmentCompat
boolean btSetting = Boolean.valueOf((String) newValue); boolean btSetting = Boolean.valueOf((String) newValue);
storeBluetoothSettings(btSetting); storeBluetoothSettings(btSetting);
} else if (preference == torNetwork) { } else if (preference == torNetwork) {
int torSetting = Integer.valueOf((String) newValue); int torNetworkSetting = Integer.valueOf((String) newValue);
storeTorSettings(torSetting); storeTorNetworkSetting(torNetworkSetting);
} else if (preference == torBlocked) {
boolean torBlockedSetting = (Boolean) newValue;
storeTorBlockedSetting(torBlockedSetting);
} else if (preference == notifyPrivateMessages) { } else if (preference == notifyPrivateMessages) {
Settings s = new Settings(); Settings s = new Settings();
s.putBoolean(PREF_NOTIFY_PRIVATE, (Boolean) newValue); s.putBoolean(PREF_NOTIFY_PRIVATE, (Boolean) newValue);
@@ -480,39 +508,33 @@ public class SettingsFragment extends PreferenceFragmentCompat
builder.show(); builder.show();
} }
private void storeTorSettings(int torSetting) { private void storeTorNetworkSetting(int torNetworkSetting) {
listener.runOnDbThread(() -> { Settings s = new Settings();
try { s.putInt(PREF_TOR_NETWORK, torNetworkSetting);
Settings s = new Settings(); mergeSettings(s, TOR_NAMESPACE);
s.putInt(PREF_TOR_NETWORK, torSetting); }
long start = now();
settingsManager.mergeSettings(s, TOR_NAMESPACE); private void storeTorBlockedSetting(boolean torBlockedSetting) {
logDuration(LOG, "Merging settings", start); Settings s = new Settings();
} catch (DbException e) { s.putBoolean(PREF_TOR_DISABLE_BLOCKED, torBlockedSetting);
logException(LOG, WARNING, e); mergeSettings(s, TOR_NAMESPACE);
}
});
} }
private void storeBluetoothSettings(boolean btSetting) { private void storeBluetoothSettings(boolean btSetting) {
listener.runOnDbThread(() -> { Settings s = new Settings();
try { s.putBoolean(PREF_BT_ENABLE, btSetting);
Settings s = new Settings(); mergeSettings(s, BT_NAMESPACE);
s.putBoolean(PREF_BT_ENABLE, btSetting);
long start = now();
settingsManager.mergeSettings(s, BT_NAMESPACE);
logDuration(LOG, "Merging settings", start);
} catch (DbException e) {
logException(LOG, WARNING, e);
}
});
} }
private void storeSettings(Settings settings) { private void storeSettings(Settings s) {
mergeSettings(s, SETTINGS_NAMESPACE);
}
private void mergeSettings(Settings s, String namespace) {
listener.runOnDbThread(() -> { listener.runOnDbThread(() -> {
try { try {
long start = now(); long start = now();
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE); settingsManager.mergeSettings(s, namespace);
logDuration(LOG, "Merging settings", start); logDuration(LOG, "Merging settings", start);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); logException(LOG, WARNING, e);

View File

@@ -348,6 +348,8 @@
<string name="tor_network_setting_never">Never</string> <string name="tor_network_setting_never">Never</string>
<string name="tor_network_setting_wifi">Only when using Wi-Fi</string> <string name="tor_network_setting_wifi">Only when using Wi-Fi</string>
<string name="tor_network_setting_always">When using Wi-Fi or mobile data</string> <string name="tor_network_setting_always">When using Wi-Fi or mobile data</string>
<string name="tor_location_setting_title">Disable Tor based on location</string>
<string name="tor_location_setting_hint_format">Disable Tor in countries where it is likely to be blocked (%1$s)</string>
<!-- Settings Security and Panic --> <!-- Settings Security and Panic -->
<string name="security_settings_title">Security</string> <string name="security_settings_title">Security</string>

View File

@@ -44,6 +44,12 @@
android:summary="%s" android:summary="%s"
android:title="@string/tor_network_setting"/> android:title="@string/tor_network_setting"/>
<CheckBoxPreference
android:defaultValue="true"
android:key="pref_key_tor_location"
android:persistent="false"
android:title="@string/tor_location_setting_title"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory