From 66d9dd4b2b46ed98e811c31152b2d04e3ccbe771 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 5 Aug 2022 13:18:44 +0200 Subject: adapt the route to point to the obfuscation proxy instead of the openvpn gateway --- app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/eip') 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..9cc16902 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java @@ -455,17 +455,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); } -- cgit v1.2.3 From f0899797c8907d1ebcba205dad69f2a8a6594bcd Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 5 Aug 2022 18:15:25 +0200 Subject: revert gateway selection during gateway pinning --- app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/eip') 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); -- cgit v1.2.3 From 9234a7b970109970cfb33f3b6351f702a05c66cb Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 5 Aug 2022 18:22:38 +0200 Subject: initiate gateway Manager with only one pinned gateway if obfuscation proxy pinning is enabled --- .../se/leap/bitmaskclient/eip/GatewaysManager.java | 51 +++++++++++++++++----- 1 file changed, 39 insertions(+), 12 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/eip') 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..e5795941 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 gateways = new LinkedHashMap<>(); @@ -118,7 +124,11 @@ public class GatewaysManager { */ public Pair 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; } @@ -374,18 +384,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) { -- cgit v1.2.3 From 5d9072d9739882386fe30419a25ceb80166a5990 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 5 Aug 2022 18:26:34 +0200 Subject: localize 'Unknown Location' --- .../main/java/se/leap/bitmaskclient/eip/GatewaysManager.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/eip') 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 e5795941..521d095e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java @@ -238,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 -- cgit v1.2.3 From b2336a5dc626cbaaaa12b27629c50c44e1d76353 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 5 Aug 2022 18:30:14 +0200 Subject: remove redundant code that tweaks the transports for pinned gateways --- .../java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/eip') 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 9cc16902..8864822a 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); -- cgit v1.2.3 From 69ee8926dbdebd97cf0f8a9232050677730415a5 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 5 Aug 2022 18:33:26 +0200 Subject: let a gateway have only one transport if obfuscation proxy pinning is enabled --- .../leap/bitmaskclient/eip/VpnConfigGenerator.java | 69 +++++++++++----------- 1 file changed, 34 insertions(+), 35 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/eip') 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 8864822a..f60d89ce 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java @@ -123,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; } } @@ -139,11 +139,15 @@ public class VpnConfigGenerator { public HashMap generateVpnProfiles() throws ConfigParser.ConfigParseError, - NumberFormatException, - JSONException, - IOException { + NumberFormatException { HashMap 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)); @@ -158,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) { @@ -365,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 @@ -408,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; -- cgit v1.2.3