diff --git a/CHANGELOG b/CHANGELOG index 50b9cb4598f4f4eb4c33b7542fca75cfbb5cc214..31ff7a8d741b6bd3059d99fb65cc5cf0463c0ea4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +1.5.2RC2 Obfuscation Update beta release +bugfixes: +- fix parsing invite code parameters, fixes bucket authentication + 1.5.2RC1 Obfuscation Update beta release features: - handle Quic as obfuscation protocol diff --git a/app/build.gradle b/app/build.gradle index cedeca7cc0274cc06c26de544e801ce71bfc5a1d..7fc949737145cd2f2fc8c69067a278f69a50e06b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -32,8 +32,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 180000 - versionName "1.5.2RC1" + versionCode 181000 + versionName "1.5.2RC2" compileSdk 34 minSdkVersion 21 targetSdkVersion 34 diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java index 7048c48d0d81b7e5bb1b9ef27c9f5c2ad005f28c..32eabadfb28d464c48b4519a49d6594f15ea6a2a 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java @@ -1,12 +1,13 @@ package se.leap.bitmaskclient.base.models; +import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; import java.io.UnsupportedEncodingException; -import java.net.URI; import java.net.URISyntaxException; import java.net.URLEncoder; +import java.util.Locale; public class Introducer implements Parcelable { private String type; @@ -87,38 +88,32 @@ public class Introducer implements Parcelable { } public static Introducer fromUrl(String introducerUrl) throws URISyntaxException, IllegalArgumentException { - URI uri = new URI(introducerUrl); - String fqdn = getQueryParam(uri, "fqdn"); + Uri uri = Uri.parse(introducerUrl); + String fqdn = uri.getQueryParameter("fqdn"); if (fqdn == null || fqdn.isEmpty()) { throw new IllegalArgumentException("FQDN not found in the introducer URL"); } - boolean kcp = "1".equals(getQueryParam(uri, "kcp")); + boolean kcp = "1".equals(uri.getQueryParameter( "kcp")); - String cert = getQueryParam(uri, "cert"); + String cert = uri.getQueryParameter( "cert"); if (cert == null || cert.isEmpty()) { throw new IllegalArgumentException("Cert not found in the introducer URL"); } - String auth = getQueryParam(uri, "auth"); + String auth = uri.getQueryParameter( "auth"); if (auth == null || auth.isEmpty()) { throw new IllegalArgumentException("Authentication token not found in the introducer URL"); } return new Introducer(uri.getScheme(), uri.getAuthority(), cert, fqdn, kcp, auth); } - public String toUrl() throws UnsupportedEncodingException { - return String.format("%s://%s?fqdn=%s&kcp=%d&cert=%s&auth=%s", type, address, URLEncoder.encode(fullyQualifiedDomainName, "UTF-8"), kcpEnabled ? 1 : 0, URLEncoder.encode(certificate, "UTF-8"), URLEncoder.encode(auth, "UTF-8")); + public String getAuthToken() { + return auth; } - private static String getQueryParam(URI uri, String param) { - String[] queryParams = uri.getQuery().split("&"); - for (String queryParam : queryParams) { - String[] keyValue = queryParam.split("="); - if (keyValue.length == 2 && keyValue[0].equals(param)) { - return keyValue[1]; - } - } - return null; + public String toUrl() throws UnsupportedEncodingException { + return String.format(Locale.US, "%s://%s?fqdn=%s&kcp=%d&cert=%s&auth=%s", type, address, URLEncoder.encode(fullyQualifiedDomainName, "UTF-8"), kcpEnabled ? 1 : 0, URLEncoder.encode(certificate, "UTF-8"), URLEncoder.encode(auth, "UTF-8")); } + } \ No newline at end of file diff --git a/app/src/test/java/se/leap/bitmaskclient/base/models/IntroducerTest.java b/app/src/test/java/se/leap/bitmaskclient/base/models/IntroducerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..01989cf9d474a60b4e69ed21cd49876b67dff838 --- /dev/null +++ b/app/src/test/java/se/leap/bitmaskclient/base/models/IntroducerTest.java @@ -0,0 +1,46 @@ +package se.leap.bitmaskclient.base.models; + +import static org.junit.Assert.assertEquals; + +import android.net.Uri; +import android.os.Build; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import java.io.UnsupportedEncodingException; +import java.net.URISyntaxException; +import java.net.URLEncoder; + + +@RunWith(RobolectricTestRunner.class) +@Config(sdk = {Build.VERSION_CODES.P}) +public class IntroducerTest { + + @Test + public void testGetQueryParam() { + try { + String auth = "solitech_w4gOlm+abcdefaF2DE1Q6dg=="; + String encodedAuth = URLEncoder.encode(auth, "UTF-8"); + Uri uri = Uri.parse("obfsvpn://example.org:443?auth=" + encodedAuth); + assertEquals(auth, uri.getQueryParameter("auth")); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + + @Test + public void testFromUrl() { + try { + Introducer intro = Introducer.fromUrl("obfsvpnintro://37.2.240.90:443?fqdn=ft1.example.org&kcp=1&cert=XXXXXXX&auth=solitech_w4gOlm%2BsbF8spFL8E1Q6dg%3D%3D"); + assertEquals(intro.getFullyQualifiedDomainName(), "ft1.example.org"); + assertEquals("solitech_w4gOlm+sbF8spFL8E1Q6dg==", intro.getAuthToken()); + assertEquals("obfsvpnintro://37.2.240.90:443?fqdn=ft1.example.org&kcp=1&cert=XXXXXXX&auth=solitech_w4gOlm%2BsbF8spFL8E1Q6dg%3D%3D", intro.toUrl()); + } catch (URISyntaxException | UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } +}