summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap/bitmaskclient/eip
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/se/leap/bitmaskclient/eip')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java6
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java62
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java82
3 files changed, 83 insertions, 67 deletions
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 ff1dd05e..929935eb 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java
@@ -29,8 +29,6 @@ import static se.leap.bitmaskclient.base.models.Constants.VERSION;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.allowExperimentalTransports;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getExcludedApps;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningCert;
-import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningGatewayHost;
-import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningGatewayIP;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningGatewayLocation;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningIP;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningKCP;
@@ -50,11 +48,11 @@ import org.json.JSONObject;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Set;
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;
/**
@@ -112,9 +110,9 @@ public class Gateway {
config.experimentalTransports = allowExperimentalTransports(context);
config.excludedApps = getExcludedApps(context);
+ config.remoteGatewayIP = config.useObfuscationPinning ? getObfuscationPinningIP(context) : gateway.optString(IP_ADDRESS);
config.useObfuscationPinning = useObfuscationPinning(context);
config.profileName = config.useObfuscationPinning ? getObfuscationPinningGatewayLocation(context) : locationAsName(eipDefinition);
- config.remoteGatewayIP = config.useObfuscationPinning ? getObfuscationPinningGatewayIP(context) : gateway.optString(IP_ADDRESS);
if (config.useObfuscationPinning) {
config.obfuscationProxyIP = getObfuscationPinningIP(context);
config.obfuscationProxyPort = getObfuscationPinningPort(context);
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 7bcd0def..521d095e 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
@@ -25,10 +25,12 @@ import static se.leap.bitmaskclient.base.models.Constants.HOST;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PRIVATE_KEY;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.base.models.Constants.SORTED_GATEWAYS;
+import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningCert;
+import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningIP;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningKCP;
+import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningPort;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getPreferredCity;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseBridges;
-import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useObfuscationPinning;
import android.content.Context;
import android.util.Log;
@@ -56,10 +58,13 @@ import de.blinkt.openvpn.core.VpnStatus;
import de.blinkt.openvpn.core.connection.Connection;
import de.blinkt.openvpn.core.connection.Connection.TransportType;
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;
import se.leap.bitmaskclient.base.utils.PreferenceHelper;
/**
@@ -99,6 +104,7 @@ public class GatewaysManager {
}
private static final String TAG = GatewaysManager.class.getSimpleName();
+ public static final String PINNED_OBFUSCATION_PROXY = "pinned.obfuscation.proxy";
private final Context context;
private final LinkedHashMap<String, Gateway> gateways = new LinkedHashMap<>();
@@ -118,7 +124,11 @@ public class GatewaysManager {
*/
public Pair<Gateway, TransportType> select(int nClosest) {
if (PreferenceHelper.useObfuscationPinning(context)) {
- Gateway gateway = gateways.get(PreferenceHelper.getObfuscationPinningGatewayHost(context));
+ if (nClosest > 2) {
+ // no need to try again the pinned proxy, probably configuration error
+ return null;
+ }
+ Gateway gateway = gateways.get(PINNED_OBFUSCATION_PROXY);
if (gateway == null) {
return null;
}
@@ -228,12 +238,13 @@ public class GatewaysManager {
}
}
- public String getLocationNameForHost(String name) {
- Gateway gateway = gateways.get(name);
- if (gateway != null) {
- return gateway.getName();
+ public String getLocationNameForIP(String ip, Context context) {
+ for (Gateway gateway : gateways.values()) {
+ if (gateway.getRemoteIP().equals(ip)) {
+ return gateway.getName();
+ }
}
- return "Unknown Location";
+ return context.getString(R.string.unknown_location);
}
@Nullable
@@ -374,18 +385,35 @@ public class GatewaysManager {
e.printStackTrace();
}
- for (int i = 0; i < gatewaysDefined.length(); i++) {
+ if (PreferenceHelper.useObfuscationPinning(context)) {
try {
- JSONObject gw = gatewaysDefined.getJSONObject(i);
- Gateway aux = new Gateway(eipDefinition, secrets, gw, this.context);
- if (gateways.get(aux.getHost()) == null) {
- addGateway(aux);
- }
- } catch (JSONException | IOException e) {
+ TransportType transportType = getObfuscationPinningKCP(context) ? OBFS4_KCP : OBFS4;
+ Transport[] transports = new Transport[]{
+ new Transport(transportType.toString(),
+ new String[]{"tcp"},
+ new String[]{getObfuscationPinningPort(context)},
+ getObfuscationPinningCert(context))};
+ GatewayJson.Capabilities capabilities = new GatewayJson.Capabilities(false, false, false, transports, false);
+ GatewayJson gatewayJson = new GatewayJson(context.getString(R.string.unknown_location), getObfuscationPinningIP(context), null, PINNED_OBFUSCATION_PROXY, capabilities);
+ Gateway gateway = new Gateway(eipDefinition, secrets, new JSONObject(gatewayJson.toString()), this.context);
+ addGateway(gateway);
+ } catch (JSONException | ConfigParser.ConfigParseError | IOException e) {
e.printStackTrace();
- VpnStatus.logError("Unable to parse gateway config!");
- } catch (ConfigParser.ConfigParseError e) {
- VpnStatus.logError("Unable to parse gateway config: " + e.getLocalizedMessage());
+ }
+ } else {
+ for (int i = 0; i < gatewaysDefined.length(); i++) {
+ try {
+ JSONObject gw = gatewaysDefined.getJSONObject(i);
+ Gateway aux = new Gateway(eipDefinition, secrets, gw, this.context);
+ if (gateways.get(aux.getHost()) == null) {
+ addGateway(aux);
+ }
+ } catch (JSONException | IOException e) {
+ e.printStackTrace();
+ VpnStatus.logError("Unable to parse gateway config!");
+ } catch (ConfigParser.ConfigParseError e) {
+ VpnStatus.logError("Unable to parse gateway config: " + e.getLocalizedMessage());
+ }
}
}
} catch (NullPointerException npe) {
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 a7df99bf..f60d89ce 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
@@ -116,16 +116,6 @@ public class VpnConfigGenerator {
public void checkCapabilities() throws ConfigParser.ConfigParseError {
try {
- if (useObfuscationPinning) {
- if (obfuscationPinningKCP) {
- // the protocol TCP refers to the allowed openvpn protocol
- obfs4TKcpTransport = new JSONObject(new Transport(OBFS4_KCP.toString(), new String[]{"tcp"}, new String[]{obfuscationPinningPort}, obfuscationPinningCert).toString());
- } else {
- String jsonTransportString = new Transport(OBFS4.toString(), new String[]{"tcp"}, new String[]{obfuscationPinningPort}, obfuscationPinningCert).toString();
- obfs4Transport = new JSONObject(jsonTransportString);
- }
- return;
- }
if (apiVersion >= 3) {
JSONArray supportedTransports = gateway.getJSONObject(CAPABILITIES).getJSONArray(TRANSPORT);
@@ -133,10 +123,10 @@ public class VpnConfigGenerator {
JSONObject transport = supportedTransports.getJSONObject(i);
if (transport.getString(TYPE).equals(OBFS4.toString())) {
obfs4Transport = transport;
- if (!experimentalTransports) {
+ if (!experimentalTransports && !obfuscationPinningKCP) {
break;
}
- } else if (experimentalTransports && transport.getString(TYPE).equals(OBFS4_KCP.toString())) {
+ } else if ((experimentalTransports || obfuscationPinningKCP) && transport.getString(TYPE).equals(OBFS4_KCP.toString())) {
obfs4TKcpTransport = transport;
}
}
@@ -149,11 +139,15 @@ public class VpnConfigGenerator {
public HashMap<TransportType, VpnProfile> generateVpnProfiles() throws
ConfigParser.ConfigParseError,
- NumberFormatException,
- JSONException,
- IOException {
+ NumberFormatException {
HashMap<Connection.TransportType, VpnProfile> profiles = new HashMap<>();
- profiles.put(OPENVPN, createProfile(OPENVPN));
+ if (supportsOpenvpn()) {
+ try {
+ profiles.put(OPENVPN, createProfile(OPENVPN));
+ } catch (ConfigParser.ConfigParseError | NumberFormatException | JSONException | IOException e) {
+ e.printStackTrace();
+ }
+ }
if (supportsObfs4()) {
try {
profiles.put(OBFS4, createProfile(OBFS4));
@@ -168,15 +162,21 @@ public class VpnConfigGenerator {
e.printStackTrace();
}
}
+ if (profiles.isEmpty()) {
+ throw new ConfigParser.ConfigParseError("No supported transports detected.");
+ }
return profiles;
}
+ private boolean supportsOpenvpn() {
+ return !useObfuscationPinning && !gatewayConfiguration(OPENVPN).isEmpty();
+ }
private boolean supportsObfs4(){
- return obfs4Transport != null;
+ return obfs4Transport != null && !(useObfuscationPinning && obfuscationPinningKCP);
}
private boolean supportsObfs4Kcp() {
- return obfs4TKcpTransport != null;
+ return obfs4TKcpTransport != null && !(useObfuscationPinning && !obfuscationPinningKCP);
}
private String getConfigurationString(TransportType transportType) {
@@ -375,22 +375,8 @@ public class VpnConfigGenerator {
}
private void ptGatewayConfigMinApiv3(StringBuilder stringBuilder, String[] ipAddresses, TransportType transportType, JSONArray transports) throws JSONException {
- if (useObfuscationPinning) {
- JSONArray pinnedTransports = new JSONArray();
- for (int i = 0; i < transports.length(); i++) {
- if (OPENVPN.toString().equals(transports.getJSONObject(i).get(TYPE))) {
- pinnedTransports.put(transports.getJSONObject(i));
- break;
- }
- }
- pinnedTransports.put(supportsObfs4() ? obfs4Transport : obfs4TKcpTransport);
- transports = pinnedTransports;
- }
-
JSONObject ptTransport = getTransport(transports, transportType);
JSONArray ptProtocols = ptTransport.getJSONArray(PROTOCOLS);
- JSONObject openvpnTransport = getTransport(transports, OPENVPN);
- JSONArray gatewayProtocols = openvpnTransport.getJSONArray(PROTOCOLS);
//for now only use ipv4 gateway the syntax route remote_host 255.255.255.255 net_gateway is not yet working
// https://community.openvpn.net/openvpn/ticket/1161
@@ -418,20 +404,23 @@ public class VpnConfigGenerator {
return;
}
- // check if at least one openvpn protocol is TCP, openvpn in UDP is currently not supported for obfs4,
- // however on the wire UDP might be used
- boolean hasOpenvpnTcp = false;
- for (int i = 0; i < gatewayProtocols.length(); i++) {
- String protocol = gatewayProtocols.getString(i);
- if (protocol.contains("tcp")) {
- hasOpenvpnTcp = true;
- break;
+ if (!useObfuscationPinning) {
+ // check if at least one openvpn protocol is TCP, openvpn in UDP is currently not supported for obfs4,
+ // however on the wire UDP might be used
+ boolean hasOpenvpnTcp = false;
+ JSONObject openvpnTransport = getTransport(transports, OPENVPN);
+ JSONArray gatewayProtocols = openvpnTransport.getJSONArray(PROTOCOLS);
+ for (int i = 0; i < gatewayProtocols.length(); i++) {
+ String protocol = gatewayProtocols.getString(i);
+ if (protocol.contains("tcp")) {
+ hasOpenvpnTcp = true;
+ break;
+ }
+ }
+ if (!hasOpenvpnTcp) {
+ VpnStatus.logError("obfs4 currently only allows openvpn in TCP mode! Skipping obfs4 config for ip " + ipAddress);
+ return;
}
- }
-
- if (!hasOpenvpnTcp) {
- VpnStatus.logError("obfs4 currently only allows openvpn in TCP mode! Skipping obfs4 config for ip " + ipAddress);
- return;
}
boolean hasAllowedPTProtocol = false;
@@ -455,17 +444,18 @@ public class VpnConfigGenerator {
}
String route = "route " + ipAddress + " 255.255.255.255 net_gateway" + newLine;
- stringBuilder.append(route);
String remote;
if (useObfsVpn()) {
if (useObfuscationPinning) {
remote = REMOTE + " " + obfuscationPinningIP + " " + obfuscationPinningPort + newLine;
+ route = "route " + obfuscationPinningIP + " 255.255.255.255 net_gateway" + newLine;
} else {
remote = REMOTE + " " + ipAddress + " " + ports.getString(0) + newLine;
}
} else {
remote = REMOTE + " " + DISPATCHER_IP + " " + DISPATCHER_PORT + " tcp" + newLine;
}
+ stringBuilder.append(route);
stringBuilder.append(remote);
}