From db1e1a2045a2e6456d54765be3cf95186ce987f7 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 24 May 2019 18:01:03 +0200 Subject: squashed commit for Pluggable Transports * implement handling of different provider API version (v1 and v2) * detect provider's obfs support * shapeshifter-dispatcher installation * necessary changes to control shapeshifter-dispatcher from Bitmask * route openvpn traffic over shapeshifter-dispatcher --- .../main/java/de/blinkt/openvpn/VpnProfile.java | 33 ++-- .../java/de/blinkt/openvpn/core/ConfigParser.java | 56 +++--- .../blinkt/openvpn/core/ConnectionInterface.java | 15 ++ .../java/de/blinkt/openvpn/core/NativeUtils.java | 13 +- .../de/blinkt/openvpn/core/OpenVPNService.java | 44 ++++- .../openvpn/core/OpenVpnManagementThread.java | 16 +- .../blinkt/openvpn/core/connection/Connection.java | 207 +++++++++++++++++++++ .../openvpn/core/connection/Obfs4Connection.java | 83 +++++++++ .../openvpn/core/connection/OpenvpnConnection.java | 13 ++ 9 files changed, 432 insertions(+), 48 deletions(-) create mode 100644 app/src/main/java/de/blinkt/openvpn/core/ConnectionInterface.java create mode 100644 app/src/main/java/de/blinkt/openvpn/core/connection/Connection.java create mode 100644 app/src/main/java/de/blinkt/openvpn/core/connection/Obfs4Connection.java create mode 100644 app/src/main/java/de/blinkt/openvpn/core/connection/OpenvpnConnection.java (limited to 'app/src/main/java/de/blinkt') diff --git a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java index 7b9003aa..9f18b8ed 100644 --- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -5,6 +5,11 @@ package de.blinkt.openvpn; +import de.blinkt.openvpn.core.connection.Connection; +import de.blinkt.openvpn.core.connection.OpenvpnConnection; +import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.BuildConfig; + import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; @@ -189,7 +194,7 @@ public class VpnProfile implements Serializable, Cloneable { mProfileVersion = CURRENT_PROFILE_VERSION; mConnections = new Connection[1]; - mConnections[0] = new Connection(); + mConnections[0] = new OpenvpnConnection(); mLastUsed = System.currentTimeMillis(); } @@ -314,8 +319,8 @@ public class VpnProfile implements Serializable, Cloneable { } if (mProfileVersion < 7) { for (Connection c : mConnections) - if (c.mProxyType == null) - c.mProxyType = Connection.ProxyType.NONE; + if (c.getProxyType() == null) + c.setProxyType(Connection.ProxyType.NONE); } mProfileVersion = CURRENT_PROFILE_VERSION; @@ -324,12 +329,12 @@ public class VpnProfile implements Serializable, Cloneable { private void moveOptionsToConnection() { mConnections = new Connection[1]; - Connection conn = new Connection(); + Connection conn = new OpenvpnConnection(); - conn.mServerName = mServerName; - conn.mServerPort = mServerPort; - conn.mUseUdp = mUseUdp; - conn.mCustomConfiguration = ""; + conn.setServerName(mServerName); + conn.setServerPort(mServerPort); + conn.setUseUdp(mUseUdp); + conn.setCustomConfiguration(""); mConnections[0] = conn; @@ -425,7 +430,7 @@ public class VpnProfile implements Serializable, Cloneable { if (canUsePlainRemotes) { for (Connection conn : mConnections) { - if (conn.mEnabled) { + if (conn.isEnabled()) { cfg.append(conn.getConnectionBlock(configForOvpn3)); } } @@ -586,7 +591,7 @@ public class VpnProfile implements Serializable, Cloneable { if (mAuthenticationType != TYPE_STATICKEYS) { if (mCheckRemoteCN) { if (mRemoteCN == null || mRemoteCN.equals("")) - cfg.append("verify-x509-name ").append(openVpnEscape(mConnections[0].mServerName)).append(" name\n"); + cfg.append("verify-x509-name ").append(openVpnEscape(mConnections[0].getServerName())).append(" name\n"); else switch (mX509AuthType) { @@ -660,7 +665,7 @@ public class VpnProfile implements Serializable, Cloneable { if (!canUsePlainRemotes) { cfg.append("# Connection Options are at the end to allow global options (and global custom options) to influence connection blocks\n"); for (Connection conn : mConnections) { - if (conn.mEnabled) { + if (conn.isEnabled()) { cfg.append("\n"); cfg.append(conn.getConnectionBlock(configForOvpn3)); cfg.append("\n"); @@ -985,7 +990,7 @@ public class VpnProfile implements Serializable, Cloneable { boolean noRemoteEnabled = true; for (Connection c : mConnections) { - if (c.mEnabled) + if (c.isEnabled()) noRemoteEnabled = false; } @@ -1000,12 +1005,12 @@ public class VpnProfile implements Serializable, Cloneable { return R.string.openvpn3_pkcs12; } for (Connection conn : mConnections) { - if (conn.mProxyType == Connection.ProxyType.ORBOT || conn.mProxyType == Connection.ProxyType.SOCKS5) + if (conn.getProxyType() == Connection.ProxyType.ORBOT || conn.getProxyType() == Connection.ProxyType.SOCKS5) return R.string.openvpn3_socksproxy; } } for (Connection c : mConnections) { - if (c.mProxyType == Connection.ProxyType.ORBOT) { + if (c.getProxyType() == Connection.ProxyType.ORBOT) { if (usesExtraProxyOptions()) return R.string.error_orbot_and_proxy_options; if (!OrbotHelper.checkTorReceier(context)) diff --git a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java index 0148bfb7..0e9b1bc4 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java @@ -6,16 +6,24 @@ package de.blinkt.openvpn.core; import android.os.Build; -import android.support.v4.util.Pair; import android.text.TextUtils; +import android.support.v4.util.Pair; import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import java.io.StringReader; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Locale; +import java.util.Map; +import java.util.Vector; import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.core.connection.Connection; +import de.blinkt.openvpn.core.connection.OpenvpnConnection; //! Openvpn Config FIle Parser, probably not 100% accurate but close enough @@ -142,9 +150,9 @@ public class ConfigParser { String data = VpnProfile.getEmbeddedContent(inlinedata); String[] parts = data.split("\n"); if (parts.length >= 2) { - c.mProxyAuthUser = parts[0]; - c.mProxyAuthPassword = parts[1]; - c.mUseProxyAuth = true; + c.setProxyAuthUser(parts[0]); + c.setProxyAuthPassword(parts[1]); + c.setUseProxyAuth(true); } } @@ -605,7 +613,7 @@ public class ConfigParser { } - if (getOption("nobind", 0, 0) != null) + if (getOption("nobind", 0, 1) != null) np.mNobind = true; if (getOption("persist-tun", 0, 0) != null) @@ -713,8 +721,8 @@ public class ConfigParser { throw new ConfigParseError(String.format("Unknown protocol %s in proto-force", protoToDisable)); for (Connection conn : np.mConnections) - if (conn.mUseUdp == disableUDP) - conn.mEnabled = false; + if (conn.isUseUdp() == disableUDP) + conn.setEnabled(false); } // Parse OpenVPN Access Server extra @@ -763,27 +771,27 @@ public class ConfigParser { return null; } else - conn = new Connection(); + conn = new OpenvpnConnection(); Vector port = getOption("port", 1, 1); if (port != null) { - conn.mServerPort = port.get(1); + conn.setServerPort(port.get(1)); } Vector rport = getOption("rport", 1, 1); if (rport != null) { - conn.mServerPort = rport.get(1); + conn.setServerPort(rport.get(1)); } Vector proto = getOption("proto", 1, 1); if (proto != null) { - conn.mUseUdp = isUdpProto(proto.get(1)); + conn.setUseUdp(isUdpProto(proto.get(1))); } Vector connectTimeout = getOption("connect-timeout", 1, 1); if (connectTimeout != null) { try { - conn.mConnectTimeout = Integer.parseInt(connectTimeout.get(1)); + conn.setConnectTimeout(Integer.parseInt(connectTimeout.get(1))); } catch (NumberFormatException nfe) { throw new ConfigParseError(String.format("Argument to connect-timeout (%s) must to be an integer: %s", connectTimeout.get(1), nfe.getLocalizedMessage())); @@ -797,16 +805,16 @@ public class ConfigParser { if (proxy != null) { if (proxy.get(0).equals("socks-proxy")) { - conn.mProxyType = Connection.ProxyType.SOCKS5; + conn.setProxyType(Connection.ProxyType.SOCKS5); // socks defaults to 1080, http always sets port - conn.mProxyPort = "1080"; + conn.setProxyPort("1080"); } else { - conn.mProxyType = Connection.ProxyType.HTTP; + conn.setProxyType(Connection.ProxyType.HTTP); } - conn.mProxyName = proxy.get(1); + conn.setProxyName(proxy.get(1)); if (proxy.size() >= 3) - conn.mProxyPort = proxy.get(2); + conn.setProxyPort(proxy.get(2)); } Vector httpproxyauthhttp = getOption("http-proxy-user-pass", 1, 1); @@ -823,15 +831,15 @@ public class ConfigParser { // Assume that we need custom options if connectionDefault are set or in the connection specific set for (Map.Entry>> option : options.entrySet()) { if (connDefault != null || connectionOptionsSet.contains(option.getKey())) { - conn.mCustomConfiguration += getOptionStrings(option.getValue()); + conn.setCustomConfiguration(conn.getCustomConfiguration() + getOptionStrings(option.getValue())); optionsToRemove.add(option.getKey()); } } for (String o: optionsToRemove) options.remove(o); - if (!(conn.mCustomConfiguration == null || "".equals(conn.mCustomConfiguration.trim()))) - conn.mUseCustomConfig = true; + if (!(conn.getCustomConfiguration() == null || "".equals(conn.getCustomConfiguration().trim()))) + conn.setUseCustomConfig(true); // Make remotes empty to simplify code if (remotes == null) @@ -849,11 +857,11 @@ public class ConfigParser { } switch (remote.size()) { case 4: - connections[i].mUseUdp = isUdpProto(remote.get(3)); + connections[i].setUseUdp(isUdpProto(remote.get(3))); case 3: - connections[i].mServerPort = remote.get(2); + connections[i].setServerPort(remote.get(2)); case 2: - connections[i].mServerName = remote.get(1); + connections[i].setServerName(remote.get(1)); } i++; } diff --git a/app/src/main/java/de/blinkt/openvpn/core/ConnectionInterface.java b/app/src/main/java/de/blinkt/openvpn/core/ConnectionInterface.java new file mode 100644 index 00000000..70b4b4ec --- /dev/null +++ b/app/src/main/java/de/blinkt/openvpn/core/ConnectionInterface.java @@ -0,0 +1,15 @@ +package de.blinkt.openvpn.core; + +import java.io.Serializable; + +/** + * Created by cyberta on 11.03.19. + */ + +public interface ConnectionInterface { + + String getConnectionBlock(boolean isOpenVPN3); + boolean usesExtraProxyOptions(); + boolean isOnlyRemote(); + int getTimeout(); +} diff --git a/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java b/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java index 6b633c34..a66b7b51 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java +++ b/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java @@ -20,6 +20,8 @@ public class NativeUtils { { if (isRoboUnitTest()) return "ROBO"; + else if (isUnitTest()) + return "JUNIT"; else return getJNIAPI(); } @@ -34,7 +36,7 @@ public class NativeUtils { public static native double[] getOpenSSLSpeed(String algorithm, int testnum); static { - if (!isRoboUnitTest()) { + if (!isRoboUnitTest() && !isUnitTest()) { System.loadLibrary("opvpnutil"); if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) System.loadLibrary("jbcrypto"); @@ -44,4 +46,13 @@ public class NativeUtils { public static boolean isRoboUnitTest() { return "robolectric".equals(Build.FINGERPRINT); } + + public static boolean isUnitTest() { + try { + Class.forName("se.leap.bitmaskclient.testutils.MockHelper"); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } } diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java index 82c4e1df..55a92cb0 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -42,9 +42,13 @@ import java.util.Vector; import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.core.VpnStatus.ByteCountListener; import de.blinkt.openvpn.core.VpnStatus.StateListener; +import de.blinkt.openvpn.core.connection.Connection; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.VpnNotificationManager; +import se.leap.bitmaskclient.pluggableTransports.Dispatcher; +import de.blinkt.openvpn.core.connection.Obfs4Connection; +import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4; import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_CONNECTED; import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT; import static de.blinkt.openvpn.core.NetworkSpace.IpAddress; @@ -52,6 +56,7 @@ import static se.leap.bitmaskclient.Constants.PROVIDER_PROFILE; public class OpenVPNService extends VpnService implements StateListener, Callback, ByteCountListener, IOpenVPNServiceInternal, VpnNotificationManager.VpnServiceCallback { + public static final String TAG = OpenVPNService.class.getSimpleName(); public static final String START_SERVICE = "de.blinkt.openvpn.START_SERVICE"; public static final String START_SERVICE_STICKY = "de.blinkt.openvpn.START_SERVICE_STICKY"; public static final String ALWAYS_SHOW_NOTIFICATION = "de.blinkt.openvpn.NOTIFICATION_ALWAYS_VISIBLE"; @@ -85,6 +90,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac private Toast mlastToast; private Runnable mOpenVPNThread; private VpnNotificationManager notificationManager; + private Dispatcher dispatcher; private static final int PRIORITY_MIN = -2; private static final int PRIORITY_DEFAULT = 0; @@ -242,6 +248,9 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac if(isVpnRunning()) { if (getManagement() != null && getManagement().stopVPN(replaceConnection)) { if (!replaceConnection) { + if (dispatcher.isRunning()) { + dispatcher.stop(); + } VpnStatus.updateStateString("NOPROCESS", "VPN STOPPED", R.string.state_noprocess, ConnectionStatus.LEVEL_NOTCONNECTED); } return true; @@ -249,6 +258,9 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac return false; } else { if (!replaceConnection) { + if (dispatcher.isRunning()) { + dispatcher.stop(); + } VpnStatus.updateStateString("NOPROCESS", "VPN STOPPED", R.string.state_noprocess, ConnectionStatus.LEVEL_NOTCONNECTED); return true; } @@ -366,6 +378,36 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac /** * see change above (l. 292 ff) */ + //TODO: investigate how connections[n] with n>0 get called during vpn setup (on connection refused?) + // Do we need to check if there's any obfs4 connection in mProfile.mConnections and start + // the dispatcher here? Can we start the dispatcher at a later point of execution, e.g. when + // connections[n], n>0 gets choosen? + + VpnStatus.logInfo("Setting up dispatcher."); + Connection connection = mProfile.mConnections[0]; + + if (connection.getTransportType() == OBFS4) { + Obfs4Connection obfs4Connection = (Obfs4Connection) connection; + dispatcher = new Dispatcher(this, + obfs4Connection.getmObfs4RemoteProxyName(), + obfs4Connection.getmObfs4RemoteProxyPort(), + obfs4Connection.getmObfs4Certificate(), + obfs4Connection.getmObfs4IatMode()); + dispatcher.initSync(); + + if (dispatcher.getPort() != null && dispatcher.getPort().length() > 0) { + connection.setServerPort(dispatcher.getPort()); + Log.d(TAG, "Dispatcher running. Profile server name and port: " + + connection.getServerName() + ":" + connection.getServerPort()); + VpnStatus.logInfo("Dispatcher running. Profile server name and port: " + + connection.getServerName() + ":" + connection.getServerPort()); + } else { + Log.e(TAG, "Cannot initialize dispatcher for obfs4 connection. Shutting down."); + VpnStatus.logError("Cannot initialize dispatcher for obfs4 connection. Shutting down."); + } + } + + VpnStatus.logInfo(R.string.building_configration); VpnStatus.updateStateString("VPN_GENERATE_CONFIG", "", R.string.building_configration, ConnectionStatus.LEVEL_START); @@ -743,7 +785,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac boolean profileUsesOrBot = false; for (Connection c : mProfile.mConnections) { - if (c.mProxyType == Connection.ProxyType.ORBOT) + if (c.getProxyType() == Connection.ProxyType.ORBOT) profileUsesOrBot = true; } diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java index 4f7a5bda..91cc66bc 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -15,9 +15,10 @@ import android.os.Handler; import android.os.ParcelFileDescriptor; import android.support.annotation.NonNull; import android.support.annotation.RequiresApi; -import android.system.ErrnoException; import android.system.Os; import android.util.Log; + +import de.blinkt.openvpn.core.connection.Connection; import se.leap.bitmaskclient.R; import de.blinkt.openvpn.VpnProfile; @@ -452,10 +453,10 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { if (mProfile.mConnections.length > connectionEntryNumber) { Connection connection = mProfile.mConnections[connectionEntryNumber]; - proxyType = connection.mProxyType; - proxyname = connection.mProxyName; - proxyport = connection.mProxyPort; - proxyUseAuth = connection.mUseProxyAuth; + proxyType = connection.getProxyType(); + proxyname = connection.getProxyName(); + proxyport = connection.getProxyPort(); + proxyUseAuth = connection.isUseProxyAuth(); // Use transient variable to remember http user/password mCurrentProxyConnection = connection; @@ -696,8 +697,8 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { } else if (needed.equals("HTTP Proxy")) { if( mCurrentProxyConnection != null) { - pw = mCurrentProxyConnection.mProxyAuthPassword; - username = mCurrentProxyConnection.mProxyAuthUser; + pw = mCurrentProxyConnection.getProxyAuthPassword(); + username = mCurrentProxyConnection.getProxyAuthUser(); } } if (pw != null) { @@ -782,7 +783,6 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { boolean stopSucceed = stopOpenVPN(); if (stopSucceed) { mShuttingDown = true; - } return stopSucceed; } diff --git a/app/src/main/java/de/blinkt/openvpn/core/connection/Connection.java b/app/src/main/java/de/blinkt/openvpn/core/connection/Connection.java new file mode 100644 index 00000000..f333a13e --- /dev/null +++ b/app/src/main/java/de/blinkt/openvpn/core/connection/Connection.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2012-2016 Arne Schwabe + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt + */ + +package de.blinkt.openvpn.core.connection; + +import android.text.TextUtils; + +import java.io.Serializable; +import java.util.Locale; + +public abstract class Connection implements Serializable, Cloneable { + private String mServerName = "openvpn.example.com"; + private String mServerPort = "1194"; + private boolean mUseUdp = true; + private String mCustomConfiguration = ""; + private boolean mUseCustomConfig = false; + private boolean mEnabled = true; + private int mConnectTimeout = 0; + private static final int CONNECTION_DEFAULT_TIMEOUT = 120; + private ProxyType mProxyType = ProxyType.NONE; + private String mProxyName = "proxy.example.com"; + private String mProxyPort = "8080"; + + private boolean mUseProxyAuth; + private String mProxyAuthUser = null; + private String mProxyAuthPassword = null; + + public enum ProxyType { + NONE, + HTTP, + SOCKS5, + ORBOT + } + + public enum TransportType { + OBFS4, + OPENVPN + } + + private static final long serialVersionUID = 92031902903829089L; + + + public String getConnectionBlock(boolean isOpenVPN3) { + String cfg = ""; + + // Server Address + cfg += "remote "; + cfg += mServerName; + cfg += " "; + cfg += mServerPort; + if (mUseUdp) + cfg += " udp\n"; + else + cfg += " tcp-client\n"; + + if (mConnectTimeout != 0) + cfg += String.format(Locale.US, " connect-timeout %d\n", mConnectTimeout); + + // OpenVPN 2.x manages proxy connection via management interface + if ((isOpenVPN3 || usesExtraProxyOptions()) && mProxyType == ProxyType.HTTP) + { + cfg+=String.format(Locale.US,"http-proxy %s %s\n", mProxyName, mProxyPort); + if (mUseProxyAuth) + cfg+=String.format(Locale.US, "\n%s\n%s\n\n", mProxyAuthUser, mProxyAuthPassword); + } + if (usesExtraProxyOptions() && mProxyType == ProxyType.SOCKS5) { + cfg+=String.format(Locale.US,"socks-proxy %s %s\n", mProxyName, mProxyPort); + } + + if (!TextUtils.isEmpty(mCustomConfiguration) && mUseCustomConfig) { + cfg += mCustomConfiguration; + cfg += "\n"; + } + + + return cfg; + } + + public boolean usesExtraProxyOptions() { + return (mUseCustomConfig && mCustomConfiguration.contains("http-proxy-option ")); + } + + + @Override + public Connection clone() throws CloneNotSupportedException { + return (Connection) super.clone(); + } + + public boolean isOnlyRemote() { + return TextUtils.isEmpty(mCustomConfiguration) || !mUseCustomConfig; + } + + public int getTimeout() { + if (mConnectTimeout <= 0) + return CONNECTION_DEFAULT_TIMEOUT; + else + return mConnectTimeout; + } + + public String getServerName() { + return mServerName; + } + + public void setServerName(String mServerName) { + this.mServerName = mServerName; + } + + public String getServerPort() { + return mServerPort; + } + + public void setServerPort(String serverPort) { + this.mServerPort = serverPort; + } + + public boolean isUseUdp() { + return mUseUdp; + } + + public void setUseUdp(boolean useUdp) { + this.mUseUdp = useUdp; + } + + public String getCustomConfiguration() { + return mCustomConfiguration; + } + + public void setCustomConfiguration(String customConfiguration) { + this.mCustomConfiguration = customConfiguration; + } + + public boolean isUseCustomConfig() { + return mUseCustomConfig; + } + + public void setUseCustomConfig(boolean useCustomConfig) { + this.mUseCustomConfig = useCustomConfig; + } + + public boolean isEnabled() { + return mEnabled; + } + + public void setEnabled(boolean enabled) { + this.mEnabled = enabled; + } + + public int getConnectTimeout() { + return mConnectTimeout; + } + + public void setConnectTimeout(int connectTimeout) { + this.mConnectTimeout = connectTimeout; + } + + public ProxyType getProxyType() { + return mProxyType; + } + + public void setProxyType(ProxyType proxyType) { + this.mProxyType = proxyType; + } + + public String getProxyName() { + return mProxyName; + } + + public void setProxyName(String proxyName) { + this.mProxyName = proxyName; + } + + public String getProxyPort() { + return mProxyPort; + } + + public void setProxyPort(String proxyPort) { + this.mProxyPort = proxyPort; + } + + public boolean isUseProxyAuth() { + return mUseProxyAuth; + } + + public void setUseProxyAuth(boolean useProxyAuth) { + this.mUseProxyAuth = useProxyAuth; + } + + public String getProxyAuthUser() { + return mProxyAuthUser; + } + + public void setProxyAuthUser(String proxyAuthUser) { + this.mProxyAuthUser = proxyAuthUser; + } + + public String getProxyAuthPassword() { + return mProxyAuthPassword; + } + + public void setProxyAuthPassword(String proxyAuthPassword) { + this.mProxyAuthPassword = proxyAuthPassword; + } + + public abstract TransportType getTransportType(); +} diff --git a/app/src/main/java/de/blinkt/openvpn/core/connection/Obfs4Connection.java b/app/src/main/java/de/blinkt/openvpn/core/connection/Obfs4Connection.java new file mode 100644 index 00000000..790b8b1a --- /dev/null +++ b/app/src/main/java/de/blinkt/openvpn/core/connection/Obfs4Connection.java @@ -0,0 +1,83 @@ +package de.blinkt.openvpn.core.connection; + +import org.json.JSONObject; + +/** + * Created by cyberta on 08.03.19. + */ + +public class Obfs4Connection extends Connection { + + private static final String TAG = Obfs4Connection.class.getName(); + + + private String mObfs4RemoteProxyName = ""; + private String mObfs4RemoteProxyPort = ""; + private String mObfs4Certificate = ""; + private String mObfs4IatMode = ""; + + public Obfs4Connection() { + setDefaults(); + } + + public Obfs4Connection(Connection connection) { + mObfs4RemoteProxyName = connection.getServerName(); + setConnectTimeout(connection.getConnectTimeout()); + setCustomConfiguration(connection.getCustomConfiguration()); + setUseCustomConfig(connection.isUseCustomConfig()); + + setDefaults(); + } + + private void setDefaults() { + setUseUdp(false); + setServerName("127.0.0.1"); + setServerPort(""); + setProxyName(""); + setProxyPort(""); + setProxyAuthUser(null); + setProxyAuthPassword(null); + setProxyType(ProxyType.NONE); + setUseProxyAuth(false); + } + + public void setTransportOptions(JSONObject jsonObject) { + mObfs4Certificate = jsonObject.optString("cert"); + mObfs4IatMode = jsonObject.optString("iat-mode"); + } + + @Override + public Connection clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public TransportType getTransportType() { + return TransportType.OBFS4; + } + + public String getmObfs4RemoteProxyName() { + return mObfs4RemoteProxyName; + } + + public void setObfs4RemoteProxyName(String mObfs4RemoteProxyName) { + this.mObfs4RemoteProxyName = mObfs4RemoteProxyName; + } + + public String getmObfs4RemoteProxyPort() { + return mObfs4RemoteProxyPort; + } + + public void setObfs4RemoteProxyPort(String mObfs4RemoteProxyPort) { + this.mObfs4RemoteProxyPort = mObfs4RemoteProxyPort; + } + + public String getmObfs4Certificate() { + return mObfs4Certificate; + } + + public String getmObfs4IatMode() { + return mObfs4IatMode; + } + +} diff --git a/app/src/main/java/de/blinkt/openvpn/core/connection/OpenvpnConnection.java b/app/src/main/java/de/blinkt/openvpn/core/connection/OpenvpnConnection.java new file mode 100644 index 00000000..3a3fd0c3 --- /dev/null +++ b/app/src/main/java/de/blinkt/openvpn/core/connection/OpenvpnConnection.java @@ -0,0 +1,13 @@ +package de.blinkt.openvpn.core.connection; + +/** + * Created by cyberta on 11.03.19. + */ + +public class OpenvpnConnection extends Connection { + + @Override + public TransportType getTransportType() { + return TransportType.OPENVPN; + } +} -- cgit v1.2.3