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 --- .../providersetup/ProviderApiManager.java | 55 ++++++++++++++++++---- 1 file changed, 46 insertions(+), 9 deletions(-) (limited to 'app/src/production') 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 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(-) (limited to 'app/src/production') 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 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 --- .../providersetup/ProviderApiManager.java | 48 +++++++++++++--------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'app/src/production') 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 62d2bdacec6c54f4453f1ad20425e99254998e9a Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 23 Oct 2021 00:59:46 +0200 Subject: rename usePluggableTransports prefrence to useBridges, start snowflake if useBridges is true --- .../java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app/src/production') 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 3067c1bf..6ca3e949 100644 --- a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java +++ b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java @@ -330,7 +330,7 @@ public class ProviderApiManager extends ProviderApiManagerBase { if (tries == 0 && responseString != null && responseString.contains(ERRORS) && - PreferenceHelper.useTor(preferences) && + PreferenceHelper.getUseBridges(preferences) && EipStatus.getInstance().isDisconnected() && (TorStatusObservable.getStatus() == OFF || TorStatusObservable.getStatus() == UNKOWN) && @@ -375,7 +375,7 @@ public class ProviderApiManager extends ProviderApiManagerBase { if (tries == 0 && responseString != null && responseString.contains(ERRORS) && - PreferenceHelper.useTor(preferences) && + PreferenceHelper.getUseBridges(preferences) && EipStatus.getInstance().isDisconnected() && (TorStatusObservable.getStatus() == OFF || TorStatusObservable.getStatus() == UNKOWN) && -- cgit v1.2.3 From d27af3b17d6636de8b2755090b6fe6329531f639 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 4 Nov 2021 16:45:54 +0100 Subject: remove unused UNKNOWN TorStatus state --- .../se/leap/bitmaskclient/providersetup/ProviderApiManager.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'app/src/production') 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 6ca3e949..c60e21dc 100644 --- a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java +++ b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java @@ -57,7 +57,6 @@ 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; /** @@ -332,8 +331,7 @@ public class ProviderApiManager extends ProviderApiManagerBase { responseString.contains(ERRORS) && PreferenceHelper.getUseBridges(preferences) && EipStatus.getInstance().isDisconnected() && - (TorStatusObservable.getStatus() == OFF || - TorStatusObservable.getStatus() == UNKOWN) && + TorStatusObservable.getStatus() == OFF && startTorProxy() ) { return downloadWithCommercialCA(stringUrl, provider, 1); @@ -377,8 +375,7 @@ public class ProviderApiManager extends ProviderApiManagerBase { responseString.contains(ERRORS) && PreferenceHelper.getUseBridges(preferences) && EipStatus.getInstance().isDisconnected() && - (TorStatusObservable.getStatus() == OFF || - TorStatusObservable.getStatus() == UNKOWN) && + TorStatusObservable.getStatus() == OFF && startTorProxy() ) { return downloadFromUrlWithProviderCA(urlString, provider, 1); -- cgit v1.2.3 From 88b7dc2eb3dcbec8d1e637096867c15211818677 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 5 Nov 2021 02:38:26 +0100 Subject: Ensure tor state is set to OFF after snowflake completely stopped. --- .../java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app/src/production') 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 c60e21dc..ceb3be3e 100644 --- a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java +++ b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java @@ -336,7 +336,7 @@ public class ProviderApiManager extends ProviderApiManagerBase { ) { return downloadWithCommercialCA(stringUrl, provider, 1); } - } catch (InterruptedException | TimeoutException e) { + } catch (InterruptedException | IllegalStateException | TimeoutException e) { e.printStackTrace(); } return responseString; @@ -380,7 +380,7 @@ public class ProviderApiManager extends ProviderApiManagerBase { ) { return downloadFromUrlWithProviderCA(urlString, provider, 1); } - } catch (InterruptedException | TimeoutException e) { + } catch (InterruptedException | IllegalStateException | TimeoutException e) { e.printStackTrace(); } -- cgit v1.2.3 From eb434ae79f45dfd5c14c0901c414a287221442d4 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 6 Nov 2021 02:52:38 +0100 Subject: fix tor provider setup fallback mechanism --- .../java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java | 4 ---- 1 file changed, 4 deletions(-) (limited to 'app/src/production') 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 ceb3be3e..dfd1bfbf 100644 --- a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java +++ b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java @@ -329,8 +329,6 @@ public class ProviderApiManager extends ProviderApiManagerBase { if (tries == 0 && responseString != null && responseString.contains(ERRORS) && - PreferenceHelper.getUseBridges(preferences) && - EipStatus.getInstance().isDisconnected() && TorStatusObservable.getStatus() == OFF && startTorProxy() ) { @@ -373,8 +371,6 @@ public class ProviderApiManager extends ProviderApiManagerBase { if (tries == 0 && responseString != null && responseString.contains(ERRORS) && - PreferenceHelper.getUseBridges(preferences) && - EipStatus.getInstance().isDisconnected() && TorStatusObservable.getStatus() == OFF && startTorProxy() ) { -- cgit v1.2.3 From 5e4003572133c4bd4e31c831d6bf3729425aca29 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Mon, 8 Nov 2021 01:02:11 +0100 Subject: Don't allow fallback tor mechanism for failed geoip service calls. --- .../providersetup/ProviderApiManager.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'app/src/production') 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 dfd1bfbf..5416b1f8 100644 --- a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java +++ b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java @@ -245,7 +245,7 @@ public class ProviderApiManager extends ProviderApiManagerBase { try { URL geoIpUrl = provider.getGeoipUrl().getUrl(); - String geoipJsonString = downloadFromUrlWithProviderCA(geoIpUrl.toString(), provider); + String geoipJsonString = downloadFromUrlWithProviderCA(geoIpUrl.toString(), provider, false); if (DEBUG_MODE) { VpnStatus.logDebug("[API] MENSHEN JSON: " + geoipJsonString); } @@ -292,14 +292,14 @@ public class ProviderApiManager extends ProviderApiManagerBase { } private String downloadWithCommercialCA(String stringUrl, Provider provider) { - return downloadWithCommercialCA(stringUrl, provider, 0); + return downloadWithCommercialCA(stringUrl, provider, true); } /** * 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) { + private String downloadWithCommercialCA(String stringUrl, Provider provider, boolean allowRetry) { String responseString; JSONObject errorJson = new JSONObject(); @@ -326,13 +326,13 @@ public class ProviderApiManager extends ProviderApiManagerBase { } try { - if (tries == 0 && + if (allowRetry && responseString != null && responseString.contains(ERRORS) && TorStatusObservable.getStatus() == OFF && startTorProxy() ) { - return downloadWithCommercialCA(stringUrl, provider, 1); + return downloadWithCommercialCA(stringUrl, provider, false); } } catch (InterruptedException | IllegalStateException | TimeoutException e) { e.printStackTrace(); @@ -353,10 +353,10 @@ public class ProviderApiManager extends ProviderApiManagerBase { } private String downloadFromUrlWithProviderCA(String urlString, Provider provider) { - return downloadFromUrlWithProviderCA(urlString, provider, 0); + return downloadFromUrlWithProviderCA(urlString, provider, true); } - private String downloadFromUrlWithProviderCA(String urlString, Provider provider, int tries) { + private String downloadFromUrlWithProviderCA(String urlString, Provider provider, boolean allowRetry) { String responseString; JSONObject errorJson = new JSONObject(); OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(provider.getCaCert(), getProxyPort(), errorJson); @@ -368,13 +368,13 @@ public class ProviderApiManager extends ProviderApiManagerBase { responseString = sendGetStringToServer(urlString, headerArgs, okHttpClient); try { - if (tries == 0 && + if (allowRetry && responseString != null && responseString.contains(ERRORS) && TorStatusObservable.getStatus() == OFF && startTorProxy() ) { - return downloadFromUrlWithProviderCA(urlString, provider, 1); + return downloadFromUrlWithProviderCA(urlString, provider, false); } } catch (InterruptedException | IllegalStateException | TimeoutException e) { e.printStackTrace(); -- cgit v1.2.3