diff options
13 files changed, 382 insertions, 33 deletions
diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/TestGatewaysManager.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestGatewaysManager.java index 4817adbb..0a76638f 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/TestGatewaysManager.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/TestGatewaysManager.java @@ -19,10 +19,12 @@ package se.leap.bitmaskclient.test; import android.app.*; import android.content.*; import android.test.*; -import android.test.suitebuilder.annotation.*; import org.json.*; +import java.io.IOException; +import java.util.Arrays; + import se.leap.bitmaskclient.*; import se.leap.bitmaskclient.eip.*; @@ -42,14 +44,13 @@ public class TestGatewaysManager extends InstrumentationTestCase { @Override protected void setUp() throws Exception { + super.setUp(); context = getInstrumentation().getContext(); assets = new FromAssets(context); mockGatewaysManager(); mockRealGateway(); - super.setUp(); } - @MediumTest public void testFromEipServiceJson() { gateways_manager.fromEipServiceJson(eip_definition); assertEquals(2, gateways_manager.size()); @@ -57,13 +58,31 @@ public class TestGatewaysManager extends InstrumentationTestCase { assertEquals(2, gateways_manager.size()); } - @SmallTest + public void testOrderOfGateways_UDP_TCP() { + String[] protocolsInOrder = {"udp", "tcp"}; + manipulateSupportedProtocols(protocolsInOrder); + gateways_manager.fromEipServiceJson(eip_definition); + gateways_manager.addFromString(gateway.toString()); + assertTrue(gateways_manager.select().toString().contains("[\"udp\",\"tcp\"]")); + assertFalse(gateways_manager.select().toString().contains("[\"tcp\",\"udp\"]")); + } + + public void testOrderOfGateways_TCP_UDP() { + String[] protocolsInOrder = {"tcp", "udp"}; + manipulateSupportedProtocols(protocolsInOrder); + gateways_manager.fromEipServiceJson(eip_definition); + gateways_manager.addFromString(gateway.toString()); + assertFalse(gateways_manager.select().toString().contains("[\"udp\",\"tcp\"]")); + assertTrue(gateways_manager.select().toString().contains("[\"tcp\",\"udp\"]")); + } + public void testAddFromString() { gateways_manager.addFromString(""); + assertEquals(0, gateways_manager.size()); gateways_manager.addFromString(gateway.toString()); + assertEquals(1, gateways_manager.size()); } - @MediumTest public void testRemoveDuplicate() { gateways_manager.addFromString(gateway.toString()); assertEquals(1, gateways_manager.size()); @@ -73,7 +92,6 @@ public class TestGatewaysManager extends InstrumentationTestCase { assertEquals(1, gateways_manager.size()); } - @MediumTest public void testToString() { assertEquals("[]", gateways_manager.toString()); @@ -81,7 +99,6 @@ public class TestGatewaysManager extends InstrumentationTestCase { assertEquals("[" + gateway.toString() + "]", gateways_manager.toString()); } - @SmallTest public void testIsEmpty() { assertTrue(gateways_manager.isEmpty()); gateways_manager.addFromString(""); @@ -107,6 +124,29 @@ public class TestGatewaysManager extends InstrumentationTestCase { } } + private void manipulateSupportedProtocols(String[] protocols) { + try { + eip_definition = new JSONObject(assets.toString(TestConstants.EIP_DEFINITION_FILE)); + JSONObject secrets = new JSONObject(assets.toString(TestConstants.SECRETS_FILE)); + JSONArray protocolJsonArray = new JSONArray(Arrays.asList(protocols)); + JSONArray gateways = eip_definition.getJSONArray("gateways"); + for (int i = 0; i < gateways.length(); i++) { + JSONObject gatewayJson = gateways.getJSONObject(i); + JSONObject capabilitiesJson = gatewayJson.getJSONObject("capabilities"); + capabilitiesJson.put("protocols", protocolJsonArray); + gatewayJson.put("protocols", protocolJsonArray); + } + this.gateway = new Gateway(eip_definition, secrets, gateways.getJSONObject(0)); + } catch (JSONException e) { + e.printStackTrace(); + assertFalse(true); + } catch (IOException e) { + e.printStackTrace(); + assertFalse(true); + } + + } + private void mockArtificialGateway() { try { eip_definition = new JSONObject(assets.toString(TestConstants.EIP_DEFINITION_FILE)); diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/VpnTestController.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/VpnTestController.java index d339ab26..93b1da47 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/VpnTestController.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/VpnTestController.java @@ -33,7 +33,7 @@ public class VpnTestController { Button button = getVpnButton(); if(!isVpnButton(button)) throw new IllegalStateException(); - solo.clickOnView(button); + solo.clickOnButton(String.valueOf(button.getText())); } protected Button getVpnButton() { @@ -93,8 +93,6 @@ public class VpnTestController { protected void turningEipOff() { okToBrowserWarning(); - sayOkToDisconnect(); - int max_seconds_until_connected = 120; Condition condition = new Condition() { @@ -123,6 +121,7 @@ public class VpnTestController { solo.clickOnButton(disconnect); } + @SuppressWarnings("unused") private void sayOkToDisconnect() throws IllegalStateException { boolean disconnect_vpn_appeared = solo.waitForActivity(DisconnectVPN.class); if(disconnect_vpn_appeared){ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 025c98f0..67fd0a1a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -85,7 +85,7 @@ android:name="se.leap.bitmaskclient.Dashboard" android:label="@string/title_activity_dashboard" android:uiOptions="splitActionBarWhenNarrow" - android:launchMode="singleTask" + android:launchMode="singleTop" > <intent-filter android:label="@string/app_name"> 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 5faa1de4..835e69b3 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -322,9 +322,11 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } - Intent disconnectVPN = new Intent(this, DisconnectVPN.class); - disconnectVPN.setAction(DISCONNECT_VPN); - PendingIntent disconnectPendingIntent = PendingIntent.getActivity(this, 0, disconnectVPN, 0); + Intent disconnectVPN = new Intent(this, Dashboard.class); + disconnectVPN.putExtra(Dashboard.ACTION_ASK_TO_CANCEL_VPN, true); + disconnectVPN.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | + Intent.FLAG_ACTIVITY_SINGLE_TOP); + PendingIntent disconnectPendingIntent = PendingIntent.getActivity(this, 0, disconnectVPN, PendingIntent.FLAG_CANCEL_CURRENT); nbuilder.addAction(R.drawable.ic_menu_close_clear_cancel, getString(R.string.cancel_connection), disconnectPendingIntent); diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index dbdf0a51..a6a3717b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -66,9 +66,11 @@ public class Dashboard extends Activity implements ProviderAPIResultReceiver.Rec public static final String TAG = Dashboard.class.getSimpleName(); public static final String SHARED_PREFERENCES = "LEAPPreferences"; public static final String ACTION_QUIT = "quit"; + public static final String ACTION_ASK_TO_CANCEL_VPN = "ask to cancel vpn"; public static final String REQUEST_CODE = "request_code"; public static final String PARAMETERS = "dashboard parameters"; public static final String START_ON_BOOT = "dashboard start on boot"; + //FIXME: remove OR FIX ON_BOOT public static final String ON_BOOT = "dashboard on boot"; public static final String APP_VERSION = "bitmask version"; @@ -116,6 +118,12 @@ public class Dashboard extends Activity implements ProviderAPIResultReceiver.Rec } } + @Override + protected void onResume() { + super.onResume(); + handleVPNCancellation(getIntent()); + } + private boolean previousProviderExists(Bundle savedInstanceState) { return providerInSavedInstance(savedInstanceState) || providerInSharedPreferences(); } @@ -176,6 +184,13 @@ public class Dashboard extends Activity implements ProviderAPIResultReceiver.Rec } @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + setIntent(intent); + handleVPNCancellation(intent); + } + + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == CONFIGURE_LEAP || requestCode == SWITCH_PROVIDER) { if (resultCode == RESULT_OK && data.hasExtra(Provider.KEY)) { @@ -192,8 +207,13 @@ public class Dashboard extends Activity implements ProviderAPIResultReceiver.Rec finish(); } else configErrorDialog(); - } else if (requestCode == EIP.DISCONNECT) { - EipStatus.getInstance().setConnectedOrDisconnected(); + } + } + + private void handleVPNCancellation(Intent intent) { + if (intent.hasExtra(Dashboard.ACTION_ASK_TO_CANCEL_VPN)) { + eip_fragment.askToStopEIP(); + intent.removeExtra(ACTION_ASK_TO_CANCEL_VPN); } } @@ -247,7 +267,9 @@ public class Dashboard extends Activity implements ProviderAPIResultReceiver.Rec eip_fragment = new VpnFragment(); if (hide_and_turn_on_eip) { + //TODO: remove line below if not in use anymore... preferences.edit().remove(Dashboard.START_ON_BOOT).apply(); + //FIXME: always start on Boot? Why do we keep shared preferences then? Bundle arguments = new Bundle(); arguments.putBoolean(VpnFragment.START_ON_BOOT, true); if (eip_fragment != null) eip_fragment.setArguments(arguments); diff --git a/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java b/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java index 9e9adef1..8cd9fa0f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/VpnFragment.java @@ -19,7 +19,6 @@ package se.leap.bitmaskclient; import android.app.*; import android.content.*; import android.os.*; -import android.util.Log; import android.view.*; import android.widget.*; @@ -28,7 +27,10 @@ import org.jetbrains.annotations.*; import java.util.*; import butterknife.*; -import de.blinkt.openvpn.activities.*; +import de.blinkt.openvpn.core.IOpenVPNServiceInternal; +import de.blinkt.openvpn.core.OpenVPNService; +import de.blinkt.openvpn.core.ProfileManager; +import de.blinkt.openvpn.core.VpnStatus; import mbanje.kurt.fabbutton.*; import se.leap.bitmaskclient.eip.*; @@ -50,15 +52,31 @@ public class VpnFragment extends Fragment implements Observer { private static EipStatus eip_status; private boolean wants_to_connect; + private IOpenVPNServiceInternal mService; + private ServiceConnection openVpnConnection = new ServiceConnection() { + + + + @Override + public void onServiceConnected(ComponentName className, + IBinder service) { + + mService = IOpenVPNServiceInternal.Stub.asInterface(service); + } + + @Override + public void onServiceDisconnected(ComponentName arg0) { + mService = null; + } + + }; + //FIXME: replace with onAttach(Context context) public void onAttach(Activity activity) { super.onAttach(activity); dashboard = (Dashboard) activity; - ProviderAPIResultReceiver provider_api_receiver = new ProviderAPIResultReceiver(new Handler(), dashboard); - - if(eip_receiver != null) - ProviderAPICommand.execute(Bundle.EMPTY, ProviderAPI.DOWNLOAD_EIP_SERVICE, provider_api_receiver); + downloadEIPServiceConfig(); } @Override @@ -95,6 +113,13 @@ public class VpnFragment extends Fragment implements Observer { //FIXME: avoid race conditions while checking certificate an logging in at about the same time //eipCommand(Constants.ACTION_CHECK_CERT_VALIDITY); handleNewState(eip_status); + bindOpenVpnService(); + } + + @Override + public void onPause() { + super.onPause(); + dashboard.unbindService(openVpnConnection); } @Override @@ -104,7 +129,7 @@ public class VpnFragment extends Fragment implements Observer { super.onSaveInstanceState(outState); } - protected void saveStatus() { + private void saveStatus() { boolean is_on = eip_status.isConnected() || eip_status.isConnecting(); Dashboard.preferences.edit().putBoolean(Dashboard.START_ON_BOOT, is_on).commit(); } @@ -184,16 +209,29 @@ public class VpnFragment extends Fragment implements Observer { } private void disconnect() { - Intent disconnect_vpn = new Intent(dashboard, DisconnectVPN.class); - dashboard.startActivityForResult(disconnect_vpn, EIP.DISCONNECT); eip_status.setDisconnecting(); + ProfileManager.setConntectedVpnProfileDisconnected(dashboard); + if (mService != null) { + try { + mService.stopVPN(false); + eip_status.setConnectedOrDisconnected(); + } catch (RemoteException e) { + VpnStatus.logException(e); + } + } } protected void stopEipIfPossible() { eipCommand(Constants.ACTION_STOP_EIP); } - private void askToStopEIP() { + private void downloadEIPServiceConfig() { + ProviderAPIResultReceiver provider_api_receiver = new ProviderAPIResultReceiver(new Handler(), dashboard); + if(eip_receiver != null) + ProviderAPICommand.execute(Bundle.EMPTY, ProviderAPI.DOWNLOAD_EIP_SERVICE, provider_api_receiver); + } + + protected void askToStopEIP() { AlertDialog.Builder alertBuilder = new AlertDialog.Builder(dashboard); alertBuilder.setTitle(dashboard.getString(R.string.eip_cancel_connect_title)) .setMessage(dashboard.getString(R.string.eip_warning_browser_inconsistency)) @@ -282,6 +320,12 @@ public class VpnFragment extends Fragment implements Observer { } } + private void bindOpenVpnService() { + Intent intent = new Intent(dashboard, OpenVPNService.class); + intent.setAction(OpenVPNService.START_SERVICE); + dashboard.bindService(intent, openVpnConnection, Context.BIND_AUTO_CREATE); + } + protected class EIPReceiver extends ResultReceiver { protected EIPReceiver(Handler handler) { 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 eb83814a..73c7337b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -42,8 +42,6 @@ public final class EIP extends IntentService { public final static String TAG = EIP.class.getSimpleName(); public final static String SERVICE_API_PATH = "config/eip-service.json"; - public static final int DISCONNECT = 15; - private static Context context; private static ResultReceiver mReceiver; private static SharedPreferences preferences; 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 10a95dfb..53d81ed3 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java @@ -79,7 +79,6 @@ public class VpnConfigGenerator { String ports_keyword = "ports"; String protocol_keyword = "protocols"; String capabilities_keyword = "capabilities"; - String udp = "udp"; try { String ip_address = gateway.getString(ip_address_keyword); @@ -93,9 +92,7 @@ public class VpnConfigGenerator { String protocol = protocols.optString(j); String new_remote = remote_keyword + " " + ip_address + " " + port + " " + protocol + new_line; - port_specific_remotes = protocol.equalsIgnoreCase(udp) ? - port_specific_remotes.replaceFirst(remote_keyword, new_remote + new_line + remote_keyword) : - new_remote; + port_specific_remotes += new_remote; } remotes += port_specific_remotes; } @@ -103,7 +100,9 @@ public class VpnConfigGenerator { // TODO Auto-generated catch block e.printStackTrace(); } - + if (remotes.endsWith(new_line)) { + remotes = remotes.substring(0, remotes.lastIndexOf(new_line)); + } return remotes; } diff --git a/app/src/test/java/se/leap/bitmaskclient/eip/VpnConfigGeneratorTest.java b/app/src/test/java/se/leap/bitmaskclient/eip/VpnConfigGeneratorTest.java new file mode 100644 index 00000000..7e60edb9 --- /dev/null +++ b/app/src/test/java/se/leap/bitmaskclient/eip/VpnConfigGeneratorTest.java @@ -0,0 +1,242 @@ +package se.leap.bitmaskclient.eip; + +import org.json.JSONObject; +import org.junit.Before; +import org.junit.Test; + +import se.leap.bitmaskclient.TestUtils; + +import static junit.framework.Assert.assertTrue; + +/** + * Created by cyberta on 03.10.17. + */ +public class VpnConfigGeneratorTest { + + private VpnConfigGenerator vpnConfigGenerator; + private JSONObject generalConfig; + private JSONObject gateway; + private JSONObject secrets; + + String expectedVPNConfig_tcp_udp = "cipher AES-128-CBC \n" + + "auth SHA1 \n" + + "tun-ipv6 true \n" + + "keepalive 10 30 \n" + + "tls-cipher DHE-RSA-AES128-SHA \n" + + "client\n" + + "remote 198.252.153.84 443 tcp\n" + + "remote 198.252.153.84 443 udp\n" + + "<ca>\n" + + "-----BEGIN CERTIFICATE-----\n" + + "MIIFbzCCA1egAwIBAgIBATANBgkqhkiG9w0BAQ0FADBKMRgwFgYDVQQDDA9CaXRt\n" + + "YXNrIFJvb3QgQ0ExEDAOBgNVBAoMB0JpdG1hc2sxHDAaBgNVBAsME2h0dHBzOi8v\n" + + "Yml0bWFzay5uZXQwHhcNMTIxMTA2MDAwMDAwWhcNMjIxMTA2MDAwMDAwWjBKMRgw\n" + + "FgYDVQQDDA9CaXRtYXNrIFJvb3QgQ0ExEDAOBgNVBAoMB0JpdG1hc2sxHDAaBgNV\n" + + "BAsME2h0dHBzOi8vYml0bWFzay5uZXQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw\n" + + "ggIKAoICAQC1eV4YvayaU+maJbWrD4OHo3d7S1BtDlcvkIRS1Fw3iYDjsyDkZxai\n" + + "dHp4EUasfNQ+EVtXUvtk6170EmLco6Elg8SJBQ27trE6nielPRPCfX3fQzETRfvB\n" + + "7tNvGw4Jn2YKiYoMD79kkjgyZjkJ2r/bEHUSevmR09BRp86syHZerdNGpXYhcQ84\n" + + "CA1+V+603GFIHnrP+uQDdssW93rgDNYu+exT+Wj6STfnUkugyjmPRPjL7wh0tzy+\n" + + "znCeLl4xiV3g9sjPnc7r2EQKd5uaTe3j71sDPF92KRk0SSUndREz+B1+Dbe/RGk4\n" + + "MEqGFuOzrtsgEhPIX0hplhb0Tgz/rtug+yTT7oJjBa3u20AAOQ38/M99EfdeJvc4\n" + + "lPFF1XBBLh6X9UKF72an2NuANiX6XPySnJgZ7nZ09RiYZqVwu/qt3DfvLfhboq+0\n" + + "bQvLUPXrVDr70onv5UDjpmEA/cLmaIqqrduuTkFZOym65/PfAPvpGnt7crQj/Ibl\n" + + "DEDYZQmP7AS+6zBjoOzNjUGE5r40zWAR1RSi7zliXTu+yfsjXUIhUAWmYR6J3KxB\n" + + "lfsiHBQ+8dn9kC3YrUexWoOqBiqJOAJzZh5Y1tqgzfh+2nmHSB2dsQRs7rDRRlyy\n" + + "YMbkpzL9ZsOUO2eTP1mmar6YjCN+rggYjRrX71K2SpBG6b1zZxOG+wIDAQABo2Aw\n" + + "XjAdBgNVHQ4EFgQUuYGDLL2sswnYpHHvProt1JU+D48wDgYDVR0PAQH/BAQDAgIE\n" + + "MAwGA1UdEwQFMAMBAf8wHwYDVR0jBBgwFoAUuYGDLL2sswnYpHHvProt1JU+D48w\n" + + "DQYJKoZIhvcNAQENBQADggIBADeG67vaFcbITGpi51264kHPYPEWaXUa5XYbtmBl\n" + + "cXYyB6hY5hv/YNuVGJ1gWsDmdeXEyj0j2icGQjYdHRfwhrbEri+h1EZOm1cSBDuY\n" + + "k/P5+ctHyOXx8IE79DBsZ6IL61UKIaKhqZBfLGYcWu17DVV6+LT+AKtHhOrv3TSj\n" + + "RnAcKnCbKqXLhUPXpK0eTjPYS2zQGQGIhIy9sQXVXJJJsGrPgMxna1Xw2JikBOCG\n" + + "htD/JKwt6xBmNwktH0GI/LVtVgSp82Clbn9C4eZN9E5YbVYjLkIEDhpByeC71QhX\n" + + "EIQ0ZR56bFuJA/CwValBqV/G9gscTPQqd+iETp8yrFpAVHOW+YzSFbxjTEkBte1J\n" + + "aF0vmbqdMAWLk+LEFPQRptZh0B88igtx6tV5oVd+p5IVRM49poLhuPNJGPvMj99l\n" + + "mlZ4+AeRUnbOOeAEuvpLJbel4rhwFzmUiGoeTVoPZyMevWcVFq6BMkS+jRR2w0jK\n" + + "G6b0v5XDHlcFYPOgUrtsOBFJVwbutLvxdk6q37kIFnWCd8L3kmES5q4wjyFK47Co\n" + + "Ja8zlx64jmMZPg/t3wWqkZgXZ14qnbyG5/lGsj5CwVtfDljrhN0oCWK1FZaUmW3d\n" + + "69db12/g4f6phldhxiWuGC/W6fCW5kre7nmhshcltqAJJuU47iX+DarBFiIj816e\n" + + "yV8e\n" + + "-----END CERTIFICATE-----\n" + + "\n" + + "</ca>\n" + + "<key>\n" + + "-----BEGIN RSA PRIVATE KEY-----\n" + + "MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDUTYWeGgsHS+fjijmziniNqw6h\n" + + "MBpyK4S/cM6PxV28C33VuOWPTMcIYesctjZANWFCggfFTQSjV5Qaxq9UK4i27tayLbCdlVS6hpbl\n" + + "Vf4DuI3Gj1Pv1rtITBShtvCf3T7yBnjW4wVpOpsUAAOViKUSvUU3kPPMFWhiGQw8yHYr82ts6XMo\n" + + "jwMoonW5Ml4e7C7Cr22QesC63q7emNcpUd0pZGT9C33RgDAHZDMrlyjo4HEp1JbUfB0gbmXElJbE\n" + + "1TNdZ62HhgmMjzTUN1GGrQ1t91AEoEQwaK65o4YSj+yFv6KXZZz5OWaz94tKiN9v26EXtBFmRlyb\n" + + "6+D9ynSd9LghAgMBAAECggEBANPHLRXkhsHVj1EkzqBx7gXr8CEMmiTvknFh9zvltrZhhDoRQjWr\n" + + "chPDkcRHY2Cznvy4N0YyqQDD2ULIlZdSAgPxxothFoBruWSD47yMBmLx08ORsDpcqt/YvPAATJI8\n" + + "IpFNsXcyaXBp/M57oRemgnxp/8UJPJmFdWX99H4hvffh/jdj7POgYiWUaAl37XTYZKZ4nzKU2wpL\n" + + "EDLj9RKPz9gG7CYp2zrLC9LaAsrXVrKwPBw6g+XwbClaqFj97db3mrY4lr6mTo89qmus1AU+fBDH\n" + + "3Xlpmc8JwB+30TvhRNKrpLx9cEjuEj7K1gm8Y4dWCjPi+lNbtAyUBcgPJFa/81ECgYEA7pLoBU/Y\n" + + "ZYjyHFca8FvDBcBh6haHfqJr9doXWtgjDrbi3o2n5wHqfKhFWOH6vPEQozkOVeX1ze6HOiRmGBpW\n" + + "r+r7x8TD25L7I6HJw3M351RWOAfkF0w/RTVdetcTgduQtfN1u6BDhYSVceXMjyQYx7MhfETWI8Gh\n" + + "KSYm8OEDYiUCgYEA489fmbrCcUnXzpTsbswJ5NmSoEXbcX8cLxnQuzE0z9GHhQdrMjOpXR76reTW\n" + + "6jcuudarNcwRUYSWWhjCDKHhpx4HhasWPaHgr7jIzcRw8yZSJRSxKr8sl1qh6g7s47JcmfXOMWLt\n" + + "yuyE933XrT19Th4ODZHY40Uv35mPjMi9d00CgYEAyRNAQtndBRa7GG/B4Ls2T+6pl+aNJIo4e+no\n" + + "rURlp800wWabEPRocdBRQmyULBLxduBr2LIMzhgwGSz8b2wji/l9ZA3PFY135bxClVzSzUIjuO3N\n" + + "rGUzHl2wAAyuAFDSUshzfkPBJRNt8aVBF5PQ3t93ZYmPAmv8LPZe875yX5ECgYEAsUEcwK/ZNW7g\n" + + "dQPZR4iJNkC4Xu6cBZ6Cnn92swBheEYvLSoNlX0vDZ7aLE3/jzQqrjzC8NP8sbH5jtbuvgeDXZX3\n" + + "AmGRp5j6C6A61ihAPmEVz3ZfN8SSfJ3vl//PAIg6lyz0J+cy4Q7RkwSeuVQ72Hl4M8TEvmmKC3Af\n" + + "ispy6Y0CgYEAgl1o2lo+ACyk+oVQPaaPqK3d7WOBFp4eR2nXFor/vsx9igQOlZUgzRDQsR8jo1o9\n" + + "efOSBf87igrZGgssys89pWa2dnXnz5PMmzkKr6bw4D9Ez6u6Puc9UZhGw/8wDYg6fSosdB9utspm\n" + + "M698ycef7jBNMDgmhpSvfw5GctoNQ4s=\n" + + "-----END RSA PRIVATE KEY-----\n" + + "</key>\n" + + "<cert>\n" + + "-----BEGIN CERTIFICATE-----\n" + + "MIIEjDCCAnSgAwIBAgIQG6MBp/cd9DlY+7cdvp3R3jANBgkqhkiG9w0BAQsFADBmMRAwDgYDVQQK\n" + + "DAdCaXRtYXNrMRwwGgYDVQQLDBNodHRwczovL2JpdG1hc2submV0MTQwMgYDVQQDDCtCaXRtYXNr\n" + + "IFJvb3QgQ0EgKGNsaWVudCBjZXJ0aWZpY2F0ZXMgb25seSEpMB4XDTE0MTIwNTAwMDAwMFoXDTE1\n" + + "MDMwNTAwMDAwMFowLTErMCkGA1UEAwwiVU5MSU1JVEVEZDBwZDdkMzE4eTNtOHNkeXllaTFqYmZl\n" + + "eDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANRNhZ4aCwdL5+OKObOKeI2rDqEwGnIr\n" + + "hL9wzo/FXbwLfdW45Y9Mxwhh6xy2NkA1YUKCB8VNBKNXlBrGr1QriLbu1rItsJ2VVLqGluVV/gO4\n" + + "jcaPU+/Wu0hMFKG28J/dPvIGeNbjBWk6mxQAA5WIpRK9RTeQ88wVaGIZDDzIdivza2zpcyiPAyii\n" + + "dbkyXh7sLsKvbZB6wLrert6Y1ylR3SlkZP0LfdGAMAdkMyuXKOjgcSnUltR8HSBuZcSUlsTVM11n\n" + + "rYeGCYyPNNQ3UYatDW33UASgRDBorrmjhhKP7IW/opdlnPk5ZrP3i0qI32/boRe0EWZGXJvr4P3K\n" + + "dJ30uCECAwEAAaNvMG0wHQYDVR0OBBYEFK8bMVAM4GBB5sHptoIOAaIvlYueMAsGA1UdDwQEAwIH\n" + + "gDATBgNVHSUEDDAKBggrBgEFBQcDAjAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFId+E7bsWFsUWah9\n" + + "vZuPvZ7O+aJsMA0GCSqGSIb3DQEBCwUAA4ICAQAQOX81csVhvP422NKkZH7+g3npBpl+sEHedaGR\n" + + "xYPOu4HrA4TVF9h44sljRoRJyenGNdBZCXcLKHg889eePTf8Z5K3lTojp6hvwyA6tgxOMHT1kESW\n" + + "PfqnRw8mHfHJuE3g+4YNUMwggzwc/VZATdV/7M33sarVN9AUOHou9n9BizgCC+UnYlS+F2POumE3\n" + + "FbOhKo5uubI02MwBYlN2JVO2TBt1Q20w8wc6cU07Xi5Epp+1mkgFiOShkNtPcJmEyBWJhxDtSDOW\n" + + "2doqWYNqH2kq7B5R/kyyfcpFJqAnBTV7xs+C5rTS1mW7LpxfdCUMbYuLCpyxpO3A/DhAm8n47tUH\n" + + "lBtmo8Avdb8VdFpYiGBpB0o9kTFcsWFb2GkWFBduGfSEB8jUI7QtqhgZqocAKK/cweSRV8FwyUcn\n" + + "R0prRm3QEi9fbXqEddzjSY9y/lqWYzT7u+IOAQpKroeZ4wzgYperDNOUFuYk1rP7yuvjP2pV5rcN\n" + + "yPoBP60TPVWMRM4WJm6nTogAz2qBrFsf/XwT/ajzbsjT6HNB7QbRE+wkFkqspoXG5Agp7KQ8lW3L\n" + + "SKCDGOQJz7VIE85pD0tg7QEXBEw8oaRZtMjQ0Gvs25mxXAKka4wGasaWfYH6d0E+iKYcWn86V1rH\n" + + "K2ZoknT+Nno5jgjFuUR3fZseNizEfx7BteooKQ==\n" + + "-----END CERTIFICATE-----\n" + + "</cert>\n" + + "remote-cert-tls server\n" + + "persist-tun\n" + + "auth-retry nointeract"; + + String expectedVPNConfig_udp_tcp = "cipher AES-128-CBC \n" + + "auth SHA1 \n" + + "tun-ipv6 true \n" + + "keepalive 10 30 \n" + + "tls-cipher DHE-RSA-AES128-SHA \n" + + "client\n" + + "remote 198.252.153.84 443 udp\n" + + "remote 198.252.153.84 443 tcp\n" + + "<ca>\n" + + "-----BEGIN CERTIFICATE-----\n" + + "MIIFbzCCA1egAwIBAgIBATANBgkqhkiG9w0BAQ0FADBKMRgwFgYDVQQDDA9CaXRt\n" + + "YXNrIFJvb3QgQ0ExEDAOBgNVBAoMB0JpdG1hc2sxHDAaBgNVBAsME2h0dHBzOi8v\n" + + "Yml0bWFzay5uZXQwHhcNMTIxMTA2MDAwMDAwWhcNMjIxMTA2MDAwMDAwWjBKMRgw\n" + + "FgYDVQQDDA9CaXRtYXNrIFJvb3QgQ0ExEDAOBgNVBAoMB0JpdG1hc2sxHDAaBgNV\n" + + "BAsME2h0dHBzOi8vYml0bWFzay5uZXQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw\n" + + "ggIKAoICAQC1eV4YvayaU+maJbWrD4OHo3d7S1BtDlcvkIRS1Fw3iYDjsyDkZxai\n" + + "dHp4EUasfNQ+EVtXUvtk6170EmLco6Elg8SJBQ27trE6nielPRPCfX3fQzETRfvB\n" + + "7tNvGw4Jn2YKiYoMD79kkjgyZjkJ2r/bEHUSevmR09BRp86syHZerdNGpXYhcQ84\n" + + "CA1+V+603GFIHnrP+uQDdssW93rgDNYu+exT+Wj6STfnUkugyjmPRPjL7wh0tzy+\n" + + "znCeLl4xiV3g9sjPnc7r2EQKd5uaTe3j71sDPF92KRk0SSUndREz+B1+Dbe/RGk4\n" + + "MEqGFuOzrtsgEhPIX0hplhb0Tgz/rtug+yTT7oJjBa3u20AAOQ38/M99EfdeJvc4\n" + + "lPFF1XBBLh6X9UKF72an2NuANiX6XPySnJgZ7nZ09RiYZqVwu/qt3DfvLfhboq+0\n" + + "bQvLUPXrVDr70onv5UDjpmEA/cLmaIqqrduuTkFZOym65/PfAPvpGnt7crQj/Ibl\n" + + "DEDYZQmP7AS+6zBjoOzNjUGE5r40zWAR1RSi7zliXTu+yfsjXUIhUAWmYR6J3KxB\n" + + "lfsiHBQ+8dn9kC3YrUexWoOqBiqJOAJzZh5Y1tqgzfh+2nmHSB2dsQRs7rDRRlyy\n" + + "YMbkpzL9ZsOUO2eTP1mmar6YjCN+rggYjRrX71K2SpBG6b1zZxOG+wIDAQABo2Aw\n" + + "XjAdBgNVHQ4EFgQUuYGDLL2sswnYpHHvProt1JU+D48wDgYDVR0PAQH/BAQDAgIE\n" + + "MAwGA1UdEwQFMAMBAf8wHwYDVR0jBBgwFoAUuYGDLL2sswnYpHHvProt1JU+D48w\n" + + "DQYJKoZIhvcNAQENBQADggIBADeG67vaFcbITGpi51264kHPYPEWaXUa5XYbtmBl\n" + + "cXYyB6hY5hv/YNuVGJ1gWsDmdeXEyj0j2icGQjYdHRfwhrbEri+h1EZOm1cSBDuY\n" + + "k/P5+ctHyOXx8IE79DBsZ6IL61UKIaKhqZBfLGYcWu17DVV6+LT+AKtHhOrv3TSj\n" + + "RnAcKnCbKqXLhUPXpK0eTjPYS2zQGQGIhIy9sQXVXJJJsGrPgMxna1Xw2JikBOCG\n" + + "htD/JKwt6xBmNwktH0GI/LVtVgSp82Clbn9C4eZN9E5YbVYjLkIEDhpByeC71QhX\n" + + "EIQ0ZR56bFuJA/CwValBqV/G9gscTPQqd+iETp8yrFpAVHOW+YzSFbxjTEkBte1J\n" + + "aF0vmbqdMAWLk+LEFPQRptZh0B88igtx6tV5oVd+p5IVRM49poLhuPNJGPvMj99l\n" + + "mlZ4+AeRUnbOOeAEuvpLJbel4rhwFzmUiGoeTVoPZyMevWcVFq6BMkS+jRR2w0jK\n" + + "G6b0v5XDHlcFYPOgUrtsOBFJVwbutLvxdk6q37kIFnWCd8L3kmES5q4wjyFK47Co\n" + + "Ja8zlx64jmMZPg/t3wWqkZgXZ14qnbyG5/lGsj5CwVtfDljrhN0oCWK1FZaUmW3d\n" + + "69db12/g4f6phldhxiWuGC/W6fCW5kre7nmhshcltqAJJuU47iX+DarBFiIj816e\n" + + "yV8e\n" + + "-----END CERTIFICATE-----\n" + + "\n" + + "</ca>\n" + + "<key>\n" + + "-----BEGIN RSA PRIVATE KEY-----\n" + + "MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDUTYWeGgsHS+fjijmziniNqw6h\n" + + "MBpyK4S/cM6PxV28C33VuOWPTMcIYesctjZANWFCggfFTQSjV5Qaxq9UK4i27tayLbCdlVS6hpbl\n" + + "Vf4DuI3Gj1Pv1rtITBShtvCf3T7yBnjW4wVpOpsUAAOViKUSvUU3kPPMFWhiGQw8yHYr82ts6XMo\n" + + "jwMoonW5Ml4e7C7Cr22QesC63q7emNcpUd0pZGT9C33RgDAHZDMrlyjo4HEp1JbUfB0gbmXElJbE\n" + + "1TNdZ62HhgmMjzTUN1GGrQ1t91AEoEQwaK65o4YSj+yFv6KXZZz5OWaz94tKiN9v26EXtBFmRlyb\n" + + "6+D9ynSd9LghAgMBAAECggEBANPHLRXkhsHVj1EkzqBx7gXr8CEMmiTvknFh9zvltrZhhDoRQjWr\n" + + "chPDkcRHY2Cznvy4N0YyqQDD2ULIlZdSAgPxxothFoBruWSD47yMBmLx08ORsDpcqt/YvPAATJI8\n" + + "IpFNsXcyaXBp/M57oRemgnxp/8UJPJmFdWX99H4hvffh/jdj7POgYiWUaAl37XTYZKZ4nzKU2wpL\n" + + "EDLj9RKPz9gG7CYp2zrLC9LaAsrXVrKwPBw6g+XwbClaqFj97db3mrY4lr6mTo89qmus1AU+fBDH\n" + + "3Xlpmc8JwB+30TvhRNKrpLx9cEjuEj7K1gm8Y4dWCjPi+lNbtAyUBcgPJFa/81ECgYEA7pLoBU/Y\n" + + "ZYjyHFca8FvDBcBh6haHfqJr9doXWtgjDrbi3o2n5wHqfKhFWOH6vPEQozkOVeX1ze6HOiRmGBpW\n" + + "r+r7x8TD25L7I6HJw3M351RWOAfkF0w/RTVdetcTgduQtfN1u6BDhYSVceXMjyQYx7MhfETWI8Gh\n" + + "KSYm8OEDYiUCgYEA489fmbrCcUnXzpTsbswJ5NmSoEXbcX8cLxnQuzE0z9GHhQdrMjOpXR76reTW\n" + + "6jcuudarNcwRUYSWWhjCDKHhpx4HhasWPaHgr7jIzcRw8yZSJRSxKr8sl1qh6g7s47JcmfXOMWLt\n" + + "yuyE933XrT19Th4ODZHY40Uv35mPjMi9d00CgYEAyRNAQtndBRa7GG/B4Ls2T+6pl+aNJIo4e+no\n" + + "rURlp800wWabEPRocdBRQmyULBLxduBr2LIMzhgwGSz8b2wji/l9ZA3PFY135bxClVzSzUIjuO3N\n" + + "rGUzHl2wAAyuAFDSUshzfkPBJRNt8aVBF5PQ3t93ZYmPAmv8LPZe875yX5ECgYEAsUEcwK/ZNW7g\n" + + "dQPZR4iJNkC4Xu6cBZ6Cnn92swBheEYvLSoNlX0vDZ7aLE3/jzQqrjzC8NP8sbH5jtbuvgeDXZX3\n" + + "AmGRp5j6C6A61ihAPmEVz3ZfN8SSfJ3vl//PAIg6lyz0J+cy4Q7RkwSeuVQ72Hl4M8TEvmmKC3Af\n" + + "ispy6Y0CgYEAgl1o2lo+ACyk+oVQPaaPqK3d7WOBFp4eR2nXFor/vsx9igQOlZUgzRDQsR8jo1o9\n" + + "efOSBf87igrZGgssys89pWa2dnXnz5PMmzkKr6bw4D9Ez6u6Puc9UZhGw/8wDYg6fSosdB9utspm\n" + + "M698ycef7jBNMDgmhpSvfw5GctoNQ4s=\n" + + "-----END RSA PRIVATE KEY-----\n" + + "</key>\n" + + "<cert>\n" + + "-----BEGIN CERTIFICATE-----\n" + + "MIIEjDCCAnSgAwIBAgIQG6MBp/cd9DlY+7cdvp3R3jANBgkqhkiG9w0BAQsFADBmMRAwDgYDVQQK\n" + + "DAdCaXRtYXNrMRwwGgYDVQQLDBNodHRwczovL2JpdG1hc2submV0MTQwMgYDVQQDDCtCaXRtYXNr\n" + + "IFJvb3QgQ0EgKGNsaWVudCBjZXJ0aWZpY2F0ZXMgb25seSEpMB4XDTE0MTIwNTAwMDAwMFoXDTE1\n" + + "MDMwNTAwMDAwMFowLTErMCkGA1UEAwwiVU5MSU1JVEVEZDBwZDdkMzE4eTNtOHNkeXllaTFqYmZl\n" + + "eDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANRNhZ4aCwdL5+OKObOKeI2rDqEwGnIr\n" + + "hL9wzo/FXbwLfdW45Y9Mxwhh6xy2NkA1YUKCB8VNBKNXlBrGr1QriLbu1rItsJ2VVLqGluVV/gO4\n" + + "jcaPU+/Wu0hMFKG28J/dPvIGeNbjBWk6mxQAA5WIpRK9RTeQ88wVaGIZDDzIdivza2zpcyiPAyii\n" + + "dbkyXh7sLsKvbZB6wLrert6Y1ylR3SlkZP0LfdGAMAdkMyuXKOjgcSnUltR8HSBuZcSUlsTVM11n\n" + + "rYeGCYyPNNQ3UYatDW33UASgRDBorrmjhhKP7IW/opdlnPk5ZrP3i0qI32/boRe0EWZGXJvr4P3K\n" + + "dJ30uCECAwEAAaNvMG0wHQYDVR0OBBYEFK8bMVAM4GBB5sHptoIOAaIvlYueMAsGA1UdDwQEAwIH\n" + + "gDATBgNVHSUEDDAKBggrBgEFBQcDAjAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFId+E7bsWFsUWah9\n" + + "vZuPvZ7O+aJsMA0GCSqGSIb3DQEBCwUAA4ICAQAQOX81csVhvP422NKkZH7+g3npBpl+sEHedaGR\n" + + "xYPOu4HrA4TVF9h44sljRoRJyenGNdBZCXcLKHg889eePTf8Z5K3lTojp6hvwyA6tgxOMHT1kESW\n" + + "PfqnRw8mHfHJuE3g+4YNUMwggzwc/VZATdV/7M33sarVN9AUOHou9n9BizgCC+UnYlS+F2POumE3\n" + + "FbOhKo5uubI02MwBYlN2JVO2TBt1Q20w8wc6cU07Xi5Epp+1mkgFiOShkNtPcJmEyBWJhxDtSDOW\n" + + "2doqWYNqH2kq7B5R/kyyfcpFJqAnBTV7xs+C5rTS1mW7LpxfdCUMbYuLCpyxpO3A/DhAm8n47tUH\n" + + "lBtmo8Avdb8VdFpYiGBpB0o9kTFcsWFb2GkWFBduGfSEB8jUI7QtqhgZqocAKK/cweSRV8FwyUcn\n" + + "R0prRm3QEi9fbXqEddzjSY9y/lqWYzT7u+IOAQpKroeZ4wzgYperDNOUFuYk1rP7yuvjP2pV5rcN\n" + + "yPoBP60TPVWMRM4WJm6nTogAz2qBrFsf/XwT/ajzbsjT6HNB7QbRE+wkFkqspoXG5Agp7KQ8lW3L\n" + + "SKCDGOQJz7VIE85pD0tg7QEXBEw8oaRZtMjQ0Gvs25mxXAKka4wGasaWfYH6d0E+iKYcWn86V1rH\n" + + "K2ZoknT+Nno5jgjFuUR3fZseNizEfx7BteooKQ==\n" + + "-----END CERTIFICATE-----\n" + + "</cert>\n" + + "remote-cert-tls server\n" + + "persist-tun\n" + + "auth-retry nointeract"; + + + @Before + public void setUp() throws Exception { + generalConfig = new JSONObject(TestUtils.getInputAsString(getClass().getClassLoader().getResourceAsStream("general_configuration.json"))); + secrets = new JSONObject(TestUtils.getInputAsString(getClass().getClassLoader().getResourceAsStream("secrets.json"))); + + } + @Test + public void testGenerate_tcp_udp() throws Exception { + gateway = new JSONObject(TestUtils.getInputAsString(getClass().getClassLoader().getResourceAsStream("gateway_tcp_udp.json"))); + vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway); + + String vpnConfig = vpnConfigGenerator.generate(); + assertTrue(vpnConfig.equals(expectedVPNConfig_tcp_udp)); + } + + @Test + public void testGenerate_udp_tcp() throws Exception { + gateway = new JSONObject(TestUtils.getInputAsString(getClass().getClassLoader().getResourceAsStream("gateway_udp_tcp.json"))); + vpnConfigGenerator = new VpnConfigGenerator(generalConfig, secrets, gateway); + + String vpnConfig = vpnConfigGenerator.generate(); + assertTrue(vpnConfig.equals(expectedVPNConfig_udp_tcp)); + } + +}
\ No newline at end of file diff --git a/app/src/test/resources/gateway_tcp_udp.json b/app/src/test/resources/gateway_tcp_udp.json new file mode 100644 index 00000000..51a19ec9 --- /dev/null +++ b/app/src/test/resources/gateway_tcp_udp.json @@ -0,0 +1 @@ +{"location":"seattle__wa","ip_address":"198.252.153.84","capabilities":{"limited":false,"ports":["443"],"adblock":false,"transport":["openvpn"],"filter_dns":false,"protocols":["tcp","udp"],"user_ips":false},"host":"millipede.demo.bitmask.net"} diff --git a/app/src/test/resources/gateway_udp_tcp.json b/app/src/test/resources/gateway_udp_tcp.json new file mode 100644 index 00000000..36d0ebc2 --- /dev/null +++ b/app/src/test/resources/gateway_udp_tcp.json @@ -0,0 +1 @@ +{"location":"seattle__wa","ip_address":"198.252.153.84","capabilities":{"limited":false,"ports":["443"],"adblock":false,"transport":["openvpn"],"filter_dns":false,"protocols":["udp","tcp"],"user_ips":false},"host":"millipede.demo.bitmask.net"} diff --git a/app/src/test/resources/general_configuration.json b/app/src/test/resources/general_configuration.json new file mode 100644 index 00000000..33b0c0b5 --- /dev/null +++ b/app/src/test/resources/general_configuration.json @@ -0,0 +1 @@ +{"auth":"SHA1","cipher":"AES-128-CBC","keepalive":"10 30","tls-cipher":"DHE-RSA-AES128-SHA","tun-ipv6":true}
\ No newline at end of file diff --git a/ics-openvpn b/ics-openvpn -Subproject 05b9a9ce15dc139a7ff97b3052dec8fd2e3207e +Subproject 455ec6337157118b6d2e49808f25fd80d164956 |