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 --- app/build.gradle | 3 + .../se/leap/bitmaskclient/base/BitmaskApp.java | 4 + .../leap/bitmaskclient/base/models/Constants.java | 1 + .../bitmaskclient/base/utils/PreferenceHelper.java | 14 ++- .../leap/bitmaskclient/eip/EipSetupObserver.java | 37 +++++- .../bitmaskclient/providersetup/ProviderAPI.java | 134 +++++++++++++++++++++ .../providersetup/ProviderAPICommand.java | 18 +-- .../providersetup/ProviderApiManagerBase.java | 72 +++++++++-- .../connectivity/OkHttpClientGenerator.java | 25 ++-- .../bitmaskclient/tor/TorNotificationManager.java | 105 ++++++++++++++++ .../bitmaskclient/tor/TorStatusObservable.java | 102 ++++++++++++++++ app/src/main/res/values/strings.xml | 5 + .../providersetup/ProviderApiManager.java | 55 +++++++-- 13 files changed, 532 insertions(+), 43 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java create mode 100644 app/src/main/java/se/leap/bitmaskclient/tor/TorStatusObservable.java diff --git a/app/build.gradle b/app/build.gradle index f1331e12..7f4f667e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -391,6 +391,9 @@ dependencies { implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0' implementation 'de.hdodenhof:circleimageview:3.1.0' + implementation 'info.guardianproject:tor-android:0.4.5.7' + implementation 'info.guardianproject:jtorctl:0.4.5.7' + fatwebImplementation project(path: ':bitmask-web-core') fatImplementation project(path: ':bitmask-core') x86Implementation project(path: ':bitmask-core') diff --git a/app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java b/app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java index 4b6fea72..60c28a9a 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java @@ -34,6 +34,8 @@ import se.leap.bitmaskclient.eip.EipSetupObserver; import se.leap.bitmaskclient.base.models.ProviderObservable; import se.leap.bitmaskclient.tethering.TetheringStateManager; import se.leap.bitmaskclient.base.utils.PRNGFixes; +import se.leap.bitmaskclient.tor.TorNotificationManager; +import se.leap.bitmaskclient.tor.TorStatusObservable; import static android.content.Intent.CATEGORY_DEFAULT; import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_DOWNLOAD_SERVICE_EVENT; @@ -53,6 +55,7 @@ public class BitmaskApp extends MultiDexApplication { private RefWatcher refWatcher; private ProviderObservable providerObservable; private DownloadBroadcastReceiver downloadBroadcastReceiver; + private TorStatusObservable torStatusObservable; @Override @@ -69,6 +72,7 @@ public class BitmaskApp extends MultiDexApplication { SharedPreferences preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); providerObservable = ProviderObservable.getInstance(); providerObservable.updateProvider(getSavedProviderFromSharedPreferences(preferences)); + torStatusObservable = TorStatusObservable.getInstance(); EipSetupObserver.init(this, preferences); AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); TetheringStateManager.getInstance().init(this); diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java index 3edfbb3d..f627a24e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java @@ -41,6 +41,7 @@ public interface Constants { String RESTART_ON_UPDATE = "restart_on_update"; String LAST_UPDATE_CHECK = "last_update_check"; String PREFERRED_CITY = "preferred_city"; + String USE_TOR = "use_tor"; ////////////////////////////////////////////// diff --git a/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java b/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java index a3d1314e..cbea2815 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java @@ -34,6 +34,7 @@ import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES; import static se.leap.bitmaskclient.base.models.Constants.SHOW_EXPERIMENTAL; import static se.leap.bitmaskclient.base.models.Constants.USE_IPv6_FIREWALL; import static se.leap.bitmaskclient.base.models.Constants.USE_PLUGGABLE_TRANSPORTS; +import static se.leap.bitmaskclient.base.models.Constants.USE_TOR; /** * Created by cyberta on 18.03.18. @@ -212,6 +213,18 @@ public class PreferenceHelper { putString(context, PREFERRED_CITY, city); } + public static Boolean useTor(SharedPreferences preferences) { + return preferences.getBoolean(USE_TOR, true); + } + + public static boolean useTor(Context context) { + return getBoolean(context, USE_TOR, true); + } + + public static void setUseTor(Context context, boolean useTor) { + putBoolean(context, USE_TOR, useTor); + } + public static JSONObject getEipDefinitionFromPreferences(SharedPreferences preferences) { JSONObject result = new JSONObject(); try { @@ -278,5 +291,4 @@ public class PreferenceHelper { SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); preferences.edit().putBoolean(key, value).apply(); } - } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java index 1ad5f7d2..45c829b6 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java @@ -28,27 +28,29 @@ import android.util.Log; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import org.json.JSONObject; +import org.torproject.jni.TorService; import java.util.Vector; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import de.blinkt.openvpn.LaunchVPN; import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.core.ConnectionStatus; import de.blinkt.openvpn.core.LogItem; import de.blinkt.openvpn.core.VpnStatus; +import se.leap.bitmaskclient.appUpdate.DownloadServiceCommand; import se.leap.bitmaskclient.base.models.Provider; -import se.leap.bitmaskclient.providersetup.ProviderAPI; -import se.leap.bitmaskclient.providersetup.ProviderAPICommand; import se.leap.bitmaskclient.base.models.ProviderObservable; -import se.leap.bitmaskclient.appUpdate.DownloadServiceCommand; import se.leap.bitmaskclient.base.utils.PreferenceHelper; +import se.leap.bitmaskclient.providersetup.ProviderAPI; +import se.leap.bitmaskclient.providersetup.ProviderAPICommand; +import se.leap.bitmaskclient.tor.TorStatusObservable; import static android.app.Activity.RESULT_CANCELED; import static android.content.Intent.CATEGORY_DEFAULT; import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET; import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_NOTCONNECTED; +import static se.leap.bitmaskclient.appUpdate.DownloadServiceCommand.CHECK_VERSION_FILE; import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_EIP_EVENT; import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_GATEWAY_SETUP_OBSERVER_EVENT; import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_PROVIDER_API_EVENT; @@ -67,7 +69,8 @@ import static se.leap.bitmaskclient.providersetup.ProviderAPI.CORRECTLY_DOWNLOAD import static se.leap.bitmaskclient.providersetup.ProviderAPI.CORRECTLY_DOWNLOADED_GEOIP_JSON; import static se.leap.bitmaskclient.providersetup.ProviderAPI.CORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_DOWNLOADED_GEOIP_JSON; -import static se.leap.bitmaskclient.appUpdate.DownloadServiceCommand.CHECK_VERSION_FILE; +import static se.leap.bitmaskclient.providersetup.ProviderAPI.STOP_PROXY; +import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF; /** * Created by cyberta on 05.12.18. @@ -92,6 +95,8 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta IntentFilter updateIntentFilter = new IntentFilter(BROADCAST_GATEWAY_SETUP_OBSERVER_EVENT); updateIntentFilter.addAction(BROADCAST_EIP_EVENT); updateIntentFilter.addAction(BROADCAST_PROVIDER_API_EVENT); + updateIntentFilter.addAction(TorService.ACTION_STATUS); + updateIntentFilter.addAction(TorService.ACTION_ERROR); updateIntentFilter.addCategory(CATEGORY_DEFAULT); LocalBroadcastManager.getInstance(context.getApplicationContext()).registerReceiver(this, updateIntentFilter); instance = this; @@ -140,11 +145,30 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta case BROADCAST_PROVIDER_API_EVENT: handleProviderApiEvent(intent); break; + case TorService.ACTION_STATUS: + handleTorStatusEvent(intent); + break; + case TorService.ACTION_ERROR: + handleTorErrorEvent(intent); + break; default: break; } } + private void handleTorErrorEvent(Intent intent) { + String error = intent.getStringExtra(Intent.EXTRA_TEXT); + Log.d(TAG, "handle Tor error event: " + error); + TorStatusObservable.setLastError(error); + } + + private void handleTorStatusEvent(Intent intent) { + String status = intent.getStringExtra(TorService.EXTRA_STATUS); + Log.d(TAG, "handle Tor status event: " + status); + TorStatusObservable.updateState(context, status); + } + + private void handleProviderApiEvent(Intent intent) { int resultCode = intent.getIntExtra(BROADCAST_RESULT_CODE, RESULT_CANCELED); Bundle resultData = intent.getParcelableExtra(BROADCAST_RESULT_KEY); @@ -324,6 +348,9 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta setupNClosestGateway.set(0); observedProfileFromVpnStatus = null; this.changingGateway.set(changingGateway); + if (TorStatusObservable.getStatus() != OFF) { + ProviderAPICommand.execute(context.getApplicationContext(), STOP_PROXY, null); + } } /** diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java index 23c750a3..dcbe9636 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java @@ -17,17 +17,36 @@ package se.leap.bitmaskclient.providersetup; import android.annotation.SuppressLint; +import android.app.Notification; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.ServiceConnection; import android.content.SharedPreferences; +import android.os.Build; +import android.os.IBinder; +import android.util.Log; import androidx.annotation.NonNull; import androidx.core.app.JobIntentService; import androidx.localbroadcastmanager.content.LocalBroadcastManager; +import org.torproject.jni.TorService; + +import java.io.Closeable; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import se.leap.bitmaskclient.base.utils.PreferenceHelper; import se.leap.bitmaskclient.providersetup.connectivity.OkHttpClientGenerator; +import se.leap.bitmaskclient.tor.TorNotificationManager; +import se.leap.bitmaskclient.tor.TorStatusObservable; import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES; +import static se.leap.bitmaskclient.base.utils.ConfigHelper.ensureNotOnMainThread; +import static se.leap.bitmaskclient.tor.TorNotificationManager.TOR_SERVICE_NOTIFICATION_ID; +import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF; +import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.STOPPING; /** * Implements HTTP api methods (encapsulated in {{@link ProviderApiManager}}) @@ -49,6 +68,7 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB final public static String TAG = ProviderAPI.class.getSimpleName(), + STOP_PROXY = "stopProxy", SET_UP_PROVIDER = "setUpProvider", UPDATE_PROVIDER_DETAILS = "updateProviderDetails", DOWNLOAD_GEOIP_JSON = "downloadGeoIpJson", @@ -85,6 +105,7 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB INCORRECTLY_DOWNLOADED_GEOIP_JSON = 18; ProviderApiManager providerApiManager; + private volatile TorServiceConnection torServiceConnection; //TODO: refactor me, please! //used in insecure flavor only @@ -115,14 +136,127 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB providerApiManager.handleIntent(command); } + @Override + public void onDestroy() { + super.onDestroy(); + if (torServiceConnection != null) { + torServiceConnection.close(); + torServiceConnection = null; + } + } + @Override public void broadcastEvent(Intent intent) { LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } + + + @Override + public int initTorConnection() { + initTorServiceConnection(this); + if (torServiceConnection != null) { + Intent torServiceIntent = new Intent(this, TorService.class); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + Notification notification = TorNotificationManager.buildTorForegroundNotification(getApplicationContext()); + //noinspection NewApi + getApplicationContext().startForegroundService(torServiceIntent); + torServiceConnection.torService.startForeground(TOR_SERVICE_NOTIFICATION_ID, notification); + } else { + getApplicationContext().startService(torServiceIntent); + } + + return torServiceConnection.torService.getHttpTunnelPort(); + } + + return -1; + } + + @Override + public void stopTorConnection() { + if (TorStatusObservable.getStatus() != OFF) { + TorStatusObservable.updateState(this, STOPPING.toString()); + initTorServiceConnection(this); + if (torServiceConnection != null) { + torServiceConnection.torService.stopSelf(); + } + } + } + private ProviderApiManager initApiManager() { SharedPreferences preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); OkHttpClientGenerator clientGenerator = new OkHttpClientGenerator(getResources()); return new ProviderApiManager(preferences, getResources(), clientGenerator, this); } + + /** + * Assigns a new TorServiceConnection to ProviderAPI's member variable torServiceConnection. + * Only one thread at a time can create the service connection, that will be shared between threads + * + * @throws InterruptedException thrown if thread gets interrupted + * @throws IllegalStateException thrown if this method was not called from a background thread + */ + private void initTorServiceConnection(Context context) { + if (PreferenceHelper.useTor(context)) { + try { + if (torServiceConnection == null) { + Log.d(TAG, "serviceConnection is still null"); + torServiceConnection = new TorServiceConnection(context); + } + } catch (InterruptedException | IllegalStateException e) { + e.printStackTrace(); + } + } + } + + public static class TorServiceConnection implements Closeable { + private final Context context; + private ServiceConnection serviceConnection; + private TorService torService; + + TorServiceConnection(Context context) throws InterruptedException, IllegalStateException { + this.context = context; + ensureNotOnMainThread(context); + Log.d(TAG, "initSynchronizedServiceConnection!"); + initSynchronizedServiceConnection(context); + } + + @Override + public void close() { + context.unbindService(serviceConnection); + } + + private void initSynchronizedServiceConnection(final Context context) throws InterruptedException { + final BlockingQueue blockingQueue = new LinkedBlockingQueue<>(1); + this.serviceConnection = new ServiceConnection() { + volatile boolean mConnectedAtLeastOnce = false; + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + if (!mConnectedAtLeastOnce) { + mConnectedAtLeastOnce = true; + try { + TorService.LocalBinder binder = (TorService.LocalBinder) service; + blockingQueue.put(binder.getService()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + @Override + public void onServiceDisconnected(ComponentName name) { + } + }; + Intent intent = new Intent(context, TorService.class); + context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); + torService = blockingQueue.take(); + } + + public TorService getService() { + return torService; + } + } + } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPICommand.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPICommand.java index 1408dce8..3cdfcab0 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPICommand.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPICommand.java @@ -13,12 +13,12 @@ import se.leap.bitmaskclient.base.models.Provider; public class ProviderAPICommand { private static final String TAG = ProviderAPICommand.class.getSimpleName(); - private Context context; + private final Context context; - private String action; - private Bundle parameters; - private ResultReceiver resultReceiver; - private Provider provider; + private final String action; + private final Bundle parameters; + private final ResultReceiver resultReceiver; + private final Provider provider; private ProviderAPICommand(@NonNull Context context, @NonNull String action, @NonNull Provider provider, ResultReceiver resultReceiver) { this(context.getApplicationContext(), action, Bundle.EMPTY, provider, resultReceiver); @@ -64,22 +64,22 @@ public class ProviderAPICommand { return command; } - public static void execute(Context context, String action, @NonNull Provider provider) { + public static void execute(Context context, String action, Provider provider) { ProviderAPICommand command = new ProviderAPICommand(context, action, provider); command.execute(); } - public static void execute(Context context, String action, Bundle parameters, @NonNull Provider provider) { + public static void execute(Context context, String action, Bundle parameters, Provider provider) { ProviderAPICommand command = new ProviderAPICommand(context, action, parameters, provider); command.execute(); } - public static void execute(Context context, String action, Bundle parameters, @NonNull Provider provider, ResultReceiver resultReceiver) { + public static void execute(Context context, String action, Bundle parameters, Provider provider, ResultReceiver resultReceiver) { ProviderAPICommand command = new ProviderAPICommand(context, action, parameters, provider, resultReceiver); command.execute(); } - public static void execute(Context context, String action, @NonNull Provider provider, ResultReceiver resultReceiver) { + public static void execute(Context context, String action, Provider provider, ResultReceiver resultReceiver) { ProviderAPICommand command = new ProviderAPICommand(context, action, provider, resultReceiver); command.execute(); } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java index c5dc6572..8118c872 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java @@ -48,6 +48,9 @@ import java.security.interfaces.RSAPrivateKey; import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; +import java.util.Observer; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLPeerUnverifiedException; @@ -59,10 +62,13 @@ import se.leap.bitmaskclient.base.models.Constants.CREDENTIAL_ERRORS; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.base.models.ProviderObservable; import se.leap.bitmaskclient.base.utils.ConfigHelper; +import se.leap.bitmaskclient.base.utils.PreferenceHelper; +import se.leap.bitmaskclient.eip.EipStatus; import se.leap.bitmaskclient.providersetup.connectivity.OkHttpClientGenerator; import se.leap.bitmaskclient.providersetup.models.LeapSRPSession; import se.leap.bitmaskclient.providersetup.models.SrpCredentials; import se.leap.bitmaskclient.providersetup.models.SrpRegistrationData; +import se.leap.bitmaskclient.tor.TorStatusObservable; import static se.leap.bitmaskclient.R.string.certificate_error; import static se.leap.bitmaskclient.R.string.error_io_exception_user_message; @@ -119,6 +125,7 @@ import static se.leap.bitmaskclient.providersetup.ProviderAPI.PROVIDER_OK; import static se.leap.bitmaskclient.providersetup.ProviderAPI.RECEIVER_KEY; import static se.leap.bitmaskclient.providersetup.ProviderAPI.SET_UP_PROVIDER; import static se.leap.bitmaskclient.providersetup.ProviderAPI.SIGN_UP; +import static se.leap.bitmaskclient.providersetup.ProviderAPI.STOP_PROXY; import static se.leap.bitmaskclient.providersetup.ProviderAPI.SUCCESSFUL_LOGIN; import static se.leap.bitmaskclient.providersetup.ProviderAPI.SUCCESSFUL_LOGOUT; import static se.leap.bitmaskclient.providersetup.ProviderAPI.SUCCESSFUL_SIGNUP; @@ -128,6 +135,8 @@ import static se.leap.bitmaskclient.providersetup.ProviderAPI.USER_MESSAGE; import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_CERTIFICATE_PINNING; import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_CORRUPTED_PROVIDER_JSON; import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_INVALID_CERTIFICATE; +import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.ON; +import static se.leap.bitmaskclient.tor.TorStatusObservable.getProxyPort; /** * Implements the logic of the http api calls. The methods of this class needs to be called from @@ -140,9 +149,11 @@ public abstract class ProviderApiManagerBase { public interface ProviderApiServiceCallback { void broadcastEvent(Intent intent); + int initTorConnection(); + void stopTorConnection(); } - private ProviderApiServiceCallback serviceCallback; + private final ProviderApiServiceCallback serviceCallback; protected SharedPreferences preferences; protected Resources resources; @@ -164,17 +175,22 @@ public abstract class ProviderApiManagerBase { String action = command.getAction(); Bundle parameters = command.getBundleExtra(PARAMETERS); - Provider provider = command.getParcelableExtra(PROVIDER_KEY); + if (action == null) { + Log.e(TAG, "Intent without action sent!"); + return; + } - if (provider == null) { + Provider provider = null; + if (command.getParcelableExtra(PROVIDER_KEY) != null) { + provider = command.getParcelableExtra(PROVIDER_KEY); + } else if (!STOP_PROXY.equals(action)) { //TODO: consider returning error back e.g. NO_PROVIDER Log.e(TAG, action +" called without provider!"); return; } - if (action == null) { - Log.e(TAG, "Intent without action sent!"); - return; - } + + // uncomment for testing --v + TorStatusObservable.setProxyPort(startTorProxy()); Bundle result = new Bundle(); switch (action) { @@ -269,9 +285,43 @@ public abstract class ProviderApiManagerBase { } ProviderObservable.getInstance().setProviderForDns(null); } + break; + case STOP_PROXY: + serviceCallback.stopTorConnection(); + break; } } + protected int startTorProxy() { + int port = -1; + if (PreferenceHelper.useTor(preferences) && EipStatus.getInstance().isDisconnected() ) { + port = serviceCallback.initTorConnection(); + if (port != -1) { + try { + waitForTorCircuits(); + } catch (InterruptedException e) { + e.printStackTrace(); + port = -1; + } + } + } + return port; + } + + private void waitForTorCircuits() throws InterruptedException { + if (TorStatusObservable.getStatus() == ON) { + return; + } + CountDownLatch countDownLatch = new CountDownLatch(1); + Observer observer = (o, arg) -> { + if (TorStatusObservable.getStatus() == ON) { + countDownLatch.countDown(); + } + }; + TorStatusObservable.getInstance().addObserver(observer); + countDownLatch.await(90, TimeUnit.SECONDS); + } + void resetProviderDetails(Provider provider) { provider.reset(); deleteProviderDetailsFromPreferences(preferences, provider.getDomain()); @@ -342,7 +392,7 @@ public abstract class ProviderApiManagerBase { private Bundle register(Provider provider, String username, String password) { JSONObject stepResult = null; - OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(provider.getCaCert(), stepResult); + OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(provider.getCaCert(), getProxyPort(), stepResult); if (okHttpClient == null) { return backendErrorNotification(stepResult, username); } @@ -401,7 +451,7 @@ public abstract class ProviderApiManagerBase { String providerApiUrl = provider.getApiUrlWithVersion(); - OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(provider.getCaCert(), stepResult); + OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(provider.getCaCert(), getProxyPort(), stepResult); if (okHttpClient == null) { return backendErrorNotification(stepResult, username); } @@ -681,7 +731,7 @@ public abstract class ProviderApiManagerBase { JSONObject errorJson = new JSONObject(); String providerUrl = provider.getApiUrlString() + "/provider.json"; - OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(provider.getCaCert(), errorJson); + OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(provider.getCaCert(), getProxyPort(), errorJson); if (okHttpClient == null) { result.putString(ERRORS, errorJson.toString()); return false; @@ -950,7 +1000,7 @@ public abstract class ProviderApiManagerBase { } private boolean logOut(Provider provider) { - OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(provider.getCaCert(), new JSONObject()); + OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(provider.getCaCert(), getProxyPort(), new JSONObject()); if (okHttpClient == null) { return false; } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/connectivity/OkHttpClientGenerator.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/connectivity/OkHttpClientGenerator.java index 2077a8b9..ea619263 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/connectivity/OkHttpClientGenerator.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/connectivity/OkHttpClientGenerator.java @@ -18,6 +18,7 @@ package se.leap.bitmaskclient.providersetup.connectivity; import android.content.res.Resources; +import android.net.LocalSocketAddress; import android.os.Build; import androidx.annotation.NonNull; @@ -26,6 +27,9 @@ import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.SocketAddress; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.KeyStoreException; @@ -50,6 +54,7 @@ import static se.leap.bitmaskclient.R.string.certificate_error; import static se.leap.bitmaskclient.R.string.error_io_exception_user_message; import static se.leap.bitmaskclient.R.string.error_no_such_algorithm_exception_user_message; import static se.leap.bitmaskclient.R.string.keyChainAccessError; +import static se.leap.bitmaskclient.R.string.proxy; import static se.leap.bitmaskclient.R.string.server_unreachable_message; import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORS; import static se.leap.bitmaskclient.base.utils.ConfigHelper.getProviderFormattedString; @@ -61,34 +66,35 @@ import static se.leap.bitmaskclient.base.utils.ConfigHelper.getProviderFormatted public class OkHttpClientGenerator { Resources resources; + private final static String PROXY_HOST = "127.0.0.1"; public OkHttpClientGenerator(/*SharedPreferences preferences,*/ Resources resources) { this.resources = resources; } - public OkHttpClient initCommercialCAHttpClient(JSONObject initError) { - return initHttpClient(initError, null); + public OkHttpClient initCommercialCAHttpClient(JSONObject initError, int proxyPort) { + return initHttpClient(initError, null, proxyPort); } - public OkHttpClient initSelfSignedCAHttpClient(String caCert, JSONObject initError) { - return initHttpClient(initError, caCert); + public OkHttpClient initSelfSignedCAHttpClient(String caCert, int proxyPort, JSONObject initError) { + return initHttpClient(initError, caCert, proxyPort); } public OkHttpClient init() { try { - return createClient(null); + return createClient(null, -1); } catch (Exception e) { e.printStackTrace(); } return null; } - private OkHttpClient initHttpClient(JSONObject initError, String certificate) { + private OkHttpClient initHttpClient(JSONObject initError, String certificate, int proxyPort) { if (resources == null) { return null; } try { - return createClient(certificate); + return createClient(certificate, proxyPort); } catch (IllegalArgumentException e) { e.printStackTrace(); // TODO ca cert is invalid - show better error ?! @@ -117,7 +123,7 @@ public class OkHttpClientGenerator { return null; } - private OkHttpClient createClient(String certificate) throws Exception { + private OkHttpClient createClient(String certificate, int proxyPort) throws Exception { TLSCompatSocketFactory sslCompatFactory; ConnectionSpec spec = getConnectionSpec(); OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); @@ -131,6 +137,9 @@ public class OkHttpClientGenerator { clientBuilder.cookieJar(getCookieJar()) .connectionSpecs(Collections.singletonList(spec)); clientBuilder.dns(new DnsResolver()); + if (proxyPort != -1) { + clientBuilder.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, proxyPort))); + } return clientBuilder.build(); } diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java new file mode 100644 index 00000000..71a2735c --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java @@ -0,0 +1,105 @@ +package se.leap.bitmaskclient.tor; +/** + * Copyright (c) 2021 LEAP Encryption Access Project and contributers + * + * 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.annotation.TargetApi; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.Context; +import android.os.Build; + +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; + +import se.leap.bitmaskclient.R; + +public class TorNotificationManager { + public final static int TOR_SERVICE_NOTIFICATION_ID = 10; + static final String NOTIFICATION_CHANNEL_NEWSTATUS_ID = "bitmask_tor_service_news"; + + + public TorNotificationManager() {} + + + public static Notification buildTorForegroundNotification(Context context) { + NotificationManager notificationManager = initNotificationManager(context); + if (notificationManager == null) { + return null; + } + NotificationCompat.Builder notificationBuilder = initNotificationBuilderDefaults(context); + return notificationBuilder + .setSmallIcon(R.drawable.ic_bridge_36) + .setWhen(System.currentTimeMillis()) + .setContentTitle("Using Bridges to configure provider.").build(); + } + + public void buildTorNotification(Context context, String state) { + NotificationManager notificationManager = initNotificationManager(context); + if (notificationManager == null) { + return; + } + NotificationCompat.Builder notificationBuilder = initNotificationBuilderDefaults(context); + notificationBuilder + .setSmallIcon(R.drawable.ic_bridge_36) + .setWhen(System.currentTimeMillis()) + .setTicker(state) + .setContentTitle(context.getString(R.string.tor_provider_setup)) + .setContentText(state); + notificationManager.notify(TOR_SERVICE_NOTIFICATION_ID, notificationBuilder.build()); + } + + + private static NotificationManager initNotificationManager(Context context) { + NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + if (notificationManager == null) { + return null; + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + createNotificationChannel(notificationManager); + } + return notificationManager; + } + + @TargetApi(26) + private static void createNotificationChannel(NotificationManager notificationManager) { + CharSequence name = "Bitmask Tor Service"; + String description = "Informs about usage of bridges to configure Bitmask."; + NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_NEWSTATUS_ID, + name, + NotificationManager.IMPORTANCE_LOW); + channel.setSound(null, null); + channel.setDescription(description); + notificationManager.createNotificationChannel(channel); + } + + private static NotificationCompat.Builder initNotificationBuilderDefaults(Context context) { + NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_NEWSTATUS_ID); + notificationBuilder. + setDefaults(Notification.DEFAULT_ALL). + setAutoCancel(true); + return notificationBuilder; + } + + public void cancelNotifications(Context context) { + NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + if (notificationManager == null) { + return; + } + notificationManager.cancel(TOR_SERVICE_NOTIFICATION_ID); + } +} 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; + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e883b974..b43a0683 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -155,4 +155,9 @@ Automatic Your traffic is currently routed through: + Starting Tor with bridges. + Stopping Tor with bridges. + Running Tor with bridges to fetch provider configuration. + Using Bridges to configure provider. + diff --git a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java index 70652365..b6069982 100644 --- a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java +++ b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java @@ -34,8 +34,11 @@ import okhttp3.OkHttpClient; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.base.utils.ConfigHelper; +import se.leap.bitmaskclient.base.utils.PreferenceHelper; import se.leap.bitmaskclient.eip.EIP; +import se.leap.bitmaskclient.eip.EipStatus; import se.leap.bitmaskclient.providersetup.connectivity.OkHttpClientGenerator; +import se.leap.bitmaskclient.tor.TorStatusObservable; import static android.text.TextUtils.isEmpty; import static se.leap.bitmaskclient.BuildConfig.DEBUG_MODE; @@ -52,6 +55,9 @@ import static se.leap.bitmaskclient.base.utils.ConfigHelper.getProviderFormatted import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORS; import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_CERTIFICATE_PINNING; import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_CORRUPTED_PROVIDER_JSON; +import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF; +import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.UNKOWN; +import static se.leap.bitmaskclient.tor.TorStatusObservable.getProxyPort; /** * Implements the logic of the provider api http requests. The methods of this class need to be called from @@ -221,7 +227,7 @@ public class ProviderApiManager extends ProviderApiManagerBase { /** * Fetches the geo ip Json, containing a list of gateways sorted by distance from the users current location. * Fetching is only allowed if the cache timeout of 1 h was reached, a valid geoip service URL exists and the - * vpn is not yet active. The latter condition is needed in order to guarantee that the geoip service sees + * vpn or tor is not running. The latter condition is needed in order to guarantee that the geoip service sees * the real ip of the client * * @param provider @@ -231,7 +237,7 @@ public class ProviderApiManager extends ProviderApiManagerBase { protected Bundle getGeoIPJson(Provider provider) { Bundle result = new Bundle(); - if (!provider.shouldUpdateGeoIpJson() || provider.getGeoipUrl().isDefault() || VpnStatus.isVPNActive()) { + if (!provider.shouldUpdateGeoIpJson() || provider.getGeoipUrl().isDefault() || VpnStatus.isVPNActive() || TorStatusObservable.getStatus() != OFF) { result.putBoolean(BROADCAST_RESULT_KEY, false); return result; } @@ -285,15 +291,20 @@ public class ProviderApiManager extends ProviderApiManagerBase { return result; } - /** - * Tries to download the contents of the provided url using commercially validated CA certificate from chosen provider. - * - */ private String downloadWithCommercialCA(String stringUrl, Provider provider) { + return downloadWithCommercialCA(stringUrl, provider, 0); + } + + /** + * Tries to download the contents of the provided url using commercially validated CA certificate from chosen provider. + * + */ + private String downloadWithCommercialCA(String stringUrl, Provider provider, int tries) { + String responseString; JSONObject errorJson = new JSONObject(); - OkHttpClient okHttpClient = clientGenerator.initCommercialCAHttpClient(errorJson); + OkHttpClient okHttpClient = clientGenerator.initCommercialCAHttpClient(errorJson, getProxyPort()); if (okHttpClient == null) { return errorJson.toString(); } @@ -314,6 +325,17 @@ public class ProviderApiManager extends ProviderApiManagerBase { } } + if (tries == 0 && + responseString != null && + responseString.contains(ERRORS) && + PreferenceHelper.useTor(preferences) && + EipStatus.getInstance().isDisconnected() && + TorStatusObservable.getStatus() == OFF || + TorStatusObservable.getStatus() == UNKOWN) { + TorStatusObservable.setProxyPort(startTorProxy()); + return downloadWithCommercialCA(stringUrl, provider, 1); + } + return responseString; } @@ -330,9 +352,13 @@ public class ProviderApiManager extends ProviderApiManagerBase { } private String downloadFromUrlWithProviderCA(String urlString, Provider provider) { + return downloadFromUrlWithProviderCA(urlString, provider, 0); + } + + private String downloadFromUrlWithProviderCA(String urlString, Provider provider, int tries) { String responseString; JSONObject errorJson = new JSONObject(); - OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(provider.getCaCert(), errorJson); + OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(provider.getCaCert(), getProxyPort(), errorJson); if (okHttpClient == null) { return errorJson.toString(); } @@ -340,6 +366,17 @@ public class ProviderApiManager extends ProviderApiManagerBase { List> headerArgs = getAuthorizationHeader(); responseString = sendGetStringToServer(urlString, headerArgs, okHttpClient); + if (tries == 0 && + responseString != null && + responseString.contains(ERRORS) && + PreferenceHelper.useTor(preferences) && + EipStatus.getInstance().isDisconnected() && + TorStatusObservable.getStatus() == OFF || + TorStatusObservable.getStatus() == UNKOWN) { + TorStatusObservable.setProxyPort(startTorProxy()); + return downloadFromUrlWithProviderCA(urlString, provider, 1); + } + return responseString; } @@ -354,7 +391,7 @@ public class ProviderApiManager extends ProviderApiManagerBase { JSONObject initError = new JSONObject(); String responseString; - OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(caCert, initError); + OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(caCert, getProxyPort(), initError); if (okHttpClient == null) { return initError.toString(); } -- cgit v1.2.3 From a28080ddfe35ac85c7da552739dc27f0687734a2 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Wed, 23 Jun 2021 03:36:40 +0200 Subject: don't use hard coded strings --- app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java index 71a2735c..4acc2b7e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java @@ -45,7 +45,7 @@ public class TorNotificationManager { return notificationBuilder .setSmallIcon(R.drawable.ic_bridge_36) .setWhen(System.currentTimeMillis()) - .setContentTitle("Using Bridges to configure provider.").build(); + .setContentTitle(context.getString(R.string.tor_provider_setup)).build(); } public void buildTorNotification(Context context, String state) { -- cgit v1.2.3 From 7325a74661e943fc0f989ef5e230f0862cc8e9fb Mon Sep 17 00:00:00 2001 From: cyBerta Date: Wed, 23 Jun 2021 16:33:54 +0200 Subject: automatically start VPN after switching provider --- app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java index 126c4a98..99f6826f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java @@ -202,6 +202,7 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener, switch (requestCode) { case REQUEST_CODE_SWITCH_PROVIDER: EipCommand.stopVPN(this.getApplicationContext()); + EipCommand.startVPN(this.getApplicationContext(), false); break; case REQUEST_CODE_CONFIGURE_LEAP: Log.d(TAG, "REQUEST_CODE_CONFIGURE_LEAP - onActivityResult - MainActivity"); -- cgit v1.2.3 From 57915c157c880f29ac9577d1074bf2d54156231f Mon Sep 17 00:00:00 2001 From: cyBerta Date: Wed, 23 Jun 2021 16:35:38 +0200 Subject: automatically close navigation drawer after switch account item was selected --- .../leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java index 5cae1591..f905a7d2 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java @@ -289,8 +289,10 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen if (isDefaultBitmask()) { IconTextEntry switchProvider = drawerView.findViewById(R.id.switch_provider); switchProvider.setVisibility(VISIBLE); - switchProvider.setOnClickListener(v -> - getActivity().startActivityForResult(new Intent(getActivity(), ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER)); + switchProvider.setOnClickListener(v -> { + closeDrawer(); + getActivity().startActivityForResult(new Intent(getActivity(), ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER); + }); } } -- cgit v1.2.3 From fca60f51acf8eea48fc4086db00cba1097d097b7 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 24 Jun 2021 23:12:45 +0200 Subject: tweak wording --- app/src/main/res/values/strings.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b43a0683..7c0e6334 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -155,9 +155,8 @@ Automatic Your traffic is currently routed through: - Starting Tor with bridges. - Stopping Tor with bridges. - Running Tor with bridges to fetch provider configuration. - Using Bridges to configure provider. + Starting bridges for censorship circumvention. Please hold on… + Stopping bridges. + Using bridges for censorship circumvention. -- 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 --- .../activities/ConfigWizardBaseActivity.java | 35 ++++++++++++++++++---- .../providersetup/activities/LoginActivity.java | 2 +- .../providersetup/activities/SignupActivity.java | 2 +- .../bitmaskclient/tor/TorNotificationManager.java | 7 +++-- .../bitmaskclient/tor/TorStatusObservable.java | 2 +- .../main/res/layout-xlarge/v_loading_screen.xml | 22 ++++++++++++-- app/src/main/res/layout/v_add_provider.xml | 20 +++++++++++-- app/src/main/res/layout/v_loading_screen.xml | 22 ++++++++++++-- 8 files changed, 94 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java index b2f13e07..7d452200 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java @@ -19,11 +19,14 @@ import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.Guideline; import androidx.core.content.ContextCompat; +import java.util.Observable; +import java.util.Observer; + import butterknife.BindView; -import butterknife.Optional; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.base.views.ProviderHeaderView; +import se.leap.bitmaskclient.tor.TorStatusObservable; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.view.View.GONE; @@ -37,7 +40,7 @@ import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES; * Created by fupduck on 09.01.18. */ -public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity { +public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity implements Observer { private static final String TAG = ConfigWizardBaseActivity.class.getName(); public static final float GUIDE_LINE_COMPACT_DELTA = 0.1f; @@ -55,9 +58,13 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity { @BindView(R.id.progressbar) protected ProgressBar progressBar; + @Nullable + @BindView(R.id.progressbar_title) + protected AppCompatTextView progressbarTitle; + @Nullable @BindView(R.id.progressbar_description) - protected AppCompatTextView progressbarText; + protected AppCompatTextView progressbarDescription; //Only tablet layouts have guidelines as they are based on a ConstraintLayout @Nullable @@ -142,12 +149,15 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity { protected void onPause() { super.onPause(); isActivityShowing = false; + TorStatusObservable.getInstance().deleteObserver(this); } @Override protected void onResume() { super.onResume(); isActivityShowing = true; + TorStatusObservable.getInstance().addObserver(this); + setProgressbarDescription(TorStatusObservable.getStringForCurrentStatus(this)); } protected void restoreState(Bundle savedInstanceState) { @@ -184,11 +194,18 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity { loadingScreen.setVisibility(VISIBLE); } - protected void setProgressbarText(@StringRes int progressbarText) { - if (this.progressbarText == null) { + protected void setProgressbarTitle(@StringRes int progressbarTitle) { + if (this.progressbarTitle == null) { + return; + } + this.progressbarTitle.setText(progressbarTitle); + } + + protected void setProgressbarDescription(String progressbarDescription) { + if (this.progressbarDescription == null) { return; } - this.progressbarText.setText(progressbarText); + this.progressbarDescription.setText(progressbarDescription); } @@ -287,4 +304,10 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity { }); } + @Override + public void update(Observable o, Object arg) { + if (o instanceof TorStatusObservable) { + runOnUiThread(() -> setProgressbarDescription(TorStatusObservable.getStringForCurrentStatus(ConfigWizardBaseActivity.this))); + } + } } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/LoginActivity.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/LoginActivity.java index a8bac6d8..9a5f31f2 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/LoginActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/LoginActivity.java @@ -17,7 +17,7 @@ public class LoginActivity extends ProviderCredentialsBaseActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setProgressbarText(R.string.logging_in); + setProgressbarTitle(R.string.logging_in); setProviderHeaderLogo(R.drawable.logo); setProviderHeaderText(R.string.login_to_profile); } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SignupActivity.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SignupActivity.java index c0245845..16007a70 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SignupActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SignupActivity.java @@ -37,7 +37,7 @@ public class SignupActivity extends ProviderCredentialsBaseActivity { setProviderHeaderLogo(R.drawable.logo); setProviderHeaderText(R.string.create_profile); - setProgressbarText(R.string.signing_up); + setProgressbarTitle(R.string.signing_up); setButtonText(R.string.signup_button); passwordVerificationField.setVisibility(VISIBLE); diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java index 4acc2b7e..71b5c378 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java @@ -27,6 +27,8 @@ import androidx.annotation.NonNull; import androidx.core.app.NotificationCompat; import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.base.models.Provider; +import se.leap.bitmaskclient.base.models.ProviderObservable; public class TorNotificationManager { public final static int TOR_SERVICE_NOTIFICATION_ID = 10; @@ -45,7 +47,7 @@ public class TorNotificationManager { return notificationBuilder .setSmallIcon(R.drawable.ic_bridge_36) .setWhen(System.currentTimeMillis()) - .setContentTitle(context.getString(R.string.tor_provider_setup)).build(); + .setContentTitle(context.getString(R.string.tor_started)).build(); } public void buildTorNotification(Context context, String state) { @@ -58,8 +60,7 @@ public class TorNotificationManager { .setSmallIcon(R.drawable.ic_bridge_36) .setWhen(System.currentTimeMillis()) .setTicker(state) - .setContentTitle(context.getString(R.string.tor_provider_setup)) - .setContentText(state); + .setContentTitle(state); notificationManager.notify(TOR_SERVICE_NOTIFICATION_ID, notificationBuilder.build()); } 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); diff --git a/app/src/main/res/layout-xlarge/v_loading_screen.xml b/app/src/main/res/layout-xlarge/v_loading_screen.xml index a002665f..adcbfabc 100644 --- a/app/src/main/res/layout-xlarge/v_loading_screen.xml +++ b/app/src/main/res/layout-xlarge/v_loading_screen.xml @@ -1,11 +1,14 @@ + android:visibility="gone" + tools:visibility="visible" + > + + + android:visibility="gone" + tools:visibility="visible"> + + + android:visibility="gone" + tools:visibility="visible" + > + + Date: Thu, 24 Jun 2021 23:22:00 +0200 Subject: Stop tor proxy if provider api communication failed. Proxy will be reinitiated on next api call --- .../main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java index 45c829b6..f42a7d3d 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java @@ -68,7 +68,11 @@ import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PROFILE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.CORRECTLY_DOWNLOADED_GEOIP_JSON; import static se.leap.bitmaskclient.providersetup.ProviderAPI.CORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE; +import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_DOWNLOADED_EIP_SERVICE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_DOWNLOADED_GEOIP_JSON; +import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE; +import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE; +import static se.leap.bitmaskclient.providersetup.ProviderAPI.PROVIDER_NOK; import static se.leap.bitmaskclient.providersetup.ProviderAPI.STOP_PROXY; import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF; @@ -202,6 +206,13 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta case INCORRECTLY_DOWNLOADED_GEOIP_JSON: maybeStartEipService(resultData); break; + case PROVIDER_NOK: + case INCORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE: + case INCORRECTLY_DOWNLOADED_EIP_SERVICE: + case INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE: + if (TorStatusObservable.getStatus() != OFF) { + ProviderAPICommand.execute(context.getApplicationContext(), STOP_PROXY, null); + } default: break; } -- cgit v1.2.3 From b22698c2c4933f43e58379693f615bda235cb040 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 24 Jun 2021 23:27:21 +0200 Subject: let the tor state description in provider setup activities grow up to 2 lines --- app/src/main/res/layout-xlarge/v_loading_screen.xml | 2 +- app/src/main/res/layout/v_add_provider.xml | 2 +- app/src/main/res/layout/v_loading_screen.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/layout-xlarge/v_loading_screen.xml b/app/src/main/res/layout-xlarge/v_loading_screen.xml index adcbfabc..ed25f07b 100644 --- a/app/src/main/res/layout-xlarge/v_loading_screen.xml +++ b/app/src/main/res/layout-xlarge/v_loading_screen.xml @@ -37,7 +37,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:fadingEdge="horizontal" - android:singleLine="true" + android:maxLines="2" android:text="@string/configuring_provider" android:textAppearance="@style/Base.TextAppearance.AppCompat.Small" android:layout_marginTop="@dimen/standard_margin" diff --git a/app/src/main/res/layout/v_add_provider.xml b/app/src/main/res/layout/v_add_provider.xml index 1448e7e7..933f19d0 100644 --- a/app/src/main/res/layout/v_add_provider.xml +++ b/app/src/main/res/layout/v_add_provider.xml @@ -36,7 +36,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:fadingEdge="horizontal" - android:singleLine="true" + android:maxLines="2" android:text="@string/configuring_provider" android:textAppearance="@style/Base.TextAppearance.AppCompat.Small" android:layout_marginTop="@dimen/standard_margin" diff --git a/app/src/main/res/layout/v_loading_screen.xml b/app/src/main/res/layout/v_loading_screen.xml index 9bda063d..f7f58e7b 100644 --- a/app/src/main/res/layout/v_loading_screen.xml +++ b/app/src/main/res/layout/v_loading_screen.xml @@ -38,7 +38,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:fadingEdge="horizontal" - android:singleLine="true" + android:maxLines="2" android:text="@string/configuring_provider" android:textAppearance="@style/Base.TextAppearance.AppCompat.Small" android:layout_marginTop="@dimen/standard_margin" -- cgit v1.2.3 From 9687a96f2608be215c6ddcc22f2ecfe6a889093a Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 24 Jun 2021 23:57:48 +0200 Subject: use notifications contentText instead of contentTitle, so that the complete tor notification text can be shown --- .../main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java index 71b5c378..a2401732 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java @@ -47,7 +47,7 @@ public class TorNotificationManager { return notificationBuilder .setSmallIcon(R.drawable.ic_bridge_36) .setWhen(System.currentTimeMillis()) - .setContentTitle(context.getString(R.string.tor_started)).build(); + .setContentText(context.getString(R.string.tor_started)).build(); } public void buildTorNotification(Context context, String state) { @@ -60,7 +60,7 @@ public class TorNotificationManager { .setSmallIcon(R.drawable.ic_bridge_36) .setWhen(System.currentTimeMillis()) .setTicker(state) - .setContentTitle(state); + .setContentText(state); notificationManager.notify(TOR_SERVICE_NOTIFICATION_ID, notificationBuilder.build()); } -- cgit v1.2.3 From 8acb6f12e1e870c171d5b520cc9f58695b2eed8b Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 1 Jul 2021 17:03:49 +0200 Subject: remove snowflake submodule --- go/android_build_golib.sh | 157 ++++++++++++++++++++++++++++++++++++ go/src/github.com/cyBerta/snowflake | 1 + 2 files changed, 158 insertions(+) create mode 100755 go/android_build_golib.sh create mode 160000 go/src/github.com/cyBerta/snowflake diff --git a/go/android_build_golib.sh b/go/android_build_golib.sh new file mode 100755 index 00000000..a54a42af --- /dev/null +++ b/go/android_build_golib.sh @@ -0,0 +1,157 @@ +#!/bin/bash + +# Copyright (C) 2016 Andrew Jiang (TunnelBear Inc.) +# Convenience script for generating shapeshifter-dispatcher binaries for Android devices +# adapted for Bitmask by cyberta + +BUILD_LIBRARY="false" +BUILD_SHAPESHIFTER_DISPATCHER="false" +BUILD_SNOWFLAKE="false" + +function quit { + echo "$1." + exit 1 +} + +if [[ "$1" == "removeAll" ]]; then + echo "removing golang, sources and generated files" + for folder in /tmp/android-toolchain-*; do + if [[ -d $folder ]]; then + rm -rf $folder + fi + done + if [[ -d "./out" ]]; then + rm -rf ./out + fi + + if [[ -d "./bin" ]]; then + rm -rf ./bin + fi + + if [[ -d "./golang" ]]; then + rm -rf ./golang + fi + + if [[ -d "./src" ]]; then + rm -rf ./src + fi + echo "Done!" + exit 0 + +elif [[ "$1" == "clean" ]]; then + echo "Cleaning up..." + for folder in /tmp/android-toolchain-*; do + if [[ -d $folder ]]; then + rm -rf $folder + fi + done + if [[ -d "./out" ]]; then + rm -rf ./out + fi + + if [[ -d "./bin" ]]; then + rm -rf ./bin + fi + echo "Done!" + exit 0 + +elif [[ "$1" == "shapeshifterlib" ]]; then + BUILD_LIBRARY="true" +elif [[ "$1" == "shapeshifter-dispatcher" ]]; then + BUILD_SHAPESHIFTER_DISPATCHER="true" +elif [[ "$1" == "snowflake-client" ]]; then + BUILD_SNOWFLAKE="true" + echo "BUILD_SNOWFLAKE!" +fi + + +if [ -z $ANDROID_NDK_HOME ]; then + echo "Android NDK path not specified!" + echo "Please set \$ANDROID_NDK_HOME before starting this script!" + exit 1; +fi + +if [[ ! -f ./bin/gomobile && $BUILD_LIBRARY == true ]]; then + echo "gomobile not installed" + echo please run "install_go.sh first" + exit 1 +fi + +# Our targets are x86, x86_64, armeabi, armeabi-v7a, armv8; +# To remove targets, simply delete them from the bracket. +# NOTE: We are only currently shipping the armeabi-v7a binary +# on Android, for space reasons. +targets=(386 x86_64 armv7 arm64) +export GOOS=android + +for arch in ${targets[@]}; do + # Initialize variables + go_arch=$arch + ndk_arch=$arch + ndk_platform="android-16" + suffix=$arch + + if [ "$arch" = "386" ]; then + export CGO_ENABLED=1 + ndk_arch="x86" + suffix="x86" + binary="i686-linux-android-gcc" + elif [ "$arch" = "x86_64" ]; then + ndk_platform="android-21" + ndk_arch="x86_64" + suffix="x86_64" + binary="x86_64-linux-android-gcc" + elif [ "$arch" = "armv5" ]; then + export GOARM=5 + export CGO_ENABLED=1 + go_arch="arm" + ndk_arch="arm" + suffix="armeabi" + binary="arm-linux-androideabi-gcc" + elif [ "$arch" = "armv7" ]; then + export GOARM=7 + export CGO_ENABLED=1 + go_arch="arm" + ndk_arch="arm" + suffix="armeabi-v7a" + binary="arm-linux-androideabi-gcc" + elif [ "$arch" = "arm64" ]; then + suffix="arm64-v8a" + ndk_platform="android-21" + binary="aarch64-linux-android-gcc" + elif [ "$arch" = "mips" ]; then + binary="mipsel-linux-android-gcc" + fi + export GOARCH=${go_arch} + export GOPATH=`pwd` + export NDK_TOOLCHAIN=/tmp/android-toolchain-${ndk_arch} + + # Only generate toolchain if it does not already exist + if [ ! -d $NDK_TOOLCHAIN ]; then + echo "Generating ${suffix} toolchain..." + $ANDROID_NDK_HOME/build/tools/make-standalone-toolchain.sh \ + --arch=${ndk_arch} --platform=${ndk_platform} --install-dir=$NDK_TOOLCHAIN || quit "Failed to generate toolchain" + echo "Toolchain generated!" + fi + + export CC=$NDK_TOOLCHAIN/bin/clang + echo "Starting compilation for $suffix..." + + + # if [[ BUILD_SNOWFLAKE == "true" ]]; then + echo "cross compiling snowflake-client executable..." + pwd + ./golang/go/bin/go get github.com/cyBerta/snowflake/client + ./golang/go/bin/go build -buildmode=pie -ldflags '-w -s -extldflags=-pie' -o ./out/${suffix}/piesnowflakeclient github.com/cyBerta/snowflake/client || quit "Failed to cross-compile shapeshifter-dispatcher" + # elif [[ BUILD_LIBRARY == "true" ]]; then + # echo "cross compiling shapeshifter lib..." + # ./bin/gomobile bind -target=android -o ./lib/shapeshifter.aar se.leap.bitmaskclient/shapeshifter/ + # cp lib/shapeshifter* ../shapeshifter/. + # #./android_build_shapeshifter_lib.sh || quit "Failed to cross-compile shapeshifter-dispatcher-library" + # elif [[ BUILD_SHAPESHIFTER_DISPATCHER == "true" ]]; then + # echo "cross compiling shapeshifter-dispatcher executable..." + # ./golang/go/bin/go build -buildmode=pie -ldflags '-w -s -extldflags=-pie' -o ./out/${suffix}/piedispatcher github.com/OperatorFoundation/shapeshifter-dispatcher/shapeshifter-dispatcher || quit "Failed to cross-compile shapeshifter-dispatcher" + # fi + echo "Build succeeded!" + +done \ No newline at end of file diff --git a/go/src/github.com/cyBerta/snowflake b/go/src/github.com/cyBerta/snowflake new file mode 160000 index 00000000..af6e2c30 --- /dev/null +++ b/go/src/github.com/cyBerta/snowflake @@ -0,0 +1 @@ +Subproject commit af6e2c30e1a6aacc6e7adf9a31df0a387891cc37 -- cgit v1.2.3 From 4b74dcacf76c22f747a03f2e4d9ff3068522a9fd Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 1 Jul 2021 17:05:01 +0200 Subject: remove files in go/src/github.com/cyBerta/snowflake --- go/src/github.com/cyBerta/snowflake | 1 - 1 file changed, 1 deletion(-) delete mode 160000 go/src/github.com/cyBerta/snowflake diff --git a/go/src/github.com/cyBerta/snowflake b/go/src/github.com/cyBerta/snowflake deleted file mode 160000 index af6e2c30..00000000 --- a/go/src/github.com/cyBerta/snowflake +++ /dev/null @@ -1 +0,0 @@ -Subproject commit af6e2c30e1a6aacc6e7adf9a31df0a387891cc37 -- cgit v1.2.3 From 466408cc641d0635e61e0ec26a4178c1ebdcedc5 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 1 Jul 2021 17:07:23 +0200 Subject: re-add snowflake submodule under different path --- .gitmodules | 3 +++ go/src/git.torproject.org/pluggable-transports/snowflake | 1 + 2 files changed, 4 insertions(+) create mode 160000 go/src/git.torproject.org/pluggable-transports/snowflake diff --git a/.gitmodules b/.gitmodules index de71e2e8..95869e38 100644 --- a/.gitmodules +++ b/.gitmodules @@ -69,3 +69,6 @@ [submodule "go/src/golang.org/x/tools"] path = go/src/golang.org/x/tools url = https://github.com/golang/tools.git +[submodule "go/src/git.torproject.org/pluggable-transports/snowflake"] + path = go/src/git.torproject.org/pluggable-transports/snowflake + url = https://github.com/cyBerta/snowflake.git diff --git a/go/src/git.torproject.org/pluggable-transports/snowflake b/go/src/git.torproject.org/pluggable-transports/snowflake new file mode 160000 index 00000000..af6e2c30 --- /dev/null +++ b/go/src/git.torproject.org/pluggable-transports/snowflake @@ -0,0 +1 @@ +Subproject commit af6e2c30e1a6aacc6e7adf9a31df0a387891cc37 -- cgit v1.2.3 From b5d2d4e7cbd190824d63056421a03a6c432f791f Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 1 Jul 2021 22:20:59 +0200 Subject: fix tor fallback check for failing api calls --- .../se/leap/bitmaskclient/providersetup/ProviderApiManager.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java index b6069982..fc1f0f59 100644 --- a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java +++ b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java @@ -330,8 +330,8 @@ public class ProviderApiManager extends ProviderApiManagerBase { responseString.contains(ERRORS) && PreferenceHelper.useTor(preferences) && EipStatus.getInstance().isDisconnected() && - TorStatusObservable.getStatus() == OFF || - TorStatusObservable.getStatus() == UNKOWN) { + (TorStatusObservable.getStatus() == OFF || + TorStatusObservable.getStatus() == UNKOWN)) { TorStatusObservable.setProxyPort(startTorProxy()); return downloadWithCommercialCA(stringUrl, provider, 1); } @@ -371,8 +371,8 @@ public class ProviderApiManager extends ProviderApiManagerBase { responseString.contains(ERRORS) && PreferenceHelper.useTor(preferences) && EipStatus.getInstance().isDisconnected() && - TorStatusObservable.getStatus() == OFF || - TorStatusObservable.getStatus() == UNKOWN) { + (TorStatusObservable.getStatus() == OFF || + TorStatusObservable.getStatus() == UNKOWN)) { TorStatusObservable.setProxyPort(startTorProxy()); return downloadFromUrlWithProviderCA(urlString, provider, 1); } -- cgit v1.2.3 From 7dfe33e09a97b7cde1c8637efd215dc2749f58c1 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Wed, 7 Jul 2021 16:59:15 +0200 Subject: remove snowflake again --- .gitmodules | 3 --- go/src/git.torproject.org/pluggable-transports/snowflake | 1 - 2 files changed, 4 deletions(-) delete mode 160000 go/src/git.torproject.org/pluggable-transports/snowflake diff --git a/.gitmodules b/.gitmodules index 95869e38..de71e2e8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -69,6 +69,3 @@ [submodule "go/src/golang.org/x/tools"] path = go/src/golang.org/x/tools url = https://github.com/golang/tools.git -[submodule "go/src/git.torproject.org/pluggable-transports/snowflake"] - path = go/src/git.torproject.org/pluggable-transports/snowflake - url = https://github.com/cyBerta/snowflake.git diff --git a/go/src/git.torproject.org/pluggable-transports/snowflake b/go/src/git.torproject.org/pluggable-transports/snowflake deleted file mode 160000 index af6e2c30..00000000 --- a/go/src/git.torproject.org/pluggable-transports/snowflake +++ /dev/null @@ -1 +0,0 @@ -Subproject commit af6e2c30e1a6aacc6e7adf9a31df0a387891cc37 -- cgit v1.2.3 From ec2f97f3c8f1e0c0eaa6a3ff90406545a3ad3076 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Wed, 7 Jul 2021 17:06:34 +0200 Subject: deinit tor-android --- .gitmodules | 3 +++ tor-android | 1 + 2 files changed, 4 insertions(+) create mode 160000 tor-android diff --git a/.gitmodules b/.gitmodules index de71e2e8..9b64e5a6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -69,3 +69,6 @@ [submodule "go/src/golang.org/x/tools"] path = go/src/golang.org/x/tools url = https://github.com/golang/tools.git +[submodule "tor-android"] + path = tor-android + url = https://0xacab.org/leap/android_snowflake/tor-android.git diff --git a/tor-android b/tor-android new file mode 160000 index 00000000..bcaf9c4f --- /dev/null +++ b/tor-android @@ -0,0 +1 @@ +Subproject commit bcaf9c4fd49ad2adcf224502a037575a66b1d116 -- cgit v1.2.3 From 97450f2f82e0771d6a98aea76fabb4f341cd1112 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Wed, 7 Jul 2021 17:08:41 +0200 Subject: deinit tor-android --- .gitmodules | 3 --- tor-android | 1 - 2 files changed, 4 deletions(-) delete mode 160000 tor-android diff --git a/.gitmodules b/.gitmodules index 9b64e5a6..de71e2e8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -69,6 +69,3 @@ [submodule "go/src/golang.org/x/tools"] path = go/src/golang.org/x/tools url = https://github.com/golang/tools.git -[submodule "tor-android"] - path = tor-android - url = https://0xacab.org/leap/android_snowflake/tor-android.git diff --git a/tor-android b/tor-android deleted file mode 160000 index bcaf9c4f..00000000 --- a/tor-android +++ /dev/null @@ -1 +0,0 @@ -Subproject commit bcaf9c4fd49ad2adcf224502a037575a66b1d116 -- cgit v1.2.3 From 2b1a25acb6673278278cda51a4ab988e2466f75e Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 9 Jul 2021 02:11:42 +0200 Subject: update tor-android --- tor-android | 1 + 1 file changed, 1 insertion(+) create mode 160000 tor-android diff --git a/tor-android b/tor-android new file mode 160000 index 00000000..c9406ec6 --- /dev/null +++ b/tor-android @@ -0,0 +1 @@ +Subproject commit c9406ec6b66228b81daf3684a28e748dfcb7d3c6 -- cgit v1.2.3 From 7919dfabc1a42c2dfdcf0ded326afad352096a06 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 9 Jul 2021 02:19:29 +0200 Subject: remove golang submodules --- .gitmodules | 67 ---------------------- go/src/github.com/OperatorFoundation/obfs4 | 1 - .../OperatorFoundation/shapeshifter-dispatcher | 1 - .../github.com/OperatorFoundation/shapeshifter-ipc | 1 - .../OperatorFoundation/shapeshifter-transports | 1 - go/src/github.com/aead/chacha20 | 1 - go/src/github.com/agl/ed25519 | 1 - go/src/github.com/dchest/siphash | 1 - go/src/github.com/shadowsocks/shadowsocks-go | 1 - go/src/golang.org/x/crypto | 1 - go/src/golang.org/x/net | 1 - go/src/golang.org/x/sys | 1 - go/src/golang.org/x/tools | 1 - go/src/se.leap.bitmaskclient/shapeshifter | 1 - 14 files changed, 80 deletions(-) delete mode 160000 go/src/github.com/OperatorFoundation/obfs4 delete mode 160000 go/src/github.com/OperatorFoundation/shapeshifter-dispatcher delete mode 160000 go/src/github.com/OperatorFoundation/shapeshifter-ipc delete mode 160000 go/src/github.com/OperatorFoundation/shapeshifter-transports delete mode 160000 go/src/github.com/aead/chacha20 delete mode 160000 go/src/github.com/agl/ed25519 delete mode 160000 go/src/github.com/dchest/siphash delete mode 160000 go/src/github.com/shadowsocks/shadowsocks-go delete mode 160000 go/src/golang.org/x/crypto delete mode 160000 go/src/golang.org/x/net delete mode 160000 go/src/golang.org/x/sys delete mode 160000 go/src/golang.org/x/tools delete mode 160000 go/src/se.leap.bitmaskclient/shapeshifter diff --git a/.gitmodules b/.gitmodules index de71e2e8..97688129 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,70 +2,3 @@ path = ics-openvpn branch = new_master url = https://leap.se/git/ics_openvpn.git - -[submodule "go/src/github.com/OperatorFoundation/obfs4"] - path = go/src/github.com/OperatorFoundation/obfs4 - url = https://github.com/OperatorFoundation/obfs4.git - ignore = untracked - -[submodule "go/src/github.com/OperatorFoundation/shapeshifter-dispatcher"] - path = go/src/github.com/OperatorFoundation/shapeshifter-dispatcher - url = https://0xacab.org/leap/shapeshifter-dispatcher.git - ignore = untracked - -[submodule "go/src/github.com/OperatorFoundation/shapeshifter-ipc"] - path = go/src/github.com/OperatorFoundation/shapeshifter-ipc - url = https://github.com/OperatorFoundation/shapeshifter-ipc.git - ignore = untracked - -[submodule "go/src/github.com/OperatorFoundation/shapeshifter-transports"] - path = go/src/github.com/OperatorFoundation/shapeshifter-transports - url = https://github.com/OperatorFoundation/shapeshifter-transports.git - ignore = untracked - -[submodule "go/src/github.com/aead/chacha20"] - path = go/src/github.com/aead/chacha20 - url = https://github.com/aead/chacha20.git - ignore = untracked - -[submodule "go/src/github.com/agl/ed25519"] - path = go/src/github.com/agl/ed25519 - url = https://github.com/agl/ed25519.git - ignore = untracked - -[submodule "go/src/github.com/dchest/siphash"] - path = go/src/github.com/dchest/siphash - url = https://github.com/dchest/siphash.git - ignore = untracked - -[submodule "go/src/github.com/shadowsocks/shadowsocks-go"] - path = go/src/github.com/shadowsocks/shadowsocks-go - url = https://github.com/shadowsocks/shadowsocks-go.git - ignore = untracked - -[submodule "go/src/github.com/willscott/goturn"] - path = go/src/github.com/willscott/goturn - url = https://github.com/willscott/goturn.git - ignore = untracked - - -[submodule "go/src/golang.org/x/crypto"] - path = go/src/golang.org/x/crypto - url = https://github.com/golang/crypto.git - ignore = untracked - -[submodule "go/src/golang.org/x/net"] - path = go/src/golang.org/x/net - url = https://github.com/golang/net.git - ignore = untracked - -[submodule "go/src/golang.org/x/sys"] - path = go/src/golang.org/x/sys - url = https://github.com/golang/sys.git - ignore = untracked -[submodule "go/src/se.leap.bitmaskclient/shapeshifter"] - path = go/src/se.leap.bitmaskclient/shapeshifter - url = https://0xacab.org/leap/shapeshifter.git -[submodule "go/src/golang.org/x/tools"] - path = go/src/golang.org/x/tools - url = https://github.com/golang/tools.git diff --git a/go/src/github.com/OperatorFoundation/obfs4 b/go/src/github.com/OperatorFoundation/obfs4 deleted file mode 160000 index 17f2cb99..00000000 --- a/go/src/github.com/OperatorFoundation/obfs4 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 17f2cb99c26454c519ca23185ee5dd3176a9363d diff --git a/go/src/github.com/OperatorFoundation/shapeshifter-dispatcher b/go/src/github.com/OperatorFoundation/shapeshifter-dispatcher deleted file mode 160000 index 7f7dd9fa..00000000 --- a/go/src/github.com/OperatorFoundation/shapeshifter-dispatcher +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7f7dd9fa3e11173dc5f54b9fca7e693cfe93cc87 diff --git a/go/src/github.com/OperatorFoundation/shapeshifter-ipc b/go/src/github.com/OperatorFoundation/shapeshifter-ipc deleted file mode 160000 index 11746ba9..00000000 --- a/go/src/github.com/OperatorFoundation/shapeshifter-ipc +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 11746ba927e07aaa79ead1342256419df25ad699 diff --git a/go/src/github.com/OperatorFoundation/shapeshifter-transports b/go/src/github.com/OperatorFoundation/shapeshifter-transports deleted file mode 160000 index b69856f6..00000000 --- a/go/src/github.com/OperatorFoundation/shapeshifter-transports +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b69856f6c6f6864167030359cb556143ecafb0a0 diff --git a/go/src/github.com/aead/chacha20 b/go/src/github.com/aead/chacha20 deleted file mode 160000 index 8b13a726..00000000 --- a/go/src/github.com/aead/chacha20 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8b13a72661dae6e9e5dea04f344f0dc95ea29547 diff --git a/go/src/github.com/agl/ed25519 b/go/src/github.com/agl/ed25519 deleted file mode 160000 index 5312a615..00000000 --- a/go/src/github.com/agl/ed25519 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5312a61534124124185d41f09206b9fef1d88403 diff --git a/go/src/github.com/dchest/siphash b/go/src/github.com/dchest/siphash deleted file mode 160000 index 34f20121..00000000 --- a/go/src/github.com/dchest/siphash +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 34f201214d993633bb24f418ba11736ab8b55aa7 diff --git a/go/src/github.com/shadowsocks/shadowsocks-go b/go/src/github.com/shadowsocks/shadowsocks-go deleted file mode 160000 index 6a03846c..00000000 --- a/go/src/github.com/shadowsocks/shadowsocks-go +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6a03846ca9c02d8e94142b3c72b3182207a414b4 diff --git a/go/src/golang.org/x/crypto b/go/src/golang.org/x/crypto deleted file mode 160000 index 87dc89f0..00000000 --- a/go/src/golang.org/x/crypto +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 87dc89f01550277dc22b74ffcf4cd89fa2f40f4c diff --git a/go/src/golang.org/x/net b/go/src/golang.org/x/net deleted file mode 160000 index ec77196f..00000000 --- a/go/src/golang.org/x/net +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ec77196f6094c3492a8b61f2c11cf937f78992ae diff --git a/go/src/golang.org/x/sys b/go/src/golang.org/x/sys deleted file mode 160000 index f89234f9..00000000 --- a/go/src/golang.org/x/sys +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f89234f9a2c237c4d4cf7b32e3d9fe2f7c4eacd7 diff --git a/go/src/golang.org/x/tools b/go/src/golang.org/x/tools deleted file mode 160000 index 2b779830..00000000 --- a/go/src/golang.org/x/tools +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2b779830f9d33eccacea7d9e741475351b225b1a diff --git a/go/src/se.leap.bitmaskclient/shapeshifter b/go/src/se.leap.bitmaskclient/shapeshifter deleted file mode 160000 index f50f9089..00000000 --- a/go/src/se.leap.bitmaskclient/shapeshifter +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f50f90891c1b0dfab1c717c19c183387d08b8780 -- cgit v1.2.3 From 768fc328d2af734681894e760aad3ab69ceaf5f6 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 9 Jul 2021 02:21:50 +0200 Subject: remove go directory --- go/android_build_core.sh | 22 --- go/android_build_golib.sh | 157 --------------------- go/android_build_shapeshifter.sh | 142 ------------------- go/android_build_web_core.sh | 22 --- go/install_go.sh | 43 ------ go/src/github.com/willscott/goturn | 1 - .../se.leap.bitmaskclient/pgpverify/pgpverify.go | 45 ------ 7 files changed, 432 deletions(-) delete mode 100755 go/android_build_core.sh delete mode 100755 go/android_build_golib.sh delete mode 100755 go/android_build_shapeshifter.sh delete mode 100755 go/android_build_web_core.sh delete mode 100755 go/install_go.sh delete mode 160000 go/src/github.com/willscott/goturn delete mode 100644 go/src/se.leap.bitmaskclient/pgpverify/pgpverify.go diff --git a/go/android_build_core.sh b/go/android_build_core.sh deleted file mode 100755 index 1a6af5b7..00000000 --- a/go/android_build_core.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -export GOPATH=`pwd` -export GO_LANG=`pwd`/golang/go/bin -export GO_COMPILED=`pwd`/bin -PATH="${GO_LANG}:${GO_COMPILED}:${PATH}" - -if [ -z $ANDROID_NDK_HOME ]; then - echo "Android NDK path not specified!" - echo "Please set \$ANDROID_NDK_HOME before starting this script!" - exit 1; -fi - -./golang/go/bin/go env -echo "getting gomobile..." -./golang/go/bin/go get golang.org/x/mobile/cmd/gomobile -echo "initiating gomobile..." -./bin/gomobile init -if [ ! -d ./lib ]; then mkdir ./lib; fi -echo "cross compiling bitmask core lib (shapeshifter)..." -./bin/gomobile bind -target=android -o ./lib/bitmask-core.aar se.leap.bitmaskclient/shapeshifter/ -cp lib/bitmask-core* ../bitmask-core/. \ No newline at end of file diff --git a/go/android_build_golib.sh b/go/android_build_golib.sh deleted file mode 100755 index a54a42af..00000000 --- a/go/android_build_golib.sh +++ /dev/null @@ -1,157 +0,0 @@ -#!/bin/bash - -# Copyright (C) 2016 Andrew Jiang (TunnelBear Inc.) -# Convenience script for generating shapeshifter-dispatcher binaries for Android devices -# adapted for Bitmask by cyberta - -BUILD_LIBRARY="false" -BUILD_SHAPESHIFTER_DISPATCHER="false" -BUILD_SNOWFLAKE="false" - -function quit { - echo "$1." - exit 1 -} - -if [[ "$1" == "removeAll" ]]; then - echo "removing golang, sources and generated files" - for folder in /tmp/android-toolchain-*; do - if [[ -d $folder ]]; then - rm -rf $folder - fi - done - if [[ -d "./out" ]]; then - rm -rf ./out - fi - - if [[ -d "./bin" ]]; then - rm -rf ./bin - fi - - if [[ -d "./golang" ]]; then - rm -rf ./golang - fi - - if [[ -d "./src" ]]; then - rm -rf ./src - fi - echo "Done!" - exit 0 - -elif [[ "$1" == "clean" ]]; then - echo "Cleaning up..." - for folder in /tmp/android-toolchain-*; do - if [[ -d $folder ]]; then - rm -rf $folder - fi - done - if [[ -d "./out" ]]; then - rm -rf ./out - fi - - if [[ -d "./bin" ]]; then - rm -rf ./bin - fi - echo "Done!" - exit 0 - -elif [[ "$1" == "shapeshifterlib" ]]; then - BUILD_LIBRARY="true" -elif [[ "$1" == "shapeshifter-dispatcher" ]]; then - BUILD_SHAPESHIFTER_DISPATCHER="true" -elif [[ "$1" == "snowflake-client" ]]; then - BUILD_SNOWFLAKE="true" - echo "BUILD_SNOWFLAKE!" -fi - - -if [ -z $ANDROID_NDK_HOME ]; then - echo "Android NDK path not specified!" - echo "Please set \$ANDROID_NDK_HOME before starting this script!" - exit 1; -fi - -if [[ ! -f ./bin/gomobile && $BUILD_LIBRARY == true ]]; then - echo "gomobile not installed" - echo please run "install_go.sh first" - exit 1 -fi - -# Our targets are x86, x86_64, armeabi, armeabi-v7a, armv8; -# To remove targets, simply delete them from the bracket. -# NOTE: We are only currently shipping the armeabi-v7a binary -# on Android, for space reasons. -targets=(386 x86_64 armv7 arm64) -export GOOS=android - -for arch in ${targets[@]}; do - # Initialize variables - go_arch=$arch - ndk_arch=$arch - ndk_platform="android-16" - suffix=$arch - - if [ "$arch" = "386" ]; then - export CGO_ENABLED=1 - ndk_arch="x86" - suffix="x86" - binary="i686-linux-android-gcc" - elif [ "$arch" = "x86_64" ]; then - ndk_platform="android-21" - ndk_arch="x86_64" - suffix="x86_64" - binary="x86_64-linux-android-gcc" - elif [ "$arch" = "armv5" ]; then - export GOARM=5 - export CGO_ENABLED=1 - go_arch="arm" - ndk_arch="arm" - suffix="armeabi" - binary="arm-linux-androideabi-gcc" - elif [ "$arch" = "armv7" ]; then - export GOARM=7 - export CGO_ENABLED=1 - go_arch="arm" - ndk_arch="arm" - suffix="armeabi-v7a" - binary="arm-linux-androideabi-gcc" - elif [ "$arch" = "arm64" ]; then - suffix="arm64-v8a" - ndk_platform="android-21" - binary="aarch64-linux-android-gcc" - elif [ "$arch" = "mips" ]; then - binary="mipsel-linux-android-gcc" - fi - export GOARCH=${go_arch} - export GOPATH=`pwd` - export NDK_TOOLCHAIN=/tmp/android-toolchain-${ndk_arch} - - # Only generate toolchain if it does not already exist - if [ ! -d $NDK_TOOLCHAIN ]; then - echo "Generating ${suffix} toolchain..." - $ANDROID_NDK_HOME/build/tools/make-standalone-toolchain.sh \ - --arch=${ndk_arch} --platform=${ndk_platform} --install-dir=$NDK_TOOLCHAIN || quit "Failed to generate toolchain" - echo "Toolchain generated!" - fi - - export CC=$NDK_TOOLCHAIN/bin/clang - echo "Starting compilation for $suffix..." - - - # if [[ BUILD_SNOWFLAKE == "true" ]]; then - echo "cross compiling snowflake-client executable..." - pwd - ./golang/go/bin/go get github.com/cyBerta/snowflake/client - ./golang/go/bin/go build -buildmode=pie -ldflags '-w -s -extldflags=-pie' -o ./out/${suffix}/piesnowflakeclient github.com/cyBerta/snowflake/client || quit "Failed to cross-compile shapeshifter-dispatcher" - # elif [[ BUILD_LIBRARY == "true" ]]; then - # echo "cross compiling shapeshifter lib..." - # ./bin/gomobile bind -target=android -o ./lib/shapeshifter.aar se.leap.bitmaskclient/shapeshifter/ - # cp lib/shapeshifter* ../shapeshifter/. - # #./android_build_shapeshifter_lib.sh || quit "Failed to cross-compile shapeshifter-dispatcher-library" - # elif [[ BUILD_SHAPESHIFTER_DISPATCHER == "true" ]]; then - # echo "cross compiling shapeshifter-dispatcher executable..." - # ./golang/go/bin/go build -buildmode=pie -ldflags '-w -s -extldflags=-pie' -o ./out/${suffix}/piedispatcher github.com/OperatorFoundation/shapeshifter-dispatcher/shapeshifter-dispatcher || quit "Failed to cross-compile shapeshifter-dispatcher" - # fi - echo "Build succeeded!" - -done \ No newline at end of file diff --git a/go/android_build_shapeshifter.sh b/go/android_build_shapeshifter.sh deleted file mode 100755 index e39f9eb1..00000000 --- a/go/android_build_shapeshifter.sh +++ /dev/null @@ -1,142 +0,0 @@ -#!/bin/bash - -# Copyright (C) 2016 Andrew Jiang (TunnelBear Inc.) -# Convenience script for generating shapeshifter-dispatcher binaries for Android devices -# adapted for Bitmask by cyberta - -BUILD_LIBRARY=false; - -function quit { - echo "$1." - exit 1 -} - -if [ "$1" == "removeAll" ]; then - echo "removing golang, sources and generated files" - for folder in /tmp/android-toolchain-*; do - if [[ -d $folder ]]; then - rm -rf $folder - fi - done - if [[ -d "./out" ]]; then - rm -rf ./out - fi - - if [[ -d "./bin" ]]; then - rm -rf ./bin - fi - - if [[ -d "./golang" ]]; then - rm -rf ./golang - fi - - if [[ -d "./src" ]]; then - rm -rf ./src - fi - echo "Done!" - -elif [ "$1" == "clean" ]; then - echo "Cleaning up..." - for folder in /tmp/android-toolchain-*; do - if [[ -d $folder ]]; then - rm -rf $folder - fi - done - if [[ -d "./out" ]]; then - rm -rf ./out - fi - - if [[ -d "./bin" ]]; then - rm -rf ./bin - fi - echo "Done!" -else - if [[ "$1" == "createLibrary" ]]; then - BUILD_LIBRARY=true - fi - - if [ -z $ANDROID_NDK_HOME ]; then - echo "Android NDK path not specified!" - echo "Please set \$ANDROID_NDK_HOME before starting this script!" - exit 1; - fi - - if [[ ! -f ./bin/gomobile && $BUILD_LIBRARY == true ]]; then - echo "gomobile not installed" - echo please run "install_go.sh first" - exit 1 - fi - - # Our targets are x86, x86_64, armeabi, armeabi-v7a, armv8; - # To remove targets, simply delete them from the bracket. - # NOTE: We are only currently shipping the armeabi-v7a binary - # on Android, for space reasons. - targets=(386 x86_64 armv7 arm64) - export GOOS=android - - for arch in ${targets[@]}; do - # Initialize variables - go_arch=$arch - ndk_arch=$arch - ndk_platform="android-16" - suffix=$arch - - if [ "$arch" = "386" ]; then - export CGO_ENABLED=1 - ndk_arch="x86" - suffix="x86" - binary="i686-linux-android-gcc" - elif [ "$arch" = "x86_64" ]; then - ndk_platform="android-21" - ndk_arch="x86_64" - suffix="x86_64" - binary="x86_64-linux-android-gcc" - elif [ "$arch" = "armv5" ]; then - export GOARM=5 - export CGO_ENABLED=1 - go_arch="arm" - ndk_arch="arm" - suffix="armeabi" - binary="arm-linux-androideabi-gcc" - elif [ "$arch" = "armv7" ]; then - export GOARM=7 - export CGO_ENABLED=1 - go_arch="arm" - ndk_arch="arm" - suffix="armeabi-v7a" - binary="arm-linux-androideabi-gcc" - elif [ "$arch" = "arm64" ]; then - suffix="arm64-v8a" - ndk_platform="android-21" - binary="aarch64-linux-android-gcc" - elif [ "$arch" = "mips" ]; then - binary="mipsel-linux-android-gcc" - fi - export GOARCH=${go_arch} - export GOPATH=`pwd` - export NDK_TOOLCHAIN=/tmp/android-toolchain-${ndk_arch} - - # Only generate toolchain if it does not already exist - if [ ! -d $NDK_TOOLCHAIN ]; then - echo "Generating ${suffix} toolchain..." - $ANDROID_NDK_HOME/build/tools/make-standalone-toolchain.sh \ - --arch=${ndk_arch} --platform=${ndk_platform} --install-dir=$NDK_TOOLCHAIN || quit "Failed to generate toolchain" - echo "Toolchain generated!" - fi - - export CC=$NDK_TOOLCHAIN/bin/clang - echo "Starting compilation for $suffix..." - - if [[ BUILD_LIBRARY ]]; then - echo "cross compiling shapeshifter lib..." - ./bin/gomobile bind -target=android -o ./lib/shapeshifter.aar se.leap.bitmaskclient/shapeshifter/ - cp lib/shapeshifter* ../shapeshifter/. - #./android_build_shapeshifter_lib.sh || quit "Failed to cross-compile shapeshifter-dispatcher-library" - - else - ./golang/go/bin/go build -buildmode=pie -ldflags '-w -s -extldflags=-pie' -o ./out/${suffix}/piedispatcher github.com/OperatorFoundation/shapeshifter-dispatcher/shapeshifter-dispatcher || quit "Failed to cross-compile shapeshifter-dispatcher" - fi - echo "Build succeeded!" - - done -fi \ No newline at end of file diff --git a/go/android_build_web_core.sh b/go/android_build_web_core.sh deleted file mode 100755 index 762d4dad..00000000 --- a/go/android_build_web_core.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -export GOPATH=`pwd` -export GO_LANG=`pwd`/golang/go/bin -export GO_COMPILED=`pwd`/bin -PATH="${GO_LANG}:${GO_COMPILED}:${PATH}" - -if [ -z $ANDROID_NDK_HOME ]; then - echo "Android NDK path not specified!" - echo "Please set \$ANDROID_NDK_HOME before starting this script!" - exit 1; -fi - -./golang/go/bin/go env -echo "getting gomobile..." -./golang/go/bin/go get golang.org/x/mobile/cmd/gomobile -echo "initiating gomobile..." -./bin/gomobile init -if [ ! -d ./lib ]; then mkdir ./lib; fi -echo "cross compiling bitmask web apk core lib (shapeshifter, pgpverify)..." -./bin/gomobile bind -target=android -o ./lib/bitmask-web-core.aar se.leap.bitmaskclient/shapeshifter/ se.leap.bitmaskclient/pgpverify -cp lib/bitmask-web-core* ../bitmask-web-core/. \ No newline at end of file diff --git a/go/install_go.sh b/go/install_go.sh deleted file mode 100755 index 59aab4f0..00000000 --- a/go/install_go.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -GO_VERSION=go1.14.2.linux-amd64 -EXPECTED_FP=6272d6e940ecb71ea5636ddb5fab3933e087c1356173c61f4a803895e947ebb3 - -if [[ $(ls -A ${GO_VERSION}.tar.gz) ]] -then - echo "reusing downloaded golang bundle" -else - echo "installing go lang bundle ${GO_VERSION}.tar.gz" - curl -o $GO_VERSION.tar.gz https://dl.google.com/go/$GO_VERSION.tar.gz - ACTUAL_FP=`sha256sum $GO_VERSION.tar.gz | cut -d " " -f1` - if [[ ! $ACTUAL_FP == $EXPECTED_FP ]] - then - echo "Download seems to be corrupted. Cancelling build." - return 1 - fi -fi - -if [[ -d ./golang ]] -then - if [[ $(ls -A ./golang/*) ]] - then - rm -r ./golang/* - fi -else - mkdir ./golang -fi -tar -C ./golang -xzf $GO_VERSION.tar.gz - - -export GOPATH=`pwd` -export GO_LANG=`pwd`/golang/go/bin -export GO_COMPILED=`pwd`/bin -export PATH="${GO_LANG}:${GO_COMPILED}:${PATH}" - -./golang/go/bin/go get golang.org/x/mobile/cmd/gomobile -./golang/go/bin/go env -echo "getting gomobile..." -./golang/go/bin/go get golang.org/x/mobile/cmd/gomobile -echo "initiating gomobile..." -./bin/gomobile init - diff --git a/go/src/github.com/willscott/goturn b/go/src/github.com/willscott/goturn deleted file mode 160000 index 19f41278..00000000 --- a/go/src/github.com/willscott/goturn +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 19f41278d0c9251d64e0ee29f37d51e87a24a97b diff --git a/go/src/se.leap.bitmaskclient/pgpverify/pgpverify.go b/go/src/se.leap.bitmaskclient/pgpverify/pgpverify.go deleted file mode 100644 index 1388a33c..00000000 --- a/go/src/se.leap.bitmaskclient/pgpverify/pgpverify.go +++ /dev/null @@ -1,45 +0,0 @@ -package pgpverify - -import ( - "os" - "strings" - - "golang.org/x/crypto/openpgp" -) - -// PgpVerifier - exported struct used for file verification -type PgpVerifier struct { - Logger Logger -} - -// Logger - logging interface -type Logger interface { - Log(msg string) -} - -// Verify checks if a file was signed with the correct pgp key -// using a PEM formatted signature and a corresponding public key -func (pgpv *PgpVerifier) Verify(signature string, publicKey string, targetPath string) bool { - keyRingReader := strings.NewReader(publicKey) - signatureReader := strings.NewReader(signature) - - verificationTarget, err := os.Open(targetPath) - if err != nil { - pgpv.Logger.Log("Open verification target: " + err.Error()) - return false - } - - keyring, err := openpgp.ReadArmoredKeyRing(keyRingReader) - if err != nil { - pgpv.Logger.Log("Read Armored Key Ring: " + err.Error()) - return false - } - _, err = openpgp.CheckArmoredDetachedSignature(keyring, verificationTarget, signatureReader) - if err != nil { - pgpv.Logger.Log("Verification failed: " + err.Error()) - return false - } - pgpv.Logger.Log("Successfully verified: entity.Identities") - return true -} - -- cgit v1.2.3 From 7d415341d903ce95943055b1983672e559c5903c Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 9 Jul 2021 02:31:08 +0200 Subject: add bitmaskcore as submodule --- .gitmodules | 3 +++ bitmaskcore | 1 + 2 files changed, 4 insertions(+) create mode 160000 bitmaskcore diff --git a/.gitmodules b/.gitmodules index 97688129..539b9aab 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,6 @@ path = ics-openvpn branch = new_master url = https://leap.se/git/ics_openvpn.git +[submodule "bitmaskcore"] + path = bitmaskcore + url = https://0xacab.org/leap/android_libs/bitmaskcore.git diff --git a/bitmaskcore b/bitmaskcore new file mode 160000 index 00000000..b161c764 --- /dev/null +++ b/bitmaskcore @@ -0,0 +1 @@ +Subproject commit b161c764317c64bd49fa75881a560d826cd3d80d -- cgit v1.2.3 From 0a071696893dbfe9679361ffaca6d71721cb5eae Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 9 Jul 2021 02:33:21 +0200 Subject: remove tor-android --- tor-android | 1 - 1 file changed, 1 deletion(-) delete mode 160000 tor-android diff --git a/tor-android b/tor-android deleted file mode 160000 index c9406ec6..00000000 --- a/tor-android +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c9406ec6b66228b81daf3684a28e748dfcb7d3c6 -- cgit v1.2.3 From 8d4767b99a79997f90a377d32880769e99bd713e Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 9 Jul 2021 02:43:45 +0200 Subject: re-add tor-android --- .gitmodules | 3 +++ tor-android | 1 + 2 files changed, 4 insertions(+) create mode 160000 tor-android diff --git a/.gitmodules b/.gitmodules index 539b9aab..b8f0e8d3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,6 @@ [submodule "bitmaskcore"] path = bitmaskcore url = https://0xacab.org/leap/android_libs/bitmaskcore.git +[submodule "tor-android"] + path = tor-android + url = https://0xacab.org/leap/android_snowflake/tor-android.git diff --git a/tor-android b/tor-android new file mode 160000 index 00000000..c9406ec6 --- /dev/null +++ b/tor-android @@ -0,0 +1 @@ +Subproject commit c9406ec6b66228b81daf3684a28e748dfcb7d3c6 -- cgit v1.2.3 From eb0d4f9877e3332124ece92646deabf908d9763c Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 9 Jul 2021 02:47:48 +0200 Subject: include gradle modules bitmaskcore and tor-android --- settings.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle b/settings.gradle index 08a7095e..203bf293 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':bitmask-core', ':bitmask-web-core' \ No newline at end of file +include ':app', ':bitmask-core', ':bitmask-web-core', ':bitmaskcore', ':tor-android' \ No newline at end of file -- cgit v1.2.3 From 6d410f65f1145fd69e9417a2a99e78581630d814 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 9 Jul 2021 04:03:23 +0200 Subject: build bitmaskcore in build_deps.sh --- scripts/build_deps.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/build_deps.sh b/scripts/build_deps.sh index 1785fca8..75fd52ea 100755 --- a/scripts/build_deps.sh +++ b/scripts/build_deps.sh @@ -9,7 +9,7 @@ SCRIPT_DIR=$(dirname "$0") BASE_DIR="$SCRIPT_DIR/.." DIR_OVPNASSETS=./ics-openvpn/main/build/ovpnassets DIR_OVPNLIBS=./ics-openvpn/main/build/intermediates/cmake/noovpn3/release/obj -DIR_GOLIBS=./go/lib/ +DIR_GOLIBS=./bitmaskcore/lib/ FILE_X86=./go/out/x86/piedispatcherlib FILE_ARM=./go/out/armeabi-v7a/piedispatcherlib @@ -32,9 +32,11 @@ then echo "Dirty build: Reusing go libraries" else echo "Clean build: compiling Go libraries" - cd ./go || quit "Directory go not found" - ./install_go.sh || quit "install_go.sh failed" - ./android_build_web_core.sh || quit "android_build_web_core.sh (shapeshifter + pgpverify) failed" - ./android_build_core.sh || quit "android build core (shapeshifter) failed" + cd ./bitmaskcore || quit "Directory go not found" + if [[ ! -d lib ]] + then + mkdir lib + fi + ./build_core.sh cd .. fi -- cgit v1.2.3 From cdefcb0d109d4558d5b9531bde2178a8b9bad0dc Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 9 Jul 2021 04:56:56 +0200 Subject: use bitmaskcore libs in android project --- app/build.gradle | 12 +++---- bitmask-core/bitmask-core-sources.jar | Bin 6880 -> 0 bytes bitmask-core/bitmask-core.aar | Bin 9015381 -> 0 bytes bitmask-core/build.gradle | 2 -- bitmask-web-core/bitmask-web-core-sources.jar | Bin 8696 -> 0 bytes bitmask-web-core/bitmask-web-core.aar | Bin 10633994 -> 0 bytes bitmask-web-core/build.gradle | 37 --------------------- .../bitmaskcore_arm64-sources.jar | Bin 0 -> 8156 bytes lib-bitmask-core-arm64/bitmaskcore_arm64.aar | Bin 0 -> 6083935 bytes lib-bitmask-core-arm64/build.gradle | 2 ++ lib-bitmask-core-armv7/bitmaskcore_arm-sources.jar | Bin 0 -> 8156 bytes lib-bitmask-core-armv7/bitmaskcore_arm.aar | Bin 0 -> 6236825 bytes lib-bitmask-core-armv7/build.gradle | 2 ++ lib-bitmask-core-web/bitmaskcore_web-sources.jar | Bin 0 -> 10013 bytes lib-bitmask-core-web/bitmaskcore_web.aar | Bin 0 -> 26629129 bytes lib-bitmask-core-web/build.gradle | 2 ++ lib-bitmask-core-x86/bitmaskcore_x86-sources.jar | Bin 0 -> 8156 bytes lib-bitmask-core-x86/bitmaskcore_x86.aar | Bin 0 -> 6639027 bytes lib-bitmask-core-x86/build.gradle | 2 ++ .../bitmaskcore_x86_64-sources.jar | Bin 0 -> 8156 bytes lib-bitmask-core-x86_64/bitmaskcore_x86_64.aar | Bin 0 -> 6823506 bytes lib-bitmask-core-x86_64/build.gradle | 2 ++ lib-bitmask-core/bitmaskcore-sources.jar | Bin 0 -> 8156 bytes lib-bitmask-core/bitmaskcore.aar | Bin 0 -> 25748179 bytes lib-bitmask-core/build.gradle | 37 +++++++++++++++++++++ scripts/build_deps.sh | 16 +++++++-- settings.gradle | 2 +- 27 files changed, 68 insertions(+), 48 deletions(-) delete mode 100644 bitmask-core/bitmask-core-sources.jar delete mode 100644 bitmask-core/bitmask-core.aar delete mode 100644 bitmask-core/build.gradle delete mode 100644 bitmask-web-core/bitmask-web-core-sources.jar delete mode 100644 bitmask-web-core/bitmask-web-core.aar delete mode 100644 bitmask-web-core/build.gradle create mode 100644 lib-bitmask-core-arm64/bitmaskcore_arm64-sources.jar create mode 100644 lib-bitmask-core-arm64/bitmaskcore_arm64.aar create mode 100644 lib-bitmask-core-arm64/build.gradle create mode 100644 lib-bitmask-core-armv7/bitmaskcore_arm-sources.jar create mode 100644 lib-bitmask-core-armv7/bitmaskcore_arm.aar create mode 100644 lib-bitmask-core-armv7/build.gradle create mode 100644 lib-bitmask-core-web/bitmaskcore_web-sources.jar create mode 100644 lib-bitmask-core-web/bitmaskcore_web.aar create mode 100644 lib-bitmask-core-web/build.gradle create mode 100644 lib-bitmask-core-x86/bitmaskcore_x86-sources.jar create mode 100644 lib-bitmask-core-x86/bitmaskcore_x86.aar create mode 100644 lib-bitmask-core-x86/build.gradle create mode 100644 lib-bitmask-core-x86_64/bitmaskcore_x86_64-sources.jar create mode 100644 lib-bitmask-core-x86_64/bitmaskcore_x86_64.aar create mode 100644 lib-bitmask-core-x86_64/build.gradle create mode 100644 lib-bitmask-core/bitmaskcore-sources.jar create mode 100644 lib-bitmask-core/bitmaskcore.aar create mode 100644 lib-bitmask-core/build.gradle diff --git a/app/build.gradle b/app/build.gradle index 7f4f667e..87c28be2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -394,12 +394,12 @@ dependencies { implementation 'info.guardianproject:tor-android:0.4.5.7' implementation 'info.guardianproject:jtorctl:0.4.5.7' - fatwebImplementation project(path: ':bitmask-web-core') - fatImplementation project(path: ':bitmask-core') - x86Implementation project(path: ':bitmask-core') - x86_64Implementation project(path: ':bitmask-core') - armv7Implementation project(path: ':bitmask-core') - arm64Implementation project(path: ':bitmask-core') + fatwebImplementation project(path: ':lib-bitmask-core-web') + fatImplementation project(path: ':lib-bitmask-core') + x86Implementation project(path: ':lib-bitmask-core-x86') + x86_64Implementation project(path: ':lib-bitmask-core-x86_64') + armv7Implementation project(path: ':lib-bitmask-core-armv7') + arm64Implementation project(path: ':lib-bitmask-core-arm64') } android.applicationVariants.all { variant -> diff --git a/bitmask-core/bitmask-core-sources.jar b/bitmask-core/bitmask-core-sources.jar deleted file mode 100644 index adf7f860..00000000 Binary files a/bitmask-core/bitmask-core-sources.jar and /dev/null differ diff --git a/bitmask-core/bitmask-core.aar b/bitmask-core/bitmask-core.aar deleted file mode 100644 index bceec02d..00000000 Binary files a/bitmask-core/bitmask-core.aar and /dev/null differ diff --git a/bitmask-core/build.gradle b/bitmask-core/build.gradle deleted file mode 100644 index 51d38614..00000000 --- a/bitmask-core/build.gradle +++ /dev/null @@ -1,2 +0,0 @@ -configurations.maybeCreate("default") -artifacts.add("default", file('bitmask-core.aar')) \ No newline at end of file diff --git a/bitmask-web-core/bitmask-web-core-sources.jar b/bitmask-web-core/bitmask-web-core-sources.jar deleted file mode 100644 index 64edeb9b..00000000 Binary files a/bitmask-web-core/bitmask-web-core-sources.jar and /dev/null differ diff --git a/bitmask-web-core/bitmask-web-core.aar b/bitmask-web-core/bitmask-web-core.aar deleted file mode 100644 index 0e5108c0..00000000 Binary files a/bitmask-web-core/bitmask-web-core.aar and /dev/null differ diff --git a/bitmask-web-core/build.gradle b/bitmask-web-core/build.gradle deleted file mode 100644 index 650f38d6..00000000 --- a/bitmask-web-core/build.gradle +++ /dev/null @@ -1,37 +0,0 @@ -/*apply plugin: 'com.android.library' - -android { - compileSdkVersion 28 - buildToolsVersion "29.0.1" - - - defaultConfig { - minSdkVersion 16 - targetSdkVersion 28 - versionCode 1 - versionName "1.0" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles 'consumer-rules.pro' - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - -} - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - - implementation 'androidx.appcompat:appcompat:1.2.0' - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test.ext:junit:1.1.0' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' -} -*/ -configurations.maybeCreate("default") -artifacts.add("default", file('bitmask-web-core.aar')) \ No newline at end of file diff --git a/lib-bitmask-core-arm64/bitmaskcore_arm64-sources.jar b/lib-bitmask-core-arm64/bitmaskcore_arm64-sources.jar new file mode 100644 index 00000000..903904ed Binary files /dev/null and b/lib-bitmask-core-arm64/bitmaskcore_arm64-sources.jar differ diff --git a/lib-bitmask-core-arm64/bitmaskcore_arm64.aar b/lib-bitmask-core-arm64/bitmaskcore_arm64.aar new file mode 100644 index 00000000..bf1b3fda Binary files /dev/null and b/lib-bitmask-core-arm64/bitmaskcore_arm64.aar differ diff --git a/lib-bitmask-core-arm64/build.gradle b/lib-bitmask-core-arm64/build.gradle new file mode 100644 index 00000000..91598024 --- /dev/null +++ b/lib-bitmask-core-arm64/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('bitmaskcore_arm64.aar')) \ No newline at end of file diff --git a/lib-bitmask-core-armv7/bitmaskcore_arm-sources.jar b/lib-bitmask-core-armv7/bitmaskcore_arm-sources.jar new file mode 100644 index 00000000..903904ed Binary files /dev/null and b/lib-bitmask-core-armv7/bitmaskcore_arm-sources.jar differ diff --git a/lib-bitmask-core-armv7/bitmaskcore_arm.aar b/lib-bitmask-core-armv7/bitmaskcore_arm.aar new file mode 100644 index 00000000..f56b2b2c Binary files /dev/null and b/lib-bitmask-core-armv7/bitmaskcore_arm.aar differ diff --git a/lib-bitmask-core-armv7/build.gradle b/lib-bitmask-core-armv7/build.gradle new file mode 100644 index 00000000..b48f6c42 --- /dev/null +++ b/lib-bitmask-core-armv7/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('bitmaskcore_arm.aar')) \ No newline at end of file diff --git a/lib-bitmask-core-web/bitmaskcore_web-sources.jar b/lib-bitmask-core-web/bitmaskcore_web-sources.jar new file mode 100644 index 00000000..7507016b Binary files /dev/null and b/lib-bitmask-core-web/bitmaskcore_web-sources.jar differ diff --git a/lib-bitmask-core-web/bitmaskcore_web.aar b/lib-bitmask-core-web/bitmaskcore_web.aar new file mode 100644 index 00000000..154101b3 Binary files /dev/null and b/lib-bitmask-core-web/bitmaskcore_web.aar differ diff --git a/lib-bitmask-core-web/build.gradle b/lib-bitmask-core-web/build.gradle new file mode 100644 index 00000000..da284c75 --- /dev/null +++ b/lib-bitmask-core-web/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('bitmaskcore_web.aar')) \ No newline at end of file diff --git a/lib-bitmask-core-x86/bitmaskcore_x86-sources.jar b/lib-bitmask-core-x86/bitmaskcore_x86-sources.jar new file mode 100644 index 00000000..903904ed Binary files /dev/null and b/lib-bitmask-core-x86/bitmaskcore_x86-sources.jar differ diff --git a/lib-bitmask-core-x86/bitmaskcore_x86.aar b/lib-bitmask-core-x86/bitmaskcore_x86.aar new file mode 100644 index 00000000..64867109 Binary files /dev/null and b/lib-bitmask-core-x86/bitmaskcore_x86.aar differ diff --git a/lib-bitmask-core-x86/build.gradle b/lib-bitmask-core-x86/build.gradle new file mode 100644 index 00000000..87add92f --- /dev/null +++ b/lib-bitmask-core-x86/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('bitmaskcore_x86.aar')) \ No newline at end of file diff --git a/lib-bitmask-core-x86_64/bitmaskcore_x86_64-sources.jar b/lib-bitmask-core-x86_64/bitmaskcore_x86_64-sources.jar new file mode 100644 index 00000000..903904ed Binary files /dev/null and b/lib-bitmask-core-x86_64/bitmaskcore_x86_64-sources.jar differ diff --git a/lib-bitmask-core-x86_64/bitmaskcore_x86_64.aar b/lib-bitmask-core-x86_64/bitmaskcore_x86_64.aar new file mode 100644 index 00000000..6579fa2f Binary files /dev/null and b/lib-bitmask-core-x86_64/bitmaskcore_x86_64.aar differ diff --git a/lib-bitmask-core-x86_64/build.gradle b/lib-bitmask-core-x86_64/build.gradle new file mode 100644 index 00000000..bc8181b3 --- /dev/null +++ b/lib-bitmask-core-x86_64/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('bitmaskcore_x86_64.aar')) \ No newline at end of file diff --git a/lib-bitmask-core/bitmaskcore-sources.jar b/lib-bitmask-core/bitmaskcore-sources.jar new file mode 100644 index 00000000..903904ed Binary files /dev/null and b/lib-bitmask-core/bitmaskcore-sources.jar differ diff --git a/lib-bitmask-core/bitmaskcore.aar b/lib-bitmask-core/bitmaskcore.aar new file mode 100644 index 00000000..19da0b2a Binary files /dev/null and b/lib-bitmask-core/bitmaskcore.aar differ diff --git a/lib-bitmask-core/build.gradle b/lib-bitmask-core/build.gradle new file mode 100644 index 00000000..0b2ba086 --- /dev/null +++ b/lib-bitmask-core/build.gradle @@ -0,0 +1,37 @@ +/*apply plugin: 'com.android.library' + +android { + compileSdkVersion 28 + buildToolsVersion "29.0.1" + + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles 'consumer-rules.pro' + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' +} +*/ +configurations.maybeCreate("default") +artifacts.add("default", file('bitmaskcore.aar')) \ No newline at end of file diff --git a/scripts/build_deps.sh b/scripts/build_deps.sh index 75fd52ea..1d8d26d5 100755 --- a/scripts/build_deps.sh +++ b/scripts/build_deps.sh @@ -37,6 +37,18 @@ else then mkdir lib fi - ./build_core.sh - cd .. + ./build_core.sh || quit "failed to build bitmaskcore" + cp lib/bitmaskcore.aar ../lib-bitmask-core/. + cp lib/bitmaskcore-sources.jar ../lib-bitmask-core/. + cp lib/bitmaskcore_web.aar ../lib-bitmask-core-web/. + cp lib/bitmaskcore_web-sources.jar ../lib-bitmask-core-web/. + cp lib/bitmaskcore_arm.aar ../lib-bitmask-core-armv7/. + cp lib/bitmaskcore_arm-sources.jar ../lib-bitmask-core-armv7/. + cp lib/bitmaskcore_arm64.aar ../lib-bitmask-core-arm64/. + cp lib/bitmaskcore_arm64-sources.jar ../lib-bitmask-core-arm64/. + cp lib/bitmaskcore_x86.aar ../lib-bitmask-core-x86/. + cp lib/bitmaskcore_x86-sources.jar ../lib-bitmask-core-x86/. + cp lib/bitmaskcore_x86_64.aar ../lib-bitmask-core-x86_64/. + cp lib/bitmaskcore_x86_64-sources.jar ../lib-bitmask-core-x86_64/. + fi diff --git a/settings.gradle b/settings.gradle index 203bf293..661a41c2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':bitmask-core', ':bitmask-web-core', ':bitmaskcore', ':tor-android' \ No newline at end of file +include ':app', ':lib-bitmask-core', ':lib-bitmask-core-web', ':lib-bitmask-core-arm64', ':lib-bitmask-core-armv7', ':lib-bitmask-core-x86', ':lib-bitmask-core-x86_64', ':bitmaskcore', ':tor-android' \ No newline at end of file -- cgit v1.2.3 From 53c687fd931d6789909e5276c8a395106c3fc00e Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 9 Jul 2021 15:44:48 +0200 Subject: update bitmaskcore --- bitmaskcore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bitmaskcore b/bitmaskcore index b161c764..fe20fbd9 160000 --- a/bitmaskcore +++ b/bitmaskcore @@ -1 +1 @@ -Subproject commit b161c764317c64bd49fa75881a560d826cd3d80d +Subproject commit fe20fbd986270c881b3be0259e463e1a8b524b4a -- cgit v1.2.3 From aadae76e5641684cf854b6193f3015be0f7a1b0b Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 10 Jul 2021 03:39:10 +0200 Subject: update tor-android --- .../leap/bitmaskclient/tor/IPtProxyInterface.java | 72 ++++++++++++++++++++++ tor-android | 2 +- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyInterface.java diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyInterface.java b/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyInterface.java new file mode 100644 index 00000000..0203e082 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyInterface.java @@ -0,0 +1,72 @@ +package se.leap.bitmaskclient.tor; + +public interface IPtProxyInterface { + + /** + * StateLocation - Override TOR_PT_STATE_LOCATION, which defaults to "$TMPDIR/pt_state". + */ + void setStateLocation(String v); + + /** + * StateLocation - Override TOR_PT_STATE_LOCATION, which defaults to "$TMPDIR/pt_state". + */ + String getStateLocation(); + + /** + * SnowflakePort - Port where Snowflake will provide its service. + Only use this property after calling StartSnowflake! It might have changed after that! + */ + long snowflakePort(); + + /** + * StartSnowflake - Start the Snowflake client. + + @param ice Comma-separated list of ICE servers. + + @param url URL of signaling broker. + + @param front Front domain. + + @param logFile Name of log file. OPTIONAL + + @param logToStateDir Resolve the log file relative to Tor's PT state dir. + + @param keepLocalAddresses Keep local LAN address ICE candidates. + + @param unsafeLogging Prevent logs from being scrubbed. + + @param maxPeers Capacity for number of multiplexed WebRTC peers. DEFAULTs to 1 if less than that. + + @return Port number where Snowflake will listen on, if no error happens during start up. + */ + long startSnowflake(String ice, String url, String front, String logFile, boolean logToStateDir, boolean keepLocalAddresses, boolean unsafeLogging, long maxPeers); + + /** + * StartSnowflakeProxy - Start the Snowflake proxy. + + @param capacity Maximum concurrent clients. OPTIONAL. Defaults to 10, if 0. + + @param broker Broker URL. OPTIONAL. Defaults to https://snowflake-broker.bamsoftware.com/, if empty. + + @param relay WebSocket relay URL. OPTIONAL. Defaults to wss://snowflake.bamsoftware.com/, if empty. + + @param stun STUN URL. OPTIONAL. Defaults to stun:stun.stunprotocol.org:3478, if empty. + + @param logFile Name of log file. OPTIONAL + + @param keepLocalAddresses Keep local LAN address ICE candidates. + + @param unsafeLogging Prevent logs from being scrubbed. + */ + void startSnowflakeProxy(long capacity, String broker, String relay, String stun, String logFile, boolean keepLocalAddresses, boolean unsafeLogging); + + /** + * StopSnowflake - Stop the Snowflake client. + */ + void stopSnowflake(); + + /** + * StopSnowflakeProxy - Stop the Snowflake proxy. + */ + void stopSnowflakeProxy(); +} diff --git a/tor-android b/tor-android index c9406ec6..32621bce 160000 --- a/tor-android +++ b/tor-android @@ -1 +1 @@ -Subproject commit c9406ec6b66228b81daf3684a28e748dfcb7d3c6 +Subproject commit 32621bceff787903e2744adffea7f0bd3bcd8858 -- cgit v1.2.3 From 4f082c60a4ae5015d9624c4d6c8385484e7168a1 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 10 Jul 2021 03:44:20 +0200 Subject: update tor-android --- tor-android | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tor-android b/tor-android index 32621bce..8fba55cd 160000 --- a/tor-android +++ b/tor-android @@ -1 +1 @@ -Subproject commit 32621bceff787903e2744adffea7f0bd3bcd8858 +Subproject commit 8fba55cdbb80765d755455a63138864d9536189d -- cgit v1.2.3 From 6a3b5094cbc347bc9119214f8ea074ce53452cdb Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sun, 11 Jul 2021 16:31:30 +0200 Subject: inject IPtProxy in TorService --- app/build.gradle | 8 +++-- .../bitmaskclient/providersetup/ProviderAPI.java | 2 ++ .../se/leap/bitmaskclient/tor/IPtProxyWrapper.java | 40 ++++++++++++++++++++++ settings.gradle | 2 +- 4 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyWrapper.java diff --git a/app/build.gradle b/app/build.gradle index 87c28be2..e436df38 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -250,6 +250,7 @@ android { ] jniLibs.srcDirs = ['../ics-openvpn/main/build/intermediates/cmake/skeletonRelease/obj/'] jni.srcDirs = [] //disable automatic ndk-build + } debug { assets.srcDirs = ['src/debug/assets', @@ -391,8 +392,11 @@ dependencies { implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0' implementation 'de.hdodenhof:circleimageview:3.1.0' - implementation 'info.guardianproject:tor-android:0.4.5.7' - implementation 'info.guardianproject:jtorctl:0.4.5.7' + + + //implementation 'info.guardianproject:tor-android:0.4.5.7' + //implementation 'info.guardianproject:jtorctl:0.4.5.7' + implementation project(path: ':tor-android:tor-android-binary') fatwebImplementation project(path: ':lib-bitmask-core-web') fatImplementation project(path: ':lib-bitmask-core') diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java index dcbe9636..9ba64b31 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java @@ -39,6 +39,7 @@ import java.util.concurrent.LinkedBlockingQueue; import se.leap.bitmaskclient.base.utils.PreferenceHelper; import se.leap.bitmaskclient.providersetup.connectivity.OkHttpClientGenerator; +import se.leap.bitmaskclient.tor.IPtProxyWrapper; import se.leap.bitmaskclient.tor.TorNotificationManager; import se.leap.bitmaskclient.tor.TorStatusObservable; @@ -202,6 +203,7 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB try { if (torServiceConnection == null) { Log.d(TAG, "serviceConnection is still null"); + TorService.setIPtProxy(new IPtProxyWrapper()); torServiceConnection = new TorServiceConnection(context); } } catch (InterruptedException | IllegalStateException e) { diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyWrapper.java b/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyWrapper.java new file mode 100644 index 00000000..c7ca165e --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyWrapper.java @@ -0,0 +1,40 @@ +package se.leap.bitmaskclient.tor; + +import IPtProxy.IPtProxy; + +public class IPtProxyWrapper implements IPtProxyInterface { + @Override + public void setStateLocation(String location) { + IPtProxy.setStateLocation(location); + } + + @Override + public String getStateLocation() { + return IPtProxy.getStateLocation(); + } + + @Override + public long snowflakePort() { + return IPtProxy.snowflakePort(); + } + + @Override + public long startSnowflake(String ice, String url, String front, String logFile, boolean logToStateDir, boolean keepLocalAddresses, boolean unsafeLogging, long maxPeers) { + return IPtProxy.startSnowflake(ice, url, front, logFile, logToStateDir, keepLocalAddresses, unsafeLogging, maxPeers); + } + + @Override + public void startSnowflakeProxy(long capacity, String broker, String relay, String stun, String logFile, boolean keepLocalAddresses, boolean unsafeLogging) { + IPtProxy.startSnowflakeProxy(capacity, broker, relay, stun, logFile, keepLocalAddresses, unsafeLogging); + } + + @Override + public void stopSnowflake() { + IPtProxy.stopSnowflake(); + } + + @Override + public void stopSnowflakeProxy() { + IPtProxy.stopSnowflakeProxy(); + } +} diff --git a/settings.gradle b/settings.gradle index 661a41c2..fe0a7401 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':lib-bitmask-core', ':lib-bitmask-core-web', ':lib-bitmask-core-arm64', ':lib-bitmask-core-armv7', ':lib-bitmask-core-x86', ':lib-bitmask-core-x86_64', ':bitmaskcore', ':tor-android' \ No newline at end of file +include ':app', ':lib-bitmask-core', ':lib-bitmask-core-web', ':lib-bitmask-core-arm64', ':lib-bitmask-core-armv7', ':lib-bitmask-core-x86', ':lib-bitmask-core-x86_64', ':tor-android:tor-android-binary' \ No newline at end of file -- cgit v1.2.3 From 42eda24716f12d2357cec39ad7048a2bfb58cdd3 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sun, 11 Jul 2021 16:31:55 +0200 Subject: update tor-service --- tor-android | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tor-android b/tor-android index 8fba55cd..57814f3d 160000 --- a/tor-android +++ b/tor-android @@ -1 +1 @@ -Subproject commit 8fba55cdbb80765d755455a63138864d9536189d +Subproject commit 57814f3dc217df37885c5d89e546ab2a440bb1d9 -- cgit v1.2.3 From 02d09ff48aed5374e331f2609d27879cd801b9c3 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sun, 11 Jul 2021 19:16:39 +0200 Subject: update tor-android --- app/src/main/assets/fronts | 6 ++++++ .../main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java | 4 ++++ tor-android | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 app/src/main/assets/fronts create mode 100644 app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java diff --git a/app/src/main/assets/fronts b/app/src/main/assets/fronts new file mode 100644 index 00000000..937332df --- /dev/null +++ b/app/src/main/assets/fronts @@ -0,0 +1,6 @@ +snowflake-target https://snowflake-broker.torproject.net.global.prod.fastly.net/ +snowflake-front cdn.sstatic.net +snowflake-stun stun:stun.stunprotocol.org:3478 +moat-cdn https://d50gd378qj74g.cloudfront.net/ +moat-url https://moat.torproject.org.global.prod.fastly.net/ +moat-front cdn.sstatic.net diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java b/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java new file mode 100644 index 00000000..9ed805e4 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java @@ -0,0 +1,4 @@ +package se.leap.bitmaskclient.tor; + +public class ClientTransportPlugin { +} diff --git a/tor-android b/tor-android index 57814f3d..d757fe8e 160000 --- a/tor-android +++ b/tor-android @@ -1 +1 @@ -Subproject commit 57814f3dc217df37885c5d89e546ab2a440bb1d9 +Subproject commit d757fe8eeb98072fc4e4602c398012352b59893a -- cgit v1.2.3 From 8dc39ff8e4684cbd9235824c58a5deb70fb818ee Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sun, 11 Jul 2021 19:25:50 +0200 Subject: implement ClientTransportPluginInterface to start / stop snowflake client for tor --- .../bitmaskclient/providersetup/ProviderAPI.java | 4 +- .../bitmaskclient/tor/ClientTransportPlugin.java | 93 +++++++++++++++++++++- .../leap/bitmaskclient/tor/IPtProxyInterface.java | 72 ----------------- .../se/leap/bitmaskclient/tor/IPtProxyWrapper.java | 40 ---------- 4 files changed, 94 insertions(+), 115 deletions(-) delete mode 100644 app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyInterface.java delete mode 100644 app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyWrapper.java diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java index 9ba64b31..f2376568 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java @@ -39,7 +39,7 @@ import java.util.concurrent.LinkedBlockingQueue; import se.leap.bitmaskclient.base.utils.PreferenceHelper; import se.leap.bitmaskclient.providersetup.connectivity.OkHttpClientGenerator; -import se.leap.bitmaskclient.tor.IPtProxyWrapper; +import se.leap.bitmaskclient.tor.ClientTransportPlugin; import se.leap.bitmaskclient.tor.TorNotificationManager; import se.leap.bitmaskclient.tor.TorStatusObservable; @@ -203,7 +203,7 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB try { if (torServiceConnection == null) { Log.d(TAG, "serviceConnection is still null"); - TorService.setIPtProxy(new IPtProxyWrapper()); + TorService.setClientTransportPlugin(new ClientTransportPlugin(context.getApplicationContext())); torServiceConnection = new TorServiceConnection(context); } } catch (InterruptedException | IllegalStateException e) { diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java b/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java index 9ed805e4..9e3828de 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java @@ -1,4 +1,95 @@ package se.leap.bitmaskclient.tor; -public class ClientTransportPlugin { +import android.content.Context; +import android.util.Log; + +import androidx.annotation.Nullable; + +import org.torproject.jni.ClientTransportPluginInterface; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.ref.WeakReference; +import java.util.HashMap; + +import IPtProxy.IPtProxy; + +public class ClientTransportPlugin implements ClientTransportPluginInterface { + public static String TAG = ClientTransportPlugin.class.getSimpleName(); + + private HashMap mFronts; + private final WeakReference contextRef; + private long snowflakePort = -1; + + public ClientTransportPlugin(Context context) { + this.contextRef = new WeakReference<>(context); + loadCdnFronts(context); + } + + @Override + public void start() { + Context context = contextRef.get(); + if (context == null) { + return; + } + File logfile = new File(context.getApplicationContext().getCacheDir(), "snowflake.log"); + Log.d(TAG, "logfile at " + logfile.getAbsolutePath()); + if (!logfile.exists()) { + try { + logfile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + //this is using the current, default Tor snowflake infrastructure + String target = getCdnFront("snowflake-target"); + String front = getCdnFront("snowflake-front"); + String stunServer = getCdnFront("snowflake-stun"); + Log.d(TAG, "startSnowflake. target: " + target + ", front:" + front + ", stunServer" + stunServer); + snowflakePort = IPtProxy.startSnowflake( stunServer, target, front, logfile.getAbsolutePath(), false, false, true, 1); + Log.d(TAG, "startSnowflake running on port: " + snowflakePort); + } + + @Override + public void stop() { + IPtProxy.stopSnowflake(); + snowflakePort = -1; + } + + @Override + public String getTorrc() { + return "UseBridges 1\n" + + "ClientTransportPlugin snowflake socks5 127.0.0.1:" + snowflakePort + "\n" + + "Bridge snowflake 192.0.2.3:1"; + } + + private void loadCdnFronts(Context context) { + if (mFronts == null) { + mFronts = new HashMap<>(); + } + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(context.getAssets().open("fronts"))); + String line; + while (true) { + line = reader.readLine(); + if (line == null) break; + String[] front = line.split(" "); + mFronts.put(front[0], front[1]); + Log.d(TAG, "front: " + front[0] + ", " + front[1]); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Nullable + private String getCdnFront(String service) { + if (mFronts != null) { + return mFronts.get(service); + } + return null; + } } diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyInterface.java b/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyInterface.java deleted file mode 100644 index 0203e082..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyInterface.java +++ /dev/null @@ -1,72 +0,0 @@ -package se.leap.bitmaskclient.tor; - -public interface IPtProxyInterface { - - /** - * StateLocation - Override TOR_PT_STATE_LOCATION, which defaults to "$TMPDIR/pt_state". - */ - void setStateLocation(String v); - - /** - * StateLocation - Override TOR_PT_STATE_LOCATION, which defaults to "$TMPDIR/pt_state". - */ - String getStateLocation(); - - /** - * SnowflakePort - Port where Snowflake will provide its service. - Only use this property after calling StartSnowflake! It might have changed after that! - */ - long snowflakePort(); - - /** - * StartSnowflake - Start the Snowflake client. - - @param ice Comma-separated list of ICE servers. - - @param url URL of signaling broker. - - @param front Front domain. - - @param logFile Name of log file. OPTIONAL - - @param logToStateDir Resolve the log file relative to Tor's PT state dir. - - @param keepLocalAddresses Keep local LAN address ICE candidates. - - @param unsafeLogging Prevent logs from being scrubbed. - - @param maxPeers Capacity for number of multiplexed WebRTC peers. DEFAULTs to 1 if less than that. - - @return Port number where Snowflake will listen on, if no error happens during start up. - */ - long startSnowflake(String ice, String url, String front, String logFile, boolean logToStateDir, boolean keepLocalAddresses, boolean unsafeLogging, long maxPeers); - - /** - * StartSnowflakeProxy - Start the Snowflake proxy. - - @param capacity Maximum concurrent clients. OPTIONAL. Defaults to 10, if 0. - - @param broker Broker URL. OPTIONAL. Defaults to https://snowflake-broker.bamsoftware.com/, if empty. - - @param relay WebSocket relay URL. OPTIONAL. Defaults to wss://snowflake.bamsoftware.com/, if empty. - - @param stun STUN URL. OPTIONAL. Defaults to stun:stun.stunprotocol.org:3478, if empty. - - @param logFile Name of log file. OPTIONAL - - @param keepLocalAddresses Keep local LAN address ICE candidates. - - @param unsafeLogging Prevent logs from being scrubbed. - */ - void startSnowflakeProxy(long capacity, String broker, String relay, String stun, String logFile, boolean keepLocalAddresses, boolean unsafeLogging); - - /** - * StopSnowflake - Stop the Snowflake client. - */ - void stopSnowflake(); - - /** - * StopSnowflakeProxy - Stop the Snowflake proxy. - */ - void stopSnowflakeProxy(); -} diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyWrapper.java b/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyWrapper.java deleted file mode 100644 index c7ca165e..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/tor/IPtProxyWrapper.java +++ /dev/null @@ -1,40 +0,0 @@ -package se.leap.bitmaskclient.tor; - -import IPtProxy.IPtProxy; - -public class IPtProxyWrapper implements IPtProxyInterface { - @Override - public void setStateLocation(String location) { - IPtProxy.setStateLocation(location); - } - - @Override - public String getStateLocation() { - return IPtProxy.getStateLocation(); - } - - @Override - public long snowflakePort() { - return IPtProxy.snowflakePort(); - } - - @Override - public long startSnowflake(String ice, String url, String front, String logFile, boolean logToStateDir, boolean keepLocalAddresses, boolean unsafeLogging, long maxPeers) { - return IPtProxy.startSnowflake(ice, url, front, logFile, logToStateDir, keepLocalAddresses, unsafeLogging, maxPeers); - } - - @Override - public void startSnowflakeProxy(long capacity, String broker, String relay, String stun, String logFile, boolean keepLocalAddresses, boolean unsafeLogging) { - IPtProxy.startSnowflakeProxy(capacity, broker, relay, stun, logFile, keepLocalAddresses, unsafeLogging); - } - - @Override - public void stopSnowflake() { - IPtProxy.stopSnowflake(); - } - - @Override - public void stopSnowflakeProxy() { - IPtProxy.stopSnowflakeProxy(); - } -} -- cgit v1.2.3 From 0177f1ac3c24a45f4df928f962817e8a2e36ee36 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Mon, 12 Jul 2021 17:54:58 +0200 Subject: move assets folder to right directory --- app/assets/fronts | 6 ++++++ app/src/main/assets/fronts | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 app/assets/fronts delete mode 100644 app/src/main/assets/fronts diff --git a/app/assets/fronts b/app/assets/fronts new file mode 100644 index 00000000..937332df --- /dev/null +++ b/app/assets/fronts @@ -0,0 +1,6 @@ +snowflake-target https://snowflake-broker.torproject.net.global.prod.fastly.net/ +snowflake-front cdn.sstatic.net +snowflake-stun stun:stun.stunprotocol.org:3478 +moat-cdn https://d50gd378qj74g.cloudfront.net/ +moat-url https://moat.torproject.org.global.prod.fastly.net/ +moat-front cdn.sstatic.net diff --git a/app/src/main/assets/fronts b/app/src/main/assets/fronts deleted file mode 100644 index 937332df..00000000 --- a/app/src/main/assets/fronts +++ /dev/null @@ -1,6 +0,0 @@ -snowflake-target https://snowflake-broker.torproject.net.global.prod.fastly.net/ -snowflake-front cdn.sstatic.net -snowflake-stun stun:stun.stunprotocol.org:3478 -moat-cdn https://d50gd378qj74g.cloudfront.net/ -moat-url https://moat.torproject.org.global.prod.fastly.net/ -moat-front cdn.sstatic.net -- cgit v1.2.3 From 386d1d8cfc7fc44c837a5010ed3ed6918030e04f Mon Sep 17 00:00:00 2001 From: cyBerta Date: Mon, 12 Jul 2021 17:55:24 +0200 Subject: update bitmaskcore --- bitmaskcore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bitmaskcore b/bitmaskcore index fe20fbd9..e78518c5 160000 --- a/bitmaskcore +++ b/bitmaskcore @@ -1 +1 @@ -Subproject commit fe20fbd986270c881b3be0259e463e1a8b524b4a +Subproject commit e78518c5e207f1735441f1b971785fc1743f0911 -- cgit v1.2.3 From 8d94a1107c73a964e00859f58098019751b433bd Mon Sep 17 00:00:00 2001 From: cyBerta Date: Mon, 12 Jul 2021 19:37:21 +0200 Subject: ensure fronts file will be included in all builds --- app/build.gradle | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index e436df38..baad211a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -230,6 +230,9 @@ android { applicationIdSuffix ".beta" appSuffix = " Beta" buildConfigField "Boolean", "DEBUG_MODE", "true" + + // tor-android doesn't know this build-type, fallback to release in that case + matchingFallbacks = ['release'] } debug { testCoverageEnabled = true @@ -445,7 +448,8 @@ android.applicationVariants.all { variant -> 'urls/', '*.url', '*.json', - '*.pem']) + '*.pem', + 'fronts']) delete(filesToDelete) } } -- cgit v1.2.3 From d0c9fcab6b4c1fcfcd3022f9153dc6a117e58967 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Wed, 14 Jul 2021 23:43:48 +0200 Subject: update tor-android --- tor-android | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tor-android b/tor-android index d757fe8e..d2f0b605 160000 --- a/tor-android +++ b/tor-android @@ -1 +1 @@ -Subproject commit d757fe8eeb98072fc4e4602c398012352b59893a +Subproject commit d2f0b605d95fe530484a387eba42d2b5012fac51 -- cgit v1.2.3 From 3d9e76779f102b5cbbb29a2215415ab1a7f96aed Mon Sep 17 00:00:00 2001 From: cyBerta Date: Wed, 14 Jul 2021 23:53:26 +0200 Subject: stop torService immediately instead of queueing it in provider api service --- .../se/leap/bitmaskclient/eip/EipSetupObserver.java | 7 ++++--- .../leap/bitmaskclient/providersetup/ProviderAPI.java | 11 ----------- .../providersetup/ProviderApiManagerBase.java | 6 +----- .../activities/ProviderSetupBaseActivity.java | 19 +++++++++++++++---- 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java index f42a7d3d..1a2d8769 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java @@ -73,7 +73,6 @@ import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_DOWNLO import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.PROVIDER_NOK; -import static se.leap.bitmaskclient.providersetup.ProviderAPI.STOP_PROXY; import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF; /** @@ -211,7 +210,8 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta case INCORRECTLY_DOWNLOADED_EIP_SERVICE: case INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE: if (TorStatusObservable.getStatus() != OFF) { - ProviderAPICommand.execute(context.getApplicationContext(), STOP_PROXY, null); + Intent stopIntent = new Intent(context, TorService.class); + context.stopService(stopIntent); } default: break; @@ -360,7 +360,8 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta observedProfileFromVpnStatus = null; this.changingGateway.set(changingGateway); if (TorStatusObservable.getStatus() != OFF) { - ProviderAPICommand.execute(context.getApplicationContext(), STOP_PROXY, null); + Intent intent = new Intent(context, TorService.class); + context.stopService(intent); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java index f2376568..f88f44a5 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java @@ -174,17 +174,6 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB return -1; } - @Override - public void stopTorConnection() { - if (TorStatusObservable.getStatus() != OFF) { - TorStatusObservable.updateState(this, STOPPING.toString()); - initTorServiceConnection(this); - if (torServiceConnection != null) { - torServiceConnection.torService.stopSelf(); - } - } - } - private ProviderApiManager initApiManager() { SharedPreferences preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); OkHttpClientGenerator clientGenerator = new OkHttpClientGenerator(getResources()); diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java index 8118c872..00cbcd3e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java @@ -149,8 +149,7 @@ public abstract class ProviderApiManagerBase { public interface ProviderApiServiceCallback { void broadcastEvent(Intent intent); - int initTorConnection(); - void stopTorConnection(); + int getTorHttpTunnelPort(); } private final ProviderApiServiceCallback serviceCallback; @@ -286,9 +285,6 @@ public abstract class ProviderApiManagerBase { ProviderObservable.getInstance().setProviderForDns(null); } break; - case STOP_PROXY: - serviceCallback.stopTorConnection(); - break; } } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ProviderSetupBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ProviderSetupBaseActivity.java index 40efd811..0297bc39 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ProviderSetupBaseActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ProviderSetupBaseActivity.java @@ -29,6 +29,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager; import org.json.JSONException; import org.json.JSONObject; +import org.torproject.jni.TorService; import se.leap.bitmaskclient.base.FragmentManagerEnhanced; import se.leap.bitmaskclient.base.models.Provider; @@ -38,6 +39,7 @@ import se.leap.bitmaskclient.providersetup.ProviderApiSetupBroadcastReceiver; import se.leap.bitmaskclient.providersetup.ProviderManager; import se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog; import se.leap.bitmaskclient.providersetup.ProviderSetupInterface; +import se.leap.bitmaskclient.tor.TorStatusObservable; import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_PROVIDER_API_EVENT; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY; @@ -51,6 +53,7 @@ import static se.leap.bitmaskclient.providersetup.ProviderSetupInterface.Provide import static se.leap.bitmaskclient.providersetup.ProviderSetupInterface.ProviderConfigState.SETTING_UP_PROVIDER; import static se.leap.bitmaskclient.providersetup.ProviderSetupInterface.ProviderConfigState.SHOWING_PROVIDER_DETAILS; import static se.leap.bitmaskclient.providersetup.ProviderSetupInterface.ProviderConfigState.SHOW_FAILED_DIALOG; +import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF; /** * Created by cyberta on 19.08.18. @@ -90,7 +93,7 @@ public abstract class ProviderSetupBaseActivity extends ConfigWizardBaseActivity } else if (SHOW_FAILED_DIALOG == providerConfigState) { showProgressBar(); } else if (SHOWING_PROVIDER_DETAILS == providerConfigState) { - cancelSettingUpProvider(); + cancelSettingUpProvider(false); } else if (PENDING_SHOW_PROVIDER_DETAILS == providerConfigState) { showProviderDetails(); } @@ -156,9 +159,7 @@ public abstract class ProviderSetupBaseActivity extends ConfigWizardBaseActivity // -------- DownloadFailedDialogInterface ---v @Override public void cancelSettingUpProvider() { - providerConfigState = PROVIDER_NOT_SET; - provider = null; - hideProgressBar(); + cancelSettingUpProvider(true); } @Override @@ -167,6 +168,16 @@ public abstract class ProviderSetupBaseActivity extends ConfigWizardBaseActivity ProviderAPICommand.execute(this, UPDATE_PROVIDER_DETAILS, provider); } + public void cancelSettingUpProvider(boolean stopTor) { + if (stopTor && TorStatusObservable.getStatus() != OFF) { + Intent torServiceIntent = new Intent(getApplicationContext(), TorService.class); + stopService(torServiceIntent); + } + providerConfigState = PROVIDER_NOT_SET; + provider = null; + hideProgressBar(); + } + protected void restoreState(Bundle savedInstanceState) { super.restoreState(savedInstanceState); if (savedInstanceState == null) { -- cgit v1.2.3 From 9d16ae1456b6d6a2fc2eb67b23fc05bc878ba741 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Wed, 14 Jul 2021 23:55:21 +0200 Subject: minor language fixes in ProviderSetupBaseActivity --- .../providersetup/activities/ProviderSetupBaseActivity.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ProviderSetupBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ProviderSetupBaseActivity.java index 0297bc39..e4569c51 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ProviderSetupBaseActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ProviderSetupBaseActivity.java @@ -34,8 +34,8 @@ import org.torproject.jni.TorService; import se.leap.bitmaskclient.base.FragmentManagerEnhanced; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.providersetup.ProviderAPICommand; -import se.leap.bitmaskclient.providersetup.ProviderDetailActivity; import se.leap.bitmaskclient.providersetup.ProviderApiSetupBroadcastReceiver; +import se.leap.bitmaskclient.providersetup.ProviderDetailActivity; import se.leap.bitmaskclient.providersetup.ProviderManager; import se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog; import se.leap.bitmaskclient.providersetup.ProviderSetupInterface; @@ -60,7 +60,7 @@ import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF; */ public abstract class ProviderSetupBaseActivity extends ConfigWizardBaseActivity implements ProviderSetupInterface, ProviderSetupFailedDialog.DownloadFailedDialogInterface { - final public static String TAG = "PoviderSetupActivity"; + final public static String TAG = "ProviderSetupActivity"; final private static String ACTIVITY_STATE = "ACTIVITY STATE"; final private static String REASON_TO_FAIL = "REASON TO FAIL"; @@ -207,7 +207,7 @@ public abstract class ProviderSetupBaseActivity extends ConfigWizardBaseActivity /** * Once selected a provider, this fragment offers the user to log in, * use it anonymously (if possible) - * or cancel his/her election pressing the back button. + * or cancel their selection pressing the back button. */ public void showProviderDetails() { // show only if current activity is shown -- cgit v1.2.3 From 99fd84e800758647b4a4e178f8f5f7112b54d66f Mon Sep 17 00:00:00 2001 From: cyBerta Date: Wed, 14 Jul 2021 23:59:34 +0200 Subject: rename method --- app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java | 2 +- .../se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java index f88f44a5..15843697 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java @@ -154,7 +154,7 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB @Override - public int initTorConnection() { + public int getTorHttpTunnelPort() { initTorServiceConnection(this); if (torServiceConnection != null) { Intent torServiceIntent = new Intent(this, TorService.class); diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java index 00cbcd3e..f70be365 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java @@ -291,7 +291,7 @@ public abstract class ProviderApiManagerBase { protected int startTorProxy() { int port = -1; if (PreferenceHelper.useTor(preferences) && EipStatus.getInstance().isDisconnected() ) { - port = serviceCallback.initTorConnection(); + port = serviceCallback.getTorHttpTunnelPort(); if (port != -1) { try { waitForTorCircuits(); -- cgit v1.2.3 From 3c15fc1fb3cfb1537e2dfad740921c5f1d063259 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 15 Jul 2021 00:02:37 +0200 Subject: remove log in ProviderApiManagerBase --- .../java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java index f70be365..0fcbcdae 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java @@ -166,7 +166,6 @@ public abstract class ProviderApiManagerBase { } public void handleIntent(Intent command) { -// Log.d(TAG, "handleIntent was called!"); ResultReceiver receiver = null; if (command.getParcelableExtra(RECEIVER_KEY) != null) { receiver = command.getParcelableExtra(RECEIVER_KEY); -- cgit v1.2.3 From aa43298684367000cadf16037cb90c366ac3c000 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 15 Jul 2021 00:04:36 +0200 Subject: ensure that response.body().close() is always called when reading non-null API responses --- .../bitmaskclient/providersetup/ProviderApiConnector.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiConnector.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiConnector.java index c863abd4..35ad9cd2 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiConnector.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiConnector.java @@ -95,10 +95,15 @@ public class ProviderApiConnector { if (!response.isSuccessful()) { VpnStatus.logWarning("[API] API request failed: " + url); } - InputStream inputStream = response.body().byteStream(); - Scanner scanner = new Scanner(inputStream).useDelimiter("\\A"); - if (scanner.hasNext()) { - return scanner.next(); + + if (response.body() != null) { + InputStream inputStream = response.body().byteStream(); + Scanner scanner = new Scanner(inputStream).useDelimiter("\\A"); + if (scanner.hasNext()) { + String result = scanner.next(); + response.body().close(); + return result; + } } return null; } -- cgit v1.2.3 From b2705ea702a9eaa4a0f5566ed70cdfb4f41390d3 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 15 Jul 2021 00:06:24 +0200 Subject: don't set a new ClientTransportPlugin everytime a service connection has been initiated with TorService --- .../main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java index 15843697..15e77576 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java @@ -192,7 +192,9 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB try { if (torServiceConnection == null) { Log.d(TAG, "serviceConnection is still null"); - TorService.setClientTransportPlugin(new ClientTransportPlugin(context.getApplicationContext())); + if (!TorService.hasClientTransportPlugin()) { + TorService.setClientTransportPlugin(new ClientTransportPlugin(context.getApplicationContext())); + } torServiceConnection = new TorServiceConnection(context); } } catch (InterruptedException | IllegalStateException e) { -- cgit v1.2.3 From a3ed9483391ef38ee6665be4e4fe25a71b4c83be Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 15 Jul 2021 00:08:45 +0200 Subject: always stop tor service connection immediately after we got the http tunnel port --- .../main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java index 15e77576..322bf1cd 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java @@ -168,7 +168,10 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB getApplicationContext().startService(torServiceIntent); } - return torServiceConnection.torService.getHttpTunnelPort(); + int tunnelPort = torServiceConnection.torService.getHttpTunnelPort(); + torServiceConnection.close(); + torServiceConnection = null; + return tunnelPort; } return -1; -- cgit v1.2.3 From 818281a7fdf8b43437e14478a2276dc821b69284 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 15 Jul 2021 00:10:15 +0200 Subject: set torService to null when tor service connection disconnected --- app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java index 322bf1cd..42ded09f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java @@ -243,6 +243,7 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB @Override public void onServiceDisconnected(ComponentName name) { + torService = null; } }; Intent intent = new Intent(context, TorService.class); -- cgit v1.2.3 From 0822d3e0f62d9dcc9c1ce15bea941860affbf94f Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 15 Jul 2021 00:36:00 +0200 Subject: build tor binaries from source --- scripts/build_deps.sh | 32 +++++++++++++++++++++++++++++--- scripts/cleanProject.sh | 8 +++++++- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/scripts/build_deps.sh b/scripts/build_deps.sh index 1d8d26d5..fde8f878 100755 --- a/scripts/build_deps.sh +++ b/scripts/build_deps.sh @@ -10,9 +10,11 @@ BASE_DIR="$SCRIPT_DIR/.." DIR_OVPNASSETS=./ics-openvpn/main/build/ovpnassets DIR_OVPNLIBS=./ics-openvpn/main/build/intermediates/cmake/noovpn3/release/obj DIR_GOLIBS=./bitmaskcore/lib/ -FILE_X86=./go/out/x86/piedispatcherlib -FILE_ARM=./go/out/armeabi-v7a/piedispatcherlib - +#FILE_X86=./go/out/x86/piedispatcherlib +#FILE_ARM=./go/out/armeabi-v7a/piedispatcherlib +DIR_TORLIBS=./tor-android/external/lib +NDK_VERSION=`cat $ANDROID_NDK_HOME/source.properties | grep Pkg.Revision | cut -d "=" -f2 | sed 's/ //g'` +EXPECTED_NDK_VERSION="21.4.7075529" # init # look for empty dir @@ -51,4 +53,28 @@ else cp lib/bitmaskcore_x86_64.aar ../lib-bitmask-core-x86_64/. cp lib/bitmaskcore_x86_64-sources.jar ../lib-bitmask-core-x86_64/. + cd .. fi + +if [[ $(ls -A ${DIR_TORLIBS}) ]] +then + echo "Dirty build: Reusing tor libraries" +else + echo "Clean build: compiling tor libraries" + if [[ ! -d $DIR_TORLIBS ]] + then + mkdir $DIR_TORLIBS + fi + + cd ./tor-android + + if [[ $NDK_VERSION == $EXPECTED_NDK_VERSION ]] + then + ./tor-droid-make.sh fetch -c + ./tor-droid-make.sh build -b release + else + echo "expected NDK VERSION: $EXPECTED_NDK_VERSION. But found: $NDK_VERSION" + fi + + cd .. +fi \ No newline at end of file diff --git a/scripts/cleanProject.sh b/scripts/cleanProject.sh index 058ef20e..c1d5df7a 100755 --- a/scripts/cleanProject.sh +++ b/scripts/cleanProject.sh @@ -9,7 +9,13 @@ git checkout -- \.\* rm -r $BASE_DIR/ics-openvpn rm -r $BASE_DIR/build rm -r $BASE_DIR/app/build -rm -r $BASE_DIR/go/lib/* +rm -r $BASE_DIR/bitmaskcore/lib/* rm -r $BASE_DIR/currentReleases +rm -r $BASE_DIR/tor-android/build +rm -r $BASE_DIR/tor-android/tor-android-binary/build +rm -r $BASE_DIR/tor-android/external/bin +rm -r $BASE_DIR/tor-android/external/include/ +rm -r $BASE_DIR/tor-android/external/*.build-stamp +rm -r $BASE_DIR/tor-android/external/lib git submodule sync --recursive git submodule update --init --recursive -- cgit v1.2.3 From 9b4c03d0f80a89d1a8ac79e204d3d417a04d79d4 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 15 Jul 2021 11:34:55 +0200 Subject: quit build process if tor cannot be build --- scripts/build_deps.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/build_deps.sh b/scripts/build_deps.sh index fde8f878..7c0bfa74 100755 --- a/scripts/build_deps.sh +++ b/scripts/build_deps.sh @@ -70,10 +70,10 @@ else if [[ $NDK_VERSION == $EXPECTED_NDK_VERSION ]] then - ./tor-droid-make.sh fetch -c - ./tor-droid-make.sh build -b release + ./tor-droid-make.sh fetch -c || quit "failed to checkout tor dependencies" + ./tor-droid-make.sh build -b release || quit "failed to build tor release binaries" else - echo "expected NDK VERSION: $EXPECTED_NDK_VERSION. But found: $NDK_VERSION" + quit "expected NDK VERSION: $EXPECTED_NDK_VERSION. But found: $NDK_VERSION" fi cd .. -- cgit v1.2.3 From fd34859474f9119d90b7817eec6cf8fd5676415d Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 15 Jul 2021 11:38:38 +0200 Subject: remove golang directory when cleaning project --- scripts/cleanProject.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/cleanProject.sh b/scripts/cleanProject.sh index c1d5df7a..954b96e6 100755 --- a/scripts/cleanProject.sh +++ b/scripts/cleanProject.sh @@ -10,6 +10,7 @@ rm -r $BASE_DIR/ics-openvpn rm -r $BASE_DIR/build rm -r $BASE_DIR/app/build rm -r $BASE_DIR/bitmaskcore/lib/* +rm -r $BASE_DIR/bitmaskcore/golang/ rm -r $BASE_DIR/currentReleases rm -r $BASE_DIR/tor-android/build rm -r $BASE_DIR/tor-android/tor-android-binary/build -- cgit v1.2.3 From a747c9a01d6942a2c3a797c5d90ad1ccbbfcc83c Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 15 Jul 2021 11:46:49 +0200 Subject: reset all submodules in cleanProject --- scripts/cleanProject.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/cleanProject.sh b/scripts/cleanProject.sh index 954b96e6..e7d8460e 100755 --- a/scripts/cleanProject.sh +++ b/scripts/cleanProject.sh @@ -18,5 +18,6 @@ rm -r $BASE_DIR/tor-android/external/bin rm -r $BASE_DIR/tor-android/external/include/ rm -r $BASE_DIR/tor-android/external/*.build-stamp rm -r $BASE_DIR/tor-android/external/lib +git submodule foreach --recursive git reset --hard HEAD git submodule sync --recursive git submodule update --init --recursive -- cgit v1.2.3 From 11e501a300e40bc254780723e39869c7830944eb Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 15 Jul 2021 11:51:31 +0200 Subject: check ndk version earlier, do first the tor binary build job --- scripts/build_deps.sh | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/scripts/build_deps.sh b/scripts/build_deps.sh index 7c0bfa74..e865bd49 100755 --- a/scripts/build_deps.sh +++ b/scripts/build_deps.sh @@ -19,6 +19,27 @@ EXPECTED_NDK_VERSION="21.4.7075529" # look for empty dir cd $BASE_DIR + +if [[ $(ls -A ${DIR_TORLIBS}) ]] +then + echo "Dirty build: Reusing tor libraries" +else + echo "Clean build: compiling tor libraries" + if [[ ! -d $DIR_TORLIBS ]] + then + mkdir $DIR_TORLIBS + fi + cd ./tor-android + if [[ $NDK_VERSION == $EXPECTED_NDK_VERSION ]] + then + ./tor-droid-make.sh fetch -c || quit "failed to checkout tor dependencies" + ./tor-droid-make.sh build -b release || quit "failed to build tor release binaries" + else + quit "expected NDK VERSION: $EXPECTED_NDK_VERSION. But found: $NDK_VERSION" + fi + cd .. +fi + if [[ $(ls -A ${DIR_OVPNASSETS}) && $(ls -A ${DIR_OVPNLIBS}) ]] then echo "Dirty build: skipped externalNativeBuild - reusing existing libs" @@ -52,29 +73,5 @@ else cp lib/bitmaskcore_x86-sources.jar ../lib-bitmask-core-x86/. cp lib/bitmaskcore_x86_64.aar ../lib-bitmask-core-x86_64/. cp lib/bitmaskcore_x86_64-sources.jar ../lib-bitmask-core-x86_64/. - cd .. -fi - -if [[ $(ls -A ${DIR_TORLIBS}) ]] -then - echo "Dirty build: Reusing tor libraries" -else - echo "Clean build: compiling tor libraries" - if [[ ! -d $DIR_TORLIBS ]] - then - mkdir $DIR_TORLIBS - fi - - cd ./tor-android - - if [[ $NDK_VERSION == $EXPECTED_NDK_VERSION ]] - then - ./tor-droid-make.sh fetch -c || quit "failed to checkout tor dependencies" - ./tor-droid-make.sh build -b release || quit "failed to build tor release binaries" - else - quit "expected NDK VERSION: $EXPECTED_NDK_VERSION. But found: $NDK_VERSION" - fi - - cd .. fi \ No newline at end of file -- cgit v1.2.3 From 7b7fa94ff24aa56faf5123e867c2206c2ca69852 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 15 Jul 2021 12:11:05 +0200 Subject: try to set ANDROID_NDK_HOME to expected NDK version --- scripts/build_deps.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/build_deps.sh b/scripts/build_deps.sh index e865bd49..58ed65c5 100755 --- a/scripts/build_deps.sh +++ b/scripts/build_deps.sh @@ -13,13 +13,21 @@ DIR_GOLIBS=./bitmaskcore/lib/ #FILE_X86=./go/out/x86/piedispatcherlib #FILE_ARM=./go/out/armeabi-v7a/piedispatcherlib DIR_TORLIBS=./tor-android/external/lib -NDK_VERSION=`cat $ANDROID_NDK_HOME/source.properties | grep Pkg.Revision | cut -d "=" -f2 | sed 's/ //g'` EXPECTED_NDK_VERSION="21.4.7075529" # init # look for empty dir cd $BASE_DIR +# try to set the expected ndk version +if [[ $(ls -A ${ANDROID_HOME}/ndk/${EXPECTED_NDK_VERSION}) ]] +then + ANDROID_NDK_HOME=${ANDROID_HOME}/ndk/${EXPECTED_NDK_VERSION} +fi +NDK_VERSION=`cat $ANDROID_NDK_HOME/source.properties | grep Pkg.Revision | cut -d "=" -f2 | sed 's/ //g'` + + +# build tor libs if [[ $(ls -A ${DIR_TORLIBS}) ]] then echo "Dirty build: Reusing tor libraries" @@ -40,6 +48,7 @@ else cd .. fi +# build openvpn libs if [[ $(ls -A ${DIR_OVPNASSETS}) && $(ls -A ${DIR_OVPNLIBS}) ]] then echo "Dirty build: skipped externalNativeBuild - reusing existing libs" @@ -50,6 +59,7 @@ else cd .. fi +# build bitmask core (shapeshifter, snowflake, pgpverify) if [[ $(ls -A ${DIR_GOLIBS}) ]] then echo "Dirty build: Reusing go libraries" -- cgit v1.2.3 From f2f4d340ea2276c5e88e9451554c56f92ab616d4 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 15 Jul 2021 13:31:12 +0200 Subject: set required ndk version in build.gradle --- app/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/app/build.gradle b/app/build.gradle index baad211a..9e1d4d7b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,6 +5,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 30 + ndkVersion "21.4.7075529" compileOptions { targetCompatibility 1.8 -- cgit v1.2.3 From 7140ee36f88ce8b2b5a606926ff993bd225fab1d Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 15 Jul 2021 13:31:52 +0200 Subject: update required NDK version in docker build file --- docker/android-ndk/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/android-ndk/Dockerfile b/docker/android-ndk/Dockerfile index 97e47005..4c806eb3 100644 --- a/docker/android-ndk/Dockerfile +++ b/docker/android-ndk/Dockerfile @@ -24,8 +24,8 @@ RUN apt-get update -qq && \ # ------------------------------------------------------ # --- Install Android NDK (for running C code) -ENV ANDROID_NDK_VERSION "r20" -ENV ANDROID_NDK_HOME ${ANDROID_HOME}/android-ndk-${ANDROID_NDK_VERSION} +ENV ANDROID_NDK_VERSION "r21e" +ENV ANDROID_NDK_HOME ${ANDROID_HOME}/ndk/android-ndk-${ANDROID_NDK_VERSION} ENV ANDROID_NDK_URL http://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip RUN curl -L $ANDROID_NDK_URL -o ndk.zip \ -- cgit v1.2.3 From 20ed4cfe9c2cabe3903da64492e6df64a29c250c Mon Sep 17 00:00:00 2001 From: cyBerta Date: Mon, 19 Jul 2021 14:01:34 +0200 Subject: fix ndk path in android-ndk docker file --- docker/android-ndk/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/android-ndk/Dockerfile b/docker/android-ndk/Dockerfile index 4c806eb3..2e8e2309 100644 --- a/docker/android-ndk/Dockerfile +++ b/docker/android-ndk/Dockerfile @@ -25,7 +25,7 @@ RUN apt-get update -qq && \ # --- Install Android NDK (for running C code) ENV ANDROID_NDK_VERSION "r21e" -ENV ANDROID_NDK_HOME ${ANDROID_HOME}/ndk/android-ndk-${ANDROID_NDK_VERSION} +ENV ANDROID_NDK_HOME ${ANDROID_HOME}/android-ndk-${ANDROID_NDK_VERSION} ENV ANDROID_NDK_URL http://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip RUN curl -L $ANDROID_NDK_URL -o ndk.zip \ -- cgit v1.2.3 From 7374edbe070be0ddbb496f5ba2143599a9ea4e06 Mon Sep 17 00:00:00 2001 From: cyberta Date: Mon, 2 Aug 2021 17:26:11 +0200 Subject: update bitmaskcore --- bitmaskcore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bitmaskcore b/bitmaskcore index e78518c5..14c24b98 160000 --- a/bitmaskcore +++ b/bitmaskcore @@ -1 +1 @@ -Subproject commit e78518c5e207f1735441f1b971785fc1743f0911 +Subproject commit 14c24b98d1dda313a7aa58bd88f7ec6b3d571d32 -- cgit v1.2.3 From c28312af1d20e249ba56ca14312ad99e0822e0d4 Mon Sep 17 00:00:00 2001 From: cyberta Date: Mon, 2 Aug 2021 18:35:17 +0200 Subject: try to get more output. dockerbuild.log is not uploaded for some reason --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bd38da5d..c51f8e71 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -25,7 +25,7 @@ variables: script: - docker --version - docker info - - if ! .gitlab/build.sh ${DOCKER_IMAGE} >> dockerbuild.log 2>&1; then echo "Image build failed. Please check dockerbuild.log."; exit 1; fi; + - if ! .gitlab/build.sh ${DOCKER_IMAGE} >> dockerbuild.log 2>&1; then echo "Image build failed. Please check dockerbuild.log."; echo "tail -n 100 dockerbuild.log:"; tail -n 100 dockerbuild.log; echo "disk space:"; df -h; exit 1; fi; allow_failure: false artifacts: expire_in: 3d -- cgit v1.2.3 From 2d5ac7cdd625e920016a3b0e7d9cc65cb7919f82 Mon Sep 17 00:00:00 2001 From: cyberta Date: Mon, 2 Aug 2021 21:58:10 +0200 Subject: update url to docker apt gpg key --- docker/android-emulator/Dockerfile | 2 +- docker/android-ndk/Dockerfile | 2 +- docker/android-sdk/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/android-emulator/Dockerfile b/docker/android-emulator/Dockerfile index 9cd8294d..8ffd537c 100644 --- a/docker/android-emulator/Dockerfile +++ b/docker/android-emulator/Dockerfile @@ -16,7 +16,7 @@ RUN apt-get update -qq && \ apt-get -y dist-upgrade && \ apt-get -y install gnupg apt-transport-https RUN echo 'deb https://apt.dockerproject.org/repo debian-stretch main'> /etc/apt/sources.list.d/docker.list && \ - curl -s https://apt.dockerproject.org/gpg | apt-key add - + curl -s https://download.docker.com/linux/debian/gpg | apt-key add - RUN apt-get update -qq && \ apt-get -y install docker-engine mesa-utils && \ apt-get clean && \ diff --git a/docker/android-ndk/Dockerfile b/docker/android-ndk/Dockerfile index 2e8e2309..6a9d5a20 100644 --- a/docker/android-ndk/Dockerfile +++ b/docker/android-ndk/Dockerfile @@ -13,7 +13,7 @@ RUN apt-get update -qq && \ apt-get -y dist-upgrade && \ apt-get install -y gnupg apt-transport-https RUN echo 'deb https://apt.dockerproject.org/repo debian-stretch main'> /etc/apt/sources.list.d/docker.list && \ - curl -s https://apt.dockerproject.org/gpg | apt-key add - + curl -s https://download.docker.com/linux/debian/gpg | apt-key add - # JNI build dependencies w/ 32-bit compatible C libs RUN apt-get update -qq && \ apt-get -y install docker-engine make gcc file lib32stdc++6 lib32z1 && \ diff --git a/docker/android-sdk/Dockerfile b/docker/android-sdk/Dockerfile index 4c4cf2dd..c90d349e 100644 --- a/docker/android-sdk/Dockerfile +++ b/docker/android-sdk/Dockerfile @@ -14,7 +14,7 @@ RUN apt-get update -qq && \ apt-get -y dist-upgrade && \ apt-get -y install gnupg apt-transport-https RUN echo 'deb https://apt.dockerproject.org/repo debian-stretch main'> /etc/apt/sources.list.d/docker.list && \ - curl -s https://apt.dockerproject.org/gpg | apt-key add - + curl -s https://download.docker.com/linux/debian/gpg | apt-key add - RUN apt-get update -qq && \ apt-get install -y docker-engine \ # the basics -- cgit v1.2.3 From a5f118a494ad3f8959a1790f7674376885b650c3 Mon Sep 17 00:00:00 2001 From: cyberta Date: Mon, 2 Aug 2021 22:35:47 +0200 Subject: update url to docker debian-strech stable --- docker/android-emulator/Dockerfile | 2 +- docker/android-ndk/Dockerfile | 2 +- docker/android-sdk/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/android-emulator/Dockerfile b/docker/android-emulator/Dockerfile index 8ffd537c..09bc99de 100644 --- a/docker/android-emulator/Dockerfile +++ b/docker/android-emulator/Dockerfile @@ -15,7 +15,7 @@ ENV ANDROID_EMULATOR_USE_SYSTEM_LIBS=1 RUN apt-get update -qq && \ apt-get -y dist-upgrade && \ apt-get -y install gnupg apt-transport-https -RUN echo 'deb https://apt.dockerproject.org/repo debian-stretch main'> /etc/apt/sources.list.d/docker.list && \ +RUN echo 'deb https://download.docker.com/linux/debian debian-stretch stable' > /etc/apt/sources.list.d/docker.list && \ curl -s https://download.docker.com/linux/debian/gpg | apt-key add - RUN apt-get update -qq && \ apt-get -y install docker-engine mesa-utils && \ diff --git a/docker/android-ndk/Dockerfile b/docker/android-ndk/Dockerfile index 6a9d5a20..c60f0f15 100644 --- a/docker/android-ndk/Dockerfile +++ b/docker/android-ndk/Dockerfile @@ -12,7 +12,7 @@ ENV DEBIAN_FRONTEND noninteractive RUN apt-get update -qq && \ apt-get -y dist-upgrade && \ apt-get install -y gnupg apt-transport-https -RUN echo 'deb https://apt.dockerproject.org/repo debian-stretch main'> /etc/apt/sources.list.d/docker.list && \ +RUN echo 'deb https://download.docker.com/linux/debian debian-stretch stable' > /etc/apt/sources.list.d/docker.list && \ curl -s https://download.docker.com/linux/debian/gpg | apt-key add - # JNI build dependencies w/ 32-bit compatible C libs RUN apt-get update -qq && \ diff --git a/docker/android-sdk/Dockerfile b/docker/android-sdk/Dockerfile index c90d349e..5820dd63 100644 --- a/docker/android-sdk/Dockerfile +++ b/docker/android-sdk/Dockerfile @@ -13,7 +13,7 @@ ENV DEBIAN_FRONTEND noninteractive RUN apt-get update -qq && \ apt-get -y dist-upgrade && \ apt-get -y install gnupg apt-transport-https -RUN echo 'deb https://apt.dockerproject.org/repo debian-stretch main'> /etc/apt/sources.list.d/docker.list && \ +RUN echo 'deb https://download.docker.com/linux/debian debian-stretch stable' > /etc/apt/sources.list.d/docker.list && \ curl -s https://download.docker.com/linux/debian/gpg | apt-key add - RUN apt-get update -qq && \ apt-get install -y docker-engine \ -- cgit v1.2.3 From f7e3428d40ada6a482f5c1b02a299d1f92a29be6 Mon Sep 17 00:00:00 2001 From: cyberta Date: Mon, 2 Aug 2021 23:16:02 +0200 Subject: try to install docker according to the docs --- docker/android-emulator/Dockerfile | 6 ++++-- docker/android-ndk/Dockerfile | 6 ++++-- docker/android-sdk/Dockerfile | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/docker/android-emulator/Dockerfile b/docker/android-emulator/Dockerfile index 09bc99de..d5349da1 100644 --- a/docker/android-emulator/Dockerfile +++ b/docker/android-emulator/Dockerfile @@ -15,8 +15,10 @@ ENV ANDROID_EMULATOR_USE_SYSTEM_LIBS=1 RUN apt-get update -qq && \ apt-get -y dist-upgrade && \ apt-get -y install gnupg apt-transport-https -RUN echo 'deb https://download.docker.com/linux/debian debian-stretch stable' > /etc/apt/sources.list.d/docker.list && \ - curl -s https://download.docker.com/linux/debian/gpg | apt-key add - +RUN curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg && \ + echo \ + "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \ + $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null RUN apt-get update -qq && \ apt-get -y install docker-engine mesa-utils && \ apt-get clean && \ diff --git a/docker/android-ndk/Dockerfile b/docker/android-ndk/Dockerfile index c60f0f15..0663916b 100644 --- a/docker/android-ndk/Dockerfile +++ b/docker/android-ndk/Dockerfile @@ -12,8 +12,10 @@ ENV DEBIAN_FRONTEND noninteractive RUN apt-get update -qq && \ apt-get -y dist-upgrade && \ apt-get install -y gnupg apt-transport-https -RUN echo 'deb https://download.docker.com/linux/debian debian-stretch stable' > /etc/apt/sources.list.d/docker.list && \ - curl -s https://download.docker.com/linux/debian/gpg | apt-key add - +RUN curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg && \ + echo \ + "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \ + $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # JNI build dependencies w/ 32-bit compatible C libs RUN apt-get update -qq && \ apt-get -y install docker-engine make gcc file lib32stdc++6 lib32z1 && \ diff --git a/docker/android-sdk/Dockerfile b/docker/android-sdk/Dockerfile index 5820dd63..20ae2c48 100644 --- a/docker/android-sdk/Dockerfile +++ b/docker/android-sdk/Dockerfile @@ -13,8 +13,10 @@ ENV DEBIAN_FRONTEND noninteractive RUN apt-get update -qq && \ apt-get -y dist-upgrade && \ apt-get -y install gnupg apt-transport-https -RUN echo 'deb https://download.docker.com/linux/debian debian-stretch stable' > /etc/apt/sources.list.d/docker.list && \ - curl -s https://download.docker.com/linux/debian/gpg | apt-key add - +RUN curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg && \ + echo \ + "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \ + $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null RUN apt-get update -qq && \ apt-get install -y docker-engine \ # the basics -- cgit v1.2.3 From 0ee29854eccf82d0d387ec8bf888c22a1786baca Mon Sep 17 00:00:00 2001 From: cyberta Date: Mon, 2 Aug 2021 23:24:56 +0200 Subject: docker-engine seems to have been replaced by docker-ce package --- docker/android-emulator/Dockerfile | 2 +- docker/android-ndk/Dockerfile | 2 +- docker/android-sdk/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/android-emulator/Dockerfile b/docker/android-emulator/Dockerfile index d5349da1..138173d4 100644 --- a/docker/android-emulator/Dockerfile +++ b/docker/android-emulator/Dockerfile @@ -20,7 +20,7 @@ RUN curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null RUN apt-get update -qq && \ - apt-get -y install docker-engine mesa-utils && \ + apt-get -y install docker-ce mesa-utils && \ apt-get clean && \ apt-get autoclean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* diff --git a/docker/android-ndk/Dockerfile b/docker/android-ndk/Dockerfile index 0663916b..d35053a6 100644 --- a/docker/android-ndk/Dockerfile +++ b/docker/android-ndk/Dockerfile @@ -18,7 +18,7 @@ RUN curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # JNI build dependencies w/ 32-bit compatible C libs RUN apt-get update -qq && \ - apt-get -y install docker-engine make gcc file lib32stdc++6 lib32z1 && \ + apt-get -y install docker-ce make gcc file lib32stdc++6 lib32z1 && \ apt-get clean && \ apt-get autoclean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* diff --git a/docker/android-sdk/Dockerfile b/docker/android-sdk/Dockerfile index 20ae2c48..d10cce6f 100644 --- a/docker/android-sdk/Dockerfile +++ b/docker/android-sdk/Dockerfile @@ -18,7 +18,7 @@ RUN curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null RUN apt-get update -qq && \ - apt-get install -y docker-engine \ + apt-get install -y docker-ce \ # the basics curl unzip git locales \ # java stuff -- cgit v1.2.3 From c3fd98026f52bcc801a5ed1212c61897a48e3b44 Mon Sep 17 00:00:00 2001 From: cyberta Date: Tue, 3 Aug 2021 01:38:43 +0200 Subject: fix ANDROID_NDK_HOME if ndk was manually downloaded --- scripts/build_deps.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/build_deps.sh b/scripts/build_deps.sh index 58ed65c5..eb731fcd 100755 --- a/scripts/build_deps.sh +++ b/scripts/build_deps.sh @@ -14,6 +14,8 @@ DIR_GOLIBS=./bitmaskcore/lib/ #FILE_ARM=./go/out/armeabi-v7a/piedispatcherlib DIR_TORLIBS=./tor-android/external/lib EXPECTED_NDK_VERSION="21.4.7075529" +EXPECTED_ANDROID_NDK_RELEASE_VERSION="r21e" + # init # look for empty dir @@ -23,6 +25,9 @@ cd $BASE_DIR if [[ $(ls -A ${ANDROID_HOME}/ndk/${EXPECTED_NDK_VERSION}) ]] then ANDROID_NDK_HOME=${ANDROID_HOME}/ndk/${EXPECTED_NDK_VERSION} +else + # ndk was manually downloaded from http://dl.google.com/android/repository + ANDROID_NDK_HOME=${ANDROID_HOME}/android-ndk-${EXPECTED_ANDROID_NDK_RELEASE_VERSION} fi NDK_VERSION=`cat $ANDROID_NDK_HOME/source.properties | grep Pkg.Revision | cut -d "=" -f2 | sed 's/ //g'` -- cgit v1.2.3 From 4d4d14e45bbba8342d7c98a874e34069bf1350d8 Mon Sep 17 00:00:00 2001 From: cyberta Date: Tue, 3 Aug 2021 07:09:29 +0200 Subject: add some more debug output --- scripts/build_deps.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/build_deps.sh b/scripts/build_deps.sh index eb731fcd..5349cd63 100755 --- a/scripts/build_deps.sh +++ b/scripts/build_deps.sh @@ -29,8 +29,11 @@ else # ndk was manually downloaded from http://dl.google.com/android/repository ANDROID_NDK_HOME=${ANDROID_HOME}/android-ndk-${EXPECTED_ANDROID_NDK_RELEASE_VERSION} fi -NDK_VERSION=`cat $ANDROID_NDK_HOME/source.properties | grep Pkg.Revision | cut -d "=" -f2 | sed 's/ //g'` +NDK_VERSION=`cat ${ANDROID_NDK_HOME}/source.properties | grep Pkg.Revision | cut -d "=" -f2 | sed 's/ //g'` +ls -la ${ANDROID_HOME}/*/*ndk* +echo "ndk version: $NDK_VERSION" +echo "ANDROID_NDK_HOME: $ANDROID_NDK_HOME" # build tor libs if [[ $(ls -A ${DIR_TORLIBS}) ]] -- cgit v1.2.3 From 36d5a52fb02aa87d232f736e5c8317acb02b466d Mon Sep 17 00:00:00 2001 From: cyberta Date: Tue, 3 Aug 2021 11:17:38 +0200 Subject: add missing debian packages to build tor --- docker/android-ndk/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker/android-ndk/Dockerfile b/docker/android-ndk/Dockerfile index d35053a6..7d38973c 100644 --- a/docker/android-ndk/Dockerfile +++ b/docker/android-ndk/Dockerfile @@ -18,7 +18,8 @@ RUN curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # JNI build dependencies w/ 32-bit compatible C libs RUN apt-get update -qq && \ - apt-get -y install docker-ce make gcc file lib32stdc++6 lib32z1 && \ + apt-get -y install docker-ce make gcc file lib32stdc++6 lib32z1 \ + autoconf autogen automake autopoint autotools-dev gettext-base libtool patch pkg-config && \ apt-get clean && \ apt-get autoclean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -- cgit v1.2.3 From b02c6550ee81341671aa5ee841e45a150e5df435 Mon Sep 17 00:00:00 2001 From: cyberta Date: Tue, 3 Aug 2021 13:28:11 +0200 Subject: update bitmaskcore --- bitmaskcore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bitmaskcore b/bitmaskcore index 14c24b98..a0997ed0 160000 --- a/bitmaskcore +++ b/bitmaskcore @@ -1 +1 @@ -Subproject commit 14c24b98d1dda313a7aa58bd88f7ec6b3d571d32 +Subproject commit a0997ed0835cfbba26bbae8d4975e7b8803a9b59 -- cgit v1.2.3 From c30493db5e8e12dbfdd6c5348d78504568e20c6a Mon Sep 17 00:00:00 2001 From: cyberta Date: Tue, 3 Aug 2021 16:02:04 +0200 Subject: update bitmaskcore, updated shapeshifter with jni fix --- bitmaskcore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bitmaskcore b/bitmaskcore index a0997ed0..199f1e12 160000 --- a/bitmaskcore +++ b/bitmaskcore @@ -1 +1 @@ -Subproject commit a0997ed0835cfbba26bbae8d4975e7b8803a9b59 +Subproject commit 199f1e122a2a653863c92962adfdb2ae706b2447 -- cgit v1.2.3 From 36c90a4f65c81dcb431662302ec175b2fb0840bd Mon Sep 17 00:00:00 2001 From: cyberta Date: Wed, 4 Aug 2021 10:34:41 +0200 Subject: adapt debug output --- scripts/build_deps.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build_deps.sh b/scripts/build_deps.sh index 5349cd63..470b39b6 100755 --- a/scripts/build_deps.sh +++ b/scripts/build_deps.sh @@ -31,7 +31,7 @@ else fi NDK_VERSION=`cat ${ANDROID_NDK_HOME}/source.properties | grep Pkg.Revision | cut -d "=" -f2 | sed 's/ //g'` -ls -la ${ANDROID_HOME}/*/*ndk* +ls -la ${ANDROID_HOME}/*/*ndk echo "ndk version: $NDK_VERSION" echo "ANDROID_NDK_HOME: $ANDROID_NDK_HOME" -- cgit v1.2.3 From 3d5675f2287f22c399d9a5f4bfcef999100a1b2c Mon Sep 17 00:00:00 2001 From: cyberta Date: Wed, 4 Aug 2021 10:36:56 +0200 Subject: update import path for shapeshifter lib --- .../java/se/leap/bitmaskclient/pluggableTransports/Shapeshifter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/Shapeshifter.java b/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/Shapeshifter.java index d39f8bf3..c7893249 100644 --- a/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/Shapeshifter.java +++ b/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/Shapeshifter.java @@ -27,7 +27,7 @@ import java.util.Observer; import de.blinkt.openvpn.core.ConnectionStatus; import de.blinkt.openvpn.core.VpnStatus; import se.leap.bitmaskclient.eip.EipStatus; -import shapeshifter.ShapeShifter; +import shapeShifter.ShapeShifter; public class Shapeshifter implements Observer { @@ -43,7 +43,7 @@ public class Shapeshifter implements Observer { private int retry = 0; private Handler reconnectHandler; - public class ShapeshifterLogger implements shapeshifter.Logger { + public class ShapeshifterLogger implements shapeShifter.Logger { @Override public void log(String s) { Log.e(TAG, "SHAPESHIFTER ERROR: " + s); -- cgit v1.2.3 From 2da4c19827ed722f4dde2830bd84b21553a13bcd Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 30 Sep 2021 14:50:11 +0200 Subject: set tor setup timeout to 3 minutes --- .../se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java index 0fcbcdae..b7108225 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java @@ -314,7 +314,7 @@ public abstract class ProviderApiManagerBase { } }; TorStatusObservable.getInstance().addObserver(observer); - countDownLatch.await(90, TimeUnit.SECONDS); + countDownLatch.await(180, TimeUnit.SECONDS); } void resetProviderDetails(Provider provider) { -- cgit v1.2.3 From 780c63fc4afbe38eca70237e07165d88596b3843 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 30 Sep 2021 14:50:29 +0200 Subject: remove tor circuit setup observer once timeout reached or tor circuits have been setup successfully --- .../java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java index b7108225..9ca4c746 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java @@ -315,6 +315,7 @@ public abstract class ProviderApiManagerBase { }; TorStatusObservable.getInstance().addObserver(observer); countDownLatch.await(180, TimeUnit.SECONDS); + TorStatusObservable.getInstance().deleteObserver(observer); } void resetProviderDetails(Provider provider) { -- cgit v1.2.3 From c8a6822c27210eba74299718679db101a6ee273e Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 30 Sep 2021 16:08:57 +0200 Subject: workaround for jni issue again --- .../se/leap/bitmaskclient/pluggableTransports/Shapeshifter.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/Shapeshifter.java b/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/Shapeshifter.java index c7893249..828b90ba 100644 --- a/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/Shapeshifter.java +++ b/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/Shapeshifter.java @@ -27,7 +27,7 @@ import java.util.Observer; import de.blinkt.openvpn.core.ConnectionStatus; import de.blinkt.openvpn.core.VpnStatus; import se.leap.bitmaskclient.eip.EipStatus; -import shapeShifter.ShapeShifter; +import shapeShifter.ShapeShifter_; public class Shapeshifter implements Observer { @@ -37,11 +37,11 @@ public class Shapeshifter implements Observer { private static final int RETRY_TIME = 4000; private static final String TAG = Shapeshifter.class.getSimpleName(); - private ShapeShifter shapeShifter; + private final ShapeShifter_ shapeShifter; private boolean isErrorHandling; private boolean noNetwork; private int retry = 0; - private Handler reconnectHandler; + private final Handler reconnectHandler; public class ShapeshifterLogger implements shapeShifter.Logger { @Override @@ -61,7 +61,7 @@ public class Shapeshifter implements Observer { } public Shapeshifter(Obfs4Options options) { - shapeShifter = new ShapeShifter(); + shapeShifter = new ShapeShifter_(); shapeShifter.setLogger(new ShapeshifterLogger()); setup(options); Looper.prepare(); -- cgit v1.2.3 From 9e131a6ae3456c6b8daa99dbd5b38dc5ef5d8592 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 2 Oct 2021 11:54:17 +0200 Subject: update tor-android --- tor-android | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tor-android b/tor-android index d2f0b605..dceeebf1 160000 --- a/tor-android +++ b/tor-android @@ -1 +1 @@ -Subproject commit d2f0b605d95fe530484a387eba42d2b5012fac51 +Subproject commit dceeebf1130f990332f324907359a94a5b994a11 -- cgit v1.2.3 From 80bf751141c85316c22a0d16c1e4d6fa0f473f44 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 2 Oct 2021 13:31:36 +0200 Subject: * refactor startTorProxy() * fix setting http proxy port correctly * snowflake+tor does currently only work when being connected to a wifi, not a cellular network. For now, we check if the device is connected to a wifi, before attempting to start tor --- .../java/de/blinkt/openvpn/core/NetworkUtils.java | 30 ++++++++++++++ .../bitmaskclient/providersetup/ProviderAPI.java | 34 ++++++++------- .../providersetup/ProviderApiManagerBase.java | 41 +++++++++++------- .../providersetup/ProviderApiManager.java | 48 +++++++++++++--------- 4 files changed, 105 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/de/blinkt/openvpn/core/NetworkUtils.java b/app/src/main/java/de/blinkt/openvpn/core/NetworkUtils.java index 78799a3a..cbb58f0f 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/NetworkUtils.java +++ b/app/src/main/java/de/blinkt/openvpn/core/NetworkUtils.java @@ -9,6 +9,9 @@ import android.content.Context; import android.net.*; import android.os.Build; import android.text.TextUtils; +import android.util.Log; + +import androidx.core.net.ConnectivityManagerCompat; import java.net.Inet4Address; import java.net.Inet6Address; @@ -16,6 +19,8 @@ import java.util.Vector; public class NetworkUtils { + private static final String TAG = NetworkUtils.class.getSimpleName(); + public static Vector getLocalNetworks(Context c, boolean ipv6) { Vector nets = new Vector<>(); ConnectivityManager conn = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE); @@ -76,4 +81,29 @@ public class NetworkUtils { return nets; } + public static boolean isConnectedToWifi(Context context) { + ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { + NetworkInfo wifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); + Log.d(TAG, "isConnectedToWifi (<=LOLLIPOP_MR1): " + wifi.isConnected()); + return wifi.isConnected(); + } else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) { + NetworkInfo[] netInfos = connManager.getAllNetworkInfo(); + for (NetworkInfo netInfo : netInfos) { + if (netInfo != null && netInfo.getType() == ConnectivityManager.TYPE_WIFI) { + Log.d(TAG, "isConnectedToWifi (<= Build.VERSION_CODES.O_MR1): " + netInfo.isConnected()); + return netInfo.isConnected(); + } + } + } else { + NetworkInfo netInfo = connManager.getActiveNetworkInfo(); + if(netInfo != null) { + NetworkCapabilities networkCapabilities = connManager.getNetworkCapabilities(connManager.getActiveNetwork()); + Log.d(TAG, "isConnectedToWifi (> Build.VERSION_CODES.O_MR1): " + networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)); + return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI); + } + } + + return false; + } } \ No newline at end of file diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java index 42ded09f..e818f587 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java @@ -37,17 +37,15 @@ import java.io.Closeable; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import de.blinkt.openvpn.core.NetworkUtils; import se.leap.bitmaskclient.base.utils.PreferenceHelper; import se.leap.bitmaskclient.providersetup.connectivity.OkHttpClientGenerator; import se.leap.bitmaskclient.tor.ClientTransportPlugin; import se.leap.bitmaskclient.tor.TorNotificationManager; -import se.leap.bitmaskclient.tor.TorStatusObservable; import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES; import static se.leap.bitmaskclient.base.utils.ConfigHelper.ensureNotOnMainThread; import static se.leap.bitmaskclient.tor.TorNotificationManager.TOR_SERVICE_NOTIFICATION_ID; -import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF; -import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.STOPPING; /** * Implements HTTP api methods (encapsulated in {{@link ProviderApiManager}}) @@ -151,23 +149,31 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } + @Override + public boolean isConnectedToWifi() { + return NetworkUtils.isConnectedToWifi(getApplicationContext()); + } + + @Override + public void startTorService() { + initTorServiceConnection(this); + Intent torServiceIntent = new Intent(this, TorService.class); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + Notification notification = TorNotificationManager.buildTorForegroundNotification(getApplicationContext()); + //noinspection NewApi + getApplicationContext().startForegroundService(torServiceIntent); + torServiceConnection.torService.startForeground(TOR_SERVICE_NOTIFICATION_ID, notification); + } else { + getApplicationContext().startService(torServiceIntent); + } + } @Override public int getTorHttpTunnelPort() { initTorServiceConnection(this); if (torServiceConnection != null) { - Intent torServiceIntent = new Intent(this, TorService.class); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - Notification notification = TorNotificationManager.buildTorForegroundNotification(getApplicationContext()); - //noinspection NewApi - getApplicationContext().startForegroundService(torServiceIntent); - torServiceConnection.torService.startForeground(TOR_SERVICE_NOTIFICATION_ID, notification); - } else { - getApplicationContext().startService(torServiceIntent); - } - int tunnelPort = torServiceConnection.torService.getHttpTunnelPort(); torServiceConnection.close(); torServiceConnection = null; diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java index 9ca4c746..780ecaed 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java @@ -51,6 +51,8 @@ import java.util.NoSuchElementException; import java.util.Observer; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLPeerUnverifiedException; @@ -149,7 +151,9 @@ public abstract class ProviderApiManagerBase { public interface ProviderApiServiceCallback { void broadcastEvent(Intent intent); + void startTorService(); int getTorHttpTunnelPort(); + boolean isConnectedToWifi(); } private final ProviderApiServiceCallback serviceCallback; @@ -188,7 +192,11 @@ public abstract class ProviderApiManagerBase { } // uncomment for testing --v - TorStatusObservable.setProxyPort(startTorProxy()); + /* try { + startTorProxy(); + } catch (InterruptedException | TimeoutException e) { + e.printStackTrace(); + } */ Bundle result = new Bundle(); switch (action) { @@ -287,35 +295,38 @@ public abstract class ProviderApiManagerBase { } } - protected int startTorProxy() { - int port = -1; - if (PreferenceHelper.useTor(preferences) && EipStatus.getInstance().isDisconnected() ) { - port = serviceCallback.getTorHttpTunnelPort(); - if (port != -1) { - try { - waitForTorCircuits(); - } catch (InterruptedException e) { - e.printStackTrace(); - port = -1; - } - } + protected boolean startTorProxy() throws InterruptedException, TimeoutException { + if (PreferenceHelper.useTor(preferences) && + EipStatus.getInstance().isDisconnected() && + serviceCallback.isConnectedToWifi() + ) { + serviceCallback.startTorService(); + waitForTorCircuits(); + int port = serviceCallback.getTorHttpTunnelPort(); + TorStatusObservable.setProxyPort(port); + return port != -1; } - return port; + return false; } - private void waitForTorCircuits() throws InterruptedException { + private void waitForTorCircuits() throws InterruptedException, TimeoutException { if (TorStatusObservable.getStatus() == ON) { return; } CountDownLatch countDownLatch = new CountDownLatch(1); + AtomicBoolean successfulSetup = new AtomicBoolean(false); Observer observer = (o, arg) -> { if (TorStatusObservable.getStatus() == ON) { + successfulSetup.set(true); countDownLatch.countDown(); } }; TorStatusObservable.getInstance().addObserver(observer); countDownLatch.await(180, TimeUnit.SECONDS); TorStatusObservable.getInstance().deleteObserver(observer); + if (!successfulSetup.get()) { + throw new TimeoutException("Timeout reached"); + } } void resetProviderDetails(Provider provider) { diff --git a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java index fc1f0f59..3067c1bf 100644 --- a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java +++ b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java @@ -28,6 +28,7 @@ import org.json.JSONObject; import java.io.IOException; import java.net.URL; import java.util.List; +import java.util.concurrent.TimeoutException; import de.blinkt.openvpn.core.VpnStatus; import okhttp3.OkHttpClient; @@ -325,17 +326,21 @@ public class ProviderApiManager extends ProviderApiManagerBase { } } - if (tries == 0 && - responseString != null && - responseString.contains(ERRORS) && - PreferenceHelper.useTor(preferences) && - EipStatus.getInstance().isDisconnected() && - (TorStatusObservable.getStatus() == OFF || - TorStatusObservable.getStatus() == UNKOWN)) { - TorStatusObservable.setProxyPort(startTorProxy()); - return downloadWithCommercialCA(stringUrl, provider, 1); + try { + if (tries == 0 && + responseString != null && + responseString.contains(ERRORS) && + PreferenceHelper.useTor(preferences) && + EipStatus.getInstance().isDisconnected() && + (TorStatusObservable.getStatus() == OFF || + TorStatusObservable.getStatus() == UNKOWN) && + startTorProxy() + ) { + return downloadWithCommercialCA(stringUrl, provider, 1); + } + } catch (InterruptedException | TimeoutException e) { + e.printStackTrace(); } - return responseString; } @@ -366,15 +371,20 @@ public class ProviderApiManager extends ProviderApiManagerBase { List> headerArgs = getAuthorizationHeader(); responseString = sendGetStringToServer(urlString, headerArgs, okHttpClient); - if (tries == 0 && - responseString != null && - responseString.contains(ERRORS) && - PreferenceHelper.useTor(preferences) && - EipStatus.getInstance().isDisconnected() && - (TorStatusObservable.getStatus() == OFF || - TorStatusObservable.getStatus() == UNKOWN)) { - TorStatusObservable.setProxyPort(startTorProxy()); - return downloadFromUrlWithProviderCA(urlString, provider, 1); + try { + if (tries == 0 && + responseString != null && + responseString.contains(ERRORS) && + PreferenceHelper.useTor(preferences) && + EipStatus.getInstance().isDisconnected() && + (TorStatusObservable.getStatus() == OFF || + TorStatusObservable.getStatus() == UNKOWN) && + startTorProxy() + ) { + return downloadFromUrlWithProviderCA(urlString, provider, 1); + } + } catch (InterruptedException | TimeoutException e) { + e.printStackTrace(); } return responseString; -- cgit v1.2.3 From cdd97d8bcc65ad80ed1060b297650b8350b27a56 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 2 Oct 2021 13:36:31 +0200 Subject: add log to see if a fetch was successful --- app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java index 1a2d8769..a71a5613 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java @@ -73,6 +73,7 @@ import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_DOWNLO import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.PROVIDER_NOK; +import static se.leap.bitmaskclient.providersetup.ProviderAPI.PROVIDER_OK; import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF; /** @@ -213,6 +214,11 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta Intent stopIntent = new Intent(context, TorService.class); context.stopService(stopIntent); } + Log.d(TAG, "PROVIDER NOK - FETCH FAILED"); + break; + case PROVIDER_OK: + Log.d(TAG, "PROVIDER OK - FETCH SUCCESSFUL"); + break; default: break; } -- cgit v1.2.3 From 0f39fcfc827404a58153941d7ce1b57d272f56d7 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 2 Oct 2021 15:16:05 +0200 Subject: show snowflake logs in logcat --- .../bitmaskclient/tor/ClientTransportPlugin.java | 48 +++++++++++++++++++--- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java b/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java index 9e3828de..d0385d1e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java @@ -1,6 +1,7 @@ package se.leap.bitmaskclient.tor; import android.content.Context; +import android.os.FileObserver; import android.util.Log; import androidx.annotation.Nullable; @@ -9,10 +10,14 @@ import org.torproject.jni.ClientTransportPluginInterface; import java.io.BufferedReader; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.lang.ref.WeakReference; +import java.util.Collection; import java.util.HashMap; +import java.util.Scanner; +import java.util.Vector; import IPtProxy.IPtProxy; @@ -22,6 +27,7 @@ public class ClientTransportPlugin implements ClientTransportPluginInterface { private HashMap mFronts; private final WeakReference contextRef; private long snowflakePort = -1; + private FileObserver logFileObserver; public ClientTransportPlugin(Context context) { this.contextRef = new WeakReference<>(context); @@ -36,12 +42,13 @@ public class ClientTransportPlugin implements ClientTransportPluginInterface { } File logfile = new File(context.getApplicationContext().getCacheDir(), "snowflake.log"); Log.d(TAG, "logfile at " + logfile.getAbsolutePath()); - if (!logfile.exists()) { - try { - logfile.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); + try { + if (logfile.exists()) { + logfile.delete(); } + logfile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); } //this is using the current, default Tor snowflake infrastructure @@ -51,12 +58,43 @@ public class ClientTransportPlugin implements ClientTransportPluginInterface { Log.d(TAG, "startSnowflake. target: " + target + ", front:" + front + ", stunServer" + stunServer); snowflakePort = IPtProxy.startSnowflake( stunServer, target, front, logfile.getAbsolutePath(), false, false, true, 1); Log.d(TAG, "startSnowflake running on port: " + snowflakePort); + watchLogFile(logfile); + } + + private void watchLogFile(File logfile) { + final Vector lastBuffer = new Vector<>(); + logFileObserver = new FileObserver(logfile) { + @Override + public void onEvent(int event, @Nullable String name) { + if (FileObserver.MODIFY == event) { + try (Scanner scanner = new Scanner(logfile)) { + Vector currentBuffer = new Vector<>(); + while (scanner.hasNextLine()) { + currentBuffer.add(scanner.nextLine()); + } + if (lastBuffer.size() < currentBuffer.size()) { + int startIndex = lastBuffer.size() > 0 ? lastBuffer.size() - 1 : 0; + int endIndex = currentBuffer.size() - 1; + Collection newMessages = currentBuffer.subList(startIndex, endIndex); + for (String message : newMessages) { + Log.d("[SNOWFLAKE]", message); + } + lastBuffer.addAll(newMessages); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + } + }; + logFileObserver.startWatching(); } @Override public void stop() { IPtProxy.stopSnowflake(); snowflakePort = -1; + logFileObserver.stopWatching(); } @Override -- cgit v1.2.3 From 1d6bdaf993b2235f7ebc7ca9d2f3ebc5dee8c9cc Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 2 Oct 2021 15:18:32 +0200 Subject: set max snowflake peers to 5 for now --- app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java b/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java index d0385d1e..0fd51d15 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java @@ -56,7 +56,7 @@ public class ClientTransportPlugin implements ClientTransportPluginInterface { String front = getCdnFront("snowflake-front"); String stunServer = getCdnFront("snowflake-stun"); Log.d(TAG, "startSnowflake. target: " + target + ", front:" + front + ", stunServer" + stunServer); - snowflakePort = IPtProxy.startSnowflake( stunServer, target, front, logfile.getAbsolutePath(), false, false, true, 1); + snowflakePort = IPtProxy.startSnowflake( stunServer, target, front, logfile.getAbsolutePath(), false, false, true, 5); Log.d(TAG, "startSnowflake running on port: " + snowflakePort); watchLogFile(logfile); } -- cgit v1.2.3 From f8728ee91559e5d87f4bf51ba9348dd10a846325 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 2 Oct 2021 15:23:12 +0200 Subject: update tor-android --- tor-android | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tor-android b/tor-android index dceeebf1..016f06df 160000 --- a/tor-android +++ b/tor-android @@ -1 +1 @@ -Subproject commit dceeebf1130f990332f324907359a94a5b994a11 +Subproject commit 016f06df593fb69d46f8f0775dc02131d82c82b8 -- cgit v1.2.3 From a32b6cf537cadd895d161c3c589c14ffb97de9c5 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 16 Oct 2021 11:54:53 +0200 Subject: update tor-android --- tor-android | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tor-android b/tor-android index 016f06df..fdacce53 160000 --- a/tor-android +++ b/tor-android @@ -1 +1 @@ -Subproject commit 016f06df593fb69d46f8f0775dc02131d82c82b8 +Subproject commit fdacce53b8648b2c1d3c260d7fa1b5778aa2851a -- cgit v1.2.3 From dac7d9ce22f1eb2a96cc8a3a0fc34e6c3d4c9291 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 16 Oct 2021 11:56:25 +0200 Subject: update shapeshifter jni bindings --- .../se/leap/bitmaskclient/pluggableTransports/Shapeshifter.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/Shapeshifter.java b/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/Shapeshifter.java index 828b90ba..970703cc 100644 --- a/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/Shapeshifter.java +++ b/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/Shapeshifter.java @@ -27,7 +27,7 @@ import java.util.Observer; import de.blinkt.openvpn.core.ConnectionStatus; import de.blinkt.openvpn.core.VpnStatus; import se.leap.bitmaskclient.eip.EipStatus; -import shapeShifter.ShapeShifter_; +import shapeshifter.ShapeShifter; public class Shapeshifter implements Observer { @@ -37,13 +37,13 @@ public class Shapeshifter implements Observer { private static final int RETRY_TIME = 4000; private static final String TAG = Shapeshifter.class.getSimpleName(); - private final ShapeShifter_ shapeShifter; + private final shapeshifter.ShapeShifter shapeShifter; private boolean isErrorHandling; private boolean noNetwork; private int retry = 0; private final Handler reconnectHandler; - public class ShapeshifterLogger implements shapeShifter.Logger { + public class ShapeshifterLogger implements shapeshifter.Logger { @Override public void log(String s) { Log.e(TAG, "SHAPESHIFTER ERROR: " + s); @@ -61,7 +61,7 @@ public class Shapeshifter implements Observer { } public Shapeshifter(Obfs4Options options) { - shapeShifter = new ShapeShifter_(); + shapeShifter = new ShapeShifter(); shapeShifter.setLogger(new ShapeshifterLogger()); setup(options); Looper.prepare(); -- 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 --- .../leap/bitmaskclient/eip/EipSetupObserver.java | 4 +- .../bitmaskclient/tor/TorNotificationManager.java | 13 +++- .../bitmaskclient/tor/TorStatusObservable.java | 77 +++++++++++++++++++++- app/src/main/res/values/strings.xml | 18 ++++- 4 files changed, 104 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java index a71a5613..23fbdc0c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java @@ -169,7 +169,9 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta private void handleTorStatusEvent(Intent intent) { String status = intent.getStringExtra(TorService.EXTRA_STATUS); Log.d(TAG, "handle Tor status event: " + status); - TorStatusObservable.updateState(context, status); + Integer bootstrap = intent.getIntExtra(TorService.EXTRA_STATUS_DETAIL_BOOTSTRAP, -1); + String logKey = intent.getStringExtra(TorService.EXTRA_STATUS_DETAIL_LOGKEY); + TorStatusObservable.updateState(context, status, bootstrap, logKey); } diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java index a2401732..8148fd94 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java @@ -50,7 +50,7 @@ public class TorNotificationManager { .setContentText(context.getString(R.string.tor_started)).build(); } - public void buildTorNotification(Context context, String state) { + public void buildTorNotification(Context context, String state, String message, int progress) { NotificationManager notificationManager = initNotificationManager(context); if (notificationManager == null) { return; @@ -59,8 +59,15 @@ public class TorNotificationManager { notificationBuilder .setSmallIcon(R.drawable.ic_bridge_36) .setWhen(System.currentTimeMillis()) - .setTicker(state) - .setContentText(state); + .setStyle(new NotificationCompat.BigTextStyle(). + setBigContentTitle(state). + bigText(message)) + .setTicker(message) + .setContentTitle(state) + .setContentText(message); + if (progress > 0) { + notificationBuilder.setProgress(100, progress, false); + } notificationManager.notify(TOR_SERVICE_NOTIFICATION_ID, notificationBuilder.build()); } 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(); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7c0e6334..dfb0db0e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -155,8 +155,24 @@ Automatic Your traffic is currently routed through: - Starting bridges for censorship circumvention. Please hold on… + Starting bridges for censorship circumvention… Stopping bridges. Using bridges for censorship circumvention. + Connected to pluggable transport + Connecting to pluggable transport + Connected to a relay + Handshaking with a relay + Handshake with a relay done + Establishing an encrypted directory connection + Asking for networkstatus consensus + Loading networkstatus consensus + Loading authority key certs + Asking for relay descriptors + Loading relay descriptors + Loaded enough directory info to build circuits + Handshake finished with a relay to build circuits + Establishing a Tor circuit + Done! + -- cgit v1.2.3 From eeafd2b56a7996b163072e57cec549b9769ccd0d Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 16 Oct 2021 12:00:23 +0200 Subject: don't recompile pattern in while loop --- app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java index fc77d9a5..9d307b02 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java @@ -140,6 +140,8 @@ public class OpenVPNThread implements Runnable { InputStream in = mProcess.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); + // 1380308330.240114 18000002 Send to HTTP proxy: 'X-Online-Host: bla.blabla.com' + Pattern p = Pattern.compile("(\\d+).(\\d+) ([0-9a-f])+ (.*)"); while (true) { String logline = br.readLine(); if (logline == null) @@ -151,10 +153,6 @@ public class OpenVPNThread implements Runnable { if (logline.startsWith(BROKEN_PIE_SUPPORT) || logline.contains(BROKEN_PIE_SUPPORT2)) mBrokenPie = true; - - // 1380308330.240114 18000002 Send to HTTP proxy: 'X-Online-Host: bla.blabla.com' - - Pattern p = Pattern.compile("(\\d+).(\\d+) ([0-9a-f])+ (.*)"); Matcher m = p.matcher(logline); int logerror = 0; if (m.matches()) { -- 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/ClientTransportPlugin.java | 24 ++++++++++++- .../bitmaskclient/tor/TorStatusObservable.java | 42 +++++++++++++++------- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java b/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java index 0fd51d15..1d2b7cea 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java @@ -18,6 +18,8 @@ import java.util.Collection; import java.util.HashMap; import java.util.Scanner; import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import IPtProxy.IPtProxy; @@ -28,6 +30,7 @@ public class ClientTransportPlugin implements ClientTransportPluginInterface { private final WeakReference contextRef; private long snowflakePort = -1; private FileObserver logFileObserver; + private static final Pattern SNOWFLAKE_LOG_TIMESTAMP_PATTERN = Pattern.compile("((19|2[0-9])[0-9]{2}\\/\\d{1,2}\\/\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}) ([\\S|\\s]+)"); public ClientTransportPlugin(Context context) { this.contextRef = new WeakReference<>(context); @@ -77,7 +80,7 @@ public class ClientTransportPlugin implements ClientTransportPluginInterface { int endIndex = currentBuffer.size() - 1; Collection newMessages = currentBuffer.subList(startIndex, endIndex); for (String message : newMessages) { - Log.d("[SNOWFLAKE]", message); + logSnowflakeMessage(message); } lastBuffer.addAll(newMessages); } @@ -130,4 +133,23 @@ public class ClientTransportPlugin implements ClientTransportPluginInterface { } return null; } + + private void logSnowflakeMessage(String message) { + Matcher matcher = SNOWFLAKE_LOG_TIMESTAMP_PATTERN.matcher(message); + if (matcher.matches()) { + try { + + String strippedString = matcher.group(3).trim(); + Log.d(TAG, "log: " + message); + Log.d(TAG, "log stripped: " + strippedString); + if (strippedString.length() > 0) { + TorStatusObservable.logSnowflakeMessage(contextRef.get(), strippedString); + } + } catch (IndexOutOfBoundsException | IllegalStateException e) { + e.printStackTrace(); + } + } else { + TorStatusObservable.logSnowflakeMessage(contextRef.get(), message); + } + } } 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 f6b8a78812c46679cf416edc303d88e840750827 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 16 Oct 2021 13:52:24 +0200 Subject: cleanup imports --- .../main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java index 8148fd94..45570857 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorNotificationManager.java @@ -23,12 +23,9 @@ import android.app.NotificationManager; import android.content.Context; import android.os.Build; -import androidx.annotation.NonNull; import androidx.core.app.NotificationCompat; import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.base.models.Provider; -import se.leap.bitmaskclient.base.models.ProviderObservable; public class TorNotificationManager { public final static int TOR_SERVICE_NOTIFICATION_ID = 10; -- cgit v1.2.3 From 527c814c56626ed147778ac1e0ddabe70cb51280 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 16 Oct 2021 14:12:05 +0200 Subject: tweak tor done progess string --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dfb0db0e..4c5cffd4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -172,7 +172,7 @@ Loaded enough directory info to build circuits Handshake finished with a relay to build circuits Establishing a Tor circuit - Done! + Running -- cgit v1.2.3 From b4854af31a5026dd5129d994dd9d505dc4a63d70 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 16 Oct 2021 14:15:11 +0200 Subject: remove unneeded logs --- app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java b/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java index 1d2b7cea..6228453e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/ClientTransportPlugin.java @@ -138,10 +138,7 @@ public class ClientTransportPlugin implements ClientTransportPluginInterface { Matcher matcher = SNOWFLAKE_LOG_TIMESTAMP_PATTERN.matcher(message); if (matcher.matches()) { try { - String strippedString = matcher.group(3).trim(); - Log.d(TAG, "log: " + message); - Log.d(TAG, "log stripped: " + strippedString); if (strippedString.length() > 0) { TorStatusObservable.logSnowflakeMessage(contextRef.get(), strippedString); } -- 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(-) 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 --- .../activities/ConfigWizardBaseActivity.java | 161 ++++++++++++++++++++- .../bitmaskclient/tor/TorStatusObservable.java | 23 ++- app/src/main/res/drawable/ic_snowflake.png | Bin 0 -> 2653 bytes app/src/main/res/drawable/ic_tor.png | Bin 0 -> 10221 bytes app/src/main/res/drawable/v_vertical_gradient.xml | 8 + .../main/res/layout-xlarge/v_loading_screen.xml | 138 ++++++++++++++++++ app/src/main/res/layout/v_add_provider.xml | 57 -------- app/src/main/res/layout/v_loading_screen.xml | 139 +++++++++++++++++- app/src/main/res/layout/v_log_item.xml | 16 ++ app/src/main/res/values/strings.xml | 1 + 10 files changed, 474 insertions(+), 69 deletions(-) create mode 100644 app/src/main/res/drawable/ic_snowflake.png create mode 100644 app/src/main/res/drawable/ic_tor.png create mode 100644 app/src/main/res/drawable/v_vertical_gradient.xml delete mode 100644 app/src/main/res/layout/v_add_provider.xml create mode 100644 app/src/main/res/layout/v_log_item.xml diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java index 7d452200..a0c046de 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java @@ -5,20 +5,28 @@ import android.graphics.PorterDuff; import android.graphics.Rect; import android.os.Build; import android.os.Bundle; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; +import android.widget.Button; import android.widget.LinearLayout; import android.widget.ProgressBar; +import android.widget.RelativeLayout; import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.appcompat.widget.AppCompatTextView; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.Guideline; import androidx.core.content.ContextCompat; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import java.util.List; import java.util.Observable; import java.util.Observer; @@ -31,8 +39,14 @@ import se.leap.bitmaskclient.tor.TorStatusObservable; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.view.View.GONE; import static android.view.View.VISIBLE; +import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY; import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES; +import static se.leap.bitmaskclient.tor.TorStatusObservable.getBootstrapProgress; +import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastLogs; +import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastSnowflakeLog; +import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastTorLog; +import static se.leap.bitmaskclient.tor.TorStatusObservable.getStringForCurrentStatus; /** * Base Activity for configuration wizard activities @@ -54,6 +68,32 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity imple @BindView(R.id.loading_screen) protected LinearLayout loadingScreen; + @Nullable + @BindView(R.id.btn_connection_detail) + protected Button connectionDetailBtn; + + @Nullable + @BindView(R.id.connection_detail_container) + protected RelativeLayout connectionDetailContainer; + + @Nullable + @BindView(R.id.log_container) + protected RelativeLayout logsContainer; + + @Nullable + @BindView(R.id.tor_state) + protected AppCompatTextView torState; + + @Nullable + @BindView(R.id.snowflake_state) + protected AppCompatTextView snowflakeState; + + @Nullable + @BindView(R.id.connection_detail_logs) + protected RecyclerView connectionDetailLogs; + + private TorLogAdapter torLogAdapter; + @Nullable @BindView(R.id.progressbar) protected ProgressBar progressBar; @@ -157,7 +197,7 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity imple super.onResume(); isActivityShowing = true; TorStatusObservable.getInstance().addObserver(this); - setProgressbarDescription(TorStatusObservable.getStringForCurrentStatus(this)); + setProgressbarDescription(getStringForCurrentStatus(this)); } protected void restoreState(Bundle savedInstanceState) { @@ -178,10 +218,48 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity imple providerHeaderView.setTitle(providerHeaderText); } + protected void showConnectionDetails() { + if (loadingScreen == null) { + return; + } + LinearLayoutManager layoutManager = new LinearLayoutManager(this); + connectionDetailLogs.setLayoutManager(layoutManager); + connectionDetailLogs.addItemDecoration( new DividerItemDecoration(this, layoutManager.getOrientation())); + torLogAdapter = new TorLogAdapter(getLastLogs()); + connectionDetailLogs.setAdapter(torLogAdapter); + + connectionDetailLogs.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { + super.onScrollStateChanged(recyclerView, newState); + if (newState != SCROLL_STATE_IDLE) { + torLogAdapter.postponeUpdate = true; + } else if (newState == SCROLL_STATE_IDLE && getFirstVisibleItemPosion() == 0) { + torLogAdapter.postponeUpdate = false; + } + } + }); + + snowflakeState.setText(getLastSnowflakeLog()); + torState.setText(getLastTorLog()); + connectionDetailBtn.setOnClickListener(v -> { + connectionDetailBtn.setVisibility(GONE); + logsContainer.setVisibility(VISIBLE); + }); + connectionDetailContainer.setVisibility(VISIBLE); + } + + private int getFirstVisibleItemPosion() { + return ((LinearLayoutManager)connectionDetailLogs.getLayoutManager()).findFirstVisibleItemPosition(); + } + protected void hideProgressBar() { if (loadingScreen == null) { return; } + connectionDetailBtn.setVisibility(VISIBLE); + connectionDetailContainer.setVisibility(GONE); + logsContainer.setVisibility(GONE); loadingScreen.setVisibility(GONE); content.setVisibility(VISIBLE); } @@ -195,19 +273,28 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity imple } protected void setProgressbarTitle(@StringRes int progressbarTitle) { - if (this.progressbarTitle == null) { + if (loadingScreen == null) { return; } this.progressbarTitle.setText(progressbarTitle); } protected void setProgressbarDescription(String progressbarDescription) { - if (this.progressbarDescription == null) { + if (loadingScreen == null) { return; } this.progressbarDescription.setText(progressbarDescription); } + protected void setConfigProgress(int value) { + if (loadingScreen == null) { + return; + } + + progressBar.setProgress(value, true); + progressBar.setIndeterminate(value >= 100 || value < 0); + } + protected void showCompactLayout() { if (isCompactLayout) { @@ -307,7 +394,73 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity imple @Override public void update(Observable o, Object arg) { if (o instanceof TorStatusObservable) { - runOnUiThread(() -> setProgressbarDescription(TorStatusObservable.getStringForCurrentStatus(ConfigWizardBaseActivity.this))); + runOnUiThread(() -> { + if (TorStatusObservable.getStatus() != TorStatusObservable.TorStatus.OFF && loadingScreen != null) { + if (connectionDetailContainer.getVisibility() == GONE) { + showConnectionDetails(); + } else { + setLogs(getLastTorLog(), getLastSnowflakeLog(), getLastLogs()); + } + } + setProgressbarDescription(getStringForCurrentStatus(ConfigWizardBaseActivity.this)); + setConfigProgress(getBootstrapProgress()); + }); + } + } + + protected void setLogs(String torLog, String snowflakeLog, List lastLogs) { + if (loadingScreen == null) { + return; + } + torLogAdapter.updateData(lastLogs); + torState.setText(torLog); + snowflakeState.setText(snowflakeLog); + } + + static class TorLogAdapter extends RecyclerView.Adapter { + private List values; + private boolean postponeUpdate; + + static class ViewHolder extends RecyclerView.ViewHolder { + public AppCompatTextView logTextLabel; + public View layout; + + public ViewHolder(View v) { + super(v); + layout = v; + logTextLabel = v.findViewById(android.R.id.text1); + } + } + + public void updateData(List data) { + values = data; + if (!postponeUpdate) { + notifyDataSetChanged(); + } + } + + public TorLogAdapter(List data) { + values = data; + } + + @NonNull + @Override + public TorLogAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + LayoutInflater inflater = LayoutInflater.from( + parent.getContext()); + View v = inflater.inflate(R.layout.v_log_item, parent, false); + return new TorLogAdapter.ViewHolder(v); + } + + @Override + public void onBindViewHolder(TorLogAdapter.ViewHolder holder, final int position) { + final String log = values.get(position); + holder.logTextLabel.setText(log); + } + + @Override + public int getItemCount() { + return values.size(); } } } 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) { diff --git a/app/src/main/res/drawable/ic_snowflake.png b/app/src/main/res/drawable/ic_snowflake.png new file mode 100644 index 00000000..992662ee Binary files /dev/null and b/app/src/main/res/drawable/ic_snowflake.png differ diff --git a/app/src/main/res/drawable/ic_tor.png b/app/src/main/res/drawable/ic_tor.png new file mode 100644 index 00000000..a5f9ae89 Binary files /dev/null and b/app/src/main/res/drawable/ic_tor.png differ diff --git a/app/src/main/res/drawable/v_vertical_gradient.xml b/app/src/main/res/drawable/v_vertical_gradient.xml new file mode 100644 index 00000000..877634b5 --- /dev/null +++ b/app/src/main/res/drawable/v_vertical_gradient.xml @@ -0,0 +1,8 @@ + + + + diff --git a/app/src/main/res/layout-xlarge/v_loading_screen.xml b/app/src/main/res/layout-xlarge/v_loading_screen.xml index ed25f07b..0b71099e 100644 --- a/app/src/main/res/layout-xlarge/v_loading_screen.xml +++ b/app/src/main/res/layout-xlarge/v_loading_screen.xml @@ -56,4 +56,142 @@ android:layout_marginTop="@dimen/standard_margin" /> + + + + + + + + +