diff options
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.java | 177 |
1 files changed, 147 insertions, 30 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..7f09d21e 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,133 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.io.IOException; +import java.io.StringReader; import java.util.Iterator; +import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.core.ConfigParser; +import de.blinkt.openvpn.core.connection.Connection; +import de.blinkt.openvpn.core.connection.Obfs4Connection; import se.leap.bitmaskclient.Provider; +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; public class VpnConfigGenerator { - private JSONObject general_configuration; + private JSONObject generalConfiguration; private JSONObject gateway; private JSONObject secrets; + 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 - public VpnConfigGenerator(JSONObject general_configuration, JSONObject secrets, JSONObject gateway) { - this.general_configuration = general_configuration; + public VpnConfigGenerator(JSONObject generalConfiguration, JSONObject secrets, JSONObject gateway, int apiVersion) { + this.generalConfiguration = generalConfiguration; this.gateway = gateway; this.secrets = secrets; + this.apiVersion = apiVersion; + checkCapabilities(); } - public String generate() { - return - generalConfiguration() + public void checkCapabilities() { + + try { + switch (apiVersion) { + case 2: + 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")) { + obfs4Transport = transport; + } + } + break; + default: + break; + } + + } catch (JSONException e) { + e.printStackTrace(); + } + } + + public VpnProfile generateVpnProfile() throws IllegalStateException, + IOException, + ConfigParser.ConfigParseError, + CloneNotSupportedException, + JSONException, + NumberFormatException { + + VpnProfile profile = createOvpnProfile(); + if (supportsObfs4()) { + addPluggableTransportConnections(profile); + } + return profile; + } + + private boolean supportsObfs4(){ + return obfs4Transport != null; + } + + private void addPluggableTransportConnections(VpnProfile profile) throws JSONException, CloneNotSupportedException { + JSONArray ports = obfs4Transport.getJSONArray(PORTS); + Connection[] updatedConnections = new Connection[profile.mConnections.length + ports.length()]; + + for (int i = 0; i < ports.length(); i++) { + String port = ports.getString(i); + Obfs4Connection obfs4Connection = new Obfs4Connection(); + obfs4Connection.setObfs4RemoteProxyName(gateway.getString(IP_ADDRESS)); + obfs4Connection.setObfs4RemoteProxyPort(port); + obfs4Connection.setTransportOptions(obfs4Transport.optJSONObject(OPTIONS)); + updatedConnections[i] = obfs4Connection; + } + int k = 0; + for (int i = ports.length(); i < updatedConnections.length; i++, k++) { + updatedConnections[i] = profile.mConnections[k].clone(); + } + profile.mConnections = updatedConnections; + } + + private String getConfigurationString() { + return generalConfiguration() + newLine - + gatewayConfiguration() + + ovpnGatewayConfiguration() + newLine + secretsConfiguration() + newLine + androidCustomizations(); } + private VpnProfile createOvpnProfile() throws IOException, ConfigParser.ConfigParseError { + String configuration = getConfigurationString(); + icsOpenvpnConfigParser.parseConfig(new StringReader(configuration)); + return icsOpenvpnConfigParser.convertProfile(); + } + 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 +161,73 @@ public class VpnConfigGenerator { return commonOptions; } - private String gatewayConfiguration() { + private String ovpnGatewayConfiguration() { 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); + JSONArray transports = capabilities.getJSONArray(TRANSPORT); + switch (apiVersion) { + default: + case 1: + ovpnGatewayConfigApiv1(stringBuilder, ipAddress, capabilities); + break; + case 2: + ovpnGatewayConfigApiv2(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 ovpnGatewayConfigApiv1(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 ovpnGatewayConfigApiv2(StringBuilder stringBuilder, String ipAddress, JSONArray transports) throws JSONException { + String port; + String protocol; + for (int i = 0; i < transports.length(); i++) { + JSONObject transport = transports.getJSONObject(i); + if (!transport.getString(TYPE).equals("openvpn")) { + continue; + } + JSONArray ports = transport.getJSONArray(PORTS); + for (int j = 0; j < ports.length(); j++) { + port = ports.getString(j); + JSONArray protocols = transport.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 String secretsConfiguration() { try { String ca = |