summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/build.gradle8
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java12
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java69
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/models/FeatureVersionCode.java1
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java11
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/utils/ConfigHelper.java5
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java6
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/activities/CustomProviderSetupActivity.java6
-rw-r--r--app/src/normal/assets/urls/riseup.net.url2
-rw-r--r--app/src/normalProductionFatDebug/assets/urls/riseup.net.url2
-rw-r--r--app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java2
-rw-r--r--app/src/test/java/se/leap/bitmaskclient/base/utils/ConfigHelperTest.java16
-rw-r--r--app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java1
13 files changed, 100 insertions, 41 deletions
diff --git a/app/build.gradle b/app/build.gradle
index 668f0783..239190fd 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -22,8 +22,8 @@ android {
// the factor 1000 is used so that gplay users can upgrade from split apks ((current version number - 1) * 1000) + n
// to extracted bundle apks, supplied by google
// however we don't calculate the versionCode here, because F-Droid doesn't like that
- versionCode 163000
- versionName "1.1.5"
+ versionCode 164000
+ versionName "1.1.5RC2"
minSdkVersion 16
targetSdkVersion 31
vectorDrawables.useSupportLibrary = true
@@ -36,7 +36,7 @@ android {
// and this should not be set/altered anywhere else.
buildConfigField 'String', 'default_donation_url', '"https://riseuplabs.org/leap"'
//The field to enable donations in the app.
- buildConfigField 'boolean', 'enable_donation', 'true'
+ buildConfigField 'boolean', 'enable_donation', 'false'
//The field to enable donation reminder popup in the app if enable_donation is set to 'false' this will be disabled.
buildConfigField 'boolean', 'enable_donation_reminder', 'true'
//The duration in days to trigger the donation reminder
@@ -123,7 +123,7 @@ android {
//Set app name here
appName = "Riseup VPN"
//Provider base url, e.g. '"https://example.com"'
- def customProviderUrl = '"https://riseup.net"'
+ def customProviderUrl = '"https://black.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"'
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java b/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java
index 2ccbe514..f4dbd6bd 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java
@@ -169,6 +169,18 @@ public class StartActivity extends Activity{
}
}
+ if (hasNewFeature(FeatureVersionCode.RISEUP_PROVIDER_LILYPAD_UPDATE) && (
+ getPackageName().equals("se.leap.riseupvpn") ||
+ ProviderObservable.getInstance().getCurrentProvider().getDomain().equals("riseup.net"))) {
+ // deletion of current configured provider so that a new provider setup is triggered
+ Provider provider = ProviderObservable.getInstance().getCurrentProvider();
+ if (provider != null && !provider.isDefault()) {
+ PreferenceHelper.deleteProviderDetailsFromPreferences(preferences, provider.getDomain());
+ PreferenceHelper.deleteCurrentProviderDetailsFromPreferences(preferences);
+ ProviderObservable.getInstance().updateProvider(new Provider());
+ }
+ }
+
// always check if manual gateway selection feature switch has been disabled
if (!BuildConfig.allow_manual_gateway_selection && PreferenceHelper.getPreferredCity(this) != null) {
PreferenceHelper.setPreferredCity(this, null);
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java
index ded62fa6..a95a14ef 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java
@@ -69,6 +69,7 @@ import androidx.fragment.app.FragmentTransaction;
import java.util.Observable;
import java.util.Observer;
+import java.util.concurrent.atomic.AtomicBoolean;
import butterknife.BindView;
import butterknife.ButterKnife;
@@ -138,7 +139,8 @@ public class EipFragment extends Fragment implements Observer {
AlertDialog alertDialog;
private IOpenVPNServiceInternal mService;
- private ServiceConnection openVpnConnection;
+ // We use this service connection to detect if openvpn is running without network
+ private EipFragmentServiceConnection openVpnConnection;
@Override
public void onAttach(Context context) {
@@ -229,20 +231,16 @@ public class EipFragment extends Fragment implements Observer {
@Override
public void onResume() {
super.onResume();
- //FIXME: avoid race conditions while checking certificate an logging in at about the same time
- //eipCommand(Constants.EIP_ACTION_CHECK_CERT_VALIDITY);
- bindOpenVpnService();
+ if (!eipStatus.isDisconnected()) {
+ openVpnConnection.bindService();
+ }
handleNewState();
}
@Override
public void onPause() {
super.onPause();
-
- Activity activity = getActivity();
- if (activity != null) {
- getActivity().unbindService(openVpnConnection);
- }
+ openVpnConnection.unbindService();
}
@Override
@@ -414,6 +412,14 @@ public class EipFragment extends Fragment implements Observer {
if (observable instanceof EipStatus) {
eipStatus = (EipStatus) observable;
handleNewStateOnMain();
+
+ if (eipStatus.isConnecting()) {
+ openVpnConnection.bindService();
+ }
+ if ("NOPROCESS".equals(EipStatus.getInstance().getState())) {
+ //assure that the Service is shutdown completely if openvpn was stopped
+ openVpnConnection.unbindService();
+ }
} else if (observable instanceof ProviderObservable) {
provider = ((ProviderObservable) observable).getCurrentProvider();
} else if (observable instanceof TorStatusObservable && EipStatus.getInstance().isUpdatingVpnCert()) {
@@ -574,19 +580,6 @@ public class EipFragment extends Fragment implements Observer {
return isRunning;
}
- private void bindOpenVpnService() {
- Activity activity = getActivity();
- if (activity == null) {
- Log.e(TAG, "activity is null when binding OpenVpn");
- return;
- }
-
- Intent intent = new Intent(activity, OpenVPNService.class);
- intent.setAction(OpenVPNService.START_SERVICE);
- activity.bindService(intent, openVpnConnection, Context.BIND_AUTO_CREATE);
-
- }
-
private void greyscaleBackground() {
if (BuildConfig.use_color_filter) {
ColorMatrix matrix = new ColorMatrix();
@@ -631,6 +624,38 @@ public class EipFragment extends Fragment implements Observer {
}
private class EipFragmentServiceConnection implements ServiceConnection {
+ private final AtomicBoolean bind = new AtomicBoolean(false);
+
+ void bindService() {
+ Activity activity = getActivity();
+ if (activity == null) {
+ Log.e(TAG, "activity is null when binding OpenVpn");
+ return;
+ }
+ if (!bind.get()) {
+ activity.runOnUiThread(() -> {
+ Intent intent = new Intent(activity, OpenVPNService.class);
+ intent.setAction(OpenVPNService.START_SERVICE);
+
+ activity.bindService(intent, EipFragmentServiceConnection.this, Context.BIND_AUTO_CREATE);
+ bind.set(true);
+ });
+ }
+ }
+
+ void unbindService() {
+ Activity activity = getActivity();
+ if (activity == null) {
+ return;
+ }
+ if (bind.get()) {
+ activity.runOnUiThread(() -> {
+ activity.unbindService(EipFragmentServiceConnection.this);
+ bind.set(false);
+ });
+ }
+ }
+
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/FeatureVersionCode.java b/app/src/main/java/se/leap/bitmaskclient/base/models/FeatureVersionCode.java
index 95decb82..9f813415 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/models/FeatureVersionCode.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/models/FeatureVersionCode.java
@@ -4,4 +4,5 @@ public interface FeatureVersionCode {
int RENAMED_EIP_IN_PREFERENCES = 132;
int GEOIP_SERVICE = 148;
int CALYX_PROVIDER_LILYPAD_UPDATE = 163000;
+ int RISEUP_PROVIDER_LILYPAD_UPDATE = 164000;
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java
index 7b8f22af..13463167 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java
@@ -58,6 +58,7 @@ public final class Provider implements Parcelable {
private DefaultedURL mainUrl = new DefaultedURL();
private DefaultedURL apiUrl = new DefaultedURL();
private DefaultedURL geoipUrl = new DefaultedURL();
+ private String domain = "";
private String providerIp = ""; // ip of the provider main url
private String providerApiIp = ""; // ip of the provider api url
private String certificatePin = "";
@@ -253,7 +254,7 @@ public final class Provider implements Parcelable {
}
public String getDomain() {
- return mainUrl.getDomain();
+ return domain;
}
public String getMainUrlString() {
@@ -369,6 +370,7 @@ public final class Provider implements Parcelable {
@Override
public void writeToParcel(Parcel parcel, int i) {
+ parcel.writeString(getDomain());
parcel.writeString(getMainUrlString());
parcel.writeString(getProviderIp());
parcel.writeString(getProviderApiIp());
@@ -388,6 +390,7 @@ public final class Provider implements Parcelable {
//TODO: write a test for marshalling!
private Provider(Parcel in) {
try {
+ domain = in.readString();
mainUrl.setUrl(new URL(in.readString()));
String tmpString = in.readString();
if (!tmpString.isEmpty()) {
@@ -439,7 +442,8 @@ public final class Provider implements Parcelable {
public boolean equals(Object o) {
if (o instanceof Provider) {
Provider p = (Provider) o;
- return p.getDomain().equals(getDomain()) &&
+ return getDomain().equals(p.getDomain()) &&
+ mainUrl.getDomain().equals(p.mainUrl.getDomain()) &&
definition.toString().equals(p.getDefinition().toString()) &&
eipServiceJson.toString().equals(p.getEipServiceJsonString()) &&
geoIpJson.toString().equals(p.getGeoIpJsonString()) &&
@@ -471,7 +475,7 @@ public final class Provider implements Parcelable {
@Override
public int hashCode() {
- return getDomain().hashCode();
+ return getMainUrlString().hashCode();
}
@Override
@@ -488,6 +492,7 @@ public final class Provider implements Parcelable {
this.allowAnonymous = definition.getJSONObject(Provider.SERVICE).getBoolean(PROVIDER_ALLOW_ANONYMOUS);
this.allowRegistered = definition.getJSONObject(Provider.SERVICE).getBoolean(PROVIDER_ALLOWED_REGISTERED);
this.apiVersion = getDefinition().getString(Provider.API_VERSION);
+ this.domain = getDefinition().getString(Provider.DOMAIN);
return true;
} catch (JSONException | ArrayIndexOutOfBoundsException | MalformedURLException e) {
return false;
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/utils/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/base/utils/ConfigHelper.java
index 96518a8e..d65f6b52 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/utils/ConfigHelper.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/utils/ConfigHelper.java
@@ -52,6 +52,7 @@ import java.util.Calendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import okhttp3.internal.publicsuffix.PublicSuffixDatabase;
import se.leap.bitmaskclient.BuildConfig;
import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.providersetup.ProviderAPI;
@@ -274,6 +275,10 @@ public class ConfigHelper {
Matcher matcher = IPv4_PATTERN.matcher(ipv4);
return matcher.matches();
}
+
+ public static String getDomainFromMainURL(@NonNull String mainUrl) throws NullPointerException {
+ return PublicSuffixDatabase.get().getEffectiveTldPlusOne(mainUrl).replaceFirst("http[s]?://", "").replaceFirst("/.*", "");
+ }
public static boolean isCalyxOSWithTetheringSupport(Context context) {
return SystemPropertiesHelper.contains("ro.calyxos.version", context) &&
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java
index 607339fd..7b6a3ad6 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java
@@ -41,6 +41,7 @@ import static se.leap.bitmaskclient.base.models.Provider.CA_CERT;
import static se.leap.bitmaskclient.base.models.Provider.GEOIP_URL;
import static se.leap.bitmaskclient.base.models.Provider.PROVIDER_API_IP;
import static se.leap.bitmaskclient.base.models.Provider.PROVIDER_IP;
+import static se.leap.bitmaskclient.base.utils.ConfigHelper.getDomainFromMainURL;
import static se.leap.bitmaskclient.base.utils.ConfigHelper.getFingerprintFromCertificate;
import static se.leap.bitmaskclient.base.utils.ConfigHelper.getProviderFormattedString;
import static se.leap.bitmaskclient.base.utils.ConfigHelper.parseRsaKeyFromString;
@@ -1048,11 +1049,6 @@ public abstract class ProviderApiManagerBase {
return preferences.contains(Provider.KEY + "." + domain) && preferences.contains(CA_CERT + "." + domain);
}
- protected String getDomainFromMainURL(String mainUrl) {
- return mainUrl.replaceFirst("http[s]?://", "").replaceFirst("/.*", "");
-
- }
-
/**
* Interprets the error message as a JSON object and extract the "errors" keyword pair.
* If the error message is not a JSON object, then it is returned untouched.
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/CustomProviderSetupActivity.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/CustomProviderSetupActivity.java
index b90d14f8..0fff1ee2 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/CustomProviderSetupActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/CustomProviderSetupActivity.java
@@ -31,6 +31,7 @@ import java.io.IOException;
import se.leap.bitmaskclient.BuildConfig;
import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.base.models.Provider;
+import se.leap.bitmaskclient.base.utils.ConfigHelper;
import se.leap.bitmaskclient.providersetup.ProviderAPICommand;
import static se.leap.bitmaskclient.BuildConfig.customProviderApiIp;
@@ -72,8 +73,9 @@ public class CustomProviderSetupActivity extends ProviderSetupBaseActivity {
try {
AssetManager assetsManager = getAssets();
Provider customProvider = new Provider(customProviderUrl, geoipUrl, customProviderIp, customProviderApiIp);
- String certificate = loadInputStreamAsString(assetsManager.open(customProvider.getDomain() + EXT_PEM));
- String providerDefinition = loadInputStreamAsString(assetsManager.open(customProvider.getDomain() + EXT_JSON));
+ String domain = ConfigHelper.getDomainFromMainURL(customProviderUrl);
+ String certificate = loadInputStreamAsString(assetsManager.open(domain + EXT_PEM));
+ String providerDefinition = loadInputStreamAsString(assetsManager.open(domain + EXT_JSON));
customProvider.setCaCert(certificate);
customProvider.define(new JSONObject(providerDefinition));
setProvider(customProvider);
diff --git a/app/src/normal/assets/urls/riseup.net.url b/app/src/normal/assets/urls/riseup.net.url
index 3c1e6b49..a33898c4 100644
--- a/app/src/normal/assets/urls/riseup.net.url
+++ b/app/src/normal/assets/urls/riseup.net.url
@@ -1,5 +1,5 @@
{
- "main_url" : "https://riseup.net",
+ "main_url" : "https://black.riseup.net",
"provider_ip" : "198.252.153.70",
"provider_api_ip" : "198.252.153.107",
"geoip_url" : "https://api.black.riseup.net:9001/json"
diff --git a/app/src/normalProductionFatDebug/assets/urls/riseup.net.url b/app/src/normalProductionFatDebug/assets/urls/riseup.net.url
index 3c1e6b49..a33898c4 100644
--- a/app/src/normalProductionFatDebug/assets/urls/riseup.net.url
+++ b/app/src/normalProductionFatDebug/assets/urls/riseup.net.url
@@ -1,5 +1,5 @@
{
- "main_url" : "https://riseup.net",
+ "main_url" : "https://black.riseup.net",
"provider_ip" : "198.252.153.70",
"provider_api_ip" : "198.252.153.107",
"geoip_url" : "https://api.black.riseup.net:9001/json"
diff --git a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java
index 3ec04f32..0fa89bf2 100644
--- a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java
+++ b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java
@@ -263,7 +263,7 @@ public class ProviderApiManager extends ProviderApiManagerBase {
Bundle result = new Bundle();
try {
String caCertUrl = provider.getDefinition().getString(Provider.CA_CERT_URI);
- String providerDomain = getDomainFromMainURL(provider.getMainUrlString());
+ String providerDomain = provider.getDomain();
String certString = downloadWithCommercialCA(caCertUrl, provider);
if (validCertificate(provider, certString)) {
diff --git a/app/src/test/java/se/leap/bitmaskclient/base/utils/ConfigHelperTest.java b/app/src/test/java/se/leap/bitmaskclient/base/utils/ConfigHelperTest.java
index 75552226..6e0ceb56 100644
--- a/app/src/test/java/se/leap/bitmaskclient/base/utils/ConfigHelperTest.java
+++ b/app/src/test/java/se/leap/bitmaskclient/base/utils/ConfigHelperTest.java
@@ -1,5 +1,7 @@
package se.leap.bitmaskclient.base.utils;
+import static org.junit.Assert.assertEquals;
+
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
@@ -9,8 +11,6 @@ import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
-import static org.junit.Assert.assertEquals;
-
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(DataProviderRunner.class)
public class ConfigHelperTest {
@@ -45,4 +45,16 @@ public class ConfigHelperTest {
public void testisIPv4_validIPs_returnsTrue(String ip, boolean isValidExpected) {
assertEquals(isValidExpected, ConfigHelper.isIPv4(ip));
}
+
+ @Test
+ public void testGetDomainFromMainURL_ignoreSubdomain() {
+ assertEquals("riseup.net", ConfigHelper.getDomainFromMainURL("https://black.riseup.net"));
+ assertEquals("riseup.net", ConfigHelper.getDomainFromMainURL("https://riseup.net"));
+ }
+
+ @Test
+ public void testGetDomainFromMainURL_handleSuffix() {
+ assertEquals("domain.co.uk", ConfigHelper.getDomainFromMainURL("https://subdomain.domain.co.uk"));
+ assertEquals("domain.co.uk", ConfigHelper.getDomainFromMainURL("https://domain.co.uk"));
+ }
} \ No newline at end of file
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 a455a4bf..c6ba1e6f 100644
--- a/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
+++ b/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
@@ -425,6 +425,7 @@ public class MockHelper {
when(ConfigHelper.timezoneDistance(anyInt(), anyInt())).thenCallRealMethod();
when(ConfigHelper.isIPv4(anyString())).thenCallRealMethod();
when(ConfigHelper.isDefaultBitmask()).thenReturn(true);
+ when(ConfigHelper.getDomainFromMainURL(anyString())).thenCallRealMethod();
when(ConfigHelper.parseRsaKeyFromString(anyString())).thenReturn(new RSAPrivateKey() {
@Override
public BigInteger getPrivateExponent() {