summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap/bitmaskclient/base
diff options
context:
space:
mode:
authorNorbel Ambanumben <nambanumben@riseup.net>2024-10-11 11:54:39 +0000
committercyberta <cyberta@riseup.net>2024-10-11 11:54:39 +0000
commit55219121b127a000b2d410a841b6441a25adb1f3 (patch)
treede5e801f2df0cccf393a051976a12a7a69fcc442 /app/src/main/java/se/leap/bitmaskclient/base
parent236ce1209278fae174713d605300b6ed3f16febb (diff)
feat: add invite code to UI.
Diffstat (limited to 'app/src/main/java/se/leap/bitmaskclient/base')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java105
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java12
2 files changed, 117 insertions, 0 deletions
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
new file mode 100644
index 00000000..c31912d9
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java
@@ -0,0 +1,105 @@
+package se.leap.bitmaskclient.base.models;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+public class Introducer implements Parcelable {
+ private String type;
+ private String address;
+ private String certificate;
+ private String fullyQualifiedDomainName;
+ private boolean kcpEnabled;
+
+ public Introducer(String type, String address, String certificate, String fullyQualifiedDomainName, boolean kcpEnabled) {
+ this.type = type;
+ this.address = address;
+ this.certificate = certificate;
+ this.fullyQualifiedDomainName = fullyQualifiedDomainName;
+ this.kcpEnabled = kcpEnabled;
+ }
+
+ protected Introducer(Parcel in) {
+ type = in.readString();
+ address = in.readString();
+ certificate = in.readString();
+ fullyQualifiedDomainName = in.readString();
+ kcpEnabled = in.readByte() != 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(type);
+ dest.writeString(address);
+ dest.writeString(certificate);
+ dest.writeString(fullyQualifiedDomainName);
+ dest.writeByte((byte) (kcpEnabled ? 1 : 0));
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Creator<Introducer> CREATOR = new Creator<>() {
+ @Override
+ public Introducer createFromParcel(Parcel in) {
+ return new Introducer(in);
+ }
+
+ @Override
+ public Introducer[] newArray(int size) {
+ return new Introducer[size];
+ }
+ };
+
+ public boolean validate() {
+ if (!"obfsvpnintro".equals(type)) {
+ throw new IllegalArgumentException("Unknown type: " + type);
+ }
+ if (!address.contains(":") || address.split(":").length != 2) {
+ throw new IllegalArgumentException("Expected address in format ipaddr:port");
+ }
+ if (certificate.length() != 70) {
+ throw new IllegalArgumentException("Wrong certificate length: " + certificate.length());
+ }
+ if (!"localhost".equals(fullyQualifiedDomainName) && fullyQualifiedDomainName.split("\\.").length < 2) {
+ throw new IllegalArgumentException("Expected a FQDN, got: " + fullyQualifiedDomainName);
+ }
+ return true;
+ }
+
+ public static Introducer fromUrl(String introducerUrl) throws URISyntaxException {
+ URI uri = new URI(introducerUrl);
+ String fqdn = getQueryParam(uri, "fqdn");
+ if (fqdn == null || fqdn.isEmpty()) {
+ throw new IllegalArgumentException("FQDN not found in the introducer URL");
+ }
+
+ boolean kcp = "1".equals(getQueryParam(uri, "kcp"));
+
+ String cert = getQueryParam(uri, "cert");
+ if (cert == null || cert.isEmpty()) {
+ throw new IllegalArgumentException("Cert not found in the introducer URL");
+ }
+
+ return new Introducer(uri.getScheme(), uri.getAuthority(), cert, fqdn, kcp);
+ }
+
+ public String toUrl() {
+ return String.format("%s://%s?fqdn=%s&kcp=%d&cert=%s", type, address, fullyQualifiedDomainName, kcpEnabled ? 1 : 0, certificate);
+ }
+
+ 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;
+ }
+} \ No newline at end of file
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 725c602a..bf1e6b94 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
@@ -86,6 +86,7 @@ public final class Provider implements Parcelable {
private long lastGeoIpUpdate = 0L;
private long lastMotdUpdate = 0L;
private long lastMotdSeen = 0L;
+ private Introducer introducer = null;
private Set<String> lastMotdSeenHashes = new HashSet<>();
private boolean shouldUpdateVpnCertificate;
@@ -115,6 +116,11 @@ public final class Provider implements Parcelable {
public Provider() { }
+ public Provider(Introducer introducer) {
+ this(introducer.toUrl(), null);
+ this.introducer = introducer;
+ }
+
public Provider(String mainUrl) {
this(mainUrl, null);
}
@@ -423,6 +429,7 @@ public final class Provider implements Parcelable {
parcel.writeLong(lastMotdSeen);
parcel.writeStringList(new ArrayList<>(lastMotdSeenHashes));
parcel.writeInt(shouldUpdateVpnCertificate ? 0 : 1);
+ parcel.writeParcelable(introducer, 0);
}
@@ -484,6 +491,7 @@ public final class Provider implements Parcelable {
in.readStringList(lastMotdSeenHashes);
this.lastMotdSeenHashes = new HashSet<>(lastMotdSeenHashes);
this.shouldUpdateVpnCertificate = in.readInt() == 0;
+ this.introducer = in.readParcelable(Introducer.class.getClassLoader());
} catch (MalformedURLException | JSONException e) {
e.printStackTrace();
}
@@ -739,6 +747,10 @@ public final class Provider implements Parcelable {
return getCertificatePinEncoding() + ":" + getCertificatePin();
}
+ public boolean hasIntroducer() {
+ return introducer != null;
+ }
+
/**
* resets everything except the main url, the providerIp and the geoip
* service url (currently preseeded)