summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap/bitmaskclient/eip
diff options
context:
space:
mode:
authorcyBerta <cyberta@riseup.net>2019-10-01 00:25:54 +0200
committercyBerta <cyberta@riseup.net>2019-10-01 00:25:54 +0200
commitfca6c9dcff1b5b5400a61b7411a7f72460fbfbfa (patch)
treec8efd8b964d495467619000fa7435c2a5527efa1 /app/src/main/java/se/leap/bitmaskclient/eip
parent7820e8c0819a10c5b4729678607681fcfe30cbae (diff)
parent685da193ea29f3e7a8a42d55747dfb2f956f23b6 (diff)
Merge branch 'pluggableTransports2'
Diffstat (limited to 'app/src/main/java/se/leap/bitmaskclient/eip')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EIP.java29
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java11
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java121
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java2
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java40
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java203
6 files changed, 269 insertions, 137 deletions
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..19c539e8 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
@@ -43,16 +43,20 @@ import java.util.Observer;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
+import de.blinkt.openvpn.VpnProfile;
import de.blinkt.openvpn.core.ConnectionStatus;
import de.blinkt.openvpn.core.IOpenVPNServiceInternal;
import de.blinkt.openvpn.core.OpenVPNService;
import de.blinkt.openvpn.core.VpnStatus;
+import de.blinkt.openvpn.core.connection.Connection;
import se.leap.bitmaskclient.OnBootReceiver;
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;
@@ -74,6 +78,7 @@ import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES;
import static se.leap.bitmaskclient.MainActivityErrorDialog.DOWNLOAD_ERRORS.ERROR_INVALID_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.R.string.vpn_certificate_is_invalid;
import static se.leap.bitmaskclient.utils.ConfigHelper.ensureNotOnMainThread;
+import static se.leap.bitmaskclient.utils.PreferenceHelper.getUsePluggableTransports;
/**
* EIP is the abstract base class for interacting with and managing the Encrypted
@@ -203,11 +208,11 @@ public final class EIP extends JobIntentService implements Observer {
GatewaysManager gatewaysManager = gatewaysFromPreferences();
Gateway gateway = gatewaysManager.select(nClosestGateway);
- if (gateway != null && gateway.getProfile() != null) {
- launchActiveGateway(gateway, nClosestGateway);
+ if (launchActiveGateway(gateway, nClosestGateway)) {
tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_OK);
- } else
+ } else {
tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_CANCELED);
+ }
}
/**
@@ -218,9 +223,7 @@ public final class EIP extends JobIntentService implements Observer {
GatewaysManager gatewaysManager = gatewaysFromPreferences();
Gateway gateway = gatewaysManager.select(0);
- if (gateway != null && gateway.getProfile() != null) {
- launchActiveGateway(gateway, 0);
- } else {
+ if (!launchActiveGateway(gateway, 0)) {
Log.d(TAG, "startEIPAlwaysOnVpn no active profile available!");
}
}
@@ -240,11 +243,19 @@ public final class EIP extends JobIntentService implements Observer {
*
* @param gateway to connect to
*/
- private void launchActiveGateway(@NonNull Gateway gateway, int nClosestGateway) {
+ private boolean launchActiveGateway(Gateway gateway, int nClosestGateway) {
+ VpnProfile profile;
+ Connection.TransportType transportType = getUsePluggableTransports(this) ? OBFS4 : OPENVPN;
+ if (gateway == null ||
+ (profile = gateway.getProfile(transportType)) == null) {
+ return false;
+ }
+
Intent intent = new Intent(BROADCAST_GATEWAY_SETUP_OBSERVER_EVENT);
- intent.putExtra(PROVIDER_PROFILE, gateway.getProfile());
+ intent.putExtra(PROVIDER_PROFILE, profile);
intent.putExtra(Gateway.KEY_N_CLOSEST_GATEWAY, nClosestGateway);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
+ return true;
}
@@ -277,7 +288,7 @@ public final class EIP extends JobIntentService implements Observer {
* @return GatewaysManager
*/
private GatewaysManager gatewaysFromPreferences() {
- GatewaysManager gatewaysManager = new GatewaysManager(this, preferences);
+ GatewaysManager gatewaysManager = new GatewaysManager(preferences);
gatewaysManager.configureFromPreferences();
return gatewaysManager;
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java
index 64904816..69fc483a 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipStatus.java
@@ -78,8 +78,7 @@ public class EipStatus extends Observable implements VpnStatus.StateListener {
currentStatus.setLevel(level);
currentStatus.setEipLevel(level);
if (tmp != currentStatus.getLevel() || "RECONNECTING".equals(state)) {
- currentStatus.setChanged();
- currentStatus.notifyObservers();
+ refresh();
}
}
@@ -174,8 +173,7 @@ public class EipStatus extends Observable implements VpnStatus.StateListener {
default:
break;
}
- currentStatus.setChanged();
- currentStatus.notifyObservers();
+ refresh();
}
}
}
@@ -286,4 +284,9 @@ public class EipStatus extends Observable implements VpnStatus.StateListener {
return "State: " + state + " Level: " + vpnLevel.toString();
}
+ public static void refresh() {
+ currentStatus.setChanged();
+ currentStatus.notifyObservers();
+ }
+
}
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 09b33845..15ee13c2 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java
@@ -17,7 +17,8 @@
package se.leap.bitmaskclient.eip;
import android.content.Context;
-import android.content.SharedPreferences;
+
+import android.support.annotation.NonNull;
import com.google.gson.Gson;
@@ -25,14 +26,22 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
-import java.io.StringReader;
import java.util.HashSet;
import java.util.Set;
+import java.util.HashMap;
import de.blinkt.openvpn.VpnProfile;
import de.blinkt.openvpn.core.ConfigParser;
-import se.leap.bitmaskclient.BitmaskApp;
import se.leap.bitmaskclient.utils.PreferenceHelper;
+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;
+import static se.leap.bitmaskclient.Constants.OPENVPN_CONFIGURATION;
+import static se.leap.bitmaskclient.Constants.TIMEZONE;
+import static se.leap.bitmaskclient.Constants.VERSION;
/**
* Gateway provides objects defining gateways and their metadata.
@@ -41,6 +50,7 @@ import se.leap.bitmaskclient.utils.PreferenceHelper;
*
* @author Sean Leonard <meanderingcode@aetherislands.net>
* @author Parménides GV <parmegv@sdf.org>
+ * @author cyberta
*/
public class Gateway {
@@ -51,60 +61,69 @@ public class Gateway {
private JSONObject secrets;
private JSONObject gateway;
- private String mName;
+ private String name;
private int timezone;
- private VpnProfile mVpnProfile;
+ private int apiVersion;
+ private HashMap<Connection.TransportType, VpnProfile> vpnProfiles;
/**
* Build a gateway object from a JSON OpenVPN gateway definition in eip-service.json
* and create a VpnProfile belonging to it.
*/
- public Gateway(JSONObject eip_definition, JSONObject secrets, JSONObject gateway, Context context) {
+ public Gateway(JSONObject eipDefinition, JSONObject secrets, JSONObject gateway, Context context) {
this.gateway = gateway;
this.secrets = secrets;
- generalConfiguration = getGeneralConfiguration(eip_definition);
- timezone = getTimezone(eip_definition);
- mName = locationAsName(eip_definition);
-
- mVpnProfile = createVPNProfile();
- System.out.println("###########" + mName + "###########");
- mVpnProfile.mName = mName;
+ generalConfiguration = getGeneralConfiguration(eipDefinition);
+ timezone = getTimezone(eipDefinition);
+ name = locationAsName(eipDefinition);
+ apiVersion = getApiVersion(eipDefinition);
+ vpnProfiles = createVPNProfiles(context);
+ }
+ private void addProfileInfos(Context context, HashMap<Connection.TransportType, VpnProfile> profiles) {
Set<String> excludedAppsVpn = PreferenceHelper.getExcludedApps(context);
- if (excludedAppsVpn != null) {
- mVpnProfile.mAllowedAppsVpn = new HashSet<>(excludedAppsVpn);
- }
- else {
- mVpnProfile.mAllowedAppsVpn = null;
+ for (VpnProfile profile : profiles.values()) {
+ profile.mName = name;
+ profile.mGatewayIp = gateway.optString(IP_ADDRESS);
+ if (excludedAppsVpn != null) {
+ profile.mAllowedAppsVpn = new HashSet<>(excludedAppsVpn);
+ }
}
-
}
- private JSONObject getGeneralConfiguration(JSONObject eip_definition) {
+ private JSONObject getGeneralConfiguration(JSONObject eipDefinition) {
try {
- return eip_definition.getJSONObject("openvpn_configuration");
+ return eipDefinition.getJSONObject(OPENVPN_CONFIGURATION);
} catch (JSONException e) {
return new JSONObject();
}
}
- private int getTimezone(JSONObject eip_definition) {
- JSONObject location = getLocationInfo(eip_definition);
- return location.optInt("timezone");
+ private int getTimezone(JSONObject eipDefinition) {
+ JSONObject location = getLocationInfo(eipDefinition);
+ return location.optInt(TIMEZONE);
+ }
+
+ private int getApiVersion(JSONObject eipDefinition) {
+ return eipDefinition.optInt(VERSION);
+ }
+
+ public String getRemoteIP() {
+ return gateway.optString(IP_ADDRESS);
}
- private String locationAsName(JSONObject eip_definition) {
- JSONObject location = getLocationInfo(eip_definition);
- return location.optString("name");
+ private String locationAsName(JSONObject eipDefinition) {
+ JSONObject location = getLocationInfo(eipDefinition);
+ return location.optString(NAME);
}
private JSONObject getLocationInfo(JSONObject eipDefinition) {
try {
- JSONObject locations = eipDefinition.getJSONObject("locations");
+ JSONObject locations = eipDefinition.getJSONObject(LOCATIONS);
- return locations.getJSONObject(gateway.getString("location"));
+ return locations.getJSONObject(gateway.getString(LOCATION));
} catch (JSONException e) {
return new JSONObject();
}
@@ -113,32 +132,29 @@ public class Gateway {
/**
* Create and attach the VpnProfile to our gateway object
*/
- private VpnProfile createVPNProfile() {
+ private @NonNull HashMap<Connection.TransportType, VpnProfile> createVPNProfiles(Context context) {
+ HashMap<Connection.TransportType, VpnProfile> profiles = new HashMap<>();
try {
- ConfigParser cp = new ConfigParser();
-
- VpnConfigGenerator vpnConfigurationGenerator = new VpnConfigGenerator(generalConfiguration, secrets, gateway);
- String configuration = vpnConfigurationGenerator.generate();
-
- cp.parseConfig(new StringReader(configuration));
- return cp.convertProfile();
- } catch (ConfigParser.ConfigParseError e) {
- // FIXME We didn't get a VpnProfile! Error handling! and log level
- e.printStackTrace();
- return null;
- } catch (IOException e) {
+ VpnConfigGenerator vpnConfigurationGenerator = new VpnConfigGenerator(generalConfiguration, secrets, gateway, apiVersion);
+ profiles = vpnConfigurationGenerator.generateVpnProfiles();
+ addProfileInfos(context, 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 mName;
+ return name;
}
- public VpnProfile getProfile() {
- return mVpnProfile;
+ public HashMap<Connection.TransportType, VpnProfile> getProfiles() {
+ return vpnProfiles;
+ }
+
+ public VpnProfile getProfile(Connection.TransportType transportType) {
+ return vpnProfiles.get(transportType);
}
public int getTimezone() {
@@ -150,17 +166,4 @@ public class Gateway {
return new Gson().toJson(this, Gateway.class);
}
- @Override
- public boolean equals(Object obj) {
- return obj instanceof Gateway &&
- (this.mVpnProfile != null &&
- ((Gateway) obj).mVpnProfile != null &&
- this.mVpnProfile.mConnections != null &&
- ((Gateway) obj).mVpnProfile != null &&
- this.mVpnProfile.mConnections.length > 0 &&
- ((Gateway) obj).mVpnProfile.mConnections.length > 0 &&
- this.mVpnProfile.mConnections[0].mServerName != null &&
- this.mVpnProfile.mConnections[0].mServerName.equals(((Gateway) obj).mVpnProfile.mConnections[0].mServerName)) ||
- this.mVpnProfile == null && ((Gateway) obj).mVpnProfile == null;
- }
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java
index 2bd666bf..0ba0f207 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java
@@ -36,7 +36,7 @@ public class GatewaySelector {
}
}
- Log.e(TAG, "There are less than " + nClosest + " Gateways available.");
+ Log.e(TAG, "There are less than " + (nClosest + 1) + " Gateways available.");
return 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 6bd7b4a3..0847a07e 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
@@ -28,11 +28,12 @@ import org.json.JSONObject;
import java.lang.reflect.Type;
import java.util.ArrayList;
-import java.util.List;
+import java.util.LinkedHashMap;
import se.leap.bitmaskclient.Provider;
import se.leap.bitmaskclient.utils.PreferenceHelper;
+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;
@@ -45,11 +46,10 @@ public class GatewaysManager {
private Context context;
private SharedPreferences preferences;
- private List<Gateway> gateways = new ArrayList<>();
+ private LinkedHashMap<String, Gateway> gateways = new LinkedHashMap<>();
private Type listType = new TypeToken<ArrayList<Gateway>>() {}.getType();
- GatewaysManager(Context context, SharedPreferences preferences) {
- this.context = context;
+ GatewaysManager(SharedPreferences preferences) {
this.preferences = preferences;
}
@@ -58,7 +58,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);
}
@@ -88,37 +88,21 @@ public class GatewaysManager {
*/
void fromEipServiceJson(JSONObject eipDefinition) {
try {
- JSONArray gatewaysDefined = eipDefinition.getJSONArray("gateways");
+ JSONArray gatewaysDefined = eipDefinition.getJSONArray(GATEWAYS);
for (int i = 0; i < gatewaysDefined.length(); i++) {
JSONObject gw = gatewaysDefined.getJSONObject(i);
- if (isOpenVpnGateway(gw)) {
- JSONObject secrets = secretsConfiguration();
- Gateway aux = new Gateway(eipDefinition, secrets, gw, this.context);
- if (!gateways.contains(aux)) {
- addGateway(aux);
- }
+ JSONObject secrets = secretsConfiguration();
+ Gateway aux = new Gateway(eipDefinition, secrets, gw, this.context);
+ 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) {
- try {
- String transport = gateway.getJSONObject("capabilities").getJSONArray("transport").toString();
- return transport.contains("openvpn");
- } catch (JSONException e) {
- return false;
- }
- }
-
private JSONObject secretsConfiguration() {
JSONObject result = new JSONObject();
try {
@@ -137,7 +121,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 6f0ccf18..d9bf5dd3 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
@@ -20,48 +20,125 @@ import org.json.JSONArray;
import org.json.JSONException;
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;
+import de.blinkt.openvpn.core.ConfigParser;
+import de.blinkt.openvpn.core.connection.Connection;
import se.leap.bitmaskclient.Provider;
+import se.leap.bitmaskclient.pluggableTransports.Obfs4Options;
+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.CAPABILITIES;
+import static se.leap.bitmaskclient.Constants.IP_ADDRESS;
+import static se.leap.bitmaskclient.Constants.OPTIONS;
+import static se.leap.bitmaskclient.Constants.PORTS;
+import static se.leap.bitmaskclient.Constants.PROTOCOLS;
import static se.leap.bitmaskclient.Constants.PROVIDER_PRIVATE_KEY;
import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE;
+import static se.leap.bitmaskclient.Constants.REMOTE;
+import static se.leap.bitmaskclient.Constants.TRANSPORT;
+import static se.leap.bitmaskclient.Constants.TYPE;
+import static se.leap.bitmaskclient.pluggableTransports.Dispatcher.DISPATCHER_IP;
+import static se.leap.bitmaskclient.pluggableTransports.Dispatcher.DISPATCHER_PORT;
public class VpnConfigGenerator {
-
- private JSONObject general_configuration;
+ private JSONObject generalConfiguration;
private JSONObject gateway;
private JSONObject secrets;
+ private JSONObject obfs4Transport;
+ private int apiVersion;
+
public final static String TAG = VpnConfigGenerator.class.getSimpleName();
private final String newLine = System.getProperty("line.separator"); // Platform new line
- public VpnConfigGenerator(JSONObject general_configuration, JSONObject secrets, JSONObject gateway) {
- this.general_configuration = general_configuration;
+ public VpnConfigGenerator(JSONObject generalConfiguration, JSONObject secrets, JSONObject gateway, int apiVersion) throws ConfigParser.ConfigParseError {
+ this.generalConfiguration = generalConfiguration;
this.gateway = gateway;
this.secrets = secrets;
+ this.apiVersion = apiVersion;
+ checkCapabilities();
}
- public String generate() {
- return
- generalConfiguration()
- + newLine
- + gatewayConfiguration()
- + newLine
- + secretsConfiguration()
- + newLine
- + androidCustomizations();
+ public void checkCapabilities() throws ConfigParser.ConfigParseError {
+
+ try {
+ if (apiVersion == 3) {
+ JSONArray supportedTransports = gateway.getJSONObject(CAPABILITIES).getJSONArray(TRANSPORT);
+ for (int i = 0; i < supportedTransports.length(); i++) {
+ JSONObject transport = supportedTransports.getJSONObject(i);
+ if (transport.getString(TYPE).equals(OBFS4.toString())) {
+ obfs4Transport = transport;
+ break;
+ }
+ }
+ }
+
+ } catch (JSONException e) {
+ throw new ConfigParser.ConfigParseError("Api version ("+ apiVersion +") did not match required JSON fields");
+ }
+ }
+
+ public HashMap<Connection.TransportType, VpnProfile> generateVpnProfiles() throws
+ ConfigParser.ConfigParseError,
+ NumberFormatException,
+ JSONException,
+ IOException {
+ HashMap<Connection.TransportType, VpnProfile> profiles = new HashMap<>();
+ profiles.put(OPENVPN, createProfile(OPENVPN));
+ if (supportsObfs4()) {
+ profiles.put(OBFS4, createProfile(OBFS4));
+ }
+ return profiles;
+ }
+
+ private boolean supportsObfs4(){
+ return obfs4Transport != null;
+ }
+
+ private String getConfigurationString(Connection.TransportType transportType) {
+ return generalConfiguration()
+ + newLine
+ + gatewayConfiguration(transportType)
+ + newLine
+ + androidCustomizations()
+ + newLine
+ + secretsConfiguration();
+ }
+
+ 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.setObfs4Options(getObfs4Options());
+ }
+ return icsOpenvpnConfigParser.convertProfile(transportType);
+ }
+
+ private Obfs4Options getObfs4Options() throws JSONException {
+ JSONObject transportOptions = obfs4Transport.getJSONObject(OPTIONS);
+ String iatMode = transportOptions.getString("iat-mode");
+ String cert = transportOptions.getString("cert");
+ String port = obfs4Transport.getJSONArray(PORTS).getString(0);
+ String ip = gateway.getString(IP_ADDRESS);
+ return new Obfs4Options(ip, port, cert, iatMode);
}
private String generalConfiguration() {
String commonOptions = "";
try {
- Iterator keys = general_configuration.keys();
+ Iterator keys = generalConfiguration.keys();
while (keys.hasNext()) {
String key = keys.next().toString();
commonOptions += key + " ";
- for (String word : String.valueOf(general_configuration.get(key)).split(" "))
+ for (String word : String.valueOf(generalConfiguration.get(key)).split(" "))
commonOptions += word + " ";
commonOptions += newLine;
@@ -76,41 +153,95 @@ public class VpnConfigGenerator {
return commonOptions;
}
- private String gatewayConfiguration() {
+ private String gatewayConfiguration(Connection.TransportType transportType) {
String remotes = "";
- String ipAddressKeyword = "ip_address";
- String remoteKeyword = "remote";
- String portsKeyword = "ports";
- String protocolKeyword = "protocols";
- String capabilitiesKeyword = "capabilities";
-
+ StringBuilder stringBuilder = new StringBuilder();
try {
- String ip_address = gateway.getString(ipAddressKeyword);
- JSONObject capabilities = gateway.getJSONObject(capabilitiesKeyword);
- JSONArray ports = capabilities.getJSONArray(portsKeyword);
- for (int i = 0; i < ports.length(); i++) {
- String port_specific_remotes = "";
- int port = ports.getInt(i);
- JSONArray protocols = capabilities.getJSONArray(protocolKeyword);
- for (int j = 0; j < protocols.length(); j++) {
- String protocol = protocols.optString(j);
- String new_remote = remoteKeyword + " " + ip_address + " " + port + " " + protocol + newLine;
-
- port_specific_remotes += new_remote;
- }
- remotes += port_specific_remotes;
+ String ipAddress = gateway.getString(IP_ADDRESS);
+ JSONObject capabilities = gateway.getJSONObject(CAPABILITIES);
+ switch (apiVersion) {
+ default:
+ case 1:
+ case 2:
+ gatewayConfigApiv1(stringBuilder, ipAddress, capabilities);
+ break;
+ case 3:
+ JSONArray transports = capabilities.getJSONArray(TRANSPORT);
+ gatewayConfigApiv3(transportType, stringBuilder, ipAddress, transports);
+ break;
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
+
+ remotes = stringBuilder.toString();
if (remotes.endsWith(newLine)) {
remotes = remotes.substring(0, remotes.lastIndexOf(newLine));
}
return remotes;
}
+ private void gatewayConfigApiv3(Connection.TransportType transportType, StringBuilder stringBuilder, String ipAddress, JSONArray transports) throws JSONException {
+ if (transportType == OBFS4) {
+ obfs4GatewayConfigApiv3(stringBuilder, ipAddress, transports);
+ } else {
+ ovpnGatewayConfigApi3(stringBuilder, ipAddress, transports);
+ }
+ }
+
+ private void gatewayConfigApiv1(StringBuilder stringBuilder, String ipAddress, JSONObject capabilities) throws JSONException {
+ int port;
+ String protocol;
+ JSONArray ports = capabilities.getJSONArray(PORTS);
+ for (int i = 0; i < ports.length(); i++) {
+ port = ports.getInt(i);
+ JSONArray protocols = capabilities.getJSONArray(PROTOCOLS);
+ for (int j = 0; j < protocols.length(); j++) {
+ protocol = protocols.optString(j);
+ String newRemote = REMOTE + " " + ipAddress + " " + port + " " + protocol + newLine;
+ stringBuilder.append(newRemote);
+ }
+ }
+ }
+
+ private void ovpnGatewayConfigApi3(StringBuilder stringBuilder, String ipAddress, JSONArray transports) throws JSONException {
+ String port;
+ String protocol;
+ JSONObject openvpnTransport = getTransport(transports, OPENVPN);
+ JSONArray ports = openvpnTransport.getJSONArray(PORTS);
+ for (int j = 0; j < ports.length(); j++) {
+ port = ports.getString(j);
+ JSONArray protocols = openvpnTransport.getJSONArray(PROTOCOLS);
+ for (int k = 0; k < protocols.length(); k++) {
+ protocol = protocols.optString(k);
+ String newRemote = REMOTE + " " + ipAddress + " " + port + " " + protocol + newLine;
+ stringBuilder.append(newRemote);
+ }
+ }
+ }
+
+ private JSONObject getTransport(JSONArray transports, Connection.TransportType transportType) throws JSONException {
+ JSONObject selectedTransport = new JSONObject();
+ for (int i = 0; i < transports.length(); i++) {
+ JSONObject transport = transports.getJSONObject(i);
+ if (transport.getString(TYPE).equals(transportType.toString())) {
+ selectedTransport = transport;
+ break;
+ }
+ }
+ return selectedTransport;
+ }
+
+ private void obfs4GatewayConfigApiv3(StringBuilder stringBuilder, String ipAddress, JSONArray transports) throws JSONException {
+ JSONObject obfs4Transport = getTransport(transports, OBFS4);
+ String route = "route " + ipAddress + " 255.255.255.255 net_gateway" + newLine;
+ stringBuilder.append(route);
+ String remote = REMOTE + " " + DISPATCHER_IP + " " + DISPATCHER_PORT + " " + obfs4Transport.getJSONArray(PROTOCOLS).getString(0) + newLine;
+ stringBuilder.append(remote);
+ }
+
private String secretsConfiguration() {
try {
String ca =