summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java203
1 files changed, 167 insertions, 36 deletions
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 =