diff options
author | cyberta <cyberta@riseup.net> | 2022-08-07 21:41:16 +0000 |
---|---|---|
committer | cyberta <cyberta@riseup.net> | 2022-08-07 21:41:16 +0000 |
commit | 8d06c86a2fedf7a758801ac0b029b53b54977bd7 (patch) | |
tree | f415af41a05c766846d83c2b5d8de0ec40325ef1 | |
parent | b1cb49a2f78c80db0b3fa037a0b4e3c1c9c7dd61 (diff) | |
parent | 6e824a7bf5b127239d838a64a98c45c5d20e7e05 (diff) |
Merge branch 'bugfix_branch' into 'master'
Bugfixes and more
Closes #9110
See merge request leap/bitmask_android!205
13 files changed, 100 insertions, 41 deletions
diff --git a/app/build.gradle b/app/build.gradle index 7eec00b0..9bfade34 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 30 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 91894fb8..dbcb55b0 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 @@ -51,6 +51,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; @@ -273,6 +274,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() { |