From fa218f752003adcfb040053cfb88b36637060de7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 7 Oct 2014 17:44:46 +0200 Subject: Block traffic during first connection. Set up routes to UDP unlimited server (since openvpn hasn't finished, it simply blocks traffic) and also DNS server to 10.41.0.1. These values correspond to current leap_platform configuration (https://github.com/leapcode/leap_platform/blob/7bc79e68e5ca913d1d2843c48cde8f946feed09c/puppet/modules/site_openvpn/manifests/init.pp) --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 10 +++++++--- .../main/java/se/leap/bitmaskclient/VoidVpnService.java | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 43fe0b7c..add5a1d1 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -38,8 +38,6 @@ import de.blinkt.openvpn.activities.DisconnectVPN; import de.blinkt.openvpn.core.ConfigParser.ConfigParseError; import de.blinkt.openvpn.core.ConfigParser; import de.blinkt.openvpn.core.OpenVpnManagementThread; -import de.blinkt.openvpn.core.OpenVPNService.LocalBinder; -import de.blinkt.openvpn.core.OpenVPNService; import de.blinkt.openvpn.core.ProfileManager; import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; import java.io.IOException; @@ -67,6 +65,7 @@ import org.json.JSONObject; import se.leap.bitmaskclient.Dashboard; import se.leap.bitmaskclient.Provider; import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.VoidVpnService; /** * EIP is the abstract base class for interacting with and managing the Encrypted @@ -187,12 +186,17 @@ public final class EIP extends IntentService { */ private void startEIP() { activeGateway = selectGateway(); - + earlyRoutes(); if(activeGateway != null && activeGateway.mVpnProfile != null) { launchActiveGateway(); } } + private void earlyRoutes() { + VoidVpnService voidVpn = new VoidVpnService(); + voidVpn.setUp(context); + } + private void launchActiveGateway() { Intent intent = new Intent(this,LaunchVPN.class); intent.setAction(Intent.ACTION_MAIN); diff --git a/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java new file mode 100644 index 00000000..ec88fd48 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java @@ -0,0 +1,17 @@ +package se.leap.bitmaskclient; + +import android.content.Context; +import android.net.VpnService; + +public class VoidVpnService extends VpnService { + public void setUp(Context context) { + VpnService.prepare(context); // stops the VPN connection created by another application. + Builder builder = new Builder(); + builder.addAddress("10.42.0.8",16); + builder.addRoute("0.0.0.0", 1); + builder.addRoute("128.0.0.0", 1); + builder.addRoute("192.168.1.0", 24); + builder.addDnsServer("10.42.0.1"); + builder.establish(); + } +} -- cgit v1.2.3 From c4df01ab94c85ecf4a106b187a03e4859a857b1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 7 Oct 2014 21:17:12 +0200 Subject: Set up early routes on boot too. --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 8 +++-- .../se/leap/bitmaskclient/VoidVpnLauncher.java | 36 ++++++++++++++++++++++ .../java/se/leap/bitmaskclient/VoidVpnService.java | 30 ++++++++++++++++-- 3 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/VoidVpnLauncher.java (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index add5a1d1..0197692b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -185,16 +185,18 @@ public final class EIP extends IntentService { * Intent to {@link se.leap.openvpn.LaunchVPN} */ private void startEIP() { - activeGateway = selectGateway(); earlyRoutes(); + activeGateway = selectGateway(); + if(activeGateway != null && activeGateway.mVpnProfile != null) { launchActiveGateway(); } } private void earlyRoutes() { - VoidVpnService voidVpn = new VoidVpnService(); - voidVpn.setUp(context); + Intent void_vpn_launcher = new Intent(context, VoidVpnLauncher.class); + void_vpn_launcher.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(void_vpn_launcher); } private void launchActiveGateway() { diff --git a/app/src/main/java/se/leap/bitmaskclient/VoidVpnLauncher.java b/app/src/main/java/se/leap/bitmaskclient/VoidVpnLauncher.java new file mode 100644 index 00000000..23e61eab --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/VoidVpnLauncher.java @@ -0,0 +1,36 @@ +package se.leap.bitmaskclient; + +import android.app.Activity; +import android.content.Intent; +import android.net.VpnService; +import android.os.Bundle; + +public class VoidVpnLauncher extends Activity { + + private static final int VPN_USER_PERMISSION= 71; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setUp(); + } + + public void setUp() { + Intent blocking_intent = VpnService.prepare(getApplicationContext()); // stops the VPN connection created by another application. + if(blocking_intent != null) + startActivityForResult(blocking_intent, VPN_USER_PERMISSION); + else { + onActivityResult(VPN_USER_PERMISSION, RESULT_OK, null); + } + } + + protected void onActivityResult(int requestCode, int resultCode, Intent data){ + if(requestCode == VPN_USER_PERMISSION) { + if(resultCode == RESULT_OK) { + Intent void_vpn_service = new Intent(getApplicationContext(), VoidVpnService.class); + void_vpn_service.setAction(VoidVpnService.START_BLOCKING_VPN_PROFILE); + startService(void_vpn_service); + } + } + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java index ec88fd48..5f7c0ab1 100644 --- a/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java +++ b/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java @@ -1,11 +1,28 @@ package se.leap.bitmaskclient; -import android.content.Context; +import android.content.Intent; import android.net.VpnService; +import android.util.Log; public class VoidVpnService extends VpnService { - public void setUp(Context context) { - VpnService.prepare(context); // stops the VPN connection created by another application. + + static final String START_BLOCKING_VPN_PROFILE = "se.leap.bitmaskclient.START_BLOCKING_VPN_PROFILE"; + static final String TAG = VoidVpnService.class.getSimpleName(); + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + String action = intent.getAction(); + if (action == START_BLOCKING_VPN_PROFILE) { + new Thread(new Runnable() { + public void run() { + blockConnections(); + } + }).run(); + } + return 0; + } + + public void blockConnections() { Builder builder = new Builder(); builder.addAddress("10.42.0.8",16); builder.addRoute("0.0.0.0", 1); @@ -13,5 +30,12 @@ public class VoidVpnService extends VpnService { builder.addRoute("192.168.1.0", 24); builder.addDnsServer("10.42.0.1"); builder.establish(); + android.util.Log.d(TAG, "VoidVpnService set up"); + try { + new java.net.Socket("sdf.org", 80); + Log.d(TAG, "VoidVpnService doesn's stop traffic"); + } catch (Exception e) { + e.printStackTrace(); + } } } -- cgit v1.2.3 From 8566f7c6f3a5ee3eb668964e3dffb4a753db5b38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 7 Oct 2014 21:33:55 +0200 Subject: Finish VoidVpnLauncher activity. It was remaining there, with an empty layout. --- app/src/main/java/se/leap/bitmaskclient/VoidVpnLauncher.java | 3 ++- app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/VoidVpnLauncher.java b/app/src/main/java/se/leap/bitmaskclient/VoidVpnLauncher.java index 23e61eab..3b286fbf 100644 --- a/app/src/main/java/se/leap/bitmaskclient/VoidVpnLauncher.java +++ b/app/src/main/java/se/leap/bitmaskclient/VoidVpnLauncher.java @@ -7,7 +7,7 @@ import android.os.Bundle; public class VoidVpnLauncher extends Activity { - private static final int VPN_USER_PERMISSION= 71; + private static final int VPN_USER_PERMISSION = 71; @Override protected void onCreate(Bundle savedInstanceState) { @@ -32,5 +32,6 @@ public class VoidVpnLauncher extends Activity { startService(void_vpn_service); } } + finish(); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java index 5f7c0ab1..b7289c23 100644 --- a/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java +++ b/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java @@ -24,6 +24,7 @@ public class VoidVpnService extends VpnService { public void blockConnections() { Builder builder = new Builder(); + builder.setSession("Blocking until running"); builder.addAddress("10.42.0.8",16); builder.addRoute("0.0.0.0", 1); builder.addRoute("128.0.0.0", 1); -- cgit v1.2.3 From 35674aa6be80c153a0fbe4a4c15c54e02aef0b3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 8 Oct 2014 20:57:09 +0200 Subject: A bit of refactoring. ConfigHelper checks for IllegalArgumentException (trace from play store). EIP location code has been splitted a bit. I'd like to extract OVPNGateway out from EIP, but that's not an easy job and this branch is already lasting to much hehehe. --- .../java/se/leap/bitmaskclient/ConfigHelper.java | 5 +- app/src/main/java/se/leap/bitmaskclient/EIP.java | 305 +++++++++++---------- 2 files changed, 162 insertions(+), 148 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java index a8bd3b7a..c95d0c8b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java @@ -18,8 +18,9 @@ package se.leap.bitmaskclient; import java.io.ByteArrayInputStream; import java.io.IOException; -import java.math.BigInteger; import java.io.InputStream; +import java.math.BigInteger; +import java.lang.IllegalArgumentException; import java.security.KeyFactory; import java.security.KeyStore; import java.security.KeyStoreException; @@ -105,6 +106,8 @@ public class ConfigHelper { e.printStackTrace(); } catch (IOException e) { return null; + } catch (IllegalArgumentException e) { + return null; } return (X509Certificate) certificate; diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 0197692b..4a8bae46 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -16,33 +16,23 @@ */ package se.leap.bitmaskclient; - - - - import android.app.Activity; import android.app.IntentService; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.ServiceConnection; import android.content.SharedPreferences; -import android.drm.DrmStore.Action; import android.os.Bundle; -import android.os.IBinder; import android.os.ResultReceiver; import android.util.Log; import de.blinkt.openvpn.LaunchVPN; import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.activities.DisconnectVPN; -import de.blinkt.openvpn.core.ConfigParser.ConfigParseError; import de.blinkt.openvpn.core.ConfigParser; -import de.blinkt.openvpn.core.OpenVpnManagementThread; +import de.blinkt.openvpn.core.ConfigParser.ConfigParseError; import de.blinkt.openvpn.core.ProfileManager; import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; import java.io.IOException; import java.io.StringReader; -import java.lang.StringBuffer; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; @@ -65,7 +55,6 @@ import org.json.JSONObject; import se.leap.bitmaskclient.Dashboard; import se.leap.bitmaskclient.Provider; import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.VoidVpnService; /** * EIP is the abstract base class for interacting with and managing the Encrypted @@ -105,8 +94,6 @@ public final class EIP extends IntentService { private static Context context; private static ResultReceiver mReceiver; private static boolean mBound = false; - // Used to store actions to "resume" onServiceConnection - private static String mPending = null; private static int parsedEipSerial; private static JSONObject eipDefinition = null; @@ -139,66 +126,136 @@ public final class EIP extends IntentService { } - @Override - protected void onHandleIntent(Intent intent) { - String action = intent.getAction(); - mReceiver = intent.getParcelableExtra(RECEIVER_TAG); + @Override + protected void onHandleIntent(Intent intent) { + String action = intent.getAction(); + mReceiver = intent.getParcelableExtra(RECEIVER_TAG); - if ( action == ACTION_IS_EIP_RUNNING ) - this.isRunning(); - if ( action == ACTION_UPDATE_EIP_SERVICE ) - this.updateEIPService(); - else if ( action == ACTION_START_EIP ) - this.startEIP(); - else if ( action == ACTION_STOP_EIP ) - this.stopEIP(); - else if ( action == ACTION_CHECK_CERT_VALIDITY ) - this.checkCertValidity(); - else if ( action == ACTION_REBUILD_PROFILES ) { - this.updateGateways(); - } - } - - /** - * Checks the last stored status notified by ics-openvpn - * Sends Activity.RESULT_CANCELED to the ResultReceiver that made the - * request if it's not connected, Activity.RESULT_OK otherwise. - */ - - private void isRunning() { - Bundle resultData = new Bundle(); - resultData.putString(REQUEST_TAG, ACTION_IS_EIP_RUNNING); - int resultCode = Activity.RESULT_CANCELED; - boolean is_connected = isConnected(); - - resultCode = (is_connected) ? Activity.RESULT_OK : Activity.RESULT_CANCELED; - - if (mReceiver != null){ - mReceiver.send(resultCode, resultData); - } - - Log.d(TAG, "isRunning() = " + is_connected); - } + if ( action == ACTION_START_EIP ) + startEIP(); + else if ( action == ACTION_STOP_EIP ) + stopEIP(); + else if ( action == ACTION_IS_EIP_RUNNING ) + isRunning(); + else if ( action == ACTION_UPDATE_EIP_SERVICE ) + updateEIPService(); + else if ( action == ACTION_CHECK_CERT_VALIDITY ) + checkCertValidity(); + else if ( action == ACTION_REBUILD_PROFILES ) + updateGateways(); + } - /** - * Initiates an EIP connection by selecting a gateway and preparing and sending an - * Intent to {@link se.leap.openvpn.LaunchVPN} - */ - private void startEIP() { - earlyRoutes(); - activeGateway = selectGateway(); + /** + * Initiates an EIP connection by selecting a gateway and preparing and sending an + * Intent to {@link se.leap.openvpn.LaunchVPN}. + * It also sets up early routes. + */ + private void startEIP() { + earlyRoutes(); + activeGateway = selectGateway(); - if(activeGateway != null && activeGateway.mVpnProfile != null) { - launchActiveGateway(); - } + if(activeGateway != null && activeGateway.mVpnProfile != null) { + launchActiveGateway(); } + } + /** + * Early routes are routes that block traffic until a new + * VpnService is started properly. + */ private void earlyRoutes() { Intent void_vpn_launcher = new Intent(context, VoidVpnLauncher.class); void_vpn_launcher.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(void_vpn_launcher); } + /** + * Choose a gateway to connect to based on timezone from system locale data + * + * @return The gateway to connect to + */ + private OVPNGateway selectGateway() { + String closest_location = closestGateway(); + String chosen_host = chooseHost(closest_location); + + return new OVPNGateway(chosen_host); + } + + private String closestGateway() { + TreeMap> offsets = calculateOffsets(); + return offsets.isEmpty() ? "" : offsets.firstEntry().getValue().iterator().next(); + } + + private TreeMap> calculateOffsets() { + TreeMap> offsets = new TreeMap>(); + + int localOffset = Calendar.getInstance().get(Calendar.ZONE_OFFSET) / 3600000; + + JSONObject locations = availableLocations(); + Iterator locations_names = locations.keys(); + while(locations_names.hasNext()) { + try { + String location_name = locations_names.next(); + JSONObject location = locations.getJSONObject(location_name); + + int dist = timezoneDistance(localOffset, location.optInt("timezone")); + + Set set = (offsets.get(dist) != null) ? + offsets.get(dist) : new HashSet(); + + set.add(location_name); + offsets.put(dist, set); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + return offsets; + } + + private JSONObject availableLocations() { + JSONObject locations = null; + try { + if(eipDefinition == null) updateEIPService(); + locations = eipDefinition.getJSONObject("locations"); + } catch (JSONException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + return locations; + } + + private int timezoneDistance(int local_timezone, int remote_timezone) { + // Distance along the numberline of Prime Meridian centric, assumes UTC-11 through UTC+12 + int dist = Math.abs(local_timezone - remote_timezone); + + // Farther than 12 timezones and it's shorter around the "back" + if (dist > 12) + dist = 12 - (dist -12); // Well i'll be. Absolute values make equations do funny things. + + return dist; + } + + private String chooseHost(String location) { + String chosen_host = ""; + try { + JSONArray gateways = eipDefinition.getJSONArray("gateways"); + for (int i = 0; i < gateways.length(); i++) { + JSONObject gw = gateways.getJSONObject(i); + if ( gw.getString("location").equalsIgnoreCase(location) || location.isEmpty()){ + chosen_host = eipDefinition.getJSONObject("locations").getJSONObject(gw.getString("location")).getString("name"); + break; + } + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return chosen_host; + } + private void launchActiveGateway() { Intent intent = new Intent(this,LaunchVPN.class); intent.setAction(Intent.ACTION_MAIN); @@ -208,30 +265,48 @@ public final class EIP extends IntentService { intent.putExtra(LaunchVPN.EXTRA_HIDELOG, true); intent.putExtra(RECEIVER_TAG, mReceiver); startActivity(intent); - mPending = ACTION_START_EIP; } - - /** - * Disconnects the EIP connection gracefully through the bound service or forcefully - * if there is no bound service. Sends a message to the requesting ResultReceiver. - */ - private void stopEIP() { - if(isConnected()) { - Intent disconnect_vpn = new Intent(this, DisconnectVPN.class); - disconnect_vpn.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(disconnect_vpn); - mIsDisconnecting = true; - lastConnectionStatusLevel = ConnectionStatus.UNKNOWN_LEVEL; // Wait for the decision of the user - Log.d(TAG, "mIsDisconnecting = true"); - } + + /** + * Disconnects the EIP connection gracefully through the bound service or forcefully + * if there is no bound service. Sends a message to the requesting ResultReceiver. + */ + private void stopEIP() { + if(isConnected()) { + Intent disconnect_vpn = new Intent(this, DisconnectVPN.class); + disconnect_vpn.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(disconnect_vpn); + mIsDisconnecting = true; + lastConnectionStatusLevel = ConnectionStatus.UNKNOWN_LEVEL; // Wait for the decision of the user + Log.d(TAG, "mIsDisconnecting = true"); + } - if (mReceiver != null){ - Bundle resultData = new Bundle(); - resultData.putString(REQUEST_TAG, ACTION_STOP_EIP); - mReceiver.send(Activity.RESULT_OK, resultData); - } + tellToReceiver(ACTION_STOP_EIP, Activity.RESULT_OK); + } + + private void tellToReceiver(String action, int resultCode) { + if (mReceiver != null){ + Bundle resultData = new Bundle(); + resultData.putString(REQUEST_TAG, action); + mReceiver.send(resultCode, resultData); } + } + + /** + * Checks the last stored status notified by ics-openvpn + * Sends Activity.RESULT_CANCELED to the ResultReceiver that made the + * request if it's not connected, Activity.RESULT_OK otherwise. + */ + + private void isRunning() { + int resultCode = Activity.RESULT_CANCELED; + boolean is_connected = isConnected(); + resultCode = (is_connected) ? Activity.RESULT_OK : Activity.RESULT_CANCELED; + + tellToReceiver(ACTION_IS_EIP_RUNNING, resultCode); + } + protected static boolean isConnected() { return lastConnectionStatusLevel != null && lastConnectionStatusLevel.equals(ConnectionStatus.LEVEL_CONNECTED) && !mIsDisconnecting; } @@ -263,70 +338,6 @@ public final class EIP extends IntentService { vpl.removeProfile(context, profiles[current_profile]); } } - /** - * Choose a gateway to connect to based on timezone from system locale data - * - * @return The gateway to connect to - */ - private OVPNGateway selectGateway() { - String closestLocation = closestGateway(); - - JSONArray gateways = null; - String chosenHost = null; - try { - gateways = eipDefinition.getJSONArray("gateways"); - for (int i = 0; i < gateways.length(); i++) { - JSONObject gw = gateways.getJSONObject(i); - if ( gw.getString("location").equalsIgnoreCase(closestLocation) || closestLocation.isEmpty()){ - chosenHost = eipDefinition.getJSONObject("locations").getJSONObject(gw.getString("location")).getString("name"); - break; - } - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - return new OVPNGateway(chosenHost); - } - - private String closestGateway() { - Calendar cal = Calendar.getInstance(); - int localOffset = cal.get(Calendar.ZONE_OFFSET) / 3600000; - TreeMap> offsets = new TreeMap>(); - JSONObject locationsObjects = null; - Iterator locations = null; - try { - locationsObjects = eipDefinition.getJSONObject("locations"); - locations = locationsObjects.keys(); - } catch (JSONException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - while (locations.hasNext()) { - String locationName = locations.next(); - JSONObject location = null; - try { - location = locationsObjects.getJSONObject(locationName); - - // Distance along the numberline of Prime Meridian centric, assumes UTC-11 through UTC+12 - int dist = Math.abs(localOffset - location.optInt("timezone")); - // Farther than 12 timezones and it's shorter around the "back" - if (dist > 12) - dist = 12 - (dist -12); // Well i'll be. Absolute values make equations do funny things. - - Set set = offsets.get(dist); - if (set == null) set = new HashSet(); - set.add(locationName); - offsets.put(dist, set); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - return offsets.isEmpty() ? "" : offsets.firstEntry().getValue().iterator().next(); - } /** * Walk the list of gateways defined in eip-service.json and parse them into -- cgit v1.2.3 From 5bb1d3baf93c76e7ec70a8abd5584c33f75383b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 9 Oct 2014 18:16:28 +0200 Subject: Check self-signed fingerprint. --- .../java/se/leap/bitmaskclient/LeapHttpClient.java | 77 ---------------------- .../main/java/se/leap/bitmaskclient/Provider.java | 1 + 2 files changed, 1 insertion(+), 77 deletions(-) delete mode 100644 app/src/main/java/se/leap/bitmaskclient/LeapHttpClient.java (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/LeapHttpClient.java b/app/src/main/java/se/leap/bitmaskclient/LeapHttpClient.java deleted file mode 100644 index 885b5105..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/LeapHttpClient.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - package se.leap.bitmaskclient; - -import java.security.KeyStore; - -import org.apache.http.conn.ClientConnectionManager; -import org.apache.http.conn.scheme.PlainSocketFactory; -import org.apache.http.conn.scheme.Scheme; -import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.ssl.SSLSocketFactory; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.SingleClientConnManager; -import android.content.Context; - -/** - * Implements an HTTP client, enabling LEAP Android app to manage its own runtime keystore or bypass default Android security measures. - * - * @author rafa - * - */ -public class LeapHttpClient extends DefaultHttpClient { - - private static LeapHttpClient client; - - /** - * If the class scope client is null, it creates one and imports, if existing, the main certificate from Shared Preferences. - * @param context - * @return the new client. - */ - public static LeapHttpClient getInstance(String cert_string) { - if(client == null) { - if(cert_string != null) { - ConfigHelper.addTrustedCertificate("provider_ca_certificate", cert_string); - } - } - return client; - } - - @Override - protected ClientConnectionManager createClientConnectionManager() { - SchemeRegistry registry = new SchemeRegistry(); - registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); - registry.register(new Scheme("https", newSslSocketFactory(), 443)); - - return new SingleClientConnManager(getParams(), registry); - } - - /** - * Uses keystore from ConfigHelper for the SSLSocketFactory. - * @return - */ - private SSLSocketFactory newSslSocketFactory() { - try { - KeyStore trusted = ConfigHelper.getKeystore(); - SSLSocketFactory sf = new SSLSocketFactory(trusted); - - return sf; - } catch (Exception e) { - throw new AssertionError(e); - } - } -} diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java index 5326709f..8d6385e0 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java @@ -52,6 +52,7 @@ public final class Provider implements Serializable { KEY = "provider", CA_CERT = "ca_cert", CA_CERT_URI = "ca_cert_uri", + CA_CERT_FINGERPRINT = "ca_cert_fingerprint", NAME = "name", DESCRIPTION = "description", DOMAIN = "domain", -- cgit v1.2.3 From be4879b5f19d9c736fa3bcefdfabbe119cd9391f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 10 Oct 2014 10:23:23 +0200 Subject: ProviderAPI refactoring. Authenticate and Register methods are now renamed and split. It's much more readable, the new emacs-default indentation helps to that too. --- app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java b/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java index 29b429d1..a953a710 100644 --- a/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java +++ b/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java @@ -63,15 +63,16 @@ public class LeapSRPSession { private static int A_LEN; + /** Creates a new SRP server session object from the username, password verifier, @param username, the user ID @param password, the user clear text password @param params, the SRP parameters for the session */ - public LeapSRPSession(String username, String password, SRPParameters params) + public LeapSRPSession(String username, String password) { - this(username, password, params, null); + this(username, password, null); } /** Creates a new SRP server session object from the username, password @@ -81,9 +82,9 @@ public class LeapSRPSession { @param params, the SRP parameters for the session @param abytes, the random exponent used in the A public key */ - public LeapSRPSession(String username, String password, SRPParameters params, - byte[] abytes) { - this.params = params; + public LeapSRPSession(String username, String password, byte[] abytes) { + + params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), ConfigHelper.G.toByteArray(), BigInteger.ZERO.toByteArray(), "SHA-256"); this.g = new BigInteger(1, params.g); N_bytes = ConfigHelper.trim(params.N); this.N = new BigInteger(1, N_bytes); @@ -159,7 +160,7 @@ public class LeapSRPSession { public byte[] calculateNewSalt() { try { BigInteger salt = new BigInteger(64, SecureRandom.getInstance("SHA1PRNG")); - return salt.toByteArray(); + return ConfigHelper.trim(salt.toByteArray()); } catch(NoSuchAlgorithmException e) { e.printStackTrace(); } -- cgit v1.2.3 From 11528c3f7124090ef44675cf613a949ed07ad9bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 14 Oct 2014 18:39:03 +0200 Subject: Start EIP after downloading an authed certificate. Always. Previously we didn't do so if EIP hadn't been started before. Fix a small bug introduced during latest refactoring, authentication did not work because the final result variable wasn't assigned. --- app/src/main/java/se/leap/bitmaskclient/Dashboard.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 761afc0a..16e4cf03 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -65,6 +65,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf public static final String START_ON_BOOT = "dashboard start on boot"; final public static String ON_BOOT = "dashboard on boot"; public static final String APP_VERSION = "bitmask version"; + final public static String TAG = Dashboard.class.getSimpleName(); private EipServiceFragment eipFragment; @@ -498,10 +499,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf changeStatusMessage(resultCode); if(mProgressBar != null) mProgressBar.setVisibility(ProgressBar.GONE); - if(EipServiceFragment.isEipSwitchChecked()) - eipStart(); - else - eipStatus.setText(R.string.eip_state_not_connected); + eipStart(); } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { setResult(RESULT_CANCELED); changeStatusMessage(resultCode); -- cgit v1.2.3 From 6bc3d7da8fdf32cdbd934831f2385f5098c7f979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 14 Oct 2014 22:14:08 +0200 Subject: Big refactor, ProviderAPI looks better. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 366 +++++++++------------ app/src/main/java/se/leap/bitmaskclient/EIP.java | 1 + .../se/leap/bitmaskclient/EipServiceFragment.java | 2 +- .../java/se/leap/bitmaskclient/LogInDialog.java | 15 +- .../bitmaskclient/ProviderAPIResultReceiver.java | 2 +- .../leap/bitmaskclient/SessionDialogInterface.java | 39 +++ .../java/se/leap/bitmaskclient/SignUpDialog.java | 11 +- 7 files changed, 212 insertions(+), 224 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 16e4cf03..286d88c3 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -75,8 +75,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf protected static SharedPreferences preferences; private static Provider provider; - private TextView providerNameTV; - private boolean authed_eip = false; public ProviderAPIResultReceiver providerAPI_result_receiver; @@ -143,7 +141,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf startService(updateEIP); buildDashboard(false); invalidateOptionsMenu(); - if(data != null && data.hasExtra(LogInDialog.VERB)) { + if(data != null && data.hasExtra(LogInDialog.TAG)) { View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); logInDialog(Bundle.EMPTY); } @@ -190,7 +188,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf setContentView(R.layout.client_dashboard); - providerNameTV = (TextView) findViewById(R.id.providerName); + TextView providerNameTV = (TextView) findViewById(R.id.providerName); providerNameTV.setText(provider.getDomain()); providerNameTV.setTextSize(28); @@ -269,14 +267,13 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf startActivityForResult(new Intent(this,ConfigurationWizard.class), SWITCH_PROVIDER); return true; case R.id.login_button: - View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); logInDialog(Bundle.EMPTY); return true; case R.id.logout_button: logOut(); return true; case R.id.signup_button: - signUpDialog(((ViewGroup)findViewById(android.R.id.content)).getChildAt(0), Bundle.EMPTY); + signUpDialog(Bundle.EMPTY); return true; default: return super.onOptionsItemSelected(item); @@ -284,38 +281,59 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } - @Override - public void authenticate(String username, String password) { - mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - eipStatus = (TextView) findViewById(R.id.eipStatus); + private Intent prepareProviderAPICommand() { + mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); + eipStatus = (TextView) findViewById(R.id.eipStatus); - providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); - providerAPI_result_receiver.setReceiver(this); + providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); + providerAPI_result_receiver.setReceiver(this); - Intent provider_API_command = new Intent(this, ProviderAPI.class); - - Bundle parameters = new Bundle(); - parameters.putString(LogInDialog.USERNAME, username); - parameters.putString(LogInDialog.PASSWORD, password); + Intent command = new Intent(this, ProviderAPI.class); - JSONObject provider_json; - try { - provider_json = new JSONObject(preferences.getString(Provider.KEY, "")); - parameters.putString(Provider.API_URL, provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION)); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); + return command; + } - provider_API_command.setAction(ProviderAPI.SRP_AUTH); - provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); - provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); - - mProgressBar.setVisibility(ProgressBar.VISIBLE); - eipStatus.setText(R.string.authenticating_message); - //mProgressBar.setMax(4); - startService(provider_API_command); + private FragmentTransaction removePreviousFragment(String tag) { + FragmentTransaction transaction = getFragmentManager().beginTransaction(); + Fragment previous_fragment = getFragmentManager().findFragmentByTag(tag); + if (previous_fragment != null) { + transaction.remove(previous_fragment); } + transaction.addToBackStack(null); + + return transaction; + } + + /** + * Shows the log in dialog. + */ + public void logInDialog(Bundle resultData) { + FragmentTransaction transaction = removePreviousFragment(LogInDialog.TAG); + + DialogFragment newFragment = LogInDialog.newInstance(); + if(resultData != null && !resultData.isEmpty()) + newFragment.setArguments(resultData); + newFragment.show(transaction, LogInDialog.TAG); + } + + @Override + public void logIn(String username, String password) { + Intent provider_API_command = prepareProviderAPICommand(); + Bundle parameters = provider_API_command.getExtras().getBundle(ProviderAPI.PARAMETERS); + if(parameters == null) + parameters = new Bundle(); + + parameters.putString(SessionDialogInterface.USERNAME, username); + parameters.putString(SessionDialogInterface.PASSWORD, password); + + mProgressBar.setVisibility(ProgressBar.VISIBLE); + eipStatus.setText(R.string.authenticating_message); + + provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); + provider_API_command.setAction(ProviderAPI.SRP_AUTH); + startService(provider_API_command); + } public void cancelAuthedEipOn() { EipServiceFragment eipFragment = (EipServiceFragment) getFragmentManager().findFragmentByTag(EipServiceFragment.TAG); @@ -323,125 +341,59 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } public void cancelLoginOrSignup() { - if(mProgressBar == null) mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - if(mProgressBar != null) { - mProgressBar.setVisibility(ProgressBar.GONE); - if(eipStatus == null) eipStatus = (TextView) findViewById(R.id.eipStatus); - if(eipStatus != null) eipStatus.setText(""); - } - cancelAuthedEipOn(); + hideProgressBar(); } - /** - * Asks ProviderAPI to log out. - */ - public void logOut() { - providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); - providerAPI_result_receiver.setReceiver(this); - Intent provider_API_command = new Intent(this, ProviderAPI.class); - - Bundle parameters = new Bundle(); - - JSONObject provider_json; - try { - provider_json = new JSONObject(preferences.getString(Provider.KEY, "")); - parameters.putString(Provider.API_URL, provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION)); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - provider_API_command.setAction(ProviderAPI.LOG_OUT); - provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); - provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); - - if(mProgressBar == null) mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - mProgressBar.setVisibility(ProgressBar.VISIBLE); - if(eipStatus == null) eipStatus = (TextView) findViewById(R.id.eipStatus); - eipStatus.setText(R.string.logout_message); - // eipStatus.setText("Starting to logout"); - - startService(provider_API_command); - //mProgressBar.setMax(1); - - } - - /** - * Shows the log in dialog. - */ - public void logInDialog(Bundle resultData) { - Log.d("Dashboard", "Log In Dialog"); - FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); - Fragment previous_log_in_dialog = getFragmentManager().findFragmentByTag(LogInDialog.TAG); - if (previous_log_in_dialog != null) { - fragment_transaction.remove(previous_log_in_dialog); - } - fragment_transaction.addToBackStack(null); - - DialogFragment newFragment = LogInDialog.newInstance(); - if(resultData != null && !resultData.isEmpty()) { - newFragment.setArguments(resultData); - } - newFragment.show(fragment_transaction, LogInDialog.TAG); - } - - @Override - public void signUp(String username, String password) { - mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - eipStatus = (TextView) findViewById(R.id.eipStatus); - - providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); - providerAPI_result_receiver.setReceiver(this); - - Intent provider_API_command = new Intent(this, ProviderAPI.class); - - Bundle parameters = new Bundle(); - parameters.putString(SignUpDialog.USERNAME, username); - parameters.putString(SignUpDialog.PASSWORD, password); - - JSONObject provider_json; - try { - provider_json = new JSONObject(preferences.getString(Provider.KEY, "")); - parameters.putString(Provider.API_URL, provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION)); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - provider_API_command.setAction(ProviderAPI.SRP_REGISTER); - provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); - provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); + /** + * Asks ProviderAPI to log out. + */ + public void logOut() { + Intent provider_API_command = prepareProviderAPICommand(); + + if(mProgressBar == null) mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); + mProgressBar.setVisibility(ProgressBar.VISIBLE); + if(eipStatus == null) eipStatus = (TextView) findViewById(R.id.eipStatus); + eipStatus.setText(R.string.logout_message); - mProgressBar.setVisibility(ProgressBar.VISIBLE); - eipStatus.setText(R.string.signingup_message); - //mProgressBar.setMax(4); - startService(provider_API_command); - } + provider_API_command.setAction(ProviderAPI.LOG_OUT); + startService(provider_API_command); + } - /** - * Shows the sign up dialog. - * @param view from which the dialog is created. - */ - public void signUpDialog(View view, Bundle resultData) { - FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); - Fragment previous_sign_up_dialog = getFragmentManager().findFragmentByTag(SignUpDialog.TAG); - if (previous_sign_up_dialog != null) { - fragment_transaction.remove(previous_sign_up_dialog); - } - fragment_transaction.addToBackStack(null); - - DialogFragment newFragment = SignUpDialog.newInstance(); - if(resultData != null && !resultData.isEmpty()) { - newFragment.setArguments(resultData); - } - newFragment.show(fragment_transaction, SignUpDialog.TAG); + /** + * Shows the sign up dialog. + */ + public void signUpDialog(Bundle resultData) { + FragmentTransaction transaction = removePreviousFragment(SignUpDialog.TAG); + + DialogFragment newFragment = SignUpDialog.newInstance(); + if(resultData != null && !resultData.isEmpty()) { + newFragment.setArguments(resultData); } + newFragment.show(transaction, SignUpDialog.TAG); + } + + @Override + public void signUp(String username, String password) { + Intent provider_API_command = prepareProviderAPICommand(); + Bundle parameters = provider_API_command.getExtras().getBundle(ProviderAPI.PARAMETERS); + if(parameters == null) + parameters = new Bundle(); + + parameters.putString(SessionDialogInterface.USERNAME, username); + parameters.putString(SessionDialogInterface.PASSWORD, password); + + mProgressBar.setVisibility(ProgressBar.VISIBLE); + eipStatus.setText(R.string.signingup_message); + + provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); + provider_API_command.setAction(ProviderAPI.SRP_REGISTER); + startService(provider_API_command); + } /** * Asks ProviderAPI to download an authenticated OpenVPN certificate. - * @param session_id cookie for the server to allow us to download the certificate. */ - private void downloadAuthedUserCertificate(/*Cookie session_id*/) { + private void downloadAuthedUserCertificate() { providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); providerAPI_result_receiver.setReceiver(this); @@ -449,8 +401,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf Bundle parameters = new Bundle(); parameters.putString(ConfigurationWizard.TYPE_OF_CERTIFICATE, ConfigurationWizard.AUTHED_CERTIFICATE); - /*parameters.putString(ConfigHelper.SESSION_ID_COOKIE_KEY, session_id.getName()); - parameters.putString(ConfigHelper.SESSION_ID_KEY, session_id.getValue());*/ provider_API_command.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); @@ -461,50 +411,55 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf @Override public void onReceiveResult(int resultCode, Bundle resultData) { - if(resultCode == ProviderAPI.SRP_REGISTRATION_SUCCESSFUL){ - authenticate(resultData.getString(LogInDialog.USERNAME), resultData.getString(LogInDialog.PASSWORD)); - } else if(resultCode == ProviderAPI.SRP_REGISTRATION_FAILED){ - signUpDialog(((ViewGroup)findViewById(android.R.id.content)).getChildAt(0), resultData); - } else if(resultCode == ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL){ - String session_id_cookie_key = resultData.getString(ProviderAPI.SESSION_ID_COOKIE_KEY); - String session_id_string = resultData.getString(ProviderAPI.SESSION_ID_KEY); - setResult(RESULT_OK); - - authed_eip = true; - preferences.edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); - - invalidateOptionsMenu(); - mProgressBar.setVisibility(ProgressBar.GONE); - changeStatusMessage(resultCode); + if(resultCode == ProviderAPI.SRP_REGISTRATION_SUCCESSFUL) { + String username = resultData.getString(SessionDialogInterface.USERNAME); + String password = resultData.getString(SessionDialogInterface.PASSWORD); + logIn(username, password); + } else if(resultCode == ProviderAPI.SRP_REGISTRATION_FAILED) { + changeStatusMessage(resultCode); + hideProgressBar(); + + signUpDialog(resultData); + } else if(resultCode == ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL) { + changeStatusMessage(resultCode); + hideProgressBar(); + + invalidateOptionsMenu(); + + authed_eip = true; + preferences.edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); - //Cookie session_id = new BasicClientCookie(session_id_cookie_key, session_id_string); - downloadAuthedUserCertificate(/*session_id*/); - } else if(resultCode == ProviderAPI.SRP_AUTHENTICATION_FAILED) { - logInDialog(resultData); - } else if(resultCode == ProviderAPI.LOGOUT_SUCCESSFUL) { - authed_eip = false; - preferences.edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); - mProgressBar.setVisibility(ProgressBar.GONE); - mProgressBar.setProgress(0); - invalidateOptionsMenu(); - setResult(RESULT_OK); - changeStatusMessage(resultCode); - - } else if(resultCode == ProviderAPI.LOGOUT_FAILED) { - setResult(RESULT_CANCELED); - changeStatusMessage(resultCode); - mProgressBar.setVisibility(ProgressBar.GONE); - } else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) { - setResult(RESULT_OK); + downloadAuthedUserCertificate(); + } else if(resultCode == ProviderAPI.SRP_AUTHENTICATION_FAILED) { + changeStatusMessage(resultCode); + hideProgressBar(); + + logInDialog(resultData); + } else if(resultCode == ProviderAPI.LOGOUT_SUCCESSFUL) { + changeStatusMessage(resultCode); + hideProgressBar(); + + invalidateOptionsMenu(); + + authed_eip = false; + preferences.edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); + + } else if(resultCode == ProviderAPI.LOGOUT_FAILED) { + changeStatusMessage(resultCode); + hideProgressBar(); + + setResult(RESULT_CANCELED); + } else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) { changeStatusMessage(resultCode); - if(mProgressBar != null) - mProgressBar.setVisibility(ProgressBar.GONE); + hideProgressBar(); + + setResult(RESULT_OK); eipStart(); - } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { - setResult(RESULT_CANCELED); + } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { changeStatusMessage(resultCode); - mProgressBar.setVisibility(ProgressBar.GONE); - } + hideProgressBar(); + setResult(RESULT_CANCELED); + } } private void changeStatusMessage(final int previous_result_code) { @@ -513,6 +468,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf protected void onReceiveResult(int resultCode, Bundle resultData){ super.onReceiveResult(resultCode, resultData); String request = resultData.getString(EIP.REQUEST_TAG); + if(eipStatus == null) eipStatus = (TextView) findViewById(R.id.eipStatus); if (request.equalsIgnoreCase(EIP.ACTION_IS_EIP_RUNNING)){ if (resultCode == Activity.RESULT_OK){ @@ -532,6 +488,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf case ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL: eipStatus.setText(R.string.succesful_authentication_message); break; case ProviderAPI.SRP_AUTHENTICATION_FAILED: eipStatus.setText(R.string.authentication_failed_message); break; + case ProviderAPI.SRP_REGISTRATION_FAILED: eipStatus.setText(R.string.registration_failed_message); break; case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE: break; case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: eipStatus.setText(R.string.incorrectly_downloaded_certificate_message); break; case ProviderAPI.LOGOUT_SUCCESSFUL: eipStatus.setText(R.string.logged_out_message); break; @@ -545,6 +502,14 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf eipIsRunning(eip_status_receiver); } + private void hideProgressBar() { + if(mProgressBar == null) + mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); + + mProgressBar.setProgress(0); + mProgressBar.setVisibility(ProgressBar.GONE); + } + /** * For retrieving the base application Context in classes that don't extend * Android's Activity class @@ -556,11 +521,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } - @Override + @Override public void startActivityForResult(Intent intent, int requestCode) { intent.putExtra(Dashboard.REQUEST_CODE, requestCode); super.startActivityForResult(intent, requestCode); } + /** * Send a command to EIP * @@ -575,30 +541,22 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf startService(eip_intent); } - /** - * Send a command to EIP - * - */ - private void eipStop(){ - // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? - Intent eip_intent = new Intent(this, EIP.class); - eip_intent.setAction(EIP.ACTION_STOP_EIP); - // eip_intent.putExtra(EIP.RECEIVER_TAG, eip_receiver);fi - startService(eip_intent); - - } + private void eipStop(){ + // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? + Intent eip_intent = new Intent(this, EIP.class); + eip_intent.setAction(EIP.ACTION_STOP_EIP); + startService(eip_intent); + } - private void eipStart(){ + private void eipStart() { Intent eip_intent = new Intent(this, EIP.class); eip_intent.setAction(EIP.ACTION_START_EIP); - eip_intent.putExtra(EIP.RECEIVER_TAG, EipServiceFragment.getReceiver()); - startService(eip_intent); - + startService(eip_intent); } - protected void setProgressBarVisibility(int visibility) { + protected void showProgressBar() { if(mProgressBar == null) mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - mProgressBar.setVisibility(visibility); + mProgressBar.setVisibility(ProgressBar.VISIBLE); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 4a8bae46..1b34ac21 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -155,6 +155,7 @@ public final class EIP extends IntentService { activeGateway = selectGateway(); if(activeGateway != null && activeGateway.mVpnProfile != null) { + mReceiver = EipServiceFragment.getReceiver(); launchActiveGateway(); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 18ee0262..57e009dc 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -380,7 +380,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe case Activity.RESULT_CANCELED: Dashboard dashboard = (Dashboard) getActivity(); - dashboard.setProgressBarVisibility(ProgressBar.VISIBLE); + dashboard.showProgressBar(); String status = getResources().getString(R.string.updating_certificate_message); setEipStatus(status); diff --git a/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java b/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java index 45d3a373..5a0c9a6d 100644 --- a/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/LogInDialog.java @@ -42,15 +42,10 @@ import android.widget.TextView; * @author parmegv * */ -public class LogInDialog extends DialogFragment { +public class LogInDialog extends SessionDialogInterface { - final public static String TAG = "logInDialog"; - final public static String VERB = "log in"; - final public static String USERNAME = "username"; - final public static String PASSWORD = "password"; - final public static String USERNAME_MISSING = "username missing"; - final public static String PASSWORD_INVALID_LENGTH = "password_invalid_length"; + final public static String TAG = LogInDialog.class.getSimpleName(); private static boolean is_eip_pending = false; @@ -93,7 +88,7 @@ public class LogInDialog extends DialogFragment { String username = username_field.getText().toString(); String password = password_field.getText().toString(); dialog.dismiss(); - interface_with_Dashboard.authenticate(username, password); + interface_with_Dashboard.logIn(username, password); } }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { @@ -120,7 +115,7 @@ public class LogInDialog extends DialogFragment { * */ public interface LogInDialogInterface { - public void authenticate(String username, String password); + public void logIn(String username, String password); public void cancelAuthedEipOn(); public void signUp(String username, String password); public void cancelLoginOrSignup(); @@ -149,8 +144,8 @@ public class LogInDialog extends DialogFragment { @Override public void onCancel(DialogInterface dialog) { + super.onCancel(dialog); if(is_eip_pending) interface_with_Dashboard.cancelAuthedEipOn(); - super.onCancel(dialog); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderAPIResultReceiver.java b/app/src/main/java/se/leap/bitmaskclient/ProviderAPIResultReceiver.java index 7b256124..7e4e95d3 100644 --- a/app/src/main/java/se/leap/bitmaskclient/ProviderAPIResultReceiver.java +++ b/app/src/main/java/se/leap/bitmaskclient/ProviderAPIResultReceiver.java @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - package se.leap.bitmaskclient; +package se.leap.bitmaskclient; import android.os.Bundle; import android.os.Handler; diff --git a/app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java b/app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java new file mode 100644 index 00000000..7b08a4d1 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/SessionDialogInterface.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2013 LEAP Encryption Access Project and contributers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package se.leap.bitmaskclient; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.DialogFragment; +import android.content.DialogInterface; +import android.os.Bundle; + +/** + * @author parmegv + */ +public abstract class SessionDialogInterface extends DialogFragment { + final public static String USERNAME = "username"; + final public static String PASSWORD = "password"; + final public static String USERNAME_MISSING = "username missing"; + final public static String PASSWORD_INVALID_LENGTH = "password_invalid_length"; + + @Override + public void onAttach(Activity activity) { super.onAttach(activity); } + + @Override + public void onCancel(DialogInterface dialog) { super.onCancel(dialog); } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java b/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java index 120d4eec..3cb41f4f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java @@ -42,14 +42,9 @@ import android.widget.TextView; * @author parmegv * */ -public class SignUpDialog extends DialogFragment { - - final public static String TAG = "signUpDialog"; - final public static String VERB = "log in"; - final public static String USERNAME = "username"; - final public static String PASSWORD = "password"; - final public static String USERNAME_MISSING = "username missing"; - final public static String PASSWORD_INVALID_LENGTH = "password_invalid_length"; +public class SignUpDialog extends SessionDialogInterface { + + final public static String TAG = SignUpDialog.class.getSimpleName(); private static boolean is_eip_pending = false; -- cgit v1.2.3 From 5e1d89482034c94f22547a12298bdf956761c0ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 16 Oct 2014 10:22:27 +0200 Subject: Move blocking code to thread's run. --- .../java/se/leap/bitmaskclient/VoidVpnService.java | 36 +++++++++------------- 1 file changed, 15 insertions(+), 21 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java index b7289c23..7b597554 100644 --- a/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java +++ b/app/src/main/java/se/leap/bitmaskclient/VoidVpnService.java @@ -1,10 +1,11 @@ package se.leap.bitmaskclient; import android.content.Intent; +import android.os.Process; import android.net.VpnService; import android.util.Log; -public class VoidVpnService extends VpnService { +public class VoidVpnService extends VpnService { static final String START_BLOCKING_VPN_PROFILE = "se.leap.bitmaskclient.START_BLOCKING_VPN_PROFILE"; static final String TAG = VoidVpnService.class.getSimpleName(); @@ -14,29 +15,22 @@ public class VoidVpnService extends VpnService { String action = intent.getAction(); if (action == START_BLOCKING_VPN_PROFILE) { new Thread(new Runnable() { - public void run() { - blockConnections(); + public void run() { + Builder builder = new Builder(); + builder.setSession("Blocking until running"); + builder.addAddress("10.42.0.8",16); + builder.addRoute("0.0.0.0", 1); + builder.addRoute("192.168.1.0", 24); + builder.addDnsServer("10.42.0.1"); + try { + builder.establish(); + } catch (Exception e) { + e.printStackTrace(); + } + android.util.Log.d(TAG, "VoidVpnService set up"); } }).run(); } return 0; } - - public void blockConnections() { - Builder builder = new Builder(); - builder.setSession("Blocking until running"); - builder.addAddress("10.42.0.8",16); - builder.addRoute("0.0.0.0", 1); - builder.addRoute("128.0.0.0", 1); - builder.addRoute("192.168.1.0", 24); - builder.addDnsServer("10.42.0.1"); - builder.establish(); - android.util.Log.d(TAG, "VoidVpnService set up"); - try { - new java.net.Socket("sdf.org", 80); - Log.d(TAG, "VoidVpnService doesn's stop traffic"); - } catch (Exception e) { - e.printStackTrace(); - } - } } -- cgit v1.2.3 From 575bc1293070bfa90ed3ba0f558e564b1fc2c9e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 16 Oct 2014 18:41:57 +0200 Subject: A bit of refactoring for ConfigurationWizard. Fix a typo in the debug source of ProviderAPI. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 25 ++++------- .../bitmaskclient/FragmentManagerEnhanced.java | 51 ++++++++++++++++++++++ 2 files changed, 59 insertions(+), 17 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/FragmentManagerEnhanced.java (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 286d88c3..d80755aa 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -21,13 +21,14 @@ import org.json.JSONObject; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver; +import se.leap.bitmaskclient.FragmentManagerEnhanced; import se.leap.bitmaskclient.SignUpDialog; + import de.blinkt.openvpn.activities.LogWindow; + import android.app.Activity; import android.app.AlertDialog; import android.app.DialogFragment; -import android.app.Fragment; -import android.app.FragmentManager; import android.app.FragmentTransaction; import android.content.Context; import android.content.DialogInterface; @@ -78,6 +79,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf private boolean authed_eip = false; public ProviderAPIResultReceiver providerAPI_result_receiver; + private FragmentManagerEnhanced fragment_manager; @Override protected void onCreate(Bundle savedInstanceState) { @@ -90,6 +92,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); + fragment_manager = new FragmentManagerEnhanced(getFragmentManager()); handleVersion(); authed_eip = preferences.getBoolean(EIP.AUTHED_EIP, false); @@ -194,7 +197,6 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - FragmentManager fragMan = getFragmentManager(); if ( provider.hasEIP()){ eipFragment = new EipServiceFragment(); if (hide_and_turn_on_eip) { @@ -203,7 +205,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf arguments.putBoolean(EipServiceFragment.START_ON_BOOT, true); eipFragment.setArguments(arguments); } - fragMan.beginTransaction().replace(R.id.servicesCollection, eipFragment, EipServiceFragment.TAG).commit(); + fragment_manager.replace(R.id.servicesCollection, eipFragment, EipServiceFragment.TAG); if (hide_and_turn_on_eip) { onBackPressed(); @@ -293,23 +295,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); return command; } - - private FragmentTransaction removePreviousFragment(String tag) { - FragmentTransaction transaction = getFragmentManager().beginTransaction(); - Fragment previous_fragment = getFragmentManager().findFragmentByTag(tag); - if (previous_fragment != null) { - transaction.remove(previous_fragment); - } - transaction.addToBackStack(null); - - return transaction; - } /** * Shows the log in dialog. */ public void logInDialog(Bundle resultData) { - FragmentTransaction transaction = removePreviousFragment(LogInDialog.TAG); + FragmentTransaction transaction = fragment_manager.removePreviousFragment(LogInDialog.TAG); DialogFragment newFragment = LogInDialog.newInstance(); if(resultData != null && !resultData.isEmpty()) @@ -363,7 +354,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf * Shows the sign up dialog. */ public void signUpDialog(Bundle resultData) { - FragmentTransaction transaction = removePreviousFragment(SignUpDialog.TAG); + FragmentTransaction transaction = fragment_manager.removePreviousFragment(SignUpDialog.TAG); DialogFragment newFragment = SignUpDialog.newInstance(); if(resultData != null && !resultData.isEmpty()) { diff --git a/app/src/main/java/se/leap/bitmaskclient/FragmentManagerEnhanced.java b/app/src/main/java/se/leap/bitmaskclient/FragmentManagerEnhanced.java new file mode 100644 index 00000000..c4844be9 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/FragmentManagerEnhanced.java @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2013 LEAP Encryption Access Project and contributers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package se.leap.bitmaskclient; + +import android.app.Fragment; +import android.app.FragmentManager; +import android.app.FragmentTransaction; + +public class FragmentManagerEnhanced { + + private FragmentManager generic_fragment_manager; + + public FragmentManagerEnhanced(FragmentManager generic_fragment_manager) { + this.generic_fragment_manager = generic_fragment_manager; + } + + public FragmentTransaction removePreviousFragment(String tag) { + FragmentTransaction transaction = generic_fragment_manager.beginTransaction(); + Fragment previous_fragment = generic_fragment_manager.findFragmentByTag(tag); + if (previous_fragment != null) { + transaction.remove(previous_fragment); + } + transaction.addToBackStack(null); + + return transaction; + } + + public void replace(int containerViewId, Fragment fragment, String tag) { + FragmentTransaction transaction = generic_fragment_manager.beginTransaction(); + + transaction.replace(containerViewId, fragment, tag).commit(); + } + + public Fragment findFragmentByTag(String tag) { + return generic_fragment_manager.findFragmentByTag(tag); + } +} -- cgit v1.2.3 From e54f0cf39cce1c27b7baca77d777c7c271e4d108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 4 Nov 2014 00:20:31 +0100 Subject: Don't update eip service oncreate eip. Reuse EipServiceFragment's stopEip and startEipFromScratch in Dashboard. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 63 +++++++++++----------- app/src/main/java/se/leap/bitmaskclient/EIP.java | 26 ++++----- .../se/leap/bitmaskclient/EipServiceFragment.java | 7 ++- 3 files changed, 50 insertions(+), 46 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index d80755aa..3ae1d81a 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -213,31 +213,35 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } } - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - JSONObject provider_json; - try { - provider_json = new JSONObject(preferences.getString(Provider.KEY, "")); - JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE); - boolean authed_eip = preferences.getBoolean(EIP.AUTHED_EIP, false); - boolean allow_registered_eip = service_description.getBoolean(Provider.ALLOW_REGISTRATION); - preferences.edit().putBoolean(EIP.ALLOWED_REGISTERED, allow_registered_eip); - if(allow_registered_eip) { - if(authed_eip) { - menu.findItem(R.id.login_button).setVisible(false); - menu.findItem(R.id.logout_button).setVisible(true); - } else { - menu.findItem(R.id.login_button).setVisible(true); - menu.findItem(R.id.logout_button).setVisible(false); - } - menu.findItem(R.id.signup_button).setVisible(true); - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return true; + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + JSONObject provider_json; + try { + String provider_json_string = preferences.getString(Provider.KEY, ""); + if(provider_json_string.isEmpty() == false) { + provider_json = new JSONObject(provider_json_string); + JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE); + boolean authed_eip = preferences.getBoolean(EIP.AUTHED_EIP, false); + boolean allow_registered_eip = service_description.getBoolean(Provider.ALLOW_REGISTRATION); + preferences.edit().putBoolean(EIP.ALLOWED_REGISTERED, allow_registered_eip); + + if(allow_registered_eip) { + if(authed_eip) { + menu.findItem(R.id.login_button).setVisible(false); + menu.findItem(R.id.logout_button).setVisible(true); + } else { + menu.findItem(R.id.login_button).setVisible(true); + menu.findItem(R.id.logout_button).setVisible(false); + } + menu.findItem(R.id.signup_button).setVisible(true); + } + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } + return true; + } @Override public boolean onCreateOptionsMenu(Menu menu) { @@ -533,16 +537,13 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } private void eipStop(){ - // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? - Intent eip_intent = new Intent(this, EIP.class); - eip_intent.setAction(EIP.ACTION_STOP_EIP); - startService(eip_intent); + EipServiceFragment eipFragment = (EipServiceFragment) getFragmentManager().findFragmentByTag(EipServiceFragment.TAG); + eipFragment.stopEIP(); } private void eipStart() { - Intent eip_intent = new Intent(this, EIP.class); - eip_intent.setAction(EIP.ACTION_START_EIP); - startService(eip_intent); + EipServiceFragment eipFragment = (EipServiceFragment) getFragmentManager().findFragmentByTag(EipServiceFragment.TAG); + eipFragment.startEipFromScratch(); } protected void showProgressBar() { diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 1b34ac21..a2a06fbd 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -87,7 +87,7 @@ public final class EIP extends IntentService { public final static String SERVICE_API_PATH = "config/eip-service.json"; public final static String RECEIVER_TAG = "receiverTag"; public final static String REQUEST_TAG = "requestTag"; - public final static String TAG = "se.leap.bitmaskclient.EIP"; + public final static String TAG = EIP.class.getSimpleName(); public final static SimpleDateFormat certificate_date_format = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); @@ -113,8 +113,9 @@ public final class EIP extends IntentService { super.onCreate(); context = getApplicationContext(); - - updateEIPService(); + + // Log.d(TAG, "Update EIP Service onCreate EIP"); + // updateEIPService(); } @Override @@ -130,7 +131,7 @@ public final class EIP extends IntentService { protected void onHandleIntent(Intent intent) { String action = intent.getAction(); mReceiver = intent.getParcelableExtra(RECEIVER_TAG); - + if ( action == ACTION_START_EIP ) startEIP(); else if ( action == ACTION_STOP_EIP ) @@ -319,8 +320,11 @@ public final class EIP extends IntentService { */ private void updateEIPService() { try { - eipDefinition = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(KEY, "")); - parsedEipSerial = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getInt(PARSED_SERIAL, 0); + String eip_definition_string = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(KEY, ""); + if(eip_definition_string.isEmpty() == false) { + eipDefinition = new JSONObject(eip_definition_string); + } + parsedEipSerial = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getInt(PARSED_SERIAL, 0); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -328,16 +332,14 @@ public final class EIP extends IntentService { if(parsedEipSerial == 0) { deleteAllVpnProfiles(); } - if (eipDefinition != null && eipDefinition.optInt("serial") > parsedEipSerial) + if (eipDefinition != null && eipDefinition.optInt("serial") >= parsedEipSerial) updateGateways(); } private void deleteAllVpnProfiles() { ProfileManager vpl = ProfileManager.getInstance(context); - VpnProfile[] profiles = (VpnProfile[]) vpl.getProfiles().toArray(new VpnProfile[vpl.getProfiles().size()]); - for (int current_profile = 0; current_profile < profiles.length; current_profile++){ - vpl.removeProfile(context, profiles[current_profile]); - } + Collection profiles = vpl.getProfiles(); + profiles.removeAll(profiles); } /** @@ -347,7 +349,6 @@ public final class EIP extends IntentService { */ private void updateGateways(){ JSONArray gatewaysDefined = null; - try { gatewaysDefined = eipDefinition.getJSONArray("gateways"); for ( int i=0 ; i < gatewaysDefined.length(); i++ ){ @@ -361,7 +362,6 @@ public final class EIP extends IntentService { // TODO Auto-generated catch block e.printStackTrace(); } - getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putInt(PARSED_SERIAL, eipDefinition.optInt(Provider.API_RETURN_SERIAL)).commit(); } diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 57e009dc..a7d68198 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -195,7 +195,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe eipCommand(EIP.ACTION_START_EIP); } - private void stopEIP() { + protected void stopEIP() { EIP.mIsStarting = false; View eipProgressBar = getActivity().findViewById(R.id.eipProgress); if(eipProgressBar != null) @@ -236,7 +236,8 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe } else if(justDecidedOnDisconnect && level == ConnectionStatus.LEVEL_CONNECTED) { EIP.lastConnectionStatusLevel = ConnectionStatus.LEVEL_NOTCONNECTED; updateState(state, logmessage, localizedResId, level); - } + } // else if(isNewLevel || level == ConnectionStatus.LEVEL_AUTH_FAILED) + // handleNewState(state, logmessage, localizedResId, level); } private void handleNewState(final String state, final String logmessage, final int localizedResId, final ConnectionStatus level) { @@ -248,6 +249,8 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe setNoServerReplyUI(localizedResId, logmessage); else if (level == ConnectionStatus.LEVEL_CONNECTING_SERVER_REPLIED) setServerReplyUI(state, localizedResId, logmessage); + // else if (level == ConnectionStatus.LEVEL_AUTH_FAILED) + // handleSwitchOn(); } private boolean isDisconnectedLevel(final ConnectionStatus level) { -- cgit v1.2.3 From a137eccdde9349dc52b29fdadcb44cf317465c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 4 Nov 2014 18:46:27 +0100 Subject: Gradle 2.1 and retry connection on auth-failure --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 1 + 1 file changed, 1 insertion(+) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index a2a06fbd..cf02f32f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -484,6 +484,7 @@ public final class EIP extends IntentService { cp.parseConfig(new StringReader(certSecretFromSharedPreferences())); cp.parseConfig(new StringReader("remote-cert-tls server")); cp.parseConfig(new StringReader("persist-tun")); + cp.parseConfig(new StringReader("auth-retry nointeract")); VpnProfile vp = cp.convertProfile(); //vp.mAuthenticationType=VpnProfile.TYPE_STATICKEYS; mVpnProfile = vp; -- cgit v1.2.3 From 195f0bc8f11792781bb828b0ff088314de322e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 4 Nov 2014 19:22:18 +0100 Subject: Rebuild profiles on versionCode 94. --- app/src/main/java/se/leap/bitmaskclient/Dashboard.java | 2 ++ app/src/main/java/se/leap/bitmaskclient/EIP.java | 1 + 2 files changed, 3 insertions(+) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 3ae1d81a..547e4179 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -112,11 +112,13 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf switch(versionCode) { case 91: // 0.6.0 without Bug #5999 + case 94: // 0.8.0 with if(!preferences.getString(EIP.KEY, "").isEmpty()) { Intent rebuildVpnProfiles = new Intent(getApplicationContext(), EIP.class); rebuildVpnProfiles.setAction(EIP.ACTION_REBUILD_PROFILES); startService(rebuildVpnProfiles); } + break; } } catch (NameNotFoundException e) { } diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index cf02f32f..ad7552c8 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -350,6 +350,7 @@ public final class EIP extends IntentService { private void updateGateways(){ JSONArray gatewaysDefined = null; try { + if(eipDefinition == null) updateEIPService(); gatewaysDefined = eipDefinition.getJSONArray("gateways"); for ( int i=0 ; i < gatewaysDefined.length(); i++ ){ JSONObject gw = null; -- cgit v1.2.3 From 5304543ebd60778ad46123cd63142e27627fa150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 4 Nov 2014 20:45:42 +0100 Subject: Update ics-openvpn to rev 906. --- app/src/main/java/de/blinkt/openvpn/LaunchVPN.java | 39 +++++++------- .../main/java/de/blinkt/openvpn/VpnProfile.java | 62 +++++++++++++++++----- .../blinkt/openvpn/activities/DisconnectVPN.java | 5 ++ .../de/blinkt/openvpn/activities/LogWindow.java | 5 ++ .../main/java/de/blinkt/openvpn/core/CIDRIP.java | 5 ++ .../java/de/blinkt/openvpn/core/ConfigParser.java | 12 ++++- .../blinkt/openvpn/core/DeviceStateReceiver.java | 5 ++ .../blinkt/openvpn/core/ICSOpenVPNApplication.java | 5 ++ .../java/de/blinkt/openvpn/core/NativeUtils.java | 5 ++ .../java/de/blinkt/openvpn/core/NetworkSpace.java | 5 ++ .../de/blinkt/openvpn/core/OpenVPNManagement.java | 5 ++ .../de/blinkt/openvpn/core/OpenVPNService.java | 62 +++++++++++++--------- .../java/de/blinkt/openvpn/core/OpenVPNThread.java | 30 +++++++++-- .../openvpn/core/OpenVpnManagementThread.java | 5 ++ .../java/de/blinkt/openvpn/core/PRNGFixes.java | 5 ++ .../de/blinkt/openvpn/core/ProfileManager.java | 21 +++++--- .../de/blinkt/openvpn/core/ProxyDetection.java | 5 ++ .../de/blinkt/openvpn/core/VPNLaunchHelper.java | 7 ++- .../java/de/blinkt/openvpn/core/VpnStatus.java | 5 ++ .../java/de/blinkt/openvpn/core/X509Utils.java | 5 ++ .../de/blinkt/openvpn/fragments/LogFragment.java | 5 ++ .../java/de/blinkt/openvpn/views/SeekBarTicks.java | 5 ++ 22 files changed, 240 insertions(+), 68 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java index a424a489..d7f3e110 100644 --- a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java +++ b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn; import se.leap.bitmaskclient.R; @@ -113,27 +118,25 @@ public class LaunchVPN extends Activity { } } - @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - - if(requestCode==START_VPN_PROFILE) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - boolean showlogwindow = prefs.getBoolean("showlogwindow", true); - - if(!mhideLog && showlogwindow) - showLogWindow(); - new startOpenVpnThread().start(); - } else if (resultCode == Activity.RESULT_CANCELED) { - // User does not want us to start, so we just vanish - VpnStatus.updateStateString("USER_VPN_PERMISSION_CANCELLED", "", R.string.state_user_vpn_permission_cancelled, - ConnectionStatus.LEVEL_NOTCONNECTED); - - finish(); - } + super.onActivityResult(requestCode, resultCode, data); + + if(requestCode==START_VPN_PROFILE) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + boolean showLogWindow = prefs.getBoolean("showlogwindow", true); + + if(!mhideLog && showLogWindow) + showLogWindow(); + new startOpenVpnThread().start(); + } else if (resultCode == Activity.RESULT_CANCELED) { + // User does not want us to start, so we just vanish + VpnStatus.updateStateString("USER_VPN_PERMISSION_CANCELLED", "", R.string.state_user_vpn_permission_cancelled, + ConnectionStatus.LEVEL_NOTCONNECTED); + + finish(); + } } - void showLogWindow() { Intent startLW = new Intent(getBaseContext(),LogWindow.class); diff --git a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java index 6fec5f46..65214c4f 100644 --- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn; import se.leap.bitmaskclient.R; @@ -40,6 +45,7 @@ import java.util.Collection; import java.util.Locale; import java.util.UUID; import java.util.Vector; +import java.util.concurrent.Future; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; @@ -166,6 +172,12 @@ public class VpnProfile implements Serializable { return VpnProfile.MININONPIEVPN; } + public static String[] replacePieWithNoPie(String[] mArgv) + { + mArgv[0] = mArgv[0].replace(MINIPIEVPN, MININONPIEVPN); + return mArgv; + } + public static String openVpnEscape(String unescaped) { if (unescaped == null) return null; @@ -174,7 +186,8 @@ public class VpnProfile implements Serializable { escapedString = escapedString.replace("\n", "\\n"); if (escapedString.equals(unescaped) && !escapedString.contains(" ") && - !escapedString.contains("#") && !escapedString.contains(";")) + !escapedString.contains("#") && !escapedString.contains(";") + && !escapedString.equals("")) return unescaped; else return '"' + escapedString + '"'; @@ -579,21 +592,15 @@ public class VpnProfile implements Serializable { - public Intent prepareIntent(Context context) { - String prefix = context.getPackageName(); + public Intent prepareStartService(Context context) { + Intent intent = getStartServiceIntent(context); - Intent intent = new Intent(context, OpenVPNService.class); if (mAuthenticationType == VpnProfile.TYPE_KEYSTORE || mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) { if (getKeyStoreCertificates(context) == null) return null; } - intent.putExtra(prefix + ".ARGV", buildOpenvpnArgv(context.getCacheDir())); - intent.putExtra(prefix + ".profileUUID", mUuid.toString()); - - ApplicationInfo info = context.getApplicationInfo(); - intent.putExtra(prefix + ".nativelib", info.nativeLibraryDir); try { FileWriter cfg = new FileWriter(context.getCacheDir().getAbsolutePath() + "/" + OVPNCONFIGFILE); @@ -607,6 +614,18 @@ public class VpnProfile implements Serializable { return intent; } + public Intent getStartServiceIntent(Context context) { + String prefix = context.getPackageName(); + + Intent intent = new Intent(context, OpenVPNService.class); + intent.putExtra(prefix + ".ARGV", buildOpenvpnArgv(context.getCacheDir())); + intent.putExtra(prefix + ".profileUUID", mUuid.toString()); + + ApplicationInfo info = context.getApplicationInfo(); + intent.putExtra(prefix + ".nativelib", info.nativeLibraryDir); + return intent; + } + public String[] getKeyStoreCertificates(Context context) { return getKeyStoreCertificates(context, 5); } @@ -635,6 +654,21 @@ public class VpnProfile implements Serializable { return false; } + public void checkForRestart(final Context context) { + /* This method is called when OpenVPNService is restarted */ + + if ((mAuthenticationType == VpnProfile.TYPE_KEYSTORE || mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) + && mPrivateKey==null) { + new Thread( new Runnable() { + @Override + public void run() { + getKeyStoreCertificates(context); + + } + }).start(); + } + } + class NoCertReturnedException extends Exception { public NoCertReturnedException (String msg) { @@ -841,21 +875,23 @@ public class VpnProfile implements Serializable { return false; } - public int needUserPWInput() { + public int needUserPWInput(boolean ignoreTransient) { if ((mAuthenticationType == TYPE_PKCS12 || mAuthenticationType == TYPE_USERPASS_PKCS12) && (mPKCS12Password == null || mPKCS12Password.equals(""))) { - if (mTransientPCKS12PW == null) + if (ignoreTransient || mTransientPCKS12PW == null) return R.string.pkcs12_file_encryption_key; } if (mAuthenticationType == TYPE_CERTIFICATES || mAuthenticationType == TYPE_USERPASS_CERTIFICATES) { if (requireTLSKeyPassword() && TextUtils.isEmpty(mKeyPassword)) - if (mTransientPCKS12PW == null) { + if (ignoreTransient || mTransientPCKS12PW == null) { return R.string.private_key_password; } } - if (isUserPWAuth() && !(!TextUtils.isEmpty(mUsername) && (!TextUtils.isEmpty(mPassword) || mTransientPW != null))) { + if (isUserPWAuth() && + (TextUtils.isEmpty(mUsername) || + (TextUtils.isEmpty(mPassword) && (mTransientPW == null || ignoreTransient)))) { return R.string.password; } return 0; diff --git a/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java b/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java index 5910173a..e6b73a48 100644 --- a/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java +++ b/app/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.activities; import android.app.Activity; diff --git a/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java b/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java index 7ed09dd2..5e4f9517 100644 --- a/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java +++ b/app/src/main/java/de/blinkt/openvpn/activities/LogWindow.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.activities; import android.app.Activity; diff --git a/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java b/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java index 960e7d11..ac9a8ccb 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java +++ b/app/src/main/java/de/blinkt/openvpn/core/CIDRIP.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import java.util.Locale; 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 9c3621e0..0d8230b7 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import java.io.BufferedReader; @@ -553,8 +558,13 @@ public class ConfigParser { noauthtypeset=false; } + Vector cryptoapicert = getOption("cryptoapicert",1,1); + if(cryptoapicert!=null) { + np.mAuthenticationType = VpnProfile.TYPE_KEYSTORE; + noauthtypeset=false; + } - Vector compatnames = getOption("compat-names",1,2); + Vector compatnames = getOption("compat-names",1,2); Vector nonameremapping = getOption("no-name-remapping",1,1); Vector tlsremote = getOption("tls-remote",1,1); if(tlsremote!=null){ diff --git a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java index 0126d08e..0d75ae51 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java +++ b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.content.BroadcastReceiver; diff --git a/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java b/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java index 485e5369..83e760ca 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.app.Application; 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 a2c4796d..6d7ffdf2 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java +++ b/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import java.security.InvalidKeyException; diff --git a/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java b/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java index 8c6cb1f5..35f46513 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java +++ b/app/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.os.Build; diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java index a5a3e9f4..e90c16d1 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; public interface OpenVPNManagement { 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 743e7cc5..ada065ba 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.Manifest.permission; @@ -19,6 +24,7 @@ import android.os.Message; import android.os.ParcelFileDescriptor; import android.preference.PreferenceManager; import android.text.TextUtils; +import android.util.Log; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -309,26 +315,32 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac return START_REDELIVER_INTENT; } - String UUID = "UUID"; + /* The intent is null when the service has been restarted */ if (intent == null) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - android.util.Log.d("bitmaskclient", "UUID is " + prefs.getString(UUID, "")); - mProfile = ProfileManager.get(this, prefs.getString(UUID, "")); - android.util.Log.d("bitmaskclient", "mProfile is null? " + (mProfile == null)); - if(mProfile != null) - intent = mProfile.prepareIntent(getBaseContext()); - else + mProfile = ProfileManager.getLastConnectedProfile(this, false); + + /* Got no profile, just stop */ + if (mProfile==null) { + Log.d("OpenVPN", "Got no last connected profile on null intent. Stopping"); + stopSelf(startId); return START_NOT_STICKY; - } - if(mProfile != null) - android.util.Log.d("bitmaskclient", "mProfile != null"); + } + /* Do the asynchronous keychain certificate stuff */ + mProfile.checkForRestart(this); + + /* Recreate the intent */ + intent = mProfile.getStartServiceIntent(this); + + } else { + String profileUUID = intent.getStringExtra(getPackageName() + ".profileUUID"); + mProfile = ProfileManager.get(this, profileUUID); + } + + // Extract information from the intent. String prefix = getPackageName(); String[] argv = intent.getStringArrayExtra(prefix + ".ARGV"); - String nativelibdir = intent.getStringExtra(prefix + ".nativelib"); - String profileUUID = intent.getStringExtra(prefix + ".profileUUID"); - - mProfile = ProfileManager.get(this, profileUUID); + String nativeLibraryDirectory = intent.getStringExtra(prefix + ".nativelib"); String startTitle = getString(R.string.start_vpn_title, mProfile.mName); String startTicker = getString(R.string.start_vpn_ticker, mProfile.mName); @@ -361,13 +373,12 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac // Start a new session by creating a new thread. SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - + mOvpn3 = prefs.getBoolean("ovpn3", false); if (!"ovpn3".equals(BuildConfig.FLAVOR)) mOvpn3 = false; - prefs.edit().putString(UUID, profileUUID).commit(); // Open the Management Interface if (!mOvpn3) { @@ -395,7 +406,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac } else { HashMap env = new HashMap(); - processThread = new OpenVPNThread(this, argv, env, nativelibdir); + processThread = new OpenVPNThread(this, argv, env, nativeLibraryDirectory); } synchronized (mProcessLock) { @@ -409,11 +420,12 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac ProfileManager.setConnectedVpnProfile(this, mProfile); + /* TODO: At the moment we have no way to handle asynchronous PW input + * Fixing will also allow to handle challenge/responsee authentication */ + if (mProfile.needUserPWInput(true) != 0) + return START_NOT_STICKY; - if (mProfile.mPersistTun) - return START_STICKY; - else - return START_NOT_STICKY; + return START_STICKY; } private OpenVPNManagement instantiateOpenVPN3Core() { @@ -517,7 +529,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac if ((Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT && !release.startsWith("4.4.3") && !release.startsWith("4.4.4") && !release.startsWith("4.4.5") && !release.startsWith("4.4.6")) && mMtu < 1280) { - VpnStatus.logInfo(String.format("Forcing MTU to 1280 instead of %d to workaround Android Bug #70916", mMtu)); + VpnStatus.logInfo(String.format(Locale.US, "Forcing MTU to 1280 instead of %d to workaround Android Bug #70916", mMtu)); builder.setMtu(1280); } else { builder.setMtu(mMtu); @@ -690,7 +702,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac VpnStatus.logWarning(R.string.ip_not_cidr, local, netmask, mode); } } - if (("p2p".equals(mode)) && mLocalIP.len < 32 || "net30".equals("net30") && mLocalIP.len < 30) { + if (("p2p".equals(mode) && mLocalIP.len < 32) || ("net30".equals(mode) && mLocalIP.len < 30)) { VpnStatus.logWarning(R.string.ip_looks_like_subnet, local, netmask, mode); } @@ -738,7 +750,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac String ticker = msg; showNotification(msg, ticker, lowpriority , 0, level); return; - } else { + } else { mDisplayBytecount = false; } diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java index 5fa2ab9e..e3c60854 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.util.Log; @@ -25,6 +30,7 @@ import de.blinkt.openvpn.core.VpnStatus.LogItem; public class OpenVPNThread implements Runnable { private static final String DUMP_PATH_STRING = "Dump path: "; + private static final String BROKEN_PIE_SUPPORT = "/data/data/de.blinkt.openvpn/cache/pievpn[1]: syntax error:"; private static final String TAG = "OpenVPN"; public static final int M_FATAL = (1 << 4); public static final int M_NONFATAL = (1 << 5); @@ -36,8 +42,9 @@ public class OpenVPNThread implements Runnable { private OpenVPNService mService; private String mDumpPath; private Map mProcessEnv; + private boolean mBrokenPie=false; - public OpenVPNThread(OpenVPNService service,String[] argv, Map processEnv, String nativelibdir) + public OpenVPNThread(OpenVPNService service,String[] argv, Map processEnv, String nativelibdir) { mArgv = argv; mNativeDir = nativelibdir; @@ -68,8 +75,22 @@ public class OpenVPNThread implements Runnable { } catch (InterruptedException ie) { VpnStatus.logError("InterruptedException: " + ie.getLocalizedMessage()); } - if( exitvalue != 0) - VpnStatus.logError("Process exited with exit value " + exitvalue); + if( exitvalue != 0) { + VpnStatus.logError("Process exited with exit value " + exitvalue); + if (mBrokenPie) { + String[] noPieArgv = VpnProfile.replacePieWithNoPie(mArgv); + + // We are already noPIE, nothing to gain + if (!noPieArgv.equals(mArgv)) { + mArgv = noPieArgv; + VpnStatus.logInfo("PIE Version could not be executed. Trying no PIE version"); + run(); + return; + } + + } + + } VpnStatus.updateStateString("NOPROCESS", "No process running.", R.string.state_noprocess, ConnectionStatus.LEVEL_NOTCONNECTED); if(mDumpPath!=null) { @@ -123,6 +144,9 @@ public class OpenVPNThread implements Runnable { if (logline.startsWith(DUMP_PATH_STRING)) mDumpPath = logline.substring(DUMP_PATH_STRING.length()); + + if (logline.startsWith(BROKEN_PIE_SUPPORT)) + mBrokenPie = true; // 1380308330.240114 18000002 Send to HTTP proxy: 'X-Online-Host: bla.blabla.com' 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 e200f210..37094a1b 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.content.Context; diff --git a/app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java b/app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java index dd420371..bca0a4ab 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java +++ b/app/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core;/* * This software is provided 'as-is', without any express or implied * warranty. In no event will Google be held liable for any damages diff --git a/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java b/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java index 4cfbcc8e..2a26152e 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import java.io.FileNotFoundException; @@ -23,7 +28,7 @@ public class ProfileManager { - private static final String ONBOOTPROFILE = "onBootProfile"; + private static final String LAST_CONNECTED_PROFILE = "lastConnectedProfile"; @@ -65,7 +70,7 @@ public class ProfileManager { public static void setConntectedVpnProfileDisconnected(Context c) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); Editor prefsedit = prefs.edit(); - prefsedit.putString(ONBOOTPROFILE, null); + prefsedit.putString(LAST_CONNECTED_PROFILE, null); prefsedit.apply(); } @@ -74,21 +79,23 @@ public class ProfileManager { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); Editor prefsedit = prefs.edit(); - prefsedit.putString(ONBOOTPROFILE, connectedrofile.getUUIDString()); + prefsedit.putString(LAST_CONNECTED_PROFILE, connectedrofile.getUUIDString()); prefsedit.apply(); mLastConnectedVpn=connectedrofile; } - public static VpnProfile getOnBootProfile(Context c) { + public static VpnProfile getLastConnectedProfile(Context c, boolean onBoot) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); boolean useStartOnBoot = prefs.getBoolean("restartvpnonboot", false); + if (onBoot && !useStartOnBoot) + return null; - String mBootProfileUUID = prefs.getString(ONBOOTPROFILE,null); - if(useStartOnBoot && mBootProfileUUID!=null) - return get(c, mBootProfileUUID); + String lastConnectedProfile = prefs.getString(LAST_CONNECTED_PROFILE, null); + if(lastConnectedProfile!=null) + return get(c, lastConnectedProfile); else return null; } diff --git a/app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java b/app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java index 47d88279..cf953863 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import java.net.InetSocketAddress; diff --git a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java index 57a94ee7..40f9742b 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java +++ b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.content.Context; @@ -70,7 +75,7 @@ public class VPNLaunchHelper { VpnStatus.logInfo(R.string.building_configration); - Intent startVPN = startprofile.prepareIntent(context); + Intent startVPN = startprofile.prepareStartService(context); if(startVPN!=null) context.startService(startVPN); diff --git a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java index c19daeb0..25558f13 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java +++ b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.annotation.SuppressLint; diff --git a/app/src/main/java/de/blinkt/openvpn/core/X509Utils.java b/app/src/main/java/de/blinkt/openvpn/core/X509Utils.java index 35e53c08..ff383e0f 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/X509Utils.java +++ b/app/src/main/java/de/blinkt/openvpn/core/X509Utils.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.core; import android.content.Context; diff --git a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java b/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java index ca850533..77fc21e6 100644 --- a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java +++ b/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.fragments; import se.leap.bitmaskclient.R; diff --git a/app/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java b/app/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java index 88e8e164..e25c2859 100644 --- a/app/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java +++ b/app/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2012-2014 Arne Schwabe + * Distributed under the GNU GPL v2. For full terms see the file doc/LICENSE.txt + */ + package de.blinkt.openvpn.views; import android.content.Context; -- cgit v1.2.3 From 79cebeb70258b5b3de708d4c187ac5867549cdc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 7 Nov 2014 11:01:52 +0100 Subject: 0.8.0RC2. --- app/src/main/java/se/leap/bitmaskclient/Dashboard.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 547e4179..529f6760 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -112,7 +112,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf switch(versionCode) { case 91: // 0.6.0 without Bug #5999 - case 94: // 0.8.0 with + case 95: // 0.8.0 RC2 if(!preferences.getString(EIP.KEY, "").isEmpty()) { Intent rebuildVpnProfiles = new Intent(getApplicationContext(), EIP.class); rebuildVpnProfiles.setAction(EIP.ACTION_REBUILD_PROFILES); -- cgit v1.2.3 From d87577bb6dc7fffa8ca381bef32e6069bc3c5655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 11 Nov 2014 21:47:11 +0100 Subject: Blocking VPN stays as far as no established connection exists. --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index ad7552c8..dea916f5 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -152,13 +152,13 @@ public final class EIP extends IntentService { * It also sets up early routes. */ private void startEIP() { - earlyRoutes(); activeGateway = selectGateway(); if(activeGateway != null && activeGateway.mVpnProfile != null) { mReceiver = EipServiceFragment.getReceiver(); launchActiveGateway(); } + earlyRoutes(); } /** -- cgit v1.2.3 From 055b8942d265ff10b4f6c9611cca86f585d24023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 11 Nov 2014 23:25:36 +0100 Subject: A bit of EIP refactoring. --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 206 +++++---------------- .../se/leap/bitmaskclient/VpnConfigGenerator.java | 146 +++++++++++++++ 2 files changed, 196 insertions(+), 156 deletions(-) create mode 100644 app/src/main/java/se/leap/bitmaskclient/VpnConfigGenerator.java (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index dea916f5..7f15b944 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -88,9 +88,8 @@ public final class EIP extends IntentService { public final static String RECEIVER_TAG = "receiverTag"; public final static String REQUEST_TAG = "requestTag"; public final static String TAG = EIP.class.getSimpleName(); + private static SharedPreferences preferences; - public final static SimpleDateFormat certificate_date_format = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); - private static Context context; private static ResultReceiver mReceiver; private static boolean mBound = false; @@ -104,6 +103,7 @@ public final class EIP extends IntentService { protected static boolean mIsDisconnecting = false; protected static boolean mIsStarting = false; + public static SimpleDateFormat certificate_date_format = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); public EIP(){ super("LEAPEIP"); } @@ -114,8 +114,7 @@ public final class EIP extends IntentService { context = getApplicationContext(); - // Log.d(TAG, "Update EIP Service onCreate EIP"); - // updateEIPService(); + preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE); } @Override @@ -320,11 +319,11 @@ public final class EIP extends IntentService { */ private void updateEIPService() { try { - String eip_definition_string = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(KEY, ""); + String eip_definition_string = preferences.getString(KEY, ""); if(eip_definition_string.isEmpty() == false) { eipDefinition = new JSONObject(eip_definition_string); } - parsedEipSerial = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getInt(PARSED_SERIAL, 0); + parsedEipSerial = preferences.getInt(PARSED_SERIAL, 0); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -363,42 +362,54 @@ public final class EIP extends IntentService { // TODO Auto-generated catch block e.printStackTrace(); } - getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putInt(PARSED_SERIAL, eipDefinition.optInt(Provider.API_RETURN_SERIAL)).commit(); + preferences.edit().putInt(PARSED_SERIAL, eipDefinition.optInt(Provider.API_RETURN_SERIAL)).commit(); } private void checkCertValidity() { - String certificate_string = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(CERTIFICATE, ""); - if(!certificate_string.isEmpty()) { - String date_from_certificate_string = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(DATE_FROM_CERTIFICATE, certificate_date_format.format(Calendar.getInstance().getTime()).toString()); - X509Certificate certificate_x509 = ConfigHelper.parseX509CertificateFromString(certificate_string); + String certificate = preferences.getString(CERTIFICATE, ""); + checkCertValidity(certificate); + } - Calendar offset_date = Calendar.getInstance(); - try { - Date date_from_certificate = certificate_date_format.parse(date_from_certificate_string); - long difference = Math.abs(date_from_certificate.getTime() - certificate_x509.getNotAfter().getTime())/2; - long current_date_millis = offset_date.getTimeInMillis(); - offset_date.setTimeInMillis(current_date_millis + difference); - Log.d(TAG, "certificate not after = " + certificate_x509.getNotAfter()); - } catch(ParseException e) { - e.printStackTrace(); - } - - Bundle result_data = new Bundle(); - result_data.putString(REQUEST_TAG, ACTION_CHECK_CERT_VALIDITY); + private void checkCertValidity(String certificate_string) { + if(!certificate_string.isEmpty()) { + X509Certificate certificate = ConfigHelper.parseX509CertificateFromString(certificate_string); + + Calendar offset_date = calculateOffsetCertificateValidity(certificate); + Bundle result = new Bundle(); + result.putString(REQUEST_TAG, ACTION_CHECK_CERT_VALIDITY); try { Log.d(TAG, "offset_date = " + offset_date.getTime().toString()); - certificate_x509.checkValidity(offset_date.getTime()); - mReceiver.send(Activity.RESULT_OK, result_data); + certificate.checkValidity(offset_date.getTime()); + mReceiver.send(Activity.RESULT_OK, result); Log.d(TAG, "Valid certificate"); } catch(CertificateExpiredException e) { - mReceiver.send(Activity.RESULT_CANCELED, result_data); + mReceiver.send(Activity.RESULT_CANCELED, result); Log.d(TAG, "Updating certificate"); } catch(CertificateNotYetValidException e) { - mReceiver.send(Activity.RESULT_CANCELED, result_data); + mReceiver.send(Activity.RESULT_CANCELED, result); } } } + private Calendar calculateOffsetCertificateValidity(X509Certificate certificate) { + String current_date = certificate_date_format.format(Calendar.getInstance().getTime()).toString(); + + String date_string = preferences.getString(DATE_FROM_CERTIFICATE, current_date); + + Calendar offset_date = Calendar.getInstance(); + try { + Date date = certificate_date_format.parse(date_string); + long difference = Math.abs(date.getTime() - certificate.getNotAfter().getTime())/2; + long current_date_millis = offset_date.getTimeInMillis(); + offset_date.setTimeInMillis(current_date_millis + difference); + Log.d(TAG, "certificate not after = " + certificate.getNotAfter()); + } catch(ParseException e) { + e.printStackTrace(); + } + + return offset_date; + } + /** * OVPNGateway provides objects defining gateways and their options and metadata. * Each instance contains a VpnProfile for OpenVPN specific data and member @@ -479,18 +490,19 @@ public final class EIP extends IntentService { protected void createVPNProfile(){ try { ConfigParser cp = new ConfigParser(); - cp.parseConfig(new StringReader(configFromEipServiceDotJson())); - cp.parseConfig(new StringReader(caSecretFromSharedPreferences())); - cp.parseConfig(new StringReader(keySecretFromSharedPreferences())); - cp.parseConfig(new StringReader(certSecretFromSharedPreferences())); - cp.parseConfig(new StringReader("remote-cert-tls server")); - cp.parseConfig(new StringReader("persist-tun")); - cp.parseConfig(new StringReader("auth-retry nointeract")); - VpnProfile vp = cp.convertProfile(); - //vp.mAuthenticationType=VpnProfile.TYPE_STATICKEYS; - mVpnProfile = vp; + + JSONObject openvpn_configuration = eipDefinition.getJSONObject("openvpn_configuration"); + VpnConfigGenerator vpn_configuration_generator = new VpnConfigGenerator(preferences, openvpn_configuration, mGateway); + String configuration = vpn_configuration_generator.generate(); + + cp.parseConfig(new StringReader(configuration)); + mVpnProfile = cp.convertProfile(); mVpnProfile.mName = mName = locationAsName(); Log.v(TAG,"Created VPNProfile"); + + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } catch (ConfigParseError e) { // FIXME We didn't get a VpnProfile! Error handling! and log level Log.v(TAG,"Error creating VPNProfile"); @@ -502,124 +514,6 @@ public final class EIP extends IntentService { } } - /** - * Parses data from eip-service.json to a section of the openvpn config file - */ - private String configFromEipServiceDotJson() { - String parsed_configuration = ""; - - String location_key = "location"; - String locations = "locations"; - - parsed_configuration += extractCommonOptionsFromEipServiceDotJson(); - parsed_configuration += extractRemotesFromEipServiceDotJson(); - - return parsed_configuration; - } - - private String extractCommonOptionsFromEipServiceDotJson() { - String common_options = ""; - try { - String common_options_key = "openvpn_configuration"; - JSONObject openvpn_configuration = eipDefinition.getJSONObject(common_options_key); - Iterator keys = openvpn_configuration.keys(); - Vector> value = new Vector>(); - while ( keys.hasNext() ){ - String key = keys.next().toString(); - - common_options += key + " "; - for ( String word : openvpn_configuration.getString(key).split(" ") ) - common_options += word + " "; - common_options += System.getProperty("line.separator"); - - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - common_options += "client" + System.getProperty("line.separator"); - - return common_options; - } - - - private String extractRemotesFromEipServiceDotJson() { - String remotes = ""; - - String remote = "ip_address"; - String remote_openvpn_keyword = "remote"; - String ports = "ports"; - String protos = "protocols"; - String capabilities = "capabilities"; - String udp = "udp"; - - try { - JSONArray protocolsJSON = mGateway.getJSONObject(capabilities).getJSONArray(protos); - for ( int i=0; i. + */ +package se.leap.bitmaskclient; + +import android.content.SharedPreferences; +import android.util.Log; +import java.util.Iterator; +import java.util.Vector; +import org.json.JSONArray; +import org.json.JSONObject; +import org.json.JSONException; + +import se.leap.bitmaskclient.Provider; +import se.leap.bitmaskclient.EIP; + +public class VpnConfigGenerator { + + private JSONObject general_configuration; + private JSONObject gateway; + + private static SharedPreferences preferences; + public final static String TAG = VpnConfigGenerator.class.getSimpleName(); + private final String new_line = System.getProperty("line.separator"); // Platform new line + + public VpnConfigGenerator(SharedPreferences preferences, JSONObject general_configuration, JSONObject gateway) { + this.general_configuration = general_configuration; + this.gateway = gateway; + this.preferences = preferences; + } + + public String generate() { + return + generalConfiguration() + + new_line + + gatewayConfiguration() + + new_line + + secretsConfiguration() + + new_line + + androidCustomizations(); + } + + private String generalConfiguration() { + String common_options = ""; + try { + Iterator keys = general_configuration.keys(); + Vector> value = new Vector>(); + while ( keys.hasNext() ){ + String key = keys.next().toString(); + + common_options += key + " "; + for ( String word : general_configuration.getString(key).split(" ") ) + common_options += word + " "; + common_options += new_line; + + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + common_options += "client"; + + return common_options; + } + + private String gatewayConfiguration() { + String remotes = ""; + + String remote = "ip_address"; + String remote_openvpn_keyword = "remote"; + String ports = "ports"; + String protos = "protocols"; + String capabilities = "capabilities"; + String udp = "udp"; + + try { + JSONArray protocolsJSON = gateway.getJSONObject(capabilities).getJSONArray(protos); + for ( int i=0; i" + + new_line + + preferences.getString(Provider.CA_CERT, "") + + new_line + + ""; + + String key = + "" + + new_line + + preferences.getString(EIP.PRIVATE_KEY, "") + + new_line + + ""; + + String openvpn_cert = + "" + + new_line + + preferences.getString(EIP.CERTIFICATE, "") + + new_line + + ""; + + return ca + new_line + key + new_line + openvpn_cert; + } + + private String androidCustomizations() { + return + "remote-cert-tls server" + + new_line + + "persist-tun" + + new_line + + "auth-retry nointeract"; + } +} -- cgit v1.2.3 From 5870156057b9d1f6f0bd8c22824b7e0fd8ec300b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 13 Nov 2014 01:16:36 +0100 Subject: Delete all vpn profiles if updating them. --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 7f15b944..00a0afb0 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -94,7 +94,6 @@ public final class EIP extends IntentService { private static ResultReceiver mReceiver; private static boolean mBound = false; - private static int parsedEipSerial; private static JSONObject eipDefinition = null; private static OVPNGateway activeGateway = null; @@ -323,16 +322,12 @@ public final class EIP extends IntentService { if(eip_definition_string.isEmpty() == false) { eipDefinition = new JSONObject(eip_definition_string); } - parsedEipSerial = preferences.getInt(PARSED_SERIAL, 0); + deleteAllVpnProfiles(); + updateGateways(); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } - if(parsedEipSerial == 0) { - deleteAllVpnProfiles(); - } - if (eipDefinition != null && eipDefinition.optInt("serial") >= parsedEipSerial) - updateGateways(); } private void deleteAllVpnProfiles() { -- cgit v1.2.3 From 8f37e6f940ae4034458a1d9d39dc5ffe4ff70848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 20 Nov 2014 19:48:54 +0100 Subject: Update gateways after downloading certificate. If the certificate is from an authenticated user, autostart eip. If not, show that the certificate has been updated. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 53 +++++++++++++--------- app/src/main/java/se/leap/bitmaskclient/EIP.java | 3 +- 2 files changed, 34 insertions(+), 22 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 547e4179..49614a6f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -135,21 +135,23 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data){ + protected void onActivityResult(int requestCode, int resultCode, final Intent data){ if ( requestCode == CONFIGURE_LEAP || requestCode == SWITCH_PROVIDER) { // It should be equivalent: if ( (requestCode == CONFIGURE_LEAP) || (data!= null && data.hasExtra(STOP_FIRST))) { - if ( resultCode == RESULT_OK ){ - preferences.edit().putInt(EIP.PARSED_SERIAL, 0).commit(); - preferences.edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); - Intent updateEIP = new Intent(getApplicationContext(), EIP.class); - updateEIP.setAction(EIP.ACTION_UPDATE_EIP_SERVICE); - startService(updateEIP); - buildDashboard(false); - invalidateOptionsMenu(); - if(data != null && data.hasExtra(LogInDialog.TAG)) { - View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); - logInDialog(Bundle.EMPTY); - } + if ( resultCode == RESULT_OK ){ + preferences.edit().putInt(EIP.PARSED_SERIAL, 0).commit(); + preferences.edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); + + Intent updateEIP = new Intent(getApplicationContext(), EIP.class); + updateEIP.setAction(EIP.ACTION_UPDATE_EIP_SERVICE); + startService(updateEIP); + + buildDashboard(false); + invalidateOptionsMenu(); + if(data != null && data.hasExtra(LogInDialog.TAG)) { + View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); + logInDialog(Bundle.EMPTY); + } } else if(resultCode == RESULT_CANCELED && (data == null || data.hasExtra(ACTION_QUIT))) { finish(); } else @@ -451,7 +453,22 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf hideProgressBar(); setResult(RESULT_OK); - eipStart(); + Intent updateEIP = new Intent(getApplicationContext(), EIP.class); + ResultReceiver eip_receiver = new ResultReceiver(new Handler()){ + protected void onReceiveResult(int resultCode, Bundle resultData){ + super.onReceiveResult(resultCode, resultData); + String request = resultData.getString(EIP.REQUEST_TAG); + if (resultCode == Activity.RESULT_OK){ + if(authed_eip) + eipStart(); + else + eipStatus.setText("Certificate updated"); + } + } + }; + updateEIP.putExtra(EIP.RECEIVER_TAG, eip_receiver); + updateEIP.setAction(EIP.ACTION_UPDATE_EIP_SERVICE); + startService(updateEIP); } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { changeStatusMessage(resultCode); hideProgressBar(); @@ -523,13 +540,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf intent.putExtra(Dashboard.REQUEST_CODE, requestCode); super.startActivityForResult(intent, requestCode); } - - /** - * Send a command to EIP - * - * @param action A valid String constant from EIP class representing an Intent - * filter for the EIP class - */ + private void eipIsRunning(ResultReceiver eip_receiver){ // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? Intent eip_intent = new Intent(this, EIP.class); diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 00a0afb0..0d11847e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -324,6 +324,7 @@ public final class EIP extends IntentService { } deleteAllVpnProfiles(); updateGateways(); + if(mReceiver != null) mReceiver.send(Activity.RESULT_OK, Bundle.EMPTY); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -394,7 +395,7 @@ public final class EIP extends IntentService { Calendar offset_date = Calendar.getInstance(); try { Date date = certificate_date_format.parse(date_string); - long difference = Math.abs(date.getTime() - certificate.getNotAfter().getTime())/2; + long difference = Math.abs(date.getTime() - certificate.getNotAfter().getTime())/2; long current_date_millis = offset_date.getTimeInMillis(); offset_date.setTimeInMillis(current_date_millis + difference); Log.d(TAG, "certificate not after = " + certificate.getNotAfter()); -- cgit v1.2.3 From 809c95e41458de62cee3752dd695588ef2039a5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 22 Nov 2014 11:44:05 +0100 Subject: Ask to log in to update certificate if needed. ProviderAPI from debug build uses an invalid certificate the first time it tries to download a new cert, just to test this. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 2 +- app/src/main/java/se/leap/bitmaskclient/EIP.java | 2 +- .../se/leap/bitmaskclient/EipServiceFragment.java | 31 +++++++++++++--------- 3 files changed, 20 insertions(+), 15 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 49614a6f..7d00ca77 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -225,7 +225,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf if(provider_json_string.isEmpty() == false) { provider_json = new JSONObject(provider_json_string); JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE); - boolean authed_eip = preferences.getBoolean(EIP.AUTHED_EIP, false); + boolean authed_eip = !LeapSRPSession.getToken().isEmpty(); boolean allow_registered_eip = service_description.getBoolean(Provider.ALLOW_REGISTRATION); preferences.edit().putBoolean(EIP.ALLOWED_REGISTERED, allow_registered_eip); diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 0d11847e..2ce3c20f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -156,7 +156,7 @@ public final class EIP extends IntentService { mReceiver = EipServiceFragment.getReceiver(); launchActiveGateway(); } - earlyRoutes(); + //earlyRoutes(); } /** diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index a7d68198..6d223dd6 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -85,8 +85,8 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe super.onResume(); VpnStatus.addStateListener(this); - - eipCommand(EIP.ACTION_CHECK_CERT_VALIDITY); + + eipCommand(EIP.ACTION_CHECK_CERT_VALIDITY); } @Override @@ -146,7 +146,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe private boolean canLogInToStartEIP() { boolean isAllowedRegistered = Dashboard.preferences.getBoolean(EIP.ALLOWED_REGISTERED, false); - boolean isLoggedIn = Dashboard.preferences.getBoolean(EIP.AUTHED_EIP, false); + boolean isLoggedIn = !LeapSRPSession.getToken().isEmpty(); Log.d(TAG, "Allow registered? " + isAllowedRegistered); Log.d(TAG, "Is logged in? " + isLoggedIn); return isAllowedRegistered && !isLoggedIn && !EIP.mIsStarting && !EIP.isConnected(); @@ -386,16 +386,21 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe dashboard.showProgressBar(); String status = getResources().getString(R.string.updating_certificate_message); setEipStatus(status); - - Intent provider_API_command = new Intent(getActivity(), ProviderAPI.class); - if(dashboard.providerAPI_result_receiver == null) { - dashboard.providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); - dashboard.providerAPI_result_receiver.setReceiver(dashboard); - } - - provider_API_command.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); - provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, dashboard.providerAPI_result_receiver); - getActivity().startService(provider_API_command); + + if(LeapSRPSession.getToken().isEmpty() && !Dashboard.preferences.getBoolean(EIP.ALLOWED_ANON, false)) { + dashboard.logInDialog(Bundle.EMPTY); + } else { + + Intent provider_API_command = new Intent(getActivity(), ProviderAPI.class); + if (dashboard.providerAPI_result_receiver == null) { + dashboard.providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); + dashboard.providerAPI_result_receiver.setReceiver(dashboard); + } + + provider_API_command.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); + provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, dashboard.providerAPI_result_receiver); + getActivity().startService(provider_API_command); + } break; } } -- cgit v1.2.3 From 9e8392da2c8e48f674291ebfed6b82177fade9c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 25 Nov 2014 10:02:06 +0100 Subject: Changelog + early routes uncommented + rebuild vpn profile --- app/src/main/java/se/leap/bitmaskclient/Dashboard.java | 2 +- app/src/main/java/se/leap/bitmaskclient/EIP.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 24aa17bd..364a79af 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -112,7 +112,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf switch(versionCode) { case 91: // 0.6.0 without Bug #5999 - case 95: // 0.8.0 RC2 + case 101: // 0.8.0 if(!preferences.getString(EIP.KEY, "").isEmpty()) { Intent rebuildVpnProfiles = new Intent(getApplicationContext(), EIP.class); rebuildVpnProfiles.setAction(EIP.ACTION_REBUILD_PROFILES); diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 2ce3c20f..2f06def3 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -150,13 +150,13 @@ public final class EIP extends IntentService { * It also sets up early routes. */ private void startEIP() { + earlyRoutes(); activeGateway = selectGateway(); if(activeGateway != null && activeGateway.mVpnProfile != null) { mReceiver = EipServiceFragment.getReceiver(); launchActiveGateway(); } - //earlyRoutes(); } /** -- cgit v1.2.3