diff options
author | cyberta <cyberta@riseup.net> | 2020-01-24 08:34:24 -0800 |
---|---|---|
committer | cyberta <cyberta@riseup.net> | 2020-01-24 08:34:24 -0800 |
commit | 721d222a457ec0dfec28bc4ee4908b50f04904fc (patch) | |
tree | a83724b8cda98136d5e270eeef7296f7323375b9 /app/src/main/java/se | |
parent | 95bd478d62c9ebf3e313df4915c392dfd094d615 (diff) | |
parent | df563345352a26d627415740dcf2ef58d724b868 (diff) |
Merge branch 'no-dns-fallback' into 'master'
No dns fallback
See merge request leap/bitmask_android!99
Diffstat (limited to 'app/src/main/java/se')
14 files changed, 291 insertions, 154 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/Constants.java b/app/src/main/java/se/leap/bitmaskclient/Constants.java index 0cbf82e1..5ed28806 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Constants.java +++ b/app/src/main/java/se/leap/bitmaskclient/Constants.java @@ -37,6 +37,8 @@ public interface Constants { String APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE = "configure always-on profile"; String DEFAULT_BITMASK = "normal"; String CUSTOM_BITMASK = "custom"; + String DANGER_ON = "danger_on"; + String ASK_TO_CANCEL_VPN = "ask_to_cancel_vpn"; diff --git a/app/src/main/java/se/leap/bitmaskclient/CustomProviderSetupActivity.java b/app/src/main/java/se/leap/bitmaskclient/CustomProviderSetupActivity.java index 3763f506..b3ee44ca 100644 --- a/app/src/main/java/se/leap/bitmaskclient/CustomProviderSetupActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/CustomProviderSetupActivity.java @@ -37,7 +37,7 @@ public class CustomProviderSetupActivity extends ProviderSetupBaseActivity { super.onCreate(savedInstanceState); setUpInitialUI(); restoreState(savedInstanceState); - setProvider(new Provider(BuildConfig.customProviderUrl)); + setProvider(new Provider(BuildConfig.customProviderUrl, BuildConfig.customProviderIp, BuildConfig.customProviderApiIp)); } @Override diff --git a/app/src/main/java/se/leap/bitmaskclient/DnsResolver.java b/app/src/main/java/se/leap/bitmaskclient/DnsResolver.java new file mode 100644 index 00000000..92f70492 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/DnsResolver.java @@ -0,0 +1,37 @@ +package se.leap.bitmaskclient; + +import org.jetbrains.annotations.NotNull; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; + +import okhttp3.Dns; +import se.leap.bitmaskclient.utils.IPAddress; + +class DnsResolver implements Dns { + + @Override + public List<InetAddress> lookup(@NotNull String hostname) throws UnknownHostException { + try { + return Dns.SYSTEM.lookup(hostname); + } catch (UnknownHostException e) { + ProviderObservable observable = ProviderObservable.getInstance(); + Provider currentProvider; + if (observable.getProviderForDns() != null) { + currentProvider = observable.getProviderForDns(); + } else { + currentProvider = observable.getCurrentProvider(); + } + String ip = currentProvider.getIpForHostname(hostname); + if (!ip.isEmpty()) { + ArrayList<InetAddress> addresses = new ArrayList<>(); + addresses.add(InetAddress.getByAddress(hostname, IPAddress.asBytes(ip))); + return addresses; + } else { + throw new UnknownHostException("Hostname " + hostname + " not found"); + } + } + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java b/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java index eceba0db..74f132b9 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java @@ -28,7 +28,6 @@ import se.leap.bitmaskclient.eip.GatewaysManager; import se.leap.bitmaskclient.utils.PreferenceHelper; import static android.app.Activity.RESULT_CANCELED; -import static android.content.Context.MODE_PRIVATE; 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; @@ -43,11 +42,9 @@ import static se.leap.bitmaskclient.Constants.EIP_ACTION_START_ALWAYS_ON_VPN; import static se.leap.bitmaskclient.Constants.EIP_REQUEST; import static se.leap.bitmaskclient.Constants.PROVIDER_KEY; import static se.leap.bitmaskclient.Constants.PROVIDER_PROFILE; -import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE; import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE; -import static se.leap.bitmaskclient.ProviderAPI.ERRORS; -import static se.leap.bitmaskclient.utils.PreferenceHelper.getSavedProviderFromSharedPreferences; +import static se.leap.bitmaskclient.ProviderAPI.PROVIDER_NOK; /** * Created by cyberta on 05.12.18. diff --git a/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java b/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java index 69270140..9d1168aa 100644 --- a/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java +++ b/app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java @@ -88,6 +88,7 @@ public class OkHttpClientGenerator { sslCompatFactory.initSSLSocketFactory(clientBuilder); clientBuilder.cookieJar(getCookieJar()) .connectionSpecs(Collections.singletonList(spec)); + clientBuilder.dns(new DnsResolver()); return clientBuilder.build(); } catch (IllegalArgumentException e) { e.printStackTrace(); diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java index b98c3fd3..11d685f5 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java @@ -18,6 +18,7 @@ package se.leap.bitmaskclient; import android.os.Parcel; import android.os.Parcelable; +import android.support.annotation.NonNull; import com.google.gson.Gson; @@ -29,6 +30,8 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.Locale; +import se.leap.bitmaskclient.utils.IPAddress; + import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4; import static se.leap.bitmaskclient.Constants.CAPABILITIES; import static se.leap.bitmaskclient.Constants.GATEWAYS; @@ -49,6 +52,8 @@ public final class Provider implements Parcelable { private JSONObject eipServiceJson = new JSONObject(); private DefaultedURL mainUrl = new DefaultedURL(); private DefaultedURL apiUrl = new DefaultedURL(); + private String providerIp = ""; + private String providerApiIp = ""; private String certificatePin = ""; private String certificatePinEncoding = ""; private String caCert = ""; @@ -73,7 +78,9 @@ public final class Provider implements Parcelable { NAME = "name", DESCRIPTION = "description", DOMAIN = "domain", - MAIN_URL = "main_url"; + MAIN_URL = "main_url", + PROVIDER_IP = "provider_ip", + PROVIDER_API_IP = "provider_api_ip"; private static final String API_TERM_NAME = "name"; @@ -87,12 +94,32 @@ public final class Provider implements Parcelable { } } - public Provider(URL mainUrl) { - this.mainUrl.setUrl(mainUrl); + public Provider(String mainUrl, String providerIp, String providerApiIp) { + try { + this.mainUrl.setUrl(new URL(mainUrl)); + if (providerIp != null) { + this.providerIp = providerIp; + } + if (providerApiIp != null) { + this.providerApiIp = providerApiIp; + } + } catch (MalformedURLException e) { + e.printStackTrace(); + } } - public Provider(URL mainUrl, String caCert, String definition) { - this.mainUrl.setUrl(mainUrl); + public Provider(String mainUrl, String providerIp, String providerApiIp, String caCert, String definition) { + try { + this.mainUrl.setUrl(new URL(mainUrl)); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + if (this.providerIp != null) { + this.providerIp = providerIp; + } + if (this.providerApiIp != null) { + this.providerApiIp = providerApiIp; + } if (caCert != null) { this.caCert = caCert; } @@ -146,6 +173,35 @@ public final class Provider implements Parcelable { return false; } + public String getIpForHostname(String host) { + if (host != null) { + if (host.equals(mainUrl.getUrl().getHost())) { + return providerIp; + } else if (host.equals(apiUrl.getUrl().getHost())) { + return providerApiIp; + } + } + return ""; + } + + public String getProviderApiIp() { + return this.providerApiIp; + } + + public void setProviderApiIp(String providerApiIp) { + if (providerApiIp == null) return; + this.providerApiIp = providerApiIp; + } + + public void setProviderIp(String providerIp) { + if (providerIp == null) return; + this.providerIp = providerIp; + } + + public String getProviderIp() { + return this.providerIp; + } + public void setMainUrl(URL url) { mainUrl.setUrl(url); } @@ -192,7 +248,7 @@ public final class Provider implements Parcelable { } - protected String getApiUrlString() { + public String getApiUrlString() { return getApiUrl().toString(); } @@ -265,6 +321,8 @@ public final class Provider implements Parcelable { @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(getMainUrlString()); + parcel.writeString(getProviderIp()); + parcel.writeString(getProviderApiIp()); parcel.writeString(getDefinitionString()); parcel.writeString(getCaCert()); parcel.writeString(getEipServiceJsonString()); @@ -281,6 +339,8 @@ public final class Provider implements Parcelable { definition.toString().equals(p.getDefinition().toString()) && eipServiceJson.toString().equals(p.getEipServiceJson().toString())&& mainUrl.equals(p.getMainUrl()) && + providerIp.equals(p.getProviderIp()) && + providerApiIp.equals(p.getProviderApiIp()) && apiUrl.equals(p.getApiUrl()) && certificatePin.equals(p.getCertificatePin()) && certificatePinEncoding.equals(p.getCertificatePinEncoding()) && @@ -298,7 +358,6 @@ public final class Provider implements Parcelable { JSONObject json = new JSONObject(); try { json.put(Provider.MAIN_URL, mainUrl); - //TODO: add other fields here? } catch (JSONException e) { e.printStackTrace(); } @@ -321,6 +380,14 @@ public final class Provider implements Parcelable { mainUrl.setUrl(new URL(in.readString())); String tmpString = in.readString(); if (!tmpString.isEmpty()) { + providerIp = tmpString; + } + tmpString = in.readString(); + if (!tmpString.isEmpty()) { + providerApiIp = tmpString; + } + tmpString = in.readString(); + if (!tmpString.isEmpty()) { definition = new JSONObject((tmpString)); parseDefinition(definition); } @@ -445,7 +512,7 @@ public final class Provider implements Parcelable { } /** - * resets everything except the main url + * resets everything except the main url and the providerIp */ public void reset() { definition = new JSONObject(); diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java index 0baa4e0d..7577f098 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java @@ -63,6 +63,9 @@ import static se.leap.bitmaskclient.Constants.CREDENTIALS_USERNAME; import static se.leap.bitmaskclient.Constants.PROVIDER_KEY; import static se.leap.bitmaskclient.Constants.PROVIDER_PRIVATE_KEY; import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE; +import static se.leap.bitmaskclient.Provider.CA_CERT; +import static se.leap.bitmaskclient.Provider.PROVIDER_API_IP; +import static se.leap.bitmaskclient.Provider.PROVIDER_IP; import static se.leap.bitmaskclient.ProviderAPI.BACKEND_ERROR_KEY; import static se.leap.bitmaskclient.ProviderAPI.BACKEND_ERROR_MESSAGE; import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE; @@ -159,6 +162,7 @@ public abstract class ProviderApiManagerBase { Bundle result = new Bundle(); switch (action) { case UPDATE_PROVIDER_DETAILS: + ProviderObservable.getInstance().setProviderForDns(provider); resetProviderDetails(provider); Bundle task = new Bundle(); result = setUpProvider(provider, task); @@ -167,14 +171,17 @@ public abstract class ProviderApiManagerBase { } else { sendToReceiverOrBroadcast(receiver, PROVIDER_NOK, result, provider); } + ProviderObservable.getInstance().setProviderForDns(null); break; case SET_UP_PROVIDER: + ProviderObservable.getInstance().setProviderForDns(provider); result = setUpProvider(provider, parameters); if (result.getBoolean(BROADCAST_RESULT_KEY)) { sendToReceiverOrBroadcast(receiver, PROVIDER_OK, result, provider); } else { sendToReceiverOrBroadcast(receiver, PROVIDER_NOK, result, provider); } + ProviderObservable.getInstance().setProviderForDns(null); break; case SIGN_UP: result = tryToRegister(provider, parameters); @@ -200,22 +207,27 @@ public abstract class ProviderApiManagerBase { } break; case DOWNLOAD_VPN_CERTIFICATE: + ProviderObservable.getInstance().setProviderForDns(provider); result = updateVpnCertificate(provider); if (result.getBoolean(BROADCAST_RESULT_KEY)) { sendToReceiverOrBroadcast(receiver, CORRECTLY_DOWNLOADED_VPN_CERTIFICATE, result, provider); } else { sendToReceiverOrBroadcast(receiver, INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE, result, provider); } + ProviderObservable.getInstance().setProviderForDns(null); break; case UPDATE_INVALID_VPN_CERTIFICATE: + ProviderObservable.getInstance().setProviderForDns(provider); result = updateVpnCertificate(provider); if (result.getBoolean(BROADCAST_RESULT_KEY)) { sendToReceiverOrBroadcast(receiver, CORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE, result, provider); } else { sendToReceiverOrBroadcast(receiver, INCORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE, result, provider); } + ProviderObservable.getInstance().setProviderForDns(null); break; case DOWNLOAD_SERVICE_JSON: + ProviderObservable.getInstance().setProviderForDns(provider); Log.d(TAG, "update eip service json"); result = getAndSetEipServiceJson(provider); if (result.getBoolean(BROADCAST_RESULT_KEY)) { @@ -223,6 +235,7 @@ public abstract class ProviderApiManagerBase { } else { sendToReceiverOrBroadcast(receiver, INCORRECTLY_DOWNLOADED_EIP_SERVICE, result, provider); } + ProviderObservable.getInstance().getProviderForDns(); break; case PROVIDER_SET_UP: if(provider.hasEIP() && provider.hasCaCert() && provider.hasDefinition()) { @@ -596,11 +609,11 @@ public abstract class ProviderApiManagerBase { return plainResponseBody; } - private boolean canConnect(String caCert, JSONObject providerDefinition, Bundle result) { + private boolean canConnect(Provider provider, Bundle result) { JSONObject errorJson = new JSONObject(); - String providerUrl = getApiUrl(providerDefinition) + "/provider.json"; + String providerUrl = provider.getApiUrlString() + "/provider.json"; - OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(caCert, errorJson); + OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(provider.getCaCert(), errorJson); if (okHttpClient == null) { result.putString(ERRORS, errorJson.toString()); return false; @@ -693,6 +706,8 @@ public abstract class ProviderApiManagerBase { provider.define(getPersistedProviderDefinition(providerDomain)); provider.setPrivateKey(getPersistedPrivateKey(providerDomain)); provider.setVpnCertificate(getPersistedVPNCertificate(providerDomain)); + provider.setProviderApiIp(getPersistedProviderApiIp(providerDomain)); + provider.setProviderIp(getPersistedProviderIp(providerDomain)); } } @@ -737,7 +752,7 @@ public abstract class ProviderApiManagerBase { return setErrorResult(result, warning_corrupted_provider_cert, ERROR_CERTIFICATE_PINNING.toString()); } - if (!canConnect(caCert, provider.getDefinition(), result)) { + if (!canConnect(provider, result)) { return result; } } catch (NoSuchAlgorithmException e ) { @@ -772,15 +787,6 @@ public abstract class ProviderApiManagerBase { return result; } - protected String getApiUrl(JSONObject providerDefinition) { - try { - return providerDefinition.getString(Provider.API_URL); - } catch (JSONException e) { - e.printStackTrace(); - } - return ""; - } - protected String getPersistedPrivateKey(String providerDomain) { return getFromPersistedProvider(PROVIDER_PRIVATE_KEY, providerDomain, preferences); } @@ -799,11 +805,19 @@ public abstract class ProviderApiManagerBase { } protected String getPersistedProviderCA(String providerDomain) { - return preferences.getString(Provider.CA_CERT + "." + providerDomain, ""); + return getFromPersistedProvider(CA_CERT, providerDomain, preferences); + } + + protected String getPersistedProviderApiIp(String providerDomain) { + return getFromPersistedProvider(PROVIDER_API_IP, providerDomain, preferences); + } + + protected String getPersistedProviderIp(String providerDomain) { + return getFromPersistedProvider(PROVIDER_IP, providerDomain, preferences); } protected boolean hasUpdatedProviderDetails(String domain) { - return preferences.contains(Provider.KEY + "." + domain) && preferences.contains(Provider.CA_CERT + "." + domain); + return preferences.contains(Provider.KEY + "." + domain) && preferences.contains(CA_CERT + "." + domain); } protected String getDomainFromMainURL(String mainUrl) { diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderApiSetupBroadcastReceiver.java b/app/src/main/java/se/leap/bitmaskclient/ProviderApiSetupBroadcastReceiver.java index e8f9de36..0a2e2538 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderApiSetupBroadcastReceiver.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderApiSetupBroadcastReceiver.java @@ -51,7 +51,7 @@ public class ProviderApiSetupBroadcastReceiver extends BroadcastReceiver { if (setupInterface.getConfigState() != null && setupInterface.getConfigState() == ProviderConfigState.SETTING_UP_PROVIDER) { int resultCode = intent.getIntExtra(Constants.BROADCAST_RESULT_CODE, ProviderListBaseActivity.RESULT_CANCELED); - Log.d(ProviderListBaseActivity.TAG, "Broadcast resultCode: " + Integer.toString(resultCode)); + Log.d(ProviderListBaseActivity.TAG, "Broadcast resultCode: " + resultCode); Bundle resultData = intent.getParcelableExtra(Constants.BROADCAST_RESULT_KEY); Provider handledProvider = resultData.getParcelable(Constants.PROVIDER_KEY); diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java index c8070e18..56edd534 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java @@ -108,12 +108,8 @@ public abstract class ProviderListBaseActivity extends ProviderSetupBaseActivity } public void showAndSelectProvider(String newURL) { - try { - provider = new Provider(new URL((newURL))); - autoSelectProvider(); - } catch (MalformedURLException e) { - e.printStackTrace(); - } + provider = new Provider(newURL, "", ""); + autoSelectProvider(); } private void autoSelectProvider() { diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java b/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java index dd9070af..ab165450 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderManager.java @@ -12,7 +12,6 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Collection; @@ -21,6 +20,9 @@ import java.util.Iterator; import java.util.List; import java.util.Set; +import static se.leap.bitmaskclient.Provider.MAIN_URL; +import static se.leap.bitmaskclient.Provider.PROVIDER_API_IP; +import static se.leap.bitmaskclient.Provider.PROVIDER_IP; import static se.leap.bitmaskclient.utils.FileHelper.createFile; import static se.leap.bitmaskclient.utils.FileHelper.persistFile; import static se.leap.bitmaskclient.utils.InputStreamHelper.getInputStreamFrom; @@ -84,22 +86,22 @@ public class ProviderManager implements AdapteeCollection<Provider> { for (String file : relativeFilePaths) { String mainUrl = null; + String providerIp = null; + String providerApiIp = null; String certificate = null; String providerDefinition = null; try { String provider = file.substring(0, file.length() - ".url".length()); - InputStream provider_file = assetsManager.open(directory + "/" + file); - mainUrl = extractMainUrlFromInputStream(provider_file); + InputStream providerFile = assetsManager.open(directory + "/" + file); + mainUrl = extractKeyFromInputStream(providerFile, MAIN_URL); + providerIp = extractKeyFromInputStream(providerFile, PROVIDER_IP); + providerApiIp = extractKeyFromInputStream(providerFile, PROVIDER_API_IP); certificate = loadInputStreamAsString(assetsManager.open(provider + EXT_PEM)); providerDefinition = loadInputStreamAsString(assetsManager.open(provider + EXT_JSON)); } catch (IOException e) { e.printStackTrace(); } - try { - providers.add(new Provider(new URL(mainUrl), certificate, providerDefinition)); - } catch (MalformedURLException e) { - e.printStackTrace(); - } + providers.add(new Provider(mainUrl, providerIp, providerApiIp, certificate, providerDefinition)); } return providers; @@ -118,23 +120,26 @@ public class ProviderManager implements AdapteeCollection<Provider> { Set<Provider> providers = new HashSet<>(); try { for (String file : files) { - String mainUrl = extractMainUrlFromInputStream(getInputStreamFrom(externalFilesDir.getAbsolutePath() + "/" + file)); - providers.add(new Provider(new URL(mainUrl))); + InputStream inputStream = getInputStreamFrom(externalFilesDir.getAbsolutePath() + "/" + file); + String mainUrl = extractKeyFromInputStream(inputStream, MAIN_URL); + String providerIp = extractKeyFromInputStream(inputStream, PROVIDER_IP); + String providerApiIp = extractKeyFromInputStream(inputStream, PROVIDER_API_IP); + providers.add(new Provider(mainUrl, providerIp, providerApiIp)); } - } catch (MalformedURLException | FileNotFoundException | NullPointerException e) { + } catch (FileNotFoundException | NullPointerException e) { e.printStackTrace(); } return providers; } - private String extractMainUrlFromInputStream(InputStream inputStream) { - String mainUrl = ""; + private String extractKeyFromInputStream(InputStream inputStream, String key) { + String value = ""; JSONObject fileContents = inputStreamToJson(inputStream); if (fileContents != null) - mainUrl = fileContents.optString(Provider.MAIN_URL); - return mainUrl; + value = fileContents.optString(key); + return value; } private JSONObject inputStreamToJson(InputStream inputStream) { diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderObservable.java b/app/src/main/java/se/leap/bitmaskclient/ProviderObservable.java index 776c0e92..50cc37d4 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderObservable.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderObservable.java @@ -2,14 +2,13 @@ package se.leap.bitmaskclient; import java.util.Observable; -import se.leap.bitmaskclient.utils.PreferenceHelper; - /** * Created by cyberta on 05.12.18. */ public class ProviderObservable extends Observable { private static ProviderObservable instance; private Provider currentProvider; + private Provider providerForDns; public static ProviderObservable getInstance() { if (instance == null) { @@ -20,6 +19,7 @@ public class ProviderObservable extends Observable { public synchronized void updateProvider(Provider provider) { instance.currentProvider = provider; + instance.providerForDns = null; instance.setChanged(); instance.notifyObservers(); } @@ -28,4 +28,12 @@ public class ProviderObservable extends Observable { return instance.currentProvider; } + public void setProviderForDns(Provider provider) { + this.providerForDns = provider; + } + + public Provider getProviderForDns() { + return instance.providerForDns; + } + } diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderSetupBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ProviderSetupBaseActivity.java index 3b8df0a8..b1bb3b07 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderSetupBaseActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderSetupBaseActivity.java @@ -153,6 +153,7 @@ public abstract class ProviderSetupBaseActivity extends ConfigWizardBaseActivity public void cancelSettingUpProvider() { providerConfigState = PROVIDER_NOT_SET; provider = null; + ProviderObservable.getInstance().setProviderForDns(null); hideProgressBar(); } diff --git a/app/src/main/java/se/leap/bitmaskclient/utils/IPAddress.java b/app/src/main/java/se/leap/bitmaskclient/utils/IPAddress.java new file mode 100644 index 00000000..2e3ef596 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/utils/IPAddress.java @@ -0,0 +1,102 @@ +package se.leap.bitmaskclient.utils; + +/* + * Copyright (C) 2006-2008 Alfresco Software Limited. + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ + +import java.util.StringTokenizer; + +/** + * TCP/IP Address Utility Class + * + * @author gkspencer + */ +public class IPAddress { + + + /** + * Convert a TCP/IP address string into a byte array + * + * @param addr String + * @return byte[] + */ + public static byte[] asBytes(String addr) { + + // Convert the TCP/IP address string to an integer value + int ipInt = parseNumericAddress(addr); + if (ipInt == 0) + return null; + + // Convert to bytes + byte[] ipByts = new byte[4]; + + ipByts[3] = (byte) (ipInt & 0xFF); + ipByts[2] = (byte) ((ipInt >> 8) & 0xFF); + ipByts[1] = (byte) ((ipInt >> 16) & 0xFF); + ipByts[0] = (byte) ((ipInt >> 24) & 0xFF); + + // Return the TCP/IP bytes + return ipByts; + } + /** + * Check if the specified address is a valid numeric TCP/IP address and return as an integer value + * + * @param ipaddr String + * @return int + */ + private static int parseNumericAddress(String ipaddr) { + + // Check if the string is valid + if (ipaddr == null || ipaddr.length() < 7 || ipaddr.length() > 15) + return 0; + + // Check the address string, should be n.n.n.n format + StringTokenizer token = new StringTokenizer(ipaddr,"."); + if (token.countTokens() != 4) + return 0; + + int ipInt = 0; + while (token.hasMoreTokens()) { + + // Get the current token and convert to an integer value + String ipNum = token.nextToken(); + + try { + // Validate the current address part + int ipVal = Integer.valueOf(ipNum).intValue(); + if (ipVal < 0 || ipVal > 255) + return 0; + + // Add to the integer address + ipInt = (ipInt << 8) + ipVal; + } + catch (NumberFormatException ex) { + return 0; + } + } + + // Return the integer address + return ipInt; + } +}
\ No newline at end of file diff --git a/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java b/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java index 40bb2eca..de2058c7 100644 --- a/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java @@ -2,7 +2,6 @@ package se.leap.bitmaskclient.utils; import android.content.Context; import android.content.SharedPreferences; -import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -24,6 +23,7 @@ import se.leap.bitmaskclient.Provider; import static android.content.Context.MODE_PRIVATE; import static se.leap.bitmaskclient.Constants.ALWAYS_ON_SHOW_DIALOG; import static se.leap.bitmaskclient.Constants.DEFAULT_SHARED_PREFS_BATTERY_SAVER; +import static se.leap.bitmaskclient.Constants.EXCLUDED_APPS; import static se.leap.bitmaskclient.Constants.LAST_USED_PROFILE; import static se.leap.bitmaskclient.Constants.PREFERENCES_APP_VERSION; import static se.leap.bitmaskclient.Constants.PROVIDER_CONFIGURED; @@ -33,7 +33,6 @@ import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE; import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; import static se.leap.bitmaskclient.Constants.SU_PERMISSION; import static se.leap.bitmaskclient.Constants.USE_PLUGGABLE_TRANSPORTS; -import static se.leap.bitmaskclient.Constants.EXCLUDED_APPS; /** * Created by cyberta on 18.03.18. @@ -48,6 +47,8 @@ public class PreferenceHelper { Provider provider = new Provider(); try { provider.setMainUrl(new URL(preferences.getString(Provider.MAIN_URL, ""))); + provider.setProviderIp(preferences.getString(Provider.PROVIDER_IP, "")); + provider.setProviderApiIp(preferences.getString(Provider.PROVIDER_API_IP, "")); provider.define(new JSONObject(preferences.getString(Provider.KEY, ""))); provider.setCaCert(preferences.getString(Provider.CA_CERT, "")); provider.setVpnCertificate(preferences.getString(PROVIDER_VPN_CERTIFICATE, "")); @@ -64,73 +65,12 @@ public class PreferenceHelper { return preferences.getString(toFetch + "." + providerDomain, ""); } - public static String getProviderName(String provider) { - return getProviderName(null, provider); - } - - public static String getProviderName(@Nullable SharedPreferences preferences) { - return getProviderName(preferences,null); - } - - public static String getProviderName(@Nullable SharedPreferences preferences, @Nullable String provider) { - if (provider == null && preferences != null) { - provider = preferences.getString(Provider.KEY, ""); - } - try { - JSONObject providerJson = new JSONObject(provider); - String lang = Locale.getDefault().getLanguage(); - return providerJson.getJSONObject(Provider.NAME).getString(lang); - } catch (JSONException e) { - try { - JSONObject providerJson = new JSONObject(provider); - return providerJson.getJSONObject(Provider.NAME).getString("en"); - } catch (JSONException e2) { - return null; - } - } catch (NullPointerException npe) { - return null; - } - } - - public static String getProviderDomain(SharedPreferences preferences) { - return getProviderDomain(preferences, null); - } - - public static String getProviderDomain(String provider) { - return getProviderDomain(null, provider); - } - - public static String getProviderDomain(@Nullable SharedPreferences preferences, @Nullable String provider) { - if (provider == null && preferences != null) { - provider = preferences.getString(Provider.KEY, ""); - } - try { - JSONObject providerJson = new JSONObject(provider); - return providerJson.getString(Provider.DOMAIN); - } catch (JSONException | NullPointerException e) { - return null; - } - } - - public static String getDescription(SharedPreferences preferences) { - try { - JSONObject providerJson = new JSONObject(preferences.getString(Provider.KEY, "")); - String lang = Locale.getDefault().getLanguage(); - return providerJson.getJSONObject(Provider.DESCRIPTION).getString(lang); - } catch (JSONException e) { - try { - JSONObject providerJson = new JSONObject(preferences.getString(Provider.KEY, "")); - return providerJson.getJSONObject(Provider.DESCRIPTION).getString("en"); - } catch (JSONException e1) { - return null; - } - } - } - // TODO: replace commit with apply after refactoring EIP //FIXME: don't save private keys in shared preferences! use the keystore public static void storeProviderInPreferences(SharedPreferences preferences, Provider provider) { preferences.edit().putBoolean(PROVIDER_CONFIGURED, true). + putString(Provider.PROVIDER_IP, provider.getProviderIp()). + putString(Provider.PROVIDER_API_IP, provider.getProviderApiIp()). putString(Provider.MAIN_URL, provider.getMainUrlString()). putString(Provider.KEY, provider.getDefinitionString()). putString(Provider.CA_CERT, provider.getCaCert()). @@ -141,6 +81,8 @@ public class PreferenceHelper { String providerDomain = provider.getDomain(); preferences.edit().putBoolean(PROVIDER_CONFIGURED, true). + putString(Provider.PROVIDER_IP + "." + providerDomain, provider.getProviderIp()). + putString(Provider.PROVIDER_API_IP + "." + providerDomain, provider.getProviderApiIp()). putString(Provider.MAIN_URL + "." + providerDomain, provider.getMainUrlString()). putString(Provider.KEY + "." + providerDomain, provider.getDefinitionString()). putString(Provider.CA_CERT + "." + providerDomain, provider.getCaCert()). @@ -167,48 +109,13 @@ public class PreferenceHelper { return VpnProfile.fromJson(lastConnectedProfileJson); } - - - - public static void clearDataOfLastProvider(SharedPreferences preferences) { - clearDataOfLastProvider(preferences, false); - } - - @Deprecated - public static void clearDataOfLastProvider(SharedPreferences preferences, boolean commit) { - Map<String, ?> allEntries = preferences.getAll(); - List<String> lastProvidersKeys = new ArrayList<>(); - for (Map.Entry<String, ?> entry : allEntries.entrySet()) { - //sort out all preferences that don't belong to the last provider - if (entry.getKey().startsWith(Provider.KEY + ".") || - entry.getKey().startsWith(Provider.CA_CERT + ".") || - entry.getKey().startsWith(Provider.CA_CERT_FINGERPRINT + "." )|| - entry.getKey().equals(PREFERENCES_APP_VERSION) - ) { - continue; - } - lastProvidersKeys.add(entry.getKey()); - } - - SharedPreferences.Editor preferenceEditor = preferences.edit(); - for (String key : lastProvidersKeys) { - preferenceEditor.remove(key); - } - if (commit) { - preferenceEditor.commit(); - } else { - preferenceEditor.apply(); - } - } - public static void deleteProviderDetailsFromPreferences(@NonNull SharedPreferences preferences, String providerDomain) { preferences.edit(). remove(Provider.KEY + "." + providerDomain). remove(Provider.CA_CERT + "." + providerDomain). - remove(Provider.CA_CERT_FINGERPRINT + "." + providerDomain). + remove(Provider.PROVIDER_IP + "." + providerDomain). + remove(Provider.PROVIDER_API_IP + "." + providerDomain). remove(Provider.MAIN_URL + "." + providerDomain). - remove(Provider.KEY + "." + providerDomain). - remove(Provider.CA_CERT + "." + providerDomain). remove(PROVIDER_EIP_DEFINITION + "." + providerDomain). remove(PROVIDER_PRIVATE_KEY + "." + providerDomain). remove(PROVIDER_VPN_CERTIFICATE + "." + providerDomain). |