summaryrefslogtreecommitdiff
path: root/app/src/main/java/se
diff options
context:
space:
mode:
authorcyBerta <cyberta@riseup.net>2023-03-31 15:46:09 +0200
committercyBerta <cyberta@riseup.net>2023-04-13 16:47:13 +0200
commitf6017ab12d0c472ab4f22e81d9a768ad2510b134 (patch)
tree8a38157b4218b54a12f3990beaa2852917f4de1d /app/src/main/java/se
parenta4deca391ce064510002e24ba9f18d965f0dee59 (diff)
don't handle obfs4 over kcp as a separate pluggable transport, instead 'tcp' and 'kcp' become valid protocols for obfs4
Diffstat (limited to 'app/src/main/java/se')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java23
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EIP.java17
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java7
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java33
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java36
5 files changed, 58 insertions, 58 deletions
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 53f864cf..62fb1fd2 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
@@ -16,11 +16,13 @@
*/
package se.leap.bitmaskclient.base.models;
+import static de.blinkt.openvpn.core.connection.Connection.TransportProtocol.KCP;
+import static de.blinkt.openvpn.core.connection.Connection.TransportProtocol.TCP;
import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4;
-import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4_KCP;
import static se.leap.bitmaskclient.base.models.Constants.CAPABILITIES;
import static se.leap.bitmaskclient.base.models.Constants.GATEWAYS;
import static se.leap.bitmaskclient.base.models.Constants.LOCATIONS;
+import static se.leap.bitmaskclient.base.models.Constants.PROTOCOLS;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_ALLOWED_REGISTERED;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_ALLOW_ANONYMOUS;
import static se.leap.bitmaskclient.base.models.Constants.TRANSPORT;
@@ -46,6 +48,7 @@ import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
+import de.blinkt.openvpn.core.connection.Connection.TransportProtocol;
import de.blinkt.openvpn.core.connection.Connection.TransportType;
import motd.IStringCollection;
import motd.Motd;
@@ -181,16 +184,16 @@ public final class Provider implements Parcelable {
public boolean supportsPluggableTransports() {
if (useObfsVpn()) {
- return supportsTransports(new TransportType[]{OBFS4, OBFS4_KCP});
+ return supportsTransports(new Pair[]{new Pair<>(OBFS4, TCP), new Pair<>(OBFS4, KCP)});
}
- return supportsTransports(new TransportType[]{OBFS4});
+ return supportsTransports(new Pair[]{new Pair<>(OBFS4, TCP)});
}
public boolean supportsExperimentalPluggableTransports() {
- return supportsTransports(new TransportType[]{OBFS4_KCP});
+ return supportsTransports(new Pair[]{new Pair<>(OBFS4, KCP)});
}
- private boolean supportsTransports(TransportType[] transportTypes) {
+ private boolean supportsTransports(Pair<TransportType, TransportProtocol>[] transportTypes) {
try {
JSONArray gatewayJsons = eipServiceJson.getJSONArray(GATEWAYS);
for (int i = 0; i < gatewayJsons.length(); i++) {
@@ -199,9 +202,13 @@ public final class Provider implements Parcelable {
getJSONArray(TRANSPORT);
for (int j = 0; j < transports.length(); j++) {
String supportedTransportType = transports.getJSONObject(j).getString(TYPE);
- for (TransportType transportType : transportTypes) {
- if (transportType.toString().equals(supportedTransportType)) {
- return true;
+ JSONArray transportProtocols = transports.getJSONObject(j).getJSONArray(PROTOCOLS);
+ for (Pair<TransportType, TransportProtocol> transportPair : transportTypes) {
+ for (int k = 0; k < transportProtocols.length(); k++) {
+ if (transportPair.first.toString().equals(supportedTransportType) &&
+ transportPair.second.toString().equals(transportProtocols.getString(k))) {
+ return true;
+ }
}
}
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
index 88cdc715..5b082448 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
@@ -91,6 +91,7 @@ import se.leap.bitmaskclient.base.models.Provider;
import se.leap.bitmaskclient.base.models.Pair;
import se.leap.bitmaskclient.base.models.ProviderObservable;
import se.leap.bitmaskclient.base.utils.PreferenceHelper;
+import se.leap.bitmaskclient.eip.GatewaysManager.GatewayOptions;
/**
* EIP is the abstract base class for interacting with and managing the Encrypted
@@ -255,8 +256,8 @@ public final class EIP extends JobIntentService implements Observer {
return;
}
- Pair<Gateway, Connection.TransportType> gatewayTransportTypePair = gatewaysManager.select(nClosestGateway);
- launchActiveGateway(gatewayTransportTypePair, nClosestGateway, result);
+ GatewayOptions gatewayOptions = gatewaysManager.select(nClosestGateway);
+ launchActiveGateway(gatewayOptions, nClosestGateway, result);
if (result.containsKey(BROADCAST_RESULT_KEY) && !result.getBoolean(BROADCAST_RESULT_KEY)) {
tellToReceiverOrBroadcast(this, EIP_ACTION_START, RESULT_CANCELED, result);
} else {
@@ -270,7 +271,7 @@ public final class EIP extends JobIntentService implements Observer {
*/
private void startEIPAlwaysOnVpn() {
GatewaysManager gatewaysManager = new GatewaysManager(getApplicationContext());
- Pair<Gateway, Connection.TransportType> gatewayTransportTypePair = gatewaysManager.select(0);
+ GatewayOptions gatewayOptions = gatewaysManager.select(0);
Bundle result = new Bundle();
if (shouldUpdateVPNCertificate()) {
@@ -279,7 +280,7 @@ public final class EIP extends JobIntentService implements Observer {
ProviderObservable.getInstance().updateProvider(p);
}
- launchActiveGateway(gatewayTransportTypePair, 0, result);
+ launchActiveGateway(gatewayOptions, 0, result);
if (result.containsKey(BROADCAST_RESULT_KEY) && !result.getBoolean(BROADCAST_RESULT_KEY)){
VpnStatus.logWarning("ALWAYS-ON VPN: " + getString(R.string.no_vpn_profiles_defined));
}
@@ -323,13 +324,13 @@ public final class EIP extends JobIntentService implements Observer {
/**
* starts the VPN and connects to the given gateway
*
- * @param gatewayTransportTypePair Pair of Gateway and associated transport used to connect
+ * @param gatewayOptions GatewayOptions model containing a Gateway and the associated transport used to connect
*/
- private void launchActiveGateway(@Nullable Pair<Gateway, Connection.TransportType> gatewayTransportTypePair, int nClosestGateway, Bundle result) {
+ private void launchActiveGateway(@Nullable GatewayOptions gatewayOptions, int nClosestGateway, Bundle result) {
VpnProfile profile;
- if (gatewayTransportTypePair == null || gatewayTransportTypePair.first == null ||
- (profile = gatewayTransportTypePair.first.getProfile(gatewayTransportTypePair.second)) == null) {
+ if (gatewayOptions == null || gatewayOptions.gateway == null ||
+ (profile = gatewayOptions.gateway.getProfile(gatewayOptions.transportType)) == null) {
String preferredLocation = getPreferredCity(getApplicationContext());
if (preferredLocation != null) {
setErrorResult(result, NO_MORE_GATEWAYS.toString(), getStringResourceForNoMoreGateways(), getString(R.string.app_name), preferredLocation);
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java
index 929935eb..719b960e 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java
@@ -16,6 +16,7 @@
*/
package se.leap.bitmaskclient.eip;
+import static de.blinkt.openvpn.core.connection.Connection.TransportType.PT;
import static se.leap.bitmaskclient.base.models.Constants.FULLNESS;
import static se.leap.bitmaskclient.base.models.Constants.HOST;
import static se.leap.bitmaskclient.base.models.Constants.IP_ADDRESS;
@@ -52,7 +53,6 @@ import java.util.HashSet;
import de.blinkt.openvpn.VpnProfile;
import de.blinkt.openvpn.core.ConfigParser;
import de.blinkt.openvpn.core.connection.Connection;
-import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.base.utils.ConfigHelper;
/**
@@ -77,6 +77,9 @@ public class Gateway {
private String name;
private int timezone;
private int apiVersion;
+ /** FIXME: We expect here that not more than one obfs4 transport is offered by a gateway, however
+ * it's possible to setup gateways that have obfs4 over kcp and tcp which result in different VpnProfiles each
+ */
private HashMap<Connection.TransportType, VpnProfile> vpnProfiles;
/**
@@ -209,7 +212,7 @@ public class Gateway {
}
public boolean supportsTransport(Connection.TransportType transportType) {
- if (transportType == Connection.TransportType.PT) {
+ if (transportType == PT) {
return supportsPluggableTransports();
}
return vpnProfiles.get(transportType) != null;
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
index 521d095e..28766998 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
@@ -17,7 +17,6 @@
package se.leap.bitmaskclient.eip;
import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4;
-import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4_KCP;
import static de.blinkt.openvpn.core.connection.Connection.TransportType.OPENVPN;
import static de.blinkt.openvpn.core.connection.Connection.TransportType.PT;
import static se.leap.bitmaskclient.base.models.Constants.GATEWAYS;
@@ -61,7 +60,6 @@ import se.leap.bitmaskclient.BuildConfig;
import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.base.models.GatewayJson;
import se.leap.bitmaskclient.base.models.Location;
-import se.leap.bitmaskclient.base.models.Pair;
import se.leap.bitmaskclient.base.models.Provider;
import se.leap.bitmaskclient.base.models.ProviderObservable;
import se.leap.bitmaskclient.base.models.Transport;
@@ -103,6 +101,16 @@ public class GatewaysManager {
}
}
+ public static class GatewayOptions {
+ public Gateway gateway;
+ public TransportType transportType;
+
+ public GatewayOptions(Gateway gateway, TransportType transportType) {
+ this.gateway = gateway;
+ this.transportType = transportType;
+ }
+ }
+
private static final String TAG = GatewaysManager.class.getSimpleName();
public static final String PINNED_OBFUSCATION_PROXY = "pinned.obfuscation.proxy";
@@ -122,7 +130,7 @@ public class GatewaysManager {
* select closest Gateway
* @return the n closest Gateway
*/
- public Pair<Gateway, TransportType> select(int nClosest) {
+ public GatewayOptions select(int nClosest) {
if (PreferenceHelper.useObfuscationPinning(context)) {
if (nClosest > 2) {
// no need to try again the pinned proxy, probably configuration error
@@ -132,14 +140,14 @@ public class GatewaysManager {
if (gateway == null) {
return null;
}
- return new Pair<>(gateway, getObfuscationPinningKCP(context) ? OBFS4_KCP : OBFS4);
+ return new GatewayOptions(gateway, OBFS4);
}
String selectedCity = getPreferredCity(context);
return select(nClosest, selectedCity);
}
- public Pair<Gateway, TransportType> select(int nClosest, String city) {
- TransportType[] transportTypes = getUseBridges(context) ? new TransportType[]{OBFS4, OBFS4_KCP} : new TransportType[]{OPENVPN};
+ public GatewayOptions select(int nClosest, String city) {
+ TransportType[] transportTypes = getUseBridges(context) ? new TransportType[]{OBFS4} : new TransportType[]{OPENVPN};
if (presortedList.size() > 0) {
return getGatewayFromPresortedList(nClosest, transportTypes, city);
}
@@ -266,7 +274,7 @@ public class GatewaysManager {
return Load.getLoadByValue(location.getAverageLoad(transportType));
}
- private Pair<Gateway, TransportType> getGatewayFromTimezoneCalculation(int nClosest, TransportType[] transportTypes, @Nullable String city) {
+ private GatewayOptions getGatewayFromTimezoneCalculation(int nClosest, TransportType[] transportTypes, @Nullable String city) {
List<Gateway> list = new ArrayList<>(gateways.values());
GatewaySelector gatewaySelector = new GatewaySelector(list);
Gateway gateway;
@@ -277,7 +285,7 @@ public class GatewaysManager {
if ((city == null && gateway.supportsTransport(transportType)) ||
(gateway.getName().equals(city) && gateway.supportsTransport(transportType))) {
if (found == nClosest) {
- return new Pair<>(gateway, transportType);
+ return new GatewayOptions(gateway, transportType);
}
found++;
}
@@ -287,14 +295,14 @@ public class GatewaysManager {
return null;
}
- private Pair<Gateway, TransportType> getGatewayFromPresortedList(int nClosest, TransportType[] transportTypes, @Nullable String city) {
+ private GatewayOptions getGatewayFromPresortedList(int nClosest, TransportType[] transportTypes, @Nullable String city) {
int found = 0;
for (Gateway gateway : presortedList) {
for (TransportType transportType : transportTypes) {
if ((city == null && gateway.supportsTransport(transportType)) ||
(gateway.getName().equals(city) && gateway.supportsTransport(transportType))) {
if (found == nClosest) {
- return new Pair<>(gateway, transportType);
+ return new GatewayOptions(gateway, transportType);
}
found++;
}
@@ -387,10 +395,9 @@ public class GatewaysManager {
if (PreferenceHelper.useObfuscationPinning(context)) {
try {
- TransportType transportType = getObfuscationPinningKCP(context) ? OBFS4_KCP : OBFS4;
Transport[] transports = new Transport[]{
- new Transport(transportType.toString(),
- new String[]{"tcp"},
+ new Transport(OBFS4.toString(),
+ new String[]{getObfuscationPinningKCP(context) ? "kcp" : "tcp"},
new String[]{getObfuscationPinningPort(context)},
getObfuscationPinningCert(context))};
GatewayJson.Capabilities capabilities = new GatewayJson.Capabilities(false, false, false, transports, false);
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
index 72a0d80a..141f6274 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
@@ -17,7 +17,6 @@
package se.leap.bitmaskclient.eip;
import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4;
-import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4_KCP;
import static de.blinkt.openvpn.core.connection.Connection.TransportType.OPENVPN;
import static de.blinkt.openvpn.core.connection.Connection.TransportType.PT;
import static se.leap.bitmaskclient.base.models.Constants.CAPABILITIES;
@@ -63,7 +62,6 @@ public class VpnConfigGenerator {
private final JSONObject gateway;
private final JSONObject secrets;
private JSONObject obfs4Transport;
- private JSONObject obfs4TKcpTransport;
private final int apiVersion;
private final boolean preferUDP;
private final boolean experimentalTransports;
@@ -122,11 +120,7 @@ public class VpnConfigGenerator {
JSONObject transport = supportedTransports.getJSONObject(i);
if (transport.getString(TYPE).equals(OBFS4.toString())) {
obfs4Transport = transport;
- if (!experimentalTransports && !obfuscationPinningKCP) {
- break;
- }
- } else if ((experimentalTransports || obfuscationPinningKCP) && transport.getString(TYPE).equals(OBFS4_KCP.toString())) {
- obfs4TKcpTransport = transport;
+ break;
}
}
}
@@ -154,13 +148,6 @@ public class VpnConfigGenerator {
e.printStackTrace();
}
}
- if (supportsObfs4Kcp()) {
- try {
- profiles.put(OBFS4_KCP, createProfile(OBFS4_KCP));
- } catch (ConfigParser.ConfigParseError | NumberFormatException | JSONException | IOException e) {
- e.printStackTrace();
- }
- }
if (profiles.isEmpty()) {
throw new ConfigParser.ConfigParseError("No supported transports detected.");
}
@@ -171,11 +158,7 @@ public class VpnConfigGenerator {
return !useObfuscationPinning && !gatewayConfiguration(OPENVPN).isEmpty();
}
private boolean supportsObfs4(){
- return obfs4Transport != null && !(useObfuscationPinning && obfuscationPinningKCP);
- }
-
- private boolean supportsObfs4Kcp() {
- return obfs4TKcpTransport != null && !(useObfuscationPinning && !obfuscationPinningKCP);
+ return obfs4Transport != null || useObfuscationPinning;
}
private String getConfigurationString(TransportType transportType) {
@@ -194,9 +177,10 @@ public class VpnConfigGenerator {
ConfigParser icsOpenvpnConfigParser = new ConfigParser();
icsOpenvpnConfigParser.parseConfig(new StringReader(configuration));
if (transportType == OBFS4) {
- icsOpenvpnConfigParser.setObfs4Options(getObfs4Options(obfs4Transport, false));
- } else if (transportType == OBFS4_KCP) {
- icsOpenvpnConfigParser.setObfs4Options(getObfs4Options(obfs4TKcpTransport, true));
+ JSONArray protocols = obfs4Transport.getJSONArray(PROTOCOLS);
+ // FIXME: currently only one protocol per obfs4 bridge is supported in this client
+ String protocol = protocols.optString(0);
+ icsOpenvpnConfigParser.setObfs4Options(getObfs4Options(obfs4Transport, protocol.equalsIgnoreCase("kcp")));
}
VpnProfile profile = icsOpenvpnConfigParser.convertProfile(transportType);
@@ -208,7 +192,6 @@ public class VpnConfigGenerator {
return profile;
}
- // TODO: whad does
private Obfs4Options getObfs4Options(JSONObject transportJson, boolean useUdp) throws JSONException {
JSONObject transportOptions = transportJson.getJSONObject(OPTIONS);
String iatMode = transportOptions.getString("iatMode");
@@ -367,8 +350,7 @@ public class VpnConfigGenerator {
case OPENVPN:
return "tcp".equals(protocol) || "udp".equals(protocol);
case OBFS4:
- case OBFS4_KCP:
- return "tcp".equals(protocol);
+ return "tcp".equals(protocol) || "kcp".equals(protocol);
}
return false;
}
@@ -446,10 +428,10 @@ public class VpnConfigGenerator {
String remote;
if (useObfsVpn()) {
if (useObfuscationPinning) {
- remote = REMOTE + " " + obfuscationPinningIP + " " + obfuscationPinningPort + newLine;
+ remote = REMOTE + " " + obfuscationPinningIP + " " + obfuscationPinningPort + " tcp" + newLine;
route = "route " + obfuscationPinningIP + " 255.255.255.255 net_gateway" + newLine;
} else {
- remote = REMOTE + " " + ipAddress + " " + ports.getString(0) + newLine;
+ remote = REMOTE + " " + ipAddress + " " + ports.getString(0) + " tcp" + newLine;
}
} else {
remote = REMOTE + " " + DISPATCHER_IP + " " + DISPATCHER_PORT + " tcp" + newLine;