From fe6a0e47121d17d08c7d913f1db086687a569446 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Wed, 23 Jun 2021 03:27:17 +0200 Subject: initial tor-integration to circumvent blocking attempts of the provider api --- .../bitmaskclient/tor/TorStatusObservable.java | 102 +++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java new file mode 100644 index 00000000..ed4ae24b --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -0,0 +1,102 @@ +package se.leap.bitmaskclient.tor; + +import android.content.Context; +import android.os.Handler; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.Observable; + +import se.leap.bitmaskclient.R; + +public class TorStatusObservable extends Observable { + + private static final String TAG = TorStatusObservable.class.getSimpleName(); + + public enum TorStatus { + ON, + OFF, + STARTING, + STOPPING, + UNKOWN + } + + private static TorStatusObservable instance; + private TorStatus status = TorStatus.UNKOWN; + private final TorNotificationManager torNotificationManager; + private String lastError; + private int port = -1; + + private TorStatusObservable() { + torNotificationManager = new TorNotificationManager(); + } + + public static TorStatusObservable getInstance() { + if (instance == null) { + instance = new TorStatusObservable(); + } + return instance; + } + + public static TorStatus getStatus() { + return getInstance().status; + } + + + public static void updateState(Context context, String status) { + try { + Log.d(TAG, "update tor state: " + status); + getInstance().status = TorStatus.valueOf(status); + if (getInstance().status == TorStatus.OFF) { + getInstance().torNotificationManager.cancelNotifications(context); + } else { + getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context)); + } + instance.setChanged(); + instance.notifyObservers(); + + + } catch (IllegalStateException e) { + e.printStackTrace(); + } + } + + public static void setLastError(String error) { + getInstance().lastError = error; + instance.setChanged(); + instance.notifyObservers(); + } + + public static void setProxyPort(int port) { + getInstance().port = port; + instance.setChanged(); + instance.notifyObservers(); + } + + public static int getProxyPort() { + return getInstance().port; + } + + + @Nullable + public String getLastError() { + return lastError; + } + + private static String getStringForCurrentStatus(Context context) { + switch (getInstance().status) { + case ON: + return context.getString(R.string.tor_started); + case STARTING: + return context.getString(R.string.tor_starting); + case STOPPING: + return context.getString(R.string.tor_stopping); + case OFF: + case UNKOWN: + break; + } + return null; + } +} -- cgit v1.2.3 From 236c17ec3f4348a9f0d4ec4a2454b9fbfaf8707f Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 24 Jun 2021 23:15:41 +0200 Subject: show tor status info in provider setup activies --- app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index ed4ae24b..e806e441 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -85,7 +85,7 @@ public class TorStatusObservable extends Observable { return lastError; } - private static String getStringForCurrentStatus(Context context) { + public static String getStringForCurrentStatus(Context context) { switch (getInstance().status) { case ON: return context.getString(R.string.tor_started); -- cgit v1.2.3 From fcec92a0042477347338a25cd072d622edfa03c9 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 16 Oct 2021 11:59:42 +0200 Subject: show tor bootstrapping progress in notifications --- .../bitmaskclient/tor/TorStatusObservable.java | 77 +++++++++++++++++++++- 1 file changed, 74 insertions(+), 3 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index e806e441..11baecbf 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -8,6 +8,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.util.Observable; +import java.util.Vector; import se.leap.bitmaskclient.R; @@ -28,6 +29,8 @@ public class TorStatusObservable extends Observable { private final TorNotificationManager torNotificationManager; private String lastError; private int port = -1; + private int bootstrapPercent = -1; + private Vector lastLogs = new Vector<>(100); private TorStatusObservable() { torNotificationManager = new TorNotificationManager(); @@ -44,25 +47,93 @@ public class TorStatusObservable extends Observable { return getInstance().status; } + public static void logMessage(Context context, String tag, String message) { + Log.d(tag, message); + addLog(message); + if (getInstance().status != TorStatus.OFF) { + getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context), message, getInstance().bootstrapPercent); + } + instance.setChanged(); + instance.notifyObservers(); + } + + private static void addLog(String message) { + if (instance.lastLogs.size() > 100) { + instance.lastLogs.remove(0); + } + instance.lastLogs.add(message); + } public static void updateState(Context context, String status) { + updateState(context,status, -1, null); + } + + public static void updateState(Context context, String status, int bootstrapPercent, @Nullable String logKey) { try { - Log.d(TAG, "update tor state: " + status); + Log.d(TAG, "update tor state: " + status + " " + bootstrapPercent + " "+ logKey); getInstance().status = TorStatus.valueOf(status); + if (bootstrapPercent != -1) { + getInstance().bootstrapPercent = bootstrapPercent; + } + int progress = getInstance().status == TorStatus.STARTING ? getInstance().bootstrapPercent : -1; + + if (getInstance().status == TorStatus.OFF) { getInstance().torNotificationManager.cancelNotifications(context); + } else if (logKey != null) { + String log = getStringFor(context, logKey); + addLog(log); + getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context), log, progress); } else { - getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context)); + String log = instance.lastLogs.size() > 0 ? instance.lastLogs.lastElement() : ""; + getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context), log, progress); } + instance.setChanged(); instance.notifyObservers(); - } catch (IllegalStateException e) { e.printStackTrace(); } } + private static String getStringFor(Context context, String key) { + switch (key) { + case "conn_pt": + return context.getString(R.string.log_conn_pt); + case "conn_done_pt": + return context.getString(R.string.log_conn_done_pt); + case "conn_done": + return context.getString(R.string.log_conn_done); + case "handshake": + return context.getString(R.string.log_handshake); + case "handshake_done": + return context.getString(R.string.log_handshake_done); + case "onehop_create": + return context.getString(R.string.log_onehop_create); + case "requesting_status": + return context.getString(R.string.log_requesting_status); + case "loading_status": + return context.getString(R.string.log_loading_status); + case "loading_keys": + return context.getString(R.string.log_loading_keys); + case "requesting_descriptors": + return context.getString(R.string.log_requesting_desccriptors); + case "loading_descriptors": + return context.getString(R.string.log_loading_descriptors); + case "enough_dirinfo": + return context.getString(R.string.log_enough_dirinfo); + case "ap_handshake_done": + return context.getString(R.string.log_ap_handshake_done); + case "circuit_create": + return context.getString(R.string.log_circuit_create); + case "done": + return context.getString(R.string.log_done); + default: + return key; + } + } + public static void setLastError(String error) { getInstance().lastError = error; instance.setChanged(); -- cgit v1.2.3 From bb2f6caa4ed2fae8978c578be829dcc6b08d542b Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 16 Oct 2021 13:52:03 +0200 Subject: show snowflake logs in notification --- .../bitmaskclient/tor/TorStatusObservable.java | 42 +++++++++++++++------- 1 file changed, 29 insertions(+), 13 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index 11baecbf..64e68727 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -1,10 +1,8 @@ package se.leap.bitmaskclient.tor; import android.content.Context; -import android.os.Handler; import android.util.Log; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.util.Observable; @@ -24,10 +22,15 @@ public class TorStatusObservable extends Observable { UNKOWN } + public static final String LOG_TAG_TOR = "[TOR]"; + public static final String LOG_TAG_SNOWFLAKE = "[SNOWFLAKE]"; + private static TorStatusObservable instance; private TorStatus status = TorStatus.UNKOWN; private final TorNotificationManager torNotificationManager; private String lastError; + private String lastTorLog; + private String lastSnowflakeLog; private int port = -1; private int bootstrapPercent = -1; private Vector lastLogs = new Vector<>(100); @@ -47,16 +50,32 @@ public class TorStatusObservable extends Observable { return getInstance().status; } - public static void logMessage(Context context, String tag, String message) { - Log.d(tag, message); + public static void logSnowflakeMessage(Context context, String message) { + Log.d(LOG_TAG_SNOWFLAKE, message); addLog(message); + getInstance().lastSnowflakeLog = message; if (getInstance().status != TorStatus.OFF) { - getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context), message, getInstance().bootstrapPercent); + getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context), getNotificationLog(), getNotificationProgress()); } instance.setChanged(); instance.notifyObservers(); } + private static String getNotificationLog() { + String snowflakeIcon = new String(Character.toChars(0x2744)); + String snowflakeLog = getInstance().lastSnowflakeLog; + // we don't want to show the response json in the notification + if (snowflakeLog != null && snowflakeLog.contains("Received answer: {")) { + snowflakeLog = "Received answer."; + } + return "Tor: " + getInstance().lastTorLog + "\n" + + snowflakeIcon + ": " + snowflakeLog; + } + + private static int getNotificationProgress() { + return getInstance().status == TorStatus.STARTING ? getInstance().bootstrapPercent : -1; + } + private static void addLog(String message) { if (instance.lastLogs.size() > 100) { instance.lastLogs.remove(0); @@ -75,18 +94,15 @@ public class TorStatusObservable extends Observable { if (bootstrapPercent != -1) { getInstance().bootstrapPercent = bootstrapPercent; } - int progress = getInstance().status == TorStatus.STARTING ? getInstance().bootstrapPercent : -1; - if (getInstance().status == TorStatus.OFF) { getInstance().torNotificationManager.cancelNotifications(context); - } else if (logKey != null) { - String log = getStringFor(context, logKey); - addLog(log); - getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context), log, progress); } else { - String log = instance.lastLogs.size() > 0 ? instance.lastLogs.lastElement() : ""; - getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context), log, progress); + if (logKey != null) { + getInstance().lastTorLog = getStringFor(context, logKey); + addLog(getInstance().lastTorLog); + } + getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context), getNotificationLog(), getNotificationProgress()); } instance.setChanged(); -- cgit v1.2.3 From 726f06f564e2743048baea5624daa96a511aace3 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 16 Oct 2021 15:31:33 +0200 Subject: tweak snowflake log message --- app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index 64e68727..449955af 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -66,7 +66,7 @@ public class TorStatusObservable extends Observable { String snowflakeLog = getInstance().lastSnowflakeLog; // we don't want to show the response json in the notification if (snowflakeLog != null && snowflakeLog.contains("Received answer: {")) { - snowflakeLog = "Received answer."; + snowflakeLog = "Received Answer."; } return "Tor: " + getInstance().lastTorLog + "\n" + snowflakeIcon + ": " + snowflakeLog; -- cgit v1.2.3 From 213e42d82d360cdf7f5632782a9a0cb879c1b4f5 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 22 Oct 2021 23:36:34 +0200 Subject: show tor and snowflake connection status in provider setup screens --- .../bitmaskclient/tor/TorStatusObservable.java | 23 +++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index 449955af..281b21c0 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -55,7 +55,7 @@ public class TorStatusObservable extends Observable { addLog(message); getInstance().lastSnowflakeLog = message; if (getInstance().status != TorStatus.OFF) { - getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context), getNotificationLog(), getNotificationProgress()); + getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context), getNotificationLog(), getBootstrapProgress()); } instance.setChanged(); instance.notifyObservers(); @@ -72,15 +72,15 @@ public class TorStatusObservable extends Observable { snowflakeIcon + ": " + snowflakeLog; } - private static int getNotificationProgress() { + public static int getBootstrapProgress() { return getInstance().status == TorStatus.STARTING ? getInstance().bootstrapPercent : -1; } private static void addLog(String message) { if (instance.lastLogs.size() > 100) { - instance.lastLogs.remove(0); + instance.lastLogs.remove(99); } - instance.lastLogs.add(message); + instance.lastLogs.add(0, message.trim()); } public static void updateState(Context context, String status) { @@ -102,7 +102,7 @@ public class TorStatusObservable extends Observable { getInstance().lastTorLog = getStringFor(context, logKey); addLog(getInstance().lastTorLog); } - getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context), getNotificationLog(), getNotificationProgress()); + getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context), getNotificationLog(), getBootstrapProgress()); } instance.setChanged(); @@ -168,8 +168,17 @@ public class TorStatusObservable extends Observable { @Nullable - public String getLastError() { - return lastError; + public static String getLastTorLog() { + return getInstance().lastTorLog; + } + + @Nullable + public static String getLastSnowflakeLog() { + return getInstance().lastSnowflakeLog; + } + + public static Vector getLastLogs() { + return getInstance().lastLogs; } public static String getStringForCurrentStatus(Context context) { -- cgit v1.2.3 From 01e40b1a843326036425727355550dba8bd66335 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sun, 24 Oct 2021 16:47:12 +0200 Subject: cancel tor and provider setup on pressing back button --- .../se/leap/bitmaskclient/tor/TorStatusObservable.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index 281b21c0..fb7e4d93 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -1,10 +1,13 @@ package se.leap.bitmaskclient.tor; import android.content.Context; +import android.content.Intent; import android.util.Log; import androidx.annotation.Nullable; +import org.torproject.jni.TorService; + import java.util.Observable; import java.util.Vector; @@ -22,6 +25,8 @@ public class TorStatusObservable extends Observable { UNKOWN } + private boolean cancelled = false; + public static final String LOG_TAG_TOR = "[TOR]"; public static final String LOG_TAG_SNOWFLAKE = "[SNOWFLAKE]"; @@ -97,6 +102,7 @@ public class TorStatusObservable extends Observable { if (getInstance().status == TorStatus.OFF) { getInstance().torNotificationManager.cancelNotifications(context); + getInstance().cancelled = false; } else { if (logKey != null) { getInstance().lastTorLog = getStringFor(context, logKey); @@ -195,4 +201,16 @@ public class TorStatusObservable extends Observable { } return null; } + + public static void shutdownTor(Context context) { + getInstance().cancelled = true; + getInstance().notifyObservers(); + + Intent intent = new Intent(context, TorService.class); + boolean stopped = context.stopService(intent); + } + + public static boolean isCancelled() { + return getInstance().cancelled; + } } -- cgit v1.2.3 From d27af3b17d6636de8b2755090b6fe6329531f639 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 4 Nov 2021 16:45:54 +0100 Subject: remove unused UNKNOWN TorStatus state --- app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index fb7e4d93..f4f0ff11 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -22,7 +22,7 @@ public class TorStatusObservable extends Observable { OFF, STARTING, STOPPING, - UNKOWN + // UNKOWN } private boolean cancelled = false; @@ -31,7 +31,7 @@ public class TorStatusObservable extends Observable { public static final String LOG_TAG_SNOWFLAKE = "[SNOWFLAKE]"; private static TorStatusObservable instance; - private TorStatus status = TorStatus.UNKOWN; + private TorStatus status = TorStatus.OFF; private final TorNotificationManager torNotificationManager; private String lastError; private String lastTorLog; @@ -196,7 +196,6 @@ public class TorStatusObservable extends Observable { case STOPPING: return context.getString(R.string.tor_stopping); case OFF: - case UNKOWN: break; } return null; -- cgit v1.2.3 From 88b7dc2eb3dcbec8d1e637096867c15211818677 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 5 Nov 2021 02:38:26 +0100 Subject: Ensure tor state is set to OFF after snowflake completely stopped. --- .../bitmaskclient/tor/TorStatusObservable.java | 63 ++++++++++++++++++++-- 1 file changed, 59 insertions(+), 4 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index f4f0ff11..eca0f555 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -9,7 +9,12 @@ import androidx.annotation.Nullable; import org.torproject.jni.TorService; import java.util.Observable; +import java.util.Observer; import java.util.Vector; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; import se.leap.bitmaskclient.R; @@ -17,21 +22,34 @@ public class TorStatusObservable extends Observable { private static final String TAG = TorStatusObservable.class.getSimpleName(); + public interface StatusCondition { + boolean met(); + } + public enum TorStatus { ON, OFF, STARTING, - STOPPING, - // UNKOWN + STOPPING + } + + public enum SnowflakeStatus { + ON, + OFF } + // indicates if the user has cancelled Tor, the actual TorStatus can still be different until + // the TorService has sent the shutdown signal private boolean cancelled = false; public static final String LOG_TAG_TOR = "[TOR]"; public static final String LOG_TAG_SNOWFLAKE = "[SNOWFLAKE]"; + public static final String SNOWFLAKE_STARTED = "--- Starting Snowflake Client ---"; + public static final String SNOWFLAKE_STOPPED = "---- SnowflakeConn: end collecting snowflakes ---"; private static TorStatusObservable instance; private TorStatus status = TorStatus.OFF; + private SnowflakeStatus snowflakeStatus = SnowflakeStatus.OFF; private final TorNotificationManager torNotificationManager; private String lastError; private String lastTorLog; @@ -55,13 +73,50 @@ public class TorStatusObservable extends Observable { return getInstance().status; } + public static SnowflakeStatus getSnowflakeStatus() { + return getInstance().snowflakeStatus; + } + + /** + * Waits on the current Thread until a certain tor/snowflake status has been reached + * @param condition defines when wait should be interrupted + * @param timeout Timout in seconds + * @throws InterruptedException if thread was interrupted while waiting + * @throws TimeoutException thrown if timeout was reached + */ + public static void waitUntil(StatusCondition condition, int timeout) throws InterruptedException, TimeoutException { + CountDownLatch countDownLatch = new CountDownLatch(1); + final AtomicBoolean conditionMet = new AtomicBoolean(false); + Observer observer = (o, arg) -> { + if (condition.met()) { + countDownLatch.countDown(); + conditionMet.set(true); + } + }; + if (condition.met()) { + // no need to wait + return; + } + getInstance().addObserver(observer); + countDownLatch.await(timeout, TimeUnit.SECONDS); + getInstance().deleteObserver(observer); + if (!conditionMet.get()) { + throw new TimeoutException("Status condition not met within " + timeout + "s."); + } + } + public static void logSnowflakeMessage(Context context, String message) { - Log.d(LOG_TAG_SNOWFLAKE, message); addLog(message); getInstance().lastSnowflakeLog = message; if (getInstance().status != TorStatus.OFF) { getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context), getNotificationLog(), getBootstrapProgress()); } + //TODO: implement proper state signalling in IPtProxy + if (SNOWFLAKE_STARTED.equals(message)) { + getInstance().snowflakeStatus = SnowflakeStatus.ON; + } else if (SNOWFLAKE_STOPPED.equals(message)) { + getInstance().snowflakeStatus = SnowflakeStatus.OFF; + } instance.setChanged(); instance.notifyObservers(); } @@ -206,7 +261,7 @@ public class TorStatusObservable extends Observable { getInstance().notifyObservers(); Intent intent = new Intent(context, TorService.class); - boolean stopped = context.stopService(intent); + context.stopService(intent); } public static boolean isCancelled() { -- cgit v1.2.3 From 8a7b455f011842d17de687b7cbb2b6589b78ac3f Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 6 Nov 2021 00:52:23 +0100 Subject: initiate tor status logs with empty strings --- .../main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index eca0f555..3be4ce12 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -52,8 +52,8 @@ public class TorStatusObservable extends Observable { private SnowflakeStatus snowflakeStatus = SnowflakeStatus.OFF; private final TorNotificationManager torNotificationManager; private String lastError; - private String lastTorLog; - private String lastSnowflakeLog; + private String lastTorLog = ""; + private String lastSnowflakeLog = ""; private int port = -1; private int bootstrapPercent = -1; private Vector lastLogs = new Vector<>(100); @@ -253,7 +253,7 @@ public class TorStatusObservable extends Observable { case OFF: break; } - return null; + return ""; } public static void shutdownTor(Context context) { -- cgit v1.2.3 From 7bde8bbb733dfcba7baace5c2261f67da8e0d3d0 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sun, 7 Nov 2021 05:20:25 +0100 Subject: Add provider setup unit tests wrt. Tor handling --- .../main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index 3be4ce12..fae7d063 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -83,8 +83,9 @@ public class TorStatusObservable extends Observable { * @param timeout Timout in seconds * @throws InterruptedException if thread was interrupted while waiting * @throws TimeoutException thrown if timeout was reached + * @return true return value only needed to mock this method call */ - public static void waitUntil(StatusCondition condition, int timeout) throws InterruptedException, TimeoutException { + public static boolean waitUntil(StatusCondition condition, int timeout) throws InterruptedException, TimeoutException { CountDownLatch countDownLatch = new CountDownLatch(1); final AtomicBoolean conditionMet = new AtomicBoolean(false); Observer observer = (o, arg) -> { @@ -95,7 +96,7 @@ public class TorStatusObservable extends Observable { }; if (condition.met()) { // no need to wait - return; + return true; } getInstance().addObserver(observer); countDownLatch.await(timeout, TimeUnit.SECONDS); @@ -103,6 +104,7 @@ public class TorStatusObservable extends Observable { if (!conditionMet.get()) { throw new TimeoutException("Status condition not met within " + timeout + "s."); } + return true; } public static void logSnowflakeMessage(Context context, String message) { -- cgit v1.2.3 From 840b2ca0dea22bba983698d832d3f4d1e7efacf8 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sun, 7 Nov 2021 18:41:09 +0100 Subject: always reset proxy port if tor status turns to OFF --- app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java | 1 + 1 file changed, 1 insertion(+) (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index fae7d063..2527ce83 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -160,6 +160,7 @@ public class TorStatusObservable extends Observable { if (getInstance().status == TorStatus.OFF) { getInstance().torNotificationManager.cancelNotifications(context); getInstance().cancelled = false; + getInstance().port = -1; } else { if (logKey != null) { getInstance().lastTorLog = getStringFor(context, logKey); -- cgit v1.2.3 From 0b687502d047253ca50b691c29336bc3e53a29d2 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 11 Nov 2021 21:54:40 +0100 Subject: fix snowflake on-/off state detection --- .../main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index 2527ce83..ade22e6b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -114,9 +114,11 @@ public class TorStatusObservable extends Observable { getInstance().torNotificationManager.buildTorNotification(context, getStringForCurrentStatus(context), getNotificationLog(), getBootstrapProgress()); } //TODO: implement proper state signalling in IPtProxy - if (SNOWFLAKE_STARTED.equals(message)) { + if (SNOWFLAKE_STARTED.equals(message.trim())) { + Log.d(TAG, "snowflakeStatus ON"); getInstance().snowflakeStatus = SnowflakeStatus.ON; - } else if (SNOWFLAKE_STOPPED.equals(message)) { + } else if (SNOWFLAKE_STOPPED.equals(message.trim())) { + Log.d(TAG, "snowflakeStatus OFF"); getInstance().snowflakeStatus = SnowflakeStatus.OFF; } instance.setChanged(); -- cgit v1.2.3 From a917cbe977f640345677b97dc9b00900d78c46b3 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 11 Nov 2021 22:16:15 +0100 Subject: use command pattern to start/stop tor service, similar to EIP and ProviderAPI service --- .../java/se/leap/bitmaskclient/tor/TorStatusObservable.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index ade22e6b..d426d51e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -261,12 +261,11 @@ public class TorStatusObservable extends Observable { return ""; } - public static void shutdownTor(Context context) { - getInstance().cancelled = true; - getInstance().notifyObservers(); - - Intent intent = new Intent(context, TorService.class); - context.stopService(intent); + public static void markCancelled() { + if (!getInstance().cancelled) { + getInstance().cancelled = true; + getInstance().notifyObservers(); + } } public static boolean isCancelled() { -- cgit v1.2.3 From 0728a708d8a4d7abc9cb28a0c19a8856b3b285d4 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 11 Nov 2021 23:30:32 +0100 Subject: Check if snowflake stopped with an error. Change state to OFF in that case, too --- .../java/se/leap/bitmaskclient/tor/TorStatusObservable.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index d426d51e..cde17c34 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -1,13 +1,10 @@ package se.leap.bitmaskclient.tor; import android.content.Context; -import android.content.Intent; import android.util.Log; import androidx.annotation.Nullable; -import org.torproject.jni.TorService; - import java.util.Observable; import java.util.Observer; import java.util.Vector; @@ -45,7 +42,9 @@ public class TorStatusObservable extends Observable { public static final String LOG_TAG_TOR = "[TOR]"; public static final String LOG_TAG_SNOWFLAKE = "[SNOWFLAKE]"; public static final String SNOWFLAKE_STARTED = "--- Starting Snowflake Client ---"; - public static final String SNOWFLAKE_STOPPED = "---- SnowflakeConn: end collecting snowflakes ---"; + public static final String SNOWFLAKE_STOPPED_COLLECTING = "---- SnowflakeConn: end collecting snowflakes ---"; + public static final String SNOWFLAKE_COPY_LOOP_STOPPED = "copy loop ended"; + public static final String SNOWFLAKE_SOCKS_ERROR = "SOCKS accept error"; private static TorStatusObservable instance; private TorStatus status = TorStatus.OFF; @@ -117,7 +116,9 @@ public class TorStatusObservable extends Observable { if (SNOWFLAKE_STARTED.equals(message.trim())) { Log.d(TAG, "snowflakeStatus ON"); getInstance().snowflakeStatus = SnowflakeStatus.ON; - } else if (SNOWFLAKE_STOPPED.equals(message.trim())) { + } else if (SNOWFLAKE_STOPPED_COLLECTING.equals(message.trim()) || + SNOWFLAKE_COPY_LOOP_STOPPED.equals(message.trim()) || + message.trim().contains(SNOWFLAKE_SOCKS_ERROR)) { Log.d(TAG, "snowflakeStatus OFF"); getInstance().snowflakeStatus = SnowflakeStatus.OFF; } -- cgit v1.2.3 From 8aeb4791b6e024de9aa9c61b574d8c798a3c0a2c Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 12 Nov 2021 01:41:10 +0100 Subject: add licenses --- .../se/leap/bitmaskclient/tor/TorStatusObservable.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java index cde17c34..3c280b9c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java @@ -1,5 +1,20 @@ package se.leap.bitmaskclient.tor; - +/** + * Copyright (c) 2021 LEAP Encryption Access Project and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ import android.content.Context; import android.util.Log; -- cgit v1.2.3