From 283e7531d551521dc48efa9b010127ff54316326 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 4 Jul 2019 16:44:35 +0200 Subject: create one vpnprofile per transport per gateway. implement basis to switch between obfs4 and plain openvpn connections --- .../main/java/de/blinkt/openvpn/VpnProfile.java | 2 + .../de/blinkt/openvpn/core/ProfileManager.java | 0 .../main/java/se/leap/bitmaskclient/eip/EIP.java | 8 ++-- .../java/se/leap/bitmaskclient/eip/Gateway.java | 37 ++++++++++++---- .../se/leap/bitmaskclient/eip/GatewaysManager.java | 50 +++------------------- .../leap/bitmaskclient/eip/VpnConfigGenerator.java | 19 ++++---- 6 files changed, 51 insertions(+), 65 deletions(-) create mode 100644 app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java (limited to 'app/src/main') diff --git a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java index dc12c6a8..f139fdc9 100644 --- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -174,6 +174,7 @@ public class VpnProfile implements Serializable, Cloneable { // timestamp when the profile was last used public long mLastUsed; public String importedProfileHash; + //TODO: cleanup here /* Options no longer used in new profiles */ public String mServerName = "openvpn.example.com"; public String mServerPort = "1194"; @@ -184,6 +185,7 @@ public class VpnProfile implements Serializable, Cloneable { // set members to default values private UUID mUuid; private int mProfileVersion; + public String mGatewayIp; public boolean mUsePluggableTransports; public VpnProfile(String name, Connection.TransportType transportType) { diff --git a/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java b/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java new file mode 100644 index 00000000..e69de29b 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 a5434871..1d702ec1 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -53,6 +53,8 @@ import se.leap.bitmaskclient.R; import static android.app.Activity.RESULT_CANCELED; import static android.app.Activity.RESULT_OK; import static android.content.Intent.CATEGORY_DEFAULT; +import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4; +import static de.blinkt.openvpn.core.connection.Connection.TransportType.OPENVPN; import static se.leap.bitmaskclient.Constants.BROADCAST_EIP_EVENT; import static se.leap.bitmaskclient.Constants.BROADCAST_GATEWAY_SETUP_OBSERVER_EVENT; import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_CODE; @@ -203,7 +205,7 @@ public final class EIP extends JobIntentService implements Observer { GatewaysManager gatewaysManager = gatewaysFromPreferences(); Gateway gateway = gatewaysManager.select(nClosestGateway); - if (gateway != null && gateway.getProfile() != null) { + if (gateway != null && !gateway.getProfiles().isEmpty()) { launchActiveGateway(gateway, nClosestGateway); tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_OK); } else @@ -218,7 +220,7 @@ public final class EIP extends JobIntentService implements Observer { GatewaysManager gatewaysManager = gatewaysFromPreferences(); Gateway gateway = gatewaysManager.select(0); - if (gateway != null && gateway.getProfile() != null) { + if (gateway != null && !gateway.getProfiles().isEmpty()) { launchActiveGateway(gateway, 0); } else { Log.d(TAG, "startEIPAlwaysOnVpn no active profile available!"); @@ -242,7 +244,7 @@ public final class EIP extends JobIntentService implements Observer { */ private void launchActiveGateway(@NonNull Gateway gateway, int nClosestGateway) { Intent intent = new Intent(BROADCAST_GATEWAY_SETUP_OBSERVER_EVENT); - intent.putExtra(PROVIDER_PROFILE, gateway.getProfile()); + intent.putExtra(PROVIDER_PROFILE, gateway.getProfile(OPENVPN)); intent.putExtra(Gateway.KEY_N_CLOSEST_GATEWAY, nClosestGateway); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); 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 50fe74b7..9bc07764 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java @@ -16,16 +16,21 @@ */ package se.leap.bitmaskclient.eip; +import android.support.annotation.NonNull; + import com.google.gson.Gson; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; +import java.util.HashMap; import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.core.ConfigParser; +import de.blinkt.openvpn.core.connection.Connection; +import static se.leap.bitmaskclient.Constants.IP_ADDRESS; import static se.leap.bitmaskclient.Constants.LOCATION; import static se.leap.bitmaskclient.Constants.LOCATIONS; import static se.leap.bitmaskclient.Constants.NAME; @@ -54,7 +59,7 @@ public class Gateway { private String name; private int timezone; private int apiVersion; - private VpnProfile vpnProfile; + private HashMap vpnProfiles; /** * Build a gateway object from a JSON OpenVPN gateway definition in eip-service.json @@ -69,9 +74,13 @@ public class Gateway { timezone = getTimezone(eipDefinition); name = locationAsName(eipDefinition); apiVersion = getApiVersion(eipDefinition); - vpnProfile = createVPNProfile(); - if (vpnProfile != null) { - vpnProfile.mName = name; + vpnProfiles = createVPNProfiles(); + } + + private void addProfileInfos(HashMap profiles) { + for (VpnProfile profile : profiles.values()) { + profile.mName = name; + profile.mGatewayIp = gateway.optString(IP_ADDRESS); } } @@ -92,6 +101,10 @@ public class Gateway { return eipDefinition.optInt(VERSION); } + public String getRemoteIP() { + return gateway.optString(IP_ADDRESS); + } + private String locationAsName(JSONObject eipDefinition) { JSONObject location = getLocationInfo(eipDefinition); return location.optString(NAME); @@ -110,23 +123,29 @@ public class Gateway { /** * Create and attach the VpnProfile to our gateway object */ - private VpnProfile createVPNProfile() { + private @NonNull HashMap createVPNProfiles() { + HashMap profiles = new HashMap<>(); try { VpnConfigGenerator vpnConfigurationGenerator = new VpnConfigGenerator(generalConfiguration, secrets, gateway, apiVersion); - return vpnConfigurationGenerator.generateVpnProfile(); + profiles = vpnConfigurationGenerator.generateVpnProfiles(); + addProfileInfos(profiles); } catch (ConfigParser.ConfigParseError | IOException | JSONException e) { // FIXME We didn't get a VpnProfile! Error handling! and log level e.printStackTrace(); - return null; } + return profiles; } public String getName() { return name; } - public VpnProfile getProfile() { - return vpnProfile; + public HashMap getProfiles() { + return vpnProfiles; + } + + public VpnProfile getProfile(Connection.TransportType transportType) { + return vpnProfiles.get(transportType); } public int getTimezone() { 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 cd3ec1c6..f7038bab 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java @@ -28,20 +28,14 @@ import org.json.JSONObject; import java.lang.reflect.Type; import java.util.ArrayList; -import java.util.List; +import java.util.LinkedHashMap; -import de.blinkt.openvpn.VpnProfile; -import de.blinkt.openvpn.core.connection.Connection; import se.leap.bitmaskclient.Provider; import se.leap.bitmaskclient.utils.PreferenceHelper; -import static se.leap.bitmaskclient.Constants.CAPABILITIES; import static se.leap.bitmaskclient.Constants.GATEWAYS; import static se.leap.bitmaskclient.Constants.PROVIDER_PRIVATE_KEY; import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE; -import static se.leap.bitmaskclient.Constants.TRANSPORT; -import static se.leap.bitmaskclient.Constants.TYPE; -import static se.leap.bitmaskclient.Constants.VERSION; /** * @author parmegv @@ -52,7 +46,7 @@ public class GatewaysManager { private Context context; private SharedPreferences preferences; - private List gateways = new ArrayList<>(); + private LinkedHashMap gateways = new LinkedHashMap<>(); private Type listType = new TypeToken>() {}.getType(); GatewaysManager(Context context, SharedPreferences preferences) { @@ -65,7 +59,7 @@ public class GatewaysManager { * @return the n closest Gateway */ public Gateway select(int nClosest) { - GatewaySelector gatewaySelector = new GatewaySelector(gateways); + GatewaySelector gatewaySelector = new GatewaySelector(new ArrayList<>(gateways.values())); return gatewaySelector.select(nClosest); } @@ -96,52 +90,20 @@ public class GatewaysManager { void fromEipServiceJson(JSONObject eipDefinition) { try { JSONArray gatewaysDefined = eipDefinition.getJSONArray(GATEWAYS); - int apiVersion = eipDefinition.getInt(VERSION); for (int i = 0; i < gatewaysDefined.length(); i++) { JSONObject gw = gatewaysDefined.getJSONObject(i); JSONObject secrets = secretsConfiguration(); Gateway aux = new Gateway(eipDefinition, secrets, gw); - if (!gateways.contains(aux)) { + if (gateways.get(aux.getRemoteIP()) == null) { addGateway(aux); } } - } catch (JSONException e) { + } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } - /** - * check if a gateway is an OpenVpn gateway - * @param gateway to check - * @return true if gateway is an OpenVpn gateway otherwise false - */ - private boolean isOpenVpnGateway(JSONObject gateway, int apiVersion) { - switch (apiVersion) { - default: - case 1: - try { - String transport = gateway.getJSONObject(CAPABILITIES).getJSONArray(TRANSPORT).toString(); - return transport.contains("openvpn"); - } catch (JSONException e) { - return false; - } - case 2: - try { - JSONArray transports = gateway.getJSONObject(CAPABILITIES).getJSONArray(TRANSPORT); - for (int i = 0; i < transports.length(); i++) { - JSONObject transport = transports.getJSONObject(i); - if (transport.optString(TYPE).equals("openvpn")) { - return true; - } - } - return false; - } catch (JSONException e) { - return false; - } - } - } - private JSONObject secretsConfiguration() { JSONObject result = new JSONObject(); try { @@ -160,7 +122,7 @@ public class GatewaysManager { } private void addGateway(Gateway gateway) { - gateways.add(gateway); + gateways.put(gateway.getRemoteIP(), gateway); } /** 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 18c557dc..6b76e8d9 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java @@ -22,6 +22,7 @@ import org.json.JSONObject; import java.io.IOException; import java.io.StringReader; +import java.util.HashMap; import java.util.Iterator; import de.blinkt.openvpn.VpnProfile; @@ -52,8 +53,6 @@ public class VpnConfigGenerator { private JSONObject obfs4Transport; private int apiVersion; - private ConfigParser icsOpenvpnConfigParser = new ConfigParser(); - public final static String TAG = VpnConfigGenerator.class.getSimpleName(); private final String newLine = System.getProperty("line.separator"); // Platform new line @@ -85,16 +84,17 @@ public class VpnConfigGenerator { } } - public VpnProfile generateVpnProfile() throws IllegalStateException, - IOException, + public HashMap generateVpnProfiles() throws ConfigParser.ConfigParseError, - NumberFormatException, JSONException { - + NumberFormatException, + JSONException, + IOException { + HashMap profiles = new HashMap<>(); + profiles.put(OPENVPN, createProfile(OPENVPN)); if (supportsObfs4()) { - return createProfile(OBFS4); + profiles.put(OBFS4, createProfile(OBFS4)); } - - return createProfile(OPENVPN); + return profiles; } private boolean supportsObfs4(){ @@ -113,6 +113,7 @@ public class VpnConfigGenerator { private VpnProfile createProfile(Connection.TransportType transportType) throws IOException, ConfigParser.ConfigParseError, JSONException { String configuration = getConfigurationString(transportType); + ConfigParser icsOpenvpnConfigParser = new ConfigParser(); icsOpenvpnConfigParser.parseConfig(new StringReader(configuration)); if (transportType == OBFS4) { icsOpenvpnConfigParser.setDispatcherOptions(getDispatcherOptions()); -- cgit v1.2.3