summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcyberta <cyberta@riseup.net>2020-01-24 08:34:24 -0800
committercyberta <cyberta@riseup.net>2020-01-24 08:34:24 -0800
commit721d222a457ec0dfec28bc4ee4908b50f04904fc (patch)
treea83724b8cda98136d5e270eeef7296f7323375b9
parent95bd478d62c9ebf3e313df4915c392dfd094d615 (diff)
parentdf563345352a26d627415740dcf2ef58d724b868 (diff)
Merge branch 'no-dns-fallback' into 'master'
No dns fallback See merge request leap/bitmask_android!99
-rw-r--r--app/build.gradle10
-rw-r--r--app/src/insecure/java/se/leap/bitmaskclient/AddProviderActivity.java6
-rw-r--r--app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java3
-rw-r--r--app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailActivity.java2
-rw-r--r--app/src/insecure/java/se/leap/bitmaskclient/ProviderListActivity.java14
-rw-r--r--app/src/insecure/java/se/leap/bitmaskclient/ProviderListContent.java82
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/Constants.java2
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/CustomProviderSetupActivity.java2
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/DnsResolver.java37
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java5
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/OkHttpClientGenerator.java1
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/Provider.java83
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java44
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderApiSetupBroadcastReceiver.java2
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderListBaseActivity.java8
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderManager.java35
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderObservable.java12
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderSetupBaseActivity.java1
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/utils/IPAddress.java102
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/utils/PreferenceHelper.java111
-rw-r--r--app/src/normal/assets/urls/calyx.net.url4
-rw-r--r--app/src/normal/assets/urls/demo.bitmask.net.url6
-rw-r--r--app/src/normal/assets/urls/pt.demo.bitmask.net.url4
-rw-r--r--app/src/normal/assets/urls/riseup.net.url4
-rw-r--r--app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java12
-rw-r--r--app/src/production/java/se/leap/bitmaskclient/ProviderListContent.java81
-rw-r--r--app/src/sharedTest/java/se.leap.bitmaskclient/testutils/TestSetupHelper.java14
-rw-r--r--app/src/test/java/se/leap/bitmaskclient/ProviderTest.java4
-rw-r--r--app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java14
-rw-r--r--app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java4
-rw-r--r--app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java17
31 files changed, 367 insertions, 359 deletions
diff --git a/app/build.gradle b/app/build.gradle
index 68db8926..286ddc1c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -37,8 +37,10 @@ android {
buildConfigField 'int', 'donation_reminder_duration', '30'
//skip the account creation / login screen if the provider offers anonymous vpn usage, use directly the anonymous cert instead
buildConfigField 'boolean', 'priotize_anonymous_usage', 'false'
- //ignore the following config, only used in custom flavor
+ //ignore the following configs, only used in custom flavor
buildConfigField "String", "customProviderUrl", '""'
+ buildConfigField "String", "customProviderIp", '""'
+ buildConfigField "String", "customProviderApiIp", '""'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
dexOptions {
@@ -89,6 +91,12 @@ android {
//Provider base url, e.g. '"https://example.com"'
def customProviderUrl = '"https://riseup.net"'
buildConfigField "String", "customProviderUrl", customProviderUrl
+ //static ip address of provider, using a commercially validated CA certificate to serve the provider.json
+ def customProviderIp = '"198.252.153.70"'
+ buildConfigField "String", "customProviderIp", customProviderIp
+ //static ip address of the provider api, using a self signed certificate to serve provider.json, eip-service.json etc.
+ def customProviderApiIp = '"198.252.153.107"'
+ buildConfigField "String", "customProviderApiIp", customProviderApiIp
//Change the versionCode as needed
//versionCode 1
//Change the versionName as needed
diff --git a/app/src/insecure/java/se/leap/bitmaskclient/AddProviderActivity.java b/app/src/insecure/java/se/leap/bitmaskclient/AddProviderActivity.java
index 10608a14..102a72c3 100644
--- a/app/src/insecure/java/se/leap/bitmaskclient/AddProviderActivity.java
+++ b/app/src/insecure/java/se/leap/bitmaskclient/AddProviderActivity.java
@@ -9,10 +9,10 @@ import android.widget.RelativeLayout;
import butterknife.InjectView;
import butterknife.Optional;
-import se.leap.bitmaskclient.ProviderListContent.ProviderItem;
import static android.widget.RelativeLayout.BELOW;
import static android.widget.RelativeLayout.LEFT_OF;
+import static se.leap.bitmaskclient.Constants.DANGER_ON;
public class AddProviderActivity extends AddProviderBaseActivity {
@@ -36,14 +36,14 @@ public class AddProviderActivity extends AddProviderBaseActivity {
checkboxDanger.setVisibility(View.VISIBLE);
checkboxDanger.setText(R.string.danger_checkbox);
- checkboxDanger.setChecked(preferences.getBoolean(ProviderItem.DANGER_ON, false));
+ checkboxDanger.setChecked(preferences.getBoolean(DANGER_ON, false));
}
@Override
public void setupSaveButton() {
saveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
- preferences.edit().putBoolean(ProviderItem.DANGER_ON, checkboxDanger.isChecked()).apply();
+ preferences.edit().putBoolean(DANGER_ON, checkboxDanger.isChecked()).apply();
saveProvider();
}
});
diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java b/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java
index fc91d7e4..e86ab8ea 100644
--- a/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java
+++ b/app/src/insecure/java/se/leap/bitmaskclient/ProviderApiManager.java
@@ -50,6 +50,7 @@ import se.leap.bitmaskclient.utils.ConfigHelper;
import static android.text.TextUtils.isEmpty;
import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY;
+import static se.leap.bitmaskclient.Constants.DANGER_ON;
import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.ProviderAPI.ERRORS;
@@ -94,7 +95,7 @@ public class ProviderApiManager extends ProviderApiManagerBase {
Bundle currentDownload = new Bundle();
if (task != null) {
- lastDangerOn = task.containsKey(ProviderListContent.ProviderItem.DANGER_ON) && task.getBoolean(ProviderListContent.ProviderItem.DANGER_ON);
+ lastDangerOn = task.containsKey(DANGER_ON) && task.getBoolean(DANGER_ON);
}
if (isEmpty(provider.getMainUrlString()) || provider.getMainUrl().isDefault()) {
diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailActivity.java b/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailActivity.java
index cf9ee5f5..9f2fa284 100644
--- a/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailActivity.java
+++ b/app/src/insecure/java/se/leap/bitmaskclient/ProviderDetailActivity.java
@@ -7,7 +7,7 @@ public class ProviderDetailActivity extends AbstractProviderDetailActivity {
@Override
public void onBackPressed() {
SharedPreferences.Editor editor = preferences.edit();
- editor.remove(ProviderListContent.ProviderItem.DANGER_ON).apply();
+ editor.remove(Constants.DANGER_ON).apply();
super.onBackPressed();
}
diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ProviderListActivity.java b/app/src/insecure/java/se/leap/bitmaskclient/ProviderListActivity.java
index 9107e641..dfadaf05 100644
--- a/app/src/insecure/java/se/leap/bitmaskclient/ProviderListActivity.java
+++ b/app/src/insecure/java/se/leap/bitmaskclient/ProviderListActivity.java
@@ -18,14 +18,8 @@ package se.leap.bitmaskclient;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.FragmentTransaction;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import se.leap.bitmaskclient.ProviderListContent.ProviderItem;
+import static se.leap.bitmaskclient.Constants.DANGER_ON;
import static se.leap.bitmaskclient.ProviderAPI.SET_UP_PROVIDER;
import static se.leap.bitmaskclient.ProviderSetupInterface.ProviderConfigState.SETTING_UP_PROVIDER;
@@ -41,14 +35,14 @@ public class ProviderListActivity extends ProviderListBaseActivity {
@Override
protected void onItemSelectedLogic() {
- boolean danger_on = preferences.getBoolean(ProviderItem.DANGER_ON, true);
+ boolean danger_on = preferences.getBoolean(DANGER_ON, true);
setUpProvider(danger_on);
}
@Override
public void cancelSettingUpProvider() {
super.cancelSettingUpProvider();
- preferences.edit().remove(ProviderItem.DANGER_ON).apply();
+ preferences.edit().remove(DANGER_ON).apply();
}
/**
@@ -60,7 +54,7 @@ public class ProviderListActivity extends ProviderListBaseActivity {
providerConfigState = SETTING_UP_PROVIDER;
Bundle parameters = new Bundle();
- parameters.putBoolean(ProviderItem.DANGER_ON, danger_on);
+ parameters.putBoolean(DANGER_ON, danger_on);
ProviderAPICommand.execute(this, SET_UP_PROVIDER, parameters, provider);
}
diff --git a/app/src/insecure/java/se/leap/bitmaskclient/ProviderListContent.java b/app/src/insecure/java/se/leap/bitmaskclient/ProviderListContent.java
deleted file mode 100644
index 88e31c9a..00000000
--- a/app/src/insecure/java/se/leap/bitmaskclient/ProviderListContent.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Copyright (c) 2013 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 <http://www.gnu.org/licenses/>.
- */
-package se.leap.bitmaskclient;
-
-import java.util.*;
-import java.net.*;
-
-/**
- * Models the provider list shown in the ProviderListActivity.
- *
- * @author parmegv
- */
-public class ProviderListContent {
-
- public static List<ProviderItem> ITEMS = new ArrayList<ProviderItem>();
-
- public static Map<String, ProviderItem> ITEM_MAP = new HashMap<String, ProviderItem>();
-
- /**
- * Adds a new provider item to the end of the items map, and to the items list.
- *
- * @param item
- */
- public static void addItem(ProviderItem item) {
- ITEMS.add(item);
- ITEM_MAP.put(String.valueOf(ITEMS.size()), item);
- }
-
- public static void removeItem(ProviderItem item) {
- ITEMS.remove(item);
- ITEM_MAP.remove(item);
- }
-
- /**
- * A provider item.
- */
- public static class ProviderItem {
- final public static String CUSTOM = "custom";
- final public static String DANGER_ON = "danger_on";
- private String provider_main_url;
- private String name;
-
- /**
- * @param name of the provider
- * @param provider_main_url used to download provider.json file of the provider
- */
- public ProviderItem(String name, String provider_main_url) {
- this.name = name;
- this.provider_main_url = provider_main_url;
- }
-
- public String name() {
- return name;
- }
-
- public String providerMainUrl() {
- return provider_main_url;
- }
-
- public String domain() {
- try {
- return new URL(provider_main_url).getHost();
- } catch (MalformedURLException e) {
- return provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("/.*", "");
- }
- }
- }
-}
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).
diff --git a/app/src/normal/assets/urls/calyx.net.url b/app/src/normal/assets/urls/calyx.net.url
index 807e9e18..0b26dc25 100644
--- a/app/src/normal/assets/urls/calyx.net.url
+++ b/app/src/normal/assets/urls/calyx.net.url
@@ -1,3 +1,5 @@
{
- "main_url" : "https://calyx.net"
+ "main_url" : "https://calyx.net",
+ "provider_ip" : "162.247.73.194",
+ "provider_api_ip" : "162.247.73.194"
}
diff --git a/app/src/normal/assets/urls/demo.bitmask.net.url b/app/src/normal/assets/urls/demo.bitmask.net.url
index 0c4de648..1f8065e0 100644
--- a/app/src/normal/assets/urls/demo.bitmask.net.url
+++ b/app/src/normal/assets/urls/demo.bitmask.net.url
@@ -1,3 +1,5 @@
{
- "main_url" : "https://demo.bitmask.net"
-}
+ "main_url" : "https://demo.bitmask.net",
+ "provider_ip" : "198.252.153.85",
+ "provider_api_ip" : "198.252.153.85"
+} \ No newline at end of file
diff --git a/app/src/normal/assets/urls/pt.demo.bitmask.net.url b/app/src/normal/assets/urls/pt.demo.bitmask.net.url
index d6e50462..a689a54d 100644
--- a/app/src/normal/assets/urls/pt.demo.bitmask.net.url
+++ b/app/src/normal/assets/urls/pt.demo.bitmask.net.url
@@ -1,3 +1,5 @@
{
- "main_url" : "https://pt.demo.bitmask.net"
+ "main_url" : "https://pt.demo.bitmask.net",
+ "provider_ip" : "198.252.153.85",
+ "provider_api_ip" : "198.252.153.85"
}
diff --git a/app/src/normal/assets/urls/riseup.net.url b/app/src/normal/assets/urls/riseup.net.url
index 42cdb979..a4a90f90 100644
--- a/app/src/normal/assets/urls/riseup.net.url
+++ b/app/src/normal/assets/urls/riseup.net.url
@@ -1,3 +1,5 @@
{
- "main_url" : "https://riseup.net"
+ "main_url" : "https://riseup.net",
+ "provider_ip" : "198.252.153.70",
+ "provider_api_ip" : "198.252.153.107"
}
diff --git a/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java b/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java
index 41a63ad7..6f1e3034 100644
--- a/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java
+++ b/app/src/production/java/se/leap/bitmaskclient/ProviderApiManager.java
@@ -121,14 +121,13 @@ public class ProviderApiManager extends ProviderApiManagerBase {
Bundle result = new Bundle();
String caCert = provider.getCaCert();
- JSONObject providerDefinition = provider.getDefinition();
String providerDotJsonString;
- if(providerDefinition.length() == 0 || caCert.isEmpty()) {
+ if(provider.getDefinitionString().length() == 0 || caCert.isEmpty()) {
String providerJsonUrl = provider.getMainUrlString() + "/provider.json";
providerDotJsonString = downloadWithCommercialCA(providerJsonUrl, provider);
} else {
- providerDotJsonString = downloadFromApiUrlWithProviderCA("/provider.json", caCert, providerDefinition);
+ providerDotJsonString = downloadFromApiUrlWithProviderCA("/provider.json", caCert, provider);
}
if (ConfigHelper.checkErroneousDownload(providerDotJsonString) || !isValidJson(providerDotJsonString)) {
@@ -163,8 +162,7 @@ public class ProviderApiManager extends ProviderApiManagerBase {
Bundle result = new Bundle();
String eipServiceJsonString = "";
try {
- JSONObject providerJson = provider.getDefinition();
- String eipServiceUrl = providerJson.getString(Provider.API_URL) + "/" + providerJson.getString(Provider.API_VERSION) + "/" + EIP.SERVICE_API_PATH;
+ String eipServiceUrl = provider.getApiUrlWithVersion() + "/" + EIP.SERVICE_API_PATH;
eipServiceJsonString = downloadWithProviderCA(provider.getCaCert(), eipServiceUrl);
JSONObject eipServiceJson = new JSONObject(eipServiceJsonString);
if (BuildConfig.DEBUG) {
@@ -278,10 +276,10 @@ public class ProviderApiManager extends ProviderApiManagerBase {
*
* @return an empty string if it fails, the response body if not.
*/
- private String downloadFromApiUrlWithProviderCA(String path, String caCert, JSONObject providerDefinition) {
+ private String downloadFromApiUrlWithProviderCA(String path, String caCert, Provider provider) {
String responseString;
JSONObject errorJson = new JSONObject();
- String baseUrl = getApiUrl(providerDefinition);
+ String baseUrl = provider.getApiUrlString();
OkHttpClient okHttpClient = clientGenerator.initSelfSignedCAHttpClient(caCert, errorJson);
if (okHttpClient == null) {
return errorJson.toString();
diff --git a/app/src/production/java/se/leap/bitmaskclient/ProviderListContent.java b/app/src/production/java/se/leap/bitmaskclient/ProviderListContent.java
deleted file mode 100644
index d9e1d1a9..00000000
--- a/app/src/production/java/se/leap/bitmaskclient/ProviderListContent.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * Copyright (c) 2013 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 <http://www.gnu.org/licenses/>.
- */
-package se.leap.bitmaskclient;
-
-import java.util.*;
-import java.net.*;
-
-/**
- * Models the provider list shown in the ProviderListActivity.
- *
- * @author parmegv
- */
-public class ProviderListContent {
-
- public static List<ProviderItem> ITEMS = new ArrayList<ProviderItem>();
-
- public static Map<String, ProviderItem> ITEM_MAP = new HashMap<String, ProviderItem>();
-
- /**
- * Adds a new provider item to the end of the items map, and to the items list.
- *
- * @param item
- */
- public static void addItem(ProviderItem item) {
- ITEMS.add(item);
- ITEM_MAP.put(String.valueOf(ITEMS.size()), item);
- }
-
- public static void removeItem(ProviderItem item) {
- ITEMS.remove(item);
- ITEM_MAP.remove(item);
- }
-
- /**
- * A provider item.
- */
- public static class ProviderItem {
- final public static String CUSTOM = "custom";
- private String provider_main_url;
- private String name;
-
- /**
- * @param name of the provider
- * @param provider_main_url used to download provider.json file of the provider
- */
- public ProviderItem(String name, String provider_main_url) {
- this.name = name;
- this.provider_main_url = provider_main_url;
- }
-
- public String name() {
- return name;
- }
-
- public String providerMainUrl() {
- return provider_main_url;
- }
-
- public String domain() {
- try {
- return new URL(provider_main_url).getHost();
- } catch (MalformedURLException e) {
- return provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("/.*", "");
- }
- }
- }
-}
diff --git a/app/src/sharedTest/java/se.leap.bitmaskclient/testutils/TestSetupHelper.java b/app/src/sharedTest/java/se.leap.bitmaskclient/testutils/TestSetupHelper.java
index 669abc84..c7c85f8d 100644
--- a/app/src/sharedTest/java/se.leap.bitmaskclient/testutils/TestSetupHelper.java
+++ b/app/src/sharedTest/java/se.leap.bitmaskclient/testutils/TestSetupHelper.java
@@ -51,12 +51,18 @@ public class TestSetupHelper {
public static Provider getConfiguredProvider() throws IOException, JSONException {
- return getProvider(null, null, null, null);
+ return getProvider(null, null, null, null, null, null);
}
- public static Provider getProvider(String domain, String caCertFile, String providerJson, String eipServiceJson) {
+ public static Provider getProvider(String domain, String providerIp, String providerApiIp, String caCertFile, String providerJson, String eipServiceJson) {
if (domain == null)
domain = "https://riseup.net";
+ if (providerIp == null) {
+ providerIp = "";
+ }
+ if (providerApiIp == null) {
+ providerApiIp = "";
+ }
if (caCertFile == null)
caCertFile = "riseup.net.pem";
if (providerJson == null)
@@ -67,7 +73,9 @@ public class TestSetupHelper {
try {
Provider p = new Provider(
- new URL(domain),
+ domain,
+ providerIp,
+ providerApiIp,
getInputAsString(TestSetupHelper.class.getClassLoader().getResourceAsStream(caCertFile)),
getInputAsString(TestSetupHelper.class.getClassLoader().getResourceAsStream(providerJson))
diff --git a/app/src/test/java/se/leap/bitmaskclient/ProviderTest.java b/app/src/test/java/se/leap/bitmaskclient/ProviderTest.java
index c4b8f65e..0f9d358e 100644
--- a/app/src/test/java/se/leap/bitmaskclient/ProviderTest.java
+++ b/app/src/test/java/se/leap/bitmaskclient/ProviderTest.java
@@ -53,6 +53,8 @@ public class ProviderTest {
"https://pt.demo.bitmask.net",
null,
null,
+ null,
+ null,
"ptdemo.bitmask.eip-service.json");
assertTrue(p1.supportsPluggableTransports());
}
@@ -63,6 +65,8 @@ public class ProviderTest {
null,
null,
null,
+ null,
+ null,
"eip-service-two-gateways.json");
assertFalse(p1.supportsPluggableTransports());
}
diff --git a/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java b/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java
index b37b3474..417c4bfc 100644
--- a/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java
+++ b/app/src/test/java/se/leap/bitmaskclient/eip/GatewaysManagerTest.java
@@ -107,7 +107,7 @@ public class GatewaysManagerTest {
@Test
public void testGatewayManagerFromCurrentProvider_misconfiguredProvider_noGateways() throws IOException, NullPointerException {
- Provider provider = getProvider(null, null, null, "ptdemo_misconfigured_gateway.json");
+ Provider provider = getProvider(null, null, null, null, null, "ptdemo_misconfigured_gateway.json");
MockHelper.mockProviderObserver(provider);
GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
assertEquals(0, gatewaysManager.size());
@@ -115,7 +115,7 @@ public class GatewaysManagerTest {
@Test
public void testGatewayManagerFromCurrentProvider_threeGateways() {
- Provider provider = getProvider(null, null, null, "ptdemo_three_mixed_gateways.json");
+ Provider provider = getProvider(null, null, null,null, null, "ptdemo_three_mixed_gateways.json");
MockHelper.mockProviderObserver(provider);
GatewaysManager gatewaysManager = new GatewaysManager(mockContext);
assertEquals(3, gatewaysManager.size());
@@ -123,7 +123,7 @@ public class GatewaysManagerTest {
@Test
public void TestGetPosition_VpnProfileExtistingObfs4_returnPositionZero() throws JSONException, ConfigParser.ConfigParseError, IOException {
- Provider provider = getProvider(null, null, null, "ptdemo_three_mixed_gateways.json");
+ Provider provider = getProvider(null, null, null, null, null, "ptdemo_three_mixed_gateways.json");
JSONObject eipServiceJson = provider.getEipServiceJson();
JSONObject gateway1 = eipServiceJson.getJSONArray(GATEWAYS).getJSONObject(0);
MockHelper.mockProviderObserver(provider);
@@ -140,7 +140,7 @@ public class GatewaysManagerTest {
@Test
public void TestGetPosition_VpnProfileExtistingOpenvpn_returnPositionZero() throws JSONException, ConfigParser.ConfigParseError, IOException {
- Provider provider = getProvider(null, null, null, "ptdemo_three_mixed_gateways.json");
+ Provider provider = getProvider(null, null, null, null, null, "ptdemo_three_mixed_gateways.json");
JSONObject eipServiceJson = provider.getEipServiceJson();
JSONObject gateway1 = eipServiceJson.getJSONArray(GATEWAYS).getJSONObject(0);
MockHelper.mockProviderObserver(provider);
@@ -157,7 +157,7 @@ public class GatewaysManagerTest {
@Test
public void TestGetPosition_VpnProfileDifferentIp_returnMinusOne() throws JSONException, ConfigParser.ConfigParseError, IOException {
- Provider provider = getProvider(null, null, null, "ptdemo_three_mixed_gateways.json");
+ Provider provider = getProvider(null, null, null, null, null, "ptdemo_three_mixed_gateways.json");
JSONObject eipServiceJson = provider.getEipServiceJson();
JSONObject gateway1 = eipServiceJson.getJSONArray(GATEWAYS).getJSONObject(0);
MockHelper.mockProviderObserver(provider);
@@ -174,7 +174,7 @@ public class GatewaysManagerTest {
@Test
public void TestGetPosition_VpnProfileMoscow_returnOne() throws JSONException, ConfigParser.ConfigParseError, IOException {
- Provider provider = getProvider(null, null, null, "ptdemo_three_mixed_gateways.json");
+ Provider provider = getProvider(null, null, null, null, null, "ptdemo_three_mixed_gateways.json");
JSONObject eipServiceJson = provider.getEipServiceJson();
JSONObject gateway1 = eipServiceJson.getJSONArray(GATEWAYS).getJSONObject(1);
MockHelper.mockProviderObserver(provider);
@@ -191,7 +191,7 @@ public class GatewaysManagerTest {
@Test
public void TestSelectN_selectFirstObfs4Connection_returnThirdGateway() throws JSONException, ConfigParser.ConfigParseError, IOException {
- Provider provider = getProvider(null, null, null, "ptdemo_two_openvpn_one_pt_gateways.json");
+ Provider provider = getProvider(null, null, null, null, null, "ptdemo_two_openvpn_one_pt_gateways.json");
JSONObject eipServiceJson = provider.getEipServiceJson();
JSONObject gateway3 = eipServiceJson.getJSONArray(GATEWAYS).getJSONObject(2);
diff --git a/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java b/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java
index dde0601d..753a9474 100644
--- a/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java
+++ b/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java
@@ -269,7 +269,7 @@ public class ProviderApiManagerTest {
@Test
public void test_handleIntentSetupProvider_preseededProviderAndCA_outdatedCertificate() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
- Provider provider = getProvider(null ,"outdated_cert.pem", null, null);
+ Provider provider = getProvider(null ,null, null, "outdated_cert.pem", null, null);
mockProviderApiConnector(NO_ERROR);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
@@ -386,7 +386,7 @@ public class ProviderApiManagerTest {
@Test
public void test_handleIntentSetupProvider_outdatedPreseededProviderAndCA_successfulConfiguration() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
- Provider provider = getProvider(null, null, "riseup_net_outdated_config.json", null);
+ Provider provider = getProvider(null, null, null, null, "riseup_net_outdated_config.json", null);
mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(NO_ERROR);
diff --git a/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java b/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
index 481c87cb..c0fc6531 100644
--- a/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
+++ b/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
@@ -21,6 +21,7 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.net.UnknownHostException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
@@ -398,6 +399,9 @@ public class MockHelper {
return providerFromPrefs.getDefinition().toString();
case Provider.CA_CERT_FINGERPRINT:
return providerFromPrefs.getCaCertFingerprint();
+ case Provider.CA_CERT:
+ return providerFromPrefs.getCaCert();
+
}
return null;
}
@@ -434,14 +438,23 @@ public class MockHelper {
BackendMockProvider.provideBackendResponsesFor(errorCase);
}
- public static OkHttpClientGenerator mockClientGenerator() {
+ public static OkHttpClientGenerator mockClientGenerator(boolean resolveDNS) throws UnknownHostException {
OkHttpClientGenerator mockClientGenerator = mock(OkHttpClientGenerator.class);
- OkHttpClient mockedOkHttpClient = mock(OkHttpClient.class);
+ OkHttpClient mockedOkHttpClient = mock(OkHttpClient.class, RETURNS_DEEP_STUBS);
when(mockClientGenerator.initCommercialCAHttpClient(any(JSONObject.class))).thenReturn(mockedOkHttpClient);
when(mockClientGenerator.initSelfSignedCAHttpClient(anyString(), any(JSONObject.class))).thenReturn(mockedOkHttpClient);
+ if (resolveDNS) {
+ when(mockedOkHttpClient.dns().lookup(anyString())).thenReturn(new ArrayList<>());
+ } else {
+ when(mockedOkHttpClient.dns().lookup(anyString())).thenThrow(new UnknownHostException());
+ }
return mockClientGenerator;
}
+ public static OkHttpClientGenerator mockClientGenerator() throws UnknownHostException {
+ return mockClientGenerator(true);
+ }
+
public static Resources mockResources(InputStream inputStream) throws IOException, JSONException {
Resources mockedResources = mock(Resources.class, RETURNS_DEEP_STUBS);
JSONObject errorMessages = new JSONObject(TestSetupHelper.getInputAsString(inputStream));