From 8d7bedaa40129ae809f3e1261228b00042872f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 31 Dec 2014 16:51:56 +0100 Subject: Don't remove vpn profiles if possible. --- .../test/testConfigurationWizard.java | 2 +- .../test/testDashboardIntegration.java | 13 ++++++++++ .../main/java/se/leap/bitmaskclient/Dashboard.java | 4 +++- .../java/se/leap/bitmaskclient/EipFragment.java | 17 +++++-------- .../java/se/leap/bitmaskclient/OnBootReceiver.java | 28 ++++++++++++---------- .../main/java/se/leap/bitmaskclient/eip/EIP.java | 20 ++++++++++------ .../java/se/leap/bitmaskclient/eip/Gateway.java | 25 +++++++------------ .../se/leap/bitmaskclient/ConfigurationWizard.java | 12 +++++----- 8 files changed, 67 insertions(+), 54 deletions(-) diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/testConfigurationWizard.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/testConfigurationWizard.java index 229c3452..78ce1c81 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/testConfigurationWizard.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/testConfigurationWizard.java @@ -49,7 +49,7 @@ public class testConfigurationWizard extends ActivityInstrumentationTestCase2 profiles = vpl.getProfiles(); - for (Iterator it = profiles.iterator(); it.hasNext(); ){ - VpnProfile p = it.next(); - - if ( p.mName.equalsIgnoreCase( mName ) ) { - it.remove(); - vpl.removeProfile(context, p); - } - } - mVpnProfile = createVPNProfile(); mVpnProfile.mName = mName; - - vpl.addProfile(mVpnProfile); - vpl.saveProfile(context, mVpnProfile); - vpl.saveProfileList(context); } private JSONObject getGeneralConfiguration(JSONObject eip_definition) { @@ -153,4 +137,13 @@ public class Gateway { public int getTimezone() { return timezone; } + + @Override + public boolean equals(Object o) { + if(o instanceof Gateway) { + return ((Gateway) o).getProfile().mConnections.equals(mVpnProfile.mConnections); + } + else + return super.equals(o); + } } diff --git a/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java b/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java index 3d9bb7b1..af8a5d46 100644 --- a/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java +++ b/app/src/release/java/se/leap/bitmaskclient/ConfigurationWizard.java @@ -58,16 +58,16 @@ implements NewProviderDialogInterface, ProviderDetailFragmentInterface, Download @Inject ProviderListAdapter adapter; private ProviderManager provider_manager; - private Intent mConfigState = new Intent(); + private Intent mConfigState = new Intent(); private Provider selected_provider; final public static String TAG = ConfigurationWizard.class.getSimpleName(); - final public static String TYPE_OF_CERTIFICATE = "type_of_certificate"; - final public static String ANON_CERTIFICATE = "anon_certificate"; - final public static String AUTHED_CERTIFICATE = "authed_certificate"; + final public static String TYPE_OF_CERTIFICATE = "type_of_certificate"; + final public static String ANON_CERTIFICATE = "anon_certificate"; + final public static String AUTHED_CERTIFICATE = "authed_certificate"; - final protected static String PROVIDER_SET = "PROVIDER SET"; - final protected static String SERVICES_RETRIEVED = "SERVICES RETRIEVED"; + final protected static String PROVIDER_SET = "PROVIDER SET"; + final protected static String SERVICES_RETRIEVED = "SERVICES RETRIEVED"; final protected static String ASSETS_URL_FOLDER = "urls"; final private static String PROGRESSBAR_TEXT = TAG + "PROGRESSBAR_TEXT"; -- cgit v1.2.3 From 56e05aecf8430ddad776776e536583686555443a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 31 Dec 2014 17:11:58 +0100 Subject: Update gateway also if credentials changed. --- app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java index 79239308..e23f67c7 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java @@ -141,7 +141,10 @@ public class Gateway { @Override public boolean equals(Object o) { if(o instanceof Gateway) { - return ((Gateway) o).getProfile().mConnections.equals(mVpnProfile.mConnections); + VpnProfile compared_profile = ((Gateway) o).getProfile(); + return compared_profile.mConnections.equals(mVpnProfile.mConnections) + && compared_profile.mClientCertFilename != mVpnProfile.mClientCertFilename + && compared_profile.mClientKeyFilename != mVpnProfile.mClientKeyFilename; } else return super.equals(o); -- cgit v1.2.3 From a2eb399584f29286a7177ce707b042cc84e16fe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 31 Dec 2014 17:54:15 +0100 Subject: HTTP 401 = Logged out correctly --- .../java/se/leap/bitmaskclient/ProviderAPI.java | 57 ++++++---- .../java/se/leap/bitmaskclient/ProviderAPI.java | 119 ++++++++++++--------- 2 files changed, 107 insertions(+), 69 deletions(-) diff --git a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java index ce13d322..d63d641a 100644 --- a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java @@ -232,8 +232,8 @@ public class ProviderAPI extends IntentService { Bundle result = new Bundle(); int progress = 0; - String username = (String) task.get(SessionDialog.USERNAME); - String password = (String) task.get(SessionDialog.PASSWORD); + String username = task.getString(SessionDialog.USERNAME); + String password = task.getString(SessionDialog.PASSWORD); if(validUserLoginData(username, password)) { result = authenticate(username, password); broadcast_progress(progress++); @@ -243,7 +243,7 @@ public class ProviderAPI extends IntentService { result.putString(SessionDialog.USERNAME, username); result.putBoolean(SessionDialog.PASSWORD_INVALID_LENGTH, true); } - if(username.isEmpty()) { + if(!validUsername(username)) { result.putBoolean(RESULT_KEY, false); result.putBoolean(SessionDialog.USERNAME_MISSING, true); } @@ -327,21 +327,25 @@ public class ProviderAPI extends IntentService { /** * Validates parameters entered by the user to log in - * @param entered_username - * @param entered_password + * @param username + * @param password * @return true if both parameters are present and the entered password length is greater or equal to eight (8). */ - private boolean validUserLoginData(String entered_username, String entered_password) { - return !(entered_username.isEmpty()) && wellFormedPassword(entered_password); + private boolean validUserLoginData(String username, String password) { + return validUsername(username) && wellFormedPassword(password); } + private boolean validUsername(String username) { + return username != null && !username.isEmpty(); + } + /** * Validates a password - * @param entered_password + * @param password * @return true if the entered password length is greater or equal to eight (8). */ - private boolean wellFormedPassword(String entered_password) { - return entered_password.length() >= 8; + private boolean wellFormedPassword(String password) { + return password != null && password.length() >= 8; } /** @@ -826,20 +830,23 @@ public class ProviderAPI extends IntentService { return string; } - /** - * Logs out from the api url retrieved from the task. - * @return true if there were no exceptions - */ + /** + * Logs out from the api url retrieved from the task. + * @return true if there were no exceptions + */ private boolean logOut() { + String delete_url = provider_api_url + "/logout"; + + HttpsURLConnection urlConnection = null; + int responseCode = 0; + int progress = 0; try { - String delete_url = provider_api_url + "/logout"; - int progress = 0; - HttpsURLConnection urlConnection = (HttpsURLConnection)new URL(delete_url).openConnection(); + urlConnection = (HttpsURLConnection)new URL(delete_url).openConnection(); urlConnection.setRequestMethod("DELETE"); urlConnection.setSSLSocketFactory(getProviderSSLSocketFactory()); - int responseCode = urlConnection.getResponseCode(); + responseCode = urlConnection.getResponseCode(); broadcast_progress(progress++); LeapSRPSession.setToken(""); Log.d(TAG, Integer.toString(responseCode)); @@ -853,6 +860,20 @@ public class ProviderAPI extends IntentService { return false; } catch (IOException e) { // TODO Auto-generated catch block + try { + if(urlConnection != null) { + responseCode = urlConnection.getResponseCode(); + if(responseCode == 401) { + broadcast_progress(progress++); + LeapSRPSession.setToken(""); + Log.d(TAG, Integer.toString(responseCode)); + return true; + } + } + } catch (IOException e1) { + e1.printStackTrace(); + } + e.printStackTrace(); return false; } catch (KeyManagementException e) { diff --git a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java index 8b8cabdf..d019ca59 100644 --- a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java @@ -239,7 +239,7 @@ public class ProviderAPI extends IntentService { result.putString(SessionDialog.USERNAME, username); result.putBoolean(SessionDialog.PASSWORD_INVALID_LENGTH, true); } - if(username.isEmpty()) { + if(!validUsername(username)) { result.putBoolean(RESULT_KEY, false); result.putBoolean(SessionDialog.USERNAME_MISSING, true); } @@ -320,23 +320,27 @@ public class ProviderAPI extends IntentService { sendBroadcast(intentUpdate); } - /** - * Validates parameters entered by the user to log in - * @param entered_username - * @param entered_password - * @return true if both parameters are present and the entered password length is greater or equal to eight (8). - */ - private boolean validUserLoginData(String entered_username, String entered_password) { - return !(entered_username.isEmpty()) && wellFormedPassword(entered_password); - } + /** + * Validates parameters entered by the user to log in + * @param username + * @param password + * @return true if both parameters are present and the entered password length is greater or equal to eight (8). + */ + private boolean validUserLoginData(String username, String password) { + return validUsername(username) && wellFormedPassword(password); + } + + private boolean validUsername(String username) { + return username != null && !username.isEmpty(); + } /** * Validates a password - * @param entered_password + * @param password * @return true if the entered password length is greater or equal to eight (8). */ - private boolean wellFormedPassword(String entered_password) { - return entered_password.length() >= 8; + private boolean wellFormedPassword(String password) { + return password != null && password.length() >= 8; } /** @@ -815,51 +819,64 @@ public class ProviderAPI extends IntentService { } return string; } - - /** - * Logs out from the api url retrieved from the task. - * @return true if there were no exceptions - */ - private boolean logOut() { - try { - String delete_url = provider_api_url + "/logout"; - int progress = 0; - HttpsURLConnection urlConnection = (HttpsURLConnection)new URL(delete_url).openConnection(); - urlConnection.setRequestMethod("DELETE"); - urlConnection.setSSLSocketFactory(getProviderSSLSocketFactory()); + private boolean logOut() { + String delete_url = provider_api_url + "/logout"; - int responseCode = urlConnection.getResponseCode(); + HttpsURLConnection urlConnection = null; + int responseCode = 0; + int progress = 0; + try { + + urlConnection = (HttpsURLConnection)new URL(delete_url).openConnection(); + urlConnection.setRequestMethod("DELETE"); + urlConnection.setSSLSocketFactory(getProviderSSLSocketFactory()); + + responseCode = urlConnection.getResponseCode(); + broadcast_progress(progress++); + LeapSRPSession.setToken(""); + Log.d(TAG, Integer.toString(responseCode)); + } catch (ClientProtocolException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } catch (IndexOutOfBoundsException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } catch (IOException e) { + // TODO Auto-generated catch block + try { + if(urlConnection != null) { + responseCode = urlConnection.getResponseCode(); + if(responseCode == 401) { broadcast_progress(progress++); LeapSRPSession.setToken(""); Log.d(TAG, Integer.toString(responseCode)); - } catch (ClientProtocolException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; - } catch (IndexOutOfBoundsException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; - } catch (KeyManagementException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (KeyStoreException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (CertificateException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + return true; + } } - return true; + } catch (IOException e1) { + e1.printStackTrace(); + } + + e.printStackTrace(); + return false; + } catch (KeyManagementException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (KeyStoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (CertificateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } + return true; + } /** * Downloads a new OpenVPN certificate, attaching authenticated cookie for authenticated certificate. -- cgit v1.2.3 From d23ec1613855f6582b0e79c1a9fc1538d6099944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 31 Dec 2014 20:50:51 +0100 Subject: Remove duplicated gateways when necessary. --- .../main/java/se/leap/bitmaskclient/eip/EIP.java | 71 +++++++++++++++++++--- 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 77d0cd82..cf6006e5 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -31,10 +31,13 @@ import org.json.JSONObject; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import java.util.List; +import java.util.NoSuchElementException; import de.blinkt.openvpn.LaunchVPN; import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.core.Connection; import de.blinkt.openvpn.core.ProfileManager; import se.leap.bitmaskclient.Dashboard; import se.leap.bitmaskclient.EipFragment; @@ -71,7 +74,7 @@ public final class EIP extends IntentService { private static SharedPreferences preferences; private static JSONObject eip_definition; - private static List gateways = new ArrayList(); + private static List gateways = new ArrayList<>(); private static ProfileManager profile_manager; private static Gateway gateway; @@ -190,12 +193,6 @@ public final class EIP extends IntentService { e.printStackTrace(); } } - - private void deleteAllVpnProfiles() { - Collection profiles = profile_manager.getProfiles(); - profiles.removeAll(profiles); - gateways.clear(); - } /** * Walk the list of gateways defined in eip-service.json and parse them into @@ -231,6 +228,8 @@ public final class EIP extends IntentService { private void addGateway(Gateway gateway) { VpnProfile profile = gateway.getProfile(); + removeGateway(gateway); + profile_manager.addProfile(profile); profile_manager.saveProfile(context, profile); profile_manager.saveProfileList(context); @@ -239,6 +238,64 @@ public final class EIP extends IntentService { Log.d(TAG, "Gateway added: " + gateway.getProfile().getUUIDString()); } + private void removeGateway(Gateway gateway) { + VpnProfile profile = gateway.getProfile(); + removeDuplicatedProfile(profile); + removeDuplicatedGateway(profile); + } + + private void removeDuplicatedProfile(VpnProfile remove) { + if(containsProfile(remove)) + profile_manager.removeProfile(context, duplicatedProfile(remove)); + if(containsProfile(remove)) removeDuplicatedProfile(remove); + } + + private boolean containsProfile(VpnProfile profile) { + Collection profiles = profile_manager.getProfiles(); + for(VpnProfile aux : profiles) { + if (sameConnections(profile.mConnections, aux.mConnections)) { + return true; + } + } + return false; + } + + private VpnProfile duplicatedProfile(VpnProfile profile) { + VpnProfile duplicated = null; + Collection profiles = profile_manager.getProfiles(); + for(VpnProfile aux : profiles) { + if (sameConnections(profile.mConnections, aux.mConnections)) { + duplicated = aux; + } + } + if(duplicated != null) return duplicated; + else throw new NoSuchElementException(profile.getName()); + } + + private boolean sameConnections(Connection[] c1, Connection[] c2) { + int same_connections = 0; + for(Connection c1_aux : c1) { + for(Connection c2_aux : c2) + if(c2_aux.mServerName.equals(c1_aux.mServerName)) { + same_connections++; + break; + } + } + return c1.length == c2.length && c1.length == same_connections; + + } + + private void removeDuplicatedGateway(VpnProfile profile) { + Iterator it = gateways.iterator(); + List gateways_to_remove = new ArrayList<>(); + while(it.hasNext()) { + Gateway aux = it.next(); + if(aux.getProfile().mConnections == profile.mConnections) + gateways_to_remove.add(aux); + } + gateways.removeAll(gateways_to_remove); + } + private void checkCertValidity() { VpnCertificateValidator validator = new VpnCertificateValidator(); int resultCode = validator.isValid(preferences.getString(CERTIFICATE, "")) ? -- cgit v1.2.3 From 407e3767744e39a59845423246a9ad427d933304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 2 Jan 2015 01:32:22 +0100 Subject: Update vpn profiles correctly. Before we add a new profile, we check if there are any duplicated ones with the same server IPs and ports. If they've the same credentials of the new one, we don't add anything; if not, we remove the old ones and add the new. --- .../main/java/se/leap/bitmaskclient/eip/EIP.java | 22 ++++++++++++++++++---- .../java/se/leap/bitmaskclient/eip/Gateway.java | 15 ++------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index cf6006e5..10d222c2 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -125,8 +125,9 @@ public final class EIP extends IntentService { if(gateway != null && gateway.getProfile() != null) { mReceiver = EipFragment.getReceiver(); launchActiveGateway(); - } - tellToReceiver(ACTION_START_EIP, Activity.RESULT_OK); + tellToReceiver(ACTION_START_EIP, Activity.RESULT_OK); + } else + tellToReceiver(ACTION_START_EIP, Activity.RESULT_CANCELED); } /** @@ -144,6 +145,8 @@ public final class EIP extends IntentService { intent.setAction(Intent.ACTION_MAIN); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(LaunchVPN.EXTRA_NAME, gateway.getProfile().getName()); + Log.d(TAG, gateway.getProfile().mClientCertFilename); + Log.d(TAG, gateway.getProfile().mClientKeyFilename); intent.putExtra(LaunchVPN.EXTRA_HIDELOG, true); startActivity(intent); } @@ -206,7 +209,7 @@ public final class EIP extends IntentService { JSONObject gw = gatewaysDefined.getJSONObject(i); if (isOpenVpnGateway(gw)) { Gateway gateway = new Gateway(eip_definition, context, gw); - if(!gateways.contains(gateway)) { + if(!containsProfileWithSecrets(gateway.getProfile())) { addGateway(gateway); } } @@ -260,6 +263,17 @@ public final class EIP extends IntentService { return false; } + private boolean containsProfileWithSecrets(VpnProfile profile) { + if(!containsProfile(profile)) return false; + + Collection profiles = profile_manager.getProfiles(); + for(VpnProfile aux : profiles) { + return profile.mClientCertFilename.equalsIgnoreCase(aux.mClientCertFilename) + && profile.mClientKeyFilename.equalsIgnoreCase(aux.mClientKeyFilename); + } + + return false; + } private VpnProfile duplicatedProfile(VpnProfile profile) { VpnProfile duplicated = null; Collection profiles = profile_manager.getProfiles(); @@ -290,7 +304,7 @@ public final class EIP extends IntentService { List gateways_to_remove = new ArrayList<>(); while(it.hasNext()) { Gateway aux = it.next(); - if(aux.getProfile().mConnections == profile.mConnections) + if(sameConnections(aux.getProfile().mConnections, profile.mConnections)) gateways_to_remove.add(aux); } gateways.removeAll(gateways_to_remove); diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java index e23f67c7..005d0eec 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java @@ -25,6 +25,7 @@ import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; +import java.io.Serializable; import java.io.StringReader; import java.util.Collection; import java.util.Iterator; @@ -42,7 +43,7 @@ import se.leap.bitmaskclient.Dashboard; * @author Sean Leonard * @author Parménides GV */ -public class Gateway { +public class Gateway implements Serializable { private String TAG = Gateway.class.getSimpleName(); @@ -137,16 +138,4 @@ public class Gateway { public int getTimezone() { return timezone; } - - @Override - public boolean equals(Object o) { - if(o instanceof Gateway) { - VpnProfile compared_profile = ((Gateway) o).getProfile(); - return compared_profile.mConnections.equals(mVpnProfile.mConnections) - && compared_profile.mClientCertFilename != mVpnProfile.mClientCertFilename - && compared_profile.mClientKeyFilename != mVpnProfile.mClientKeyFilename; - } - else - return super.equals(o); - } } -- cgit v1.2.3 From 38fdfbdacf414ab85fffd833f57e5fc93b03ad4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 2 Jan 2015 13:45:31 +0100 Subject: Serialized gateways and correctly updating profiles --- app/build.gradle | 1 + .../java/se/leap/bitmaskclient/EipFragment.java | 2 +- .../java/se/leap/bitmaskclient/OnBootReceiver.java | 3 + .../main/java/se/leap/bitmaskclient/eip/EIP.java | 104 ++++++++++++++++----- .../java/se/leap/bitmaskclient/eip/Gateway.java | 34 +++---- .../leap/bitmaskclient/eip/VpnConfigGenerator.java | 56 +++++------ 6 files changed, 127 insertions(+), 73 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index f0ea5ac1..b5c50fa4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -44,6 +44,7 @@ dependencies { provided 'com.squareup.dagger:dagger-compiler:1.2.2+' compile 'com.github.pedrovgs:renderers:1.3+' compile 'com.intellij:annotations:12.0' + compile 'com.google.code.gson:gson:2+' } def processFileInplace(file, Closure processText) { diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java index a21e0cd1..54432033 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java @@ -187,8 +187,8 @@ public class EipFragment extends Fragment implements Observer { if(!eip_switch.isChecked()) { eip_switch.setChecked(true); - saveStatus(); } + saveStatus(); eipCommand(Constants.ACTION_START_EIP); } diff --git a/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java b/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java index 3b1033bc..96b87085 100644 --- a/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java +++ b/app/src/main/java/se/leap/bitmaskclient/OnBootReceiver.java @@ -4,6 +4,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.util.Log; import se.leap.bitmaskclient.eip.Constants; @@ -17,6 +18,8 @@ public class OnBootReceiver extends BroadcastReceiver { preferences = context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, Context.MODE_PRIVATE); boolean provider_configured = !preferences.getString(Provider.KEY, "").isEmpty(); boolean start_on_boot = preferences.getBoolean(Dashboard.START_ON_BOOT, false); + Log.d("OnBootReceiver", "Provider configured " + String.valueOf(provider_configured)); + Log.d("OnBootReceiver", "Start on boot " + String.valueOf(start_on_boot)); if(provider_configured && start_on_boot) { Intent dashboard_intent = new Intent(context, Dashboard.class); dashboard_intent.setAction(Constants.ACTION_START_EIP); diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 10d222c2..dcf36a82 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -25,10 +25,14 @@ import android.os.Bundle; import android.os.ResultReceiver; import android.util.Log; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; @@ -41,6 +45,7 @@ import de.blinkt.openvpn.core.Connection; import de.blinkt.openvpn.core.ProfileManager; import se.leap.bitmaskclient.Dashboard; import se.leap.bitmaskclient.EipFragment; +import se.leap.bitmaskclient.Provider; import static se.leap.bitmaskclient.eip.Constants.ACTION_CHECK_CERT_VALIDITY; import static se.leap.bitmaskclient.eip.Constants.ACTION_IS_EIP_RUNNING; @@ -87,12 +92,14 @@ public final class EIP extends IntentService { super.onCreate(); context = getApplicationContext(); - profile_manager = ProfileManager.getInstance(context); + preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE); - preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE); - refreshEipDefinition(); + profile_manager = ProfileManager.getInstance(context); + eip_definition = eipDefinitionFromPreferences(); + if(gateways.isEmpty()) + gateways = gatewaysFromPreferences(); } - + @Override protected void onHandleIntent(Intent intent) { String action = intent.getAction(); @@ -122,6 +129,7 @@ public final class EIP extends IntentService { GatewaySelector gateway_selector = new GatewaySelector(gateways); gateway = gateway_selector.select(); + Log.d(TAG, "Connecting to " + gateway.getProfile().getUUIDString()); if(gateway != null && gateway.getProfile() != null) { mReceiver = EipFragment.getReceiver(); launchActiveGateway(); @@ -179,28 +187,42 @@ public final class EIP extends IntentService { * TODO Implement API call to refresh eip-service.json from the provider */ private void updateEIPService() { - refreshEipDefinition(); + eip_definition = eipDefinitionFromPreferences(); if(eip_definition != null) updateGateways(); tellToReceiver(ACTION_UPDATE_EIP_SERVICE, Activity.RESULT_OK); } - private void refreshEipDefinition() { + private JSONObject eipDefinitionFromPreferences() { try { String eip_definition_string = preferences.getString(KEY, ""); if(!eip_definition_string.isEmpty()) { - eip_definition = new JSONObject(eip_definition_string); + return new JSONObject(eip_definition_string); } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } + return null; + } + + private List gatewaysFromPreferences() { + List result; + + String gateways_string = preferences.getString(Gateway.TAG, ""); + Log.d(TAG, "Recovering gateways: " + gateways_string); + Type type_list_gateways = new TypeToken>() {}.getType(); + result = gateways_string.isEmpty() ? + new ArrayList() + : (List) new Gson().fromJson(gateways_string, type_list_gateways); + Log.d(TAG, "Gateways from preferences = " + result.size()); + preferences.edit().remove(Gateway.TAG); + return result; } /** * Walk the list of gateways defined in eip-service.json and parse them into * Gateway objects. - * TODO Store the Gateways (as Serializable) in SharedPreferences */ private void updateGateways(){ try { @@ -208,12 +230,15 @@ public final class EIP extends IntentService { for (int i = 0; i < gatewaysDefined.length(); i++) { JSONObject gw = gatewaysDefined.getJSONObject(i); if (isOpenVpnGateway(gw)) { - Gateway gateway = new Gateway(eip_definition, context, gw); - if(!containsProfileWithSecrets(gateway.getProfile())) { - addGateway(gateway); + JSONObject secrets = secretsConfiguration(); + Gateway aux = new Gateway(eip_definition, secrets, gw); + Log.d(TAG, "Possible new gateway: " + aux.getProfile().getUUIDString()); + if(!containsProfileWithSecrets(aux.getProfile())) { + addGateway(aux); } } } + gatewaysToPreferences(); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -229,6 +254,19 @@ public final class EIP extends IntentService { } } + + private JSONObject secretsConfiguration() { + JSONObject result = new JSONObject(); + try { + result.put(Provider.CA_CERT, preferences.getString(Provider.CA_CERT, "")); + result.put(Constants.PRIVATE_KEY, preferences.getString(Constants.PRIVATE_KEY, "")); + result.put(Constants.CERTIFICATE, preferences.getString(Constants.CERTIFICATE, "")); + } catch (JSONException e) { + e.printStackTrace(); + } + return result; + } + private void addGateway(Gateway gateway) { VpnProfile profile = gateway.getProfile(); removeGateway(gateway); @@ -247,10 +285,12 @@ public final class EIP extends IntentService { removeDuplicatedGateway(profile); } - private void removeDuplicatedProfile(VpnProfile remove) { - if(containsProfile(remove)) - profile_manager.removeProfile(context, duplicatedProfile(remove)); - if(containsProfile(remove)) removeDuplicatedProfile(remove); + private void removeDuplicatedProfile(VpnProfile original) { + if(containsProfile(original)) { + VpnProfile remove = duplicatedProfile(original); + profile_manager.removeProfile(context, remove); + Log.d(TAG, "Removing profile " + remove.getUUIDString()); + }if(containsProfile(original)) removeDuplicatedProfile(original); } private boolean containsProfile(VpnProfile profile) { @@ -264,16 +304,21 @@ public final class EIP extends IntentService { } private boolean containsProfileWithSecrets(VpnProfile profile) { - if(!containsProfile(profile)) return false; - - Collection profiles = profile_manager.getProfiles(); - for(VpnProfile aux : profiles) { - return profile.mClientCertFilename.equalsIgnoreCase(aux.mClientCertFilename) - && profile.mClientKeyFilename.equalsIgnoreCase(aux.mClientKeyFilename); - } - - return false; + boolean result = false; + + if(containsProfile(profile)) { + Collection profiles = profile_manager.getProfiles(); + for(VpnProfile aux : profiles) { + result = result == false ? + sameConnections(profile.mConnections, aux.mConnections) + && profile.mClientCertFilename.equalsIgnoreCase(aux.mClientCertFilename) + && profile.mClientKeyFilename.equalsIgnoreCase(aux.mClientKeyFilename) + : true; + } + } + return result; } + private VpnProfile duplicatedProfile(VpnProfile profile) { VpnProfile duplicated = null; Collection profiles = profile_manager.getProfiles(); @@ -304,12 +349,21 @@ public final class EIP extends IntentService { List gateways_to_remove = new ArrayList<>(); while(it.hasNext()) { Gateway aux = it.next(); - if(sameConnections(aux.getProfile().mConnections, profile.mConnections)) + if(sameConnections(aux.getProfile().mConnections, profile.mConnections)) { gateways_to_remove.add(aux); + Log.d(TAG, "Removing gateway " + aux.getProfile().getUUIDString()); + } } gateways.removeAll(gateways_to_remove); } + private void gatewaysToPreferences() { + Type type_list_gateways = new TypeToken>() {}.getType(); + String gateways_string = new Gson().toJson(gateways, type_list_gateways); + Log.d(TAG, "Saving gateways: " + gateways_string); + preferences.edit().putString(Gateway.TAG, gateways_string).apply(); + } + private void checkCertValidity() { VpnCertificateValidator validator = new VpnCertificateValidator(); int resultCode = validator.isValid(preferences.getString(CERTIFICATE, "")) ? diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java index 005d0eec..daf7d4a7 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java @@ -17,7 +17,6 @@ package se.leap.bitmaskclient.eip; import android.app.Activity; -import android.content.Context; import android.content.SharedPreferences; import android.util.Log; @@ -25,14 +24,10 @@ import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; -import java.io.Serializable; import java.io.StringReader; -import java.util.Collection; -import java.util.Iterator; import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.core.ConfigParser; -import de.blinkt.openvpn.core.ProfileManager; import se.leap.bitmaskclient.Dashboard; /** @@ -43,28 +38,26 @@ import se.leap.bitmaskclient.Dashboard; * @author Sean Leonard * @author Parménides GV */ -public class Gateway implements Serializable { - - private String TAG = Gateway.class.getSimpleName(); +public class Gateway { + public static String TAG = Gateway.class.getSimpleName(); + + private JSONObject general_configuration; + private JSONObject secrets; + private JSONObject gateway; + private String mName; private int timezone; - private JSONObject general_configuration; - private Context context; private VpnProfile mVpnProfile; - private JSONObject mGateway; - /** * Build a gateway object from a JSON OpenVPN gateway definition in eip-service.json * and create a VpnProfile belonging to it. - * - * @param gateway The JSON OpenVPN gateway definition to parse */ - protected Gateway(JSONObject eip_definition, Context context, JSONObject gateway){ + protected Gateway(JSONObject eip_definition, JSONObject secrets, JSONObject gateway){ + + this.gateway = gateway; + this.secrets = secrets; - mGateway = gateway; - - this.context = context; general_configuration = getGeneralConfiguration(eip_definition); timezone = getTimezone(eip_definition); mName = locationAsName(eip_definition); @@ -95,7 +88,7 @@ public class Gateway implements Serializable { try { JSONObject locations = eip_definition.getJSONObject("locations"); - return locations.getJSONObject(mGateway.getString("location")); + return locations.getJSONObject(gateway.getString("location")); } catch (JSONException e) { return new JSONObject(); } @@ -108,8 +101,7 @@ public class Gateway implements Serializable { try { ConfigParser cp = new ConfigParser(); - SharedPreferences preferences = context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE); - VpnConfigGenerator vpn_configuration_generator = new VpnConfigGenerator(preferences, general_configuration, mGateway); + VpnConfigGenerator vpn_configuration_generator = new VpnConfigGenerator(general_configuration, secrets, gateway); String configuration = vpn_configuration_generator.generate(); cp.parseConfig(new StringReader(configuration)); diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java index a320bee5..6f260f55 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java @@ -31,15 +31,15 @@ public class VpnConfigGenerator { private JSONObject general_configuration; private JSONObject gateway; - - private static SharedPreferences preferences; + private JSONObject secrets; + 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) { + public VpnConfigGenerator(JSONObject general_configuration, JSONObject secrets, JSONObject gateway) { this.general_configuration = general_configuration; this.gateway = gateway; - VpnConfigGenerator.preferences = preferences; + this.secrets = secrets; } public String generate() { @@ -113,29 +113,33 @@ public class VpnConfigGenerator { } private String secretsConfiguration() { - - String ca = - "" - + new_line - + preferences.getString(Provider.CA_CERT, "") - + new_line - + ""; - - String key = - "" - + new_line - + preferences.getString(Constants.PRIVATE_KEY, "") - + new_line - + ""; - - String openvpn_cert = - "" - + new_line - + preferences.getString(Constants.CERTIFICATE, "") - + new_line - + ""; + try { + String ca = + "" + + new_line + + secrets.getString(Provider.CA_CERT) + + new_line + + ""; + + String key = + "" + + new_line + + secrets.getString(Constants.PRIVATE_KEY) + + new_line + + ""; + + String openvpn_cert = + "" + + new_line + + secrets.getString(Constants.CERTIFICATE) + + new_line + + ""; - return ca + new_line + key + new_line + openvpn_cert; + return ca + new_line + key + new_line + openvpn_cert; + } catch(JSONException e) { + e.printStackTrace(); + return ""; + } } private String androidCustomizations() { -- cgit v1.2.3