diff options
author | cyBerta <cyberta@riseup.net> | 2024-11-08 02:11:25 +0100 |
---|---|---|
committer | cyberta <cyberta@riseup.net> | 2024-12-11 00:09:34 +0000 |
commit | fc2b879b45a4a4caf7e14ba78e1782c9efc4558c (patch) | |
tree | d1c25ddfb3d20e41582d43f9f7c4552fce245f82 /app/src/main/java/se | |
parent | ddfa650c99af401d143bc4dbad7ff5ed68678907 (diff) |
alwaysy use bitmask-core to fetch provider.json, avoid downloading it twice
Diffstat (limited to 'app/src/main/java/se')
4 files changed, 52 insertions, 180 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java index 8ae5bfea..b370f0f6 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java @@ -1,15 +1,6 @@ package se.leap.bitmaskclient.providersetup; -import static se.leap.bitmaskclient.BuildConfig.DEBUG_MODE; -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_json_exception_user_message; -import static se.leap.bitmaskclient.R.string.error_no_such_algorithm_exception_user_message; import static se.leap.bitmaskclient.R.string.malformed_url; -import static se.leap.bitmaskclient.R.string.server_unreachable_message; -import static se.leap.bitmaskclient.R.string.service_is_down_error; -import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_details; -import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_RESULT_KEY; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY; import static se.leap.bitmaskclient.providersetup.ProviderAPI.DELAY; import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORS; @@ -19,17 +10,17 @@ import static se.leap.bitmaskclient.providersetup.ProviderAPI.PROVIDER_NOK; import static se.leap.bitmaskclient.providersetup.ProviderAPI.RECEIVER_KEY; import static se.leap.bitmaskclient.providersetup.ProviderAPI.TOR_EXCEPTION; import static se.leap.bitmaskclient.providersetup.ProviderAPI.TOR_TIMEOUT; -import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_CORRUPTED_PROVIDER_JSON; +import static se.leap.bitmaskclient.providersetup.ProviderApiManagerV5.PROXY_HOST; +import static se.leap.bitmaskclient.providersetup.ProviderApiManagerV5.SOCKS_PROXY_SCHEME; import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_TOR_TIMEOUT; +import static se.leap.bitmaskclient.providersetup.ProviderSetupObservable.DOWNLOADED_PROVIDER_JSON; import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF; -import static se.leap.bitmaskclient.tor.TorStatusObservable.getProxyPort; import android.content.Intent; import android.content.res.Resources; import android.os.Bundle; import android.os.ResultReceiver; import android.util.Log; -import android.util.Pair; import androidx.core.content.IntentCompat; @@ -37,26 +28,15 @@ import org.jetbrains.annotations.Blocking; import org.json.JSONException; import org.json.JSONObject; -import java.io.IOException; -import java.net.ConnectException; -import java.net.MalformedURLException; -import java.net.SocketTimeoutException; -import java.net.UnknownHostException; -import java.net.UnknownServiceException; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.TimeoutException; -import javax.net.ssl.SSLHandshakeException; -import javax.net.ssl.SSLPeerUnverifiedException; - import de.blinkt.openvpn.core.VpnStatus; -import okhttp3.OkHttpClient; +import mobile.BitmaskMobile; +import se.leap.bitmaskclient.BuildConfig; 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.providersetup.connectivity.OkHttpClientGenerator; import se.leap.bitmaskclient.tor.TorStatusObservable; public class ProviderApiManager extends ProviderApiManagerBase { @@ -87,7 +67,7 @@ public class ProviderApiManager extends ProviderApiManagerBase { provider = IntentCompat.getParcelableExtra(command, PROVIDER_KEY, Provider.class); } else { //TODO: consider returning error back e.g. NO_PROVIDER - Log.e(TAG, action +" called without provider!"); + Log.e(TAG, action + " called without provider!"); return; } @@ -123,9 +103,8 @@ public class ProviderApiManager extends ProviderApiManagerBase { return; } - if (!provider.hasDefinition()) { - downloadProviderDefinition(result, provider); + result = downloadProviderDefinition(result, provider); if (result.containsKey(ERRORS)) { eventSender.sendToReceiverOrBroadcast(receiver, PROVIDER_NOK, result, provider); return; @@ -136,102 +115,52 @@ public class ProviderApiManager extends ProviderApiManagerBase { apiManager.handleAction(action, provider, parameters, receiver); } - private void downloadProviderDefinition(Bundle result, Provider provider) { + private Bundle downloadProviderDefinition(Bundle result, Provider provider) { getPersistedProviderUpdates(provider); if (provider.hasDefinition()) { - return; - } - getAndSetProviderJson(result, provider); - } - - private Bundle getAndSetProviderJson(Bundle result, Provider provider) { - String providerJsonUrl = provider.getMainUrl() + "/provider.json"; - String providerDotJsonString = fetch(providerJsonUrl, true); - - if (ConfigHelper.checkErroneousDownload(providerDotJsonString) || !isValidJson(providerDotJsonString)) { - return eventSender.setErrorResult(result, malformed_url, null); + return result; } - if (DEBUG_MODE) { - VpnStatus.logDebug("[API] PROVIDER JSON: " + providerDotJsonString); - } try { - JSONObject providerJson = new JSONObject(providerDotJsonString); - - if (provider.define(providerJson)) { - result.putBoolean(BROADCAST_RESULT_KEY, true); - } else { - return eventSender.setErrorResult(result, warning_corrupted_provider_details, ERROR_CORRUPTED_PROVIDER_JSON.toString()); + String providerString = fetch(provider, true); + if (ConfigHelper.checkErroneousDownload(providerString) || !isValidJson(providerString)) { + return eventSender.setErrorResult(result, malformed_url, null); } - } catch (JSONException e) { - return eventSender.setErrorResult(result, providerDotJsonString); + JSONObject jsonObject = new JSONObject(providerString); + provider.define(jsonObject); + provider.setModelsProvider(providerString); + ProviderSetupObservable.updateProgress(DOWNLOADED_PROVIDER_JSON); + } catch (Exception e) { + return eventSender.setErrorResult(result, R.string.malformed_url, null); } + return result; } - - - /** - * Tries to download the contents of the provided url using commercially validated CA certificate from chosen provider. - * - */ - private String fetch(String url, boolean allowRetry) { - - JSONObject errorJson = new JSONObject(); - OkHttpClientGenerator clientGenerator = new OkHttpClientGenerator(resources); - - OkHttpClient okHttpClient = clientGenerator.initCommercialCAHttpClient(errorJson, getProxyPort()); - List<Pair<String, String>> headerArgs = new ArrayList<>(); - if (okHttpClient == null) { - return errorJson.toString(); - } - - String plainResponseBody; - - try { - - plainResponseBody = ProviderApiConnector.requestStringFromServer(url, "GET", null, headerArgs, okHttpClient); - - } catch (NullPointerException npe) { - plainResponseBody = eventSender.formatErrorMessage(error_json_exception_user_message); - VpnStatus.logWarning("[API] Null response body for request " + url + ": " + npe.getLocalizedMessage()); - } catch (UnknownHostException | SocketTimeoutException e) { - plainResponseBody = eventSender.formatErrorMessage(server_unreachable_message); - VpnStatus.logWarning("[API] UnknownHostException or SocketTimeoutException for request " + url + ": " + e.getLocalizedMessage()); - } catch (MalformedURLException e) { - plainResponseBody = eventSender.formatErrorMessage(malformed_url); - VpnStatus.logWarning("[API] MalformedURLException for request " + url + ": " + e.getLocalizedMessage()); - } catch (SSLHandshakeException | SSLPeerUnverifiedException e) { - plainResponseBody = eventSender.formatErrorMessage(certificate_error); - VpnStatus.logWarning("[API] SSLHandshakeException or SSLPeerUnverifiedException for request " + url + ": " + e.getLocalizedMessage()); - } catch (ConnectException e) { - plainResponseBody = eventSender.formatErrorMessage(service_is_down_error); - VpnStatus.logWarning("[API] ConnectException for request " + url + ": " + e.getLocalizedMessage()); - } catch (IllegalArgumentException e) { - plainResponseBody = eventSender.formatErrorMessage(error_no_such_algorithm_exception_user_message); - VpnStatus.logWarning("[API] IllegalArgumentException for request " + url + ": " + e.getLocalizedMessage()); - } catch (UnknownServiceException e) { - //unable to find acceptable protocols - tlsv1.2 not enabled? - plainResponseBody = eventSender.formatErrorMessage(error_no_such_algorithm_exception_user_message); - VpnStatus.logWarning("[API] UnknownServiceException for request " + url + ": " + e.getLocalizedMessage()); - } catch (IOException e) { - plainResponseBody = eventSender.formatErrorMessage(error_io_exception_user_message); - VpnStatus.logWarning("[API] IOException for request " + url + ": " + e.getLocalizedMessage()); - } - + private String fetch(Provider provider, Boolean allowRetry) { + BitmaskMobile bm; try { - if (allowRetry && - plainResponseBody != null && - plainResponseBody.contains(ERRORS) && - TorStatusObservable.getStatus() == OFF && - torHandler.startTorProxy() - ) { - return fetch(url, false); + bm = new BitmaskMobile(provider.getMainUrl(), new PreferenceHelper.SharedPreferenceStore()); + bm.setDebug(BuildConfig.DEBUG); + if (TorStatusObservable.isRunning() && TorStatusObservable.getSocksProxyPort() != -1) { + bm.setSocksProxy(SOCKS_PROXY_SCHEME + PROXY_HOST + ":" + TorStatusObservable.getSocksProxyPort()); + } else if (provider.hasIntroducer()) { + bm.setIntroducer(provider.getIntroducer().toUrl()); + } + return bm.getProvider(); + } catch (Exception e) { + try { + if (allowRetry && + TorStatusObservable.getStatus() == OFF && + torHandler.startTorProxy() + ) { + return fetch(provider, false); + } + } catch (InterruptedException | TimeoutException ex) { + ex.printStackTrace(); } - } catch (InterruptedException | IllegalStateException | TimeoutException e) { - e.printStackTrace(); } - return plainResponseBody; + return 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 85af48b0..60a41325 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java @@ -17,8 +17,6 @@ package se.leap.bitmaskclient.providersetup; -import static se.leap.bitmaskclient.R.string.vpn_certificate_is_invalid; -import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_RESULT_KEY; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_MODELS_BRIDGES; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_MODELS_EIPSERVICE; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_MODELS_GATEWAYS; @@ -38,35 +36,20 @@ import static se.leap.bitmaskclient.base.utils.ConfigHelper.getDomainFromMainURL import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getFromPersistedProvider; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getLongFromPersistedProvider; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getStringSetFromPersistedProvider; -import static se.leap.bitmaskclient.base.utils.PrivateKeyHelper.ED_25519_KEY_BEGIN; -import static se.leap.bitmaskclient.base.utils.PrivateKeyHelper.ED_25519_KEY_END; -import static se.leap.bitmaskclient.base.utils.PrivateKeyHelper.RSA_KEY_BEGIN; -import static se.leap.bitmaskclient.base.utils.PrivateKeyHelper.RSA_KEY_END; -import static se.leap.bitmaskclient.base.utils.PrivateKeyHelper.parsePrivateKeyFromString; import android.content.Intent; import android.content.res.Resources; -import android.os.Bundle; -import android.util.Base64; - -import com.google.gson.JsonSyntaxException; import org.json.JSONException; import org.json.JSONObject; import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateException; import java.security.cert.X509Certificate; -import java.security.interfaces.RSAPrivateKey; import java.util.ArrayList; import java.util.Set; import java.util.concurrent.TimeoutException; -import io.swagger.client.JSON; -import io.swagger.client.model.ModelsBridge; -import io.swagger.client.model.ModelsProvider; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.base.utils.ConfigHelper; import se.leap.bitmaskclient.base.utils.PreferenceHelper; @@ -79,6 +62,8 @@ import se.leap.bitmaskclient.base.utils.PreferenceHelper; public abstract class ProviderApiManagerBase { private final static String TAG = ProviderApiManagerBase.class.getName(); + public static final String PROXY_HOST = "127.0.0.1"; + public static final String SOCKS_PROXY_SCHEME = "socks5://"; public interface ProviderApiServiceCallback { void broadcastEvent(Intent intent); @@ -213,24 +198,6 @@ public abstract class ProviderApiManagerBase { } } - protected ModelsProvider getPersistedModelsProvider(String providerDomain) { - try { - String json = getFromPersistedProvider(PROVIDER_MODELS_PROVIDER, providerDomain); - return json != null ? JSON.createGson().create().fromJson(json, ModelsProvider.class) : null; - } catch (JsonSyntaxException e) { - return null; - } - } - - protected ModelsBridge[] getPersistedModelsBridge(String providerDomain) { - try { - String json = getFromPersistedProvider(PROVIDER_MODELS_BRIDGES, providerDomain); - return json != null ? JSON.createGson().create().fromJson(json, ModelsBridge[].class) : null; - } catch (JsonSyntaxException e) { - return null; - } - } - protected long getPersistedMotdLastSeen(String providerDomain) { return getLongFromPersistedProvider(PROVIDER_MOTD_LAST_SEEN, providerDomain); } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV3.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV3.java index 0c6878c6..9f5d4853 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV3.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV3.java @@ -244,27 +244,15 @@ public class ProviderApiManagerV3 extends ProviderApiManagerBase implements IPro return currentDownload; } - getPersistedProviderUpdates(provider); - currentDownload = validateProviderDetails(provider); - - //provider certificate invalid - if (currentDownload.containsKey(ERRORS)) { - currentDownload.putParcelable(PROVIDER_KEY, provider); - return currentDownload; - } - - //no provider json or certificate available - if (currentDownload.containsKey(BROADCAST_RESULT_KEY) && !currentDownload.getBoolean(BROADCAST_RESULT_KEY)) { - resetProviderDetails(provider); + if (!provider.hasDefinition()) { + currentDownload = getAndSetProviderJson(provider); } - - currentDownload = getAndSetProviderJson(provider); - if (provider.hasDefinition() || (currentDownload.containsKey(BROADCAST_RESULT_KEY) && currentDownload.getBoolean(BROADCAST_RESULT_KEY))) { + if (provider.hasDefinition()) { ProviderSetupObservable.updateProgress(DOWNLOADED_PROVIDER_JSON); if (!provider.hasCaCert()) { currentDownload = downloadCACert(provider); } - if (provider.hasCaCert() || (currentDownload.containsKey(BROADCAST_RESULT_KEY) && currentDownload.getBoolean(BROADCAST_RESULT_KEY))) { + if (provider.hasCaCert()) { ProviderSetupObservable.updateProgress(DOWNLOADED_CA_CERT); currentDownload = getAndSetEipServiceJson(provider); } @@ -379,9 +367,9 @@ public class ProviderApiManagerV3 extends ProviderApiManagerBase implements IPro for (int i = 0; i < certAndKey.length - 1; i++) { if (certAndKey[i].contains("KEY")) { - keyString += certAndKey[i++] + certAndKey[i]; + keyString = certAndKey[i++] + certAndKey[i]; } else if (certAndKey[i].contains("CERTIFICATE")) { - certificateString += certAndKey[i++] + certAndKey[i]; + certificateString = certAndKey[i++] + certAndKey[i]; } } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV5.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV5.java index 16cb01a2..4b30b792 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV5.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerV5.java @@ -52,8 +52,6 @@ import se.leap.bitmaskclient.tor.TorStatusObservable; public class ProviderApiManagerV5 extends ProviderApiManagerBase implements IProviderApiManager { private static final String TAG = ProviderApiManagerV5.class.getSimpleName(); - private static final String PROXY_HOST = "127.0.0.1"; - private static final String SOCKS_PROXY_SCHEME = "socks5://"; ProviderApiManagerV5(Resources resources, ProviderApiServiceCallback callback) { super(resources, callback); @@ -123,9 +121,9 @@ public class ProviderApiManagerV5 extends ProviderApiManagerBase implements IPro // TODO: send failed to fetch bridges event } } else { - try { - String gatewaysJson = bm.getAllGateways("", "", ""); - provider.setGateways(gatewaysJson); + try { + String gatewaysJson = bm.getAllGateways("", "", ""); + provider.setGateways(gatewaysJson); } catch (Exception e) { // TODO: send return eventSender.setErrorResult(currentDownload, R.string.config_error_found, null); @@ -169,16 +167,6 @@ public class ProviderApiManagerV5 extends ProviderApiManagerBase implements IPro configureBaseCountryCode(bm, parameters); try { - String providerJson = bm.getProvider(); - Log.d(TAG, "provider Json reponse: " + providerJson); - provider.setModelsProvider(providerJson); - ProviderSetupObservable.updateProgress(DOWNLOADED_PROVIDER_JSON); - } catch (Exception e) { - Log.w(TAG, "failed fo fetch provider.json: " + e.getMessage()); - e.printStackTrace(); - return eventSender.setErrorResult(currentDownload, R.string.error_json_exception_user_message, null); - } - try { String serviceJson = bm.getService(); Log.d(TAG, "service Json reponse: " + serviceJson); provider.setService(serviceJson); @@ -292,7 +280,7 @@ public class ProviderApiManagerV5 extends ProviderApiManagerBase implements IPro certificate.checkValidity(); validCertificates.add(certificate); } catch (CertificateNotYetValidException | - CertificateExpiredException e) { + CertificateExpiredException e) { e.printStackTrace(); invalidCertificates++; } |