From ee49de021bab8838ed44897f1046cb7d0f8f5921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 16 Jun 2014 22:31:50 +0200 Subject: Check if there is an active gateway selected. The active gateway cannot be null. --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 59faf93f..a7a17e5f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -234,8 +234,9 @@ public final class EIP extends IntentService { * Intent to {@link se.leap.openvpn.LaunchVPN} */ private void startEIP() { - activeGateway = selectGateway(); + activeGateway = selectGateway(); + if(activeGateway != null && activeGateway.mVpnProfile != null) { Intent intent = new Intent(this,LaunchVPN.class); intent.setAction(Intent.ACTION_MAIN); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -245,6 +246,7 @@ public final class EIP extends IntentService { intent.putExtra(RECEIVER_TAG, mReceiver); startActivity(intent); mPending = ACTION_START_EIP; + } } /** -- cgit v1.2.3 From 55c7a76f27b04db8a05400882897f88f8436bfac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 17 Jun 2014 12:24:36 +0200 Subject: Progressbar can be null if there is no EIP service This happens when you've used a eip enabled provider, and then you switch to a non eip enabled one (e.g., choosing demo.bitmask.net and then switching to cdev.bitmask.net in their current configurations). I've also disabled the build task dependency on updating ics-openvpn. It's causing problems, while not fixing anything. --- app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 446ba1d9..299d89a4 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -221,7 +221,8 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe mEipStartPending = false; } else if ( level == ConnectionStatus.LEVEL_NONETWORK || level == ConnectionStatus.LEVEL_NOTCONNECTED || level == ConnectionStatus.LEVEL_AUTH_FAILED) { statusMessage = getString(R.string.eip_state_not_connected); - getActivity().findViewById(R.id.eipProgress).setVisibility(View.GONE); + if(getActivity() != null && getActivity().findViewById(R.id.eipProgress) != null) + getActivity().findViewById(R.id.eipProgress).setVisibility(View.GONE); mEipStartPending = false; switchState = false; } else if (level == ConnectionStatus.LEVEL_CONNECTING_SERVER_REPLIED) { -- cgit v1.2.3 From b762eed7b3f9117ec682fc6e44125934dddc8d41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 18 Jun 2014 20:35:58 +0200 Subject: provider.json is downloaded before ca.crt We don't assume ca.crt is in /ca.crt anymore, but fetch the complete url from provider.json. We also signup against users.json file instead of simple "users", which worked for *.bitmask.net domains. --- app/src/main/java/se/leap/bitmaskclient/Provider.java | 1 + 1 file changed, 1 insertion(+) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java index 216f4261..5326709f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java @@ -51,6 +51,7 @@ public final class Provider implements Serializable { SERVICE = "service", KEY = "provider", CA_CERT = "ca_cert", + CA_CERT_URI = "ca_cert_uri", NAME = "name", DESCRIPTION = "description", DOMAIN = "domain", -- cgit v1.2.3 From d0383a325d3ec81be8dc354cb806f74b8d047c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 20 Jun 2014 00:35:08 +0200 Subject: Removed isRunning from OpenVpnService. We use the broadcasted eip status from ics-openvpn to know if we're connected or not. --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index a7a17e5f..c439d6b7 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -142,7 +142,7 @@ public final class EIP extends IntentService { return bindService(bindIntent, mVpnServiceConn, BIND_AUTO_CREATE); } - private static ServiceConnection mVpnServiceConn = new ServiceConnection() { + private ServiceConnection mVpnServiceConn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { LocalBinder binder = (LocalBinder) service; @@ -151,7 +151,7 @@ public final class EIP extends IntentService { if (mReceiver != null && mPending != null) { - boolean running = mVpnService.isRunning(); + boolean running = isConnected(); int resultCode = Activity.RESULT_CANCELED; @@ -202,7 +202,7 @@ public final class EIP extends IntentService { Bundle resultData = new Bundle(); resultData.putString(REQUEST_TAG, ACTION_IS_EIP_RUNNING); int resultCode = Activity.RESULT_CANCELED; - boolean is_connected = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(STATUS, "").equalsIgnoreCase("LEVEL_CONNECTED"); + boolean is_connected = isConnected(); if (mBound) { resultCode = (is_connected) ? Activity.RESULT_OK : Activity.RESULT_CANCELED; @@ -228,6 +228,10 @@ public final class EIP extends IntentService { } } } + + private boolean isConnected() { + return getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(STATUS, "").equalsIgnoreCase("LEVEL_CONNECTED"); + } /** * Initiates an EIP connection by selecting a gateway and preparing and sending an -- cgit v1.2.3 From 93d5f11aed48eb822f02a9fede4a2819d053ad83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 20 Jun 2014 02:42:43 +0200 Subject: Removed setDefinition from ConfigParser. We now directly use the parseConfiguration method, translating the eip-service.json openvpn options to a string containing the corresponding openvpn config file lines. --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 181 ++++++++++------------- 1 file changed, 79 insertions(+), 102 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index c439d6b7..c340467c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -16,6 +16,8 @@ */ package se.leap.bitmaskclient; +import java.io.StringReader; +import java.io.IOException; import java.util.Calendar; import java.util.Collection; import java.util.HashMap; @@ -472,7 +474,6 @@ public final class EIP extends IntentService { } } - this.parseOptions(); this.createVPNProfile(); setUniqueProfileName(vpl); @@ -508,125 +509,101 @@ public final class EIP extends IntentService { } } - /** - * FIXME This method is really the outline of the refactoring needed in se.leap.openvpn.ConfigParser - */ - private void parseOptions(){ - - // FIXME move these to a common API (& version) definition place, like ProviderAPI or ConfigHelper - String common_options = "openvpn_configuration"; - String remote = "ip_address"; - String ports = "ports"; - String protos = "protocols"; - String capabilities = "capabilities"; - String location_key = "location"; - String locations = "locations"; - - Vector arg = new Vector(); - Vector> args = new Vector>(); + /** + * Parses data from eip-service.json to a section of the openvpn config file + */ + private StringReader configFromEipServiceDotJson() { + String parsed_configuration = ""; + + String common_options = "openvpn_configuration"; + String remote = "ip_address"; + String ports = "ports"; + String protos = "protocols"; + String capabilities = "capabilities"; + String location_key = "location"; + String locations = "locations"; + + Vector arg = new Vector(); + Vector> args = new Vector>(); - try { - JSONObject def = (JSONObject) eipDefinition.get(common_options); - Iterator keys = def.keys(); - Vector> value = new Vector>(); - while ( keys.hasNext() ){ - String key = keys.next().toString(); + try { + JSONObject openvpn_configuration = eipDefinition.getJSONObject(common_options); + Iterator keys = openvpn_configuration.keys(); + Vector> value = new Vector>(); + while ( keys.hasNext() ){ + String key = keys.next().toString(); - arg.add(key); - for ( String word : def.getString(key).split(" ") ) - arg.add(word); - value.add( (Vector) arg.clone() ); - options.put(key, (Vector>) value.clone()); - value.clear(); - arg.clear(); - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - // We are always client, because the ifconfig will be received by a needed command - options.put("client", null); - - try { - arg.add(remote); - arg.add(mGateway.getString(remote)); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - args.add((Vector) arg.clone()); - options.put("remote", (Vector>) args.clone() ); - arg.clear(); - args.clear(); - - + parsed_configuration += key + " "; + for ( String word : openvpn_configuration.getString(key).split(" ") ) + parsed_configuration += word + " "; + parsed_configuration += System.getProperty("line.separator"); - // try { - // arg.add(location_key); - // String locationText = ""; - // locationText = eipDefinition.getJSONObject(locations).getJSONObject(mGateway.getString(location_key)).getString("name"); - // arg.add(locationText); - // Log.d(TAG, "location = " + locationText); + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } - // } catch (JSONException e) { - // // TODO Auto-generated catch block - // e.printStackTrace(); - // } - // args.add((Vector) arg.clone()); - // options.put("location", (Vector>) args.clone() ); + parsed_configuration += "client" + System.getProperty("line.separator"); - // arg.clear(); - // args.clear(); - JSONArray protocolsJSON = null; - arg.add("proto"); - try { - protocolsJSON = mGateway.getJSONObject(capabilities).getJSONArray(protos); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - Vector protocols = new Vector(); - for ( int i=0; i) arg.clone()); - options.put("proto", (Vector>) args.clone()); - arg.clear(); - args.clear(); - - - String port = null; - arg.add("port"); - try { - port = mGateway.getJSONObject(capabilities).getJSONArray(ports).optString(0); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - arg.add(port); - args.add((Vector) arg.clone()); - options.put("port", (Vector>) args.clone()); - args.clear(); - arg.clear(); + try { + JSONArray protocolsJSON = mGateway.getJSONObject(capabilities).getJSONArray(protos); + String remote_line = "remote"; + for ( int i=0; i>) args.clone() ); + + // arg.clear(); + // args.clear(); + + Log.d("EIP", "parsed configuration"); + Log.d("EIP", parsed_configuration); + return new StringReader(parsed_configuration.trim()); + } + /** * Create and attach the VpnProfile to our gateway object */ protected void createVPNProfile(){ try { ConfigParser cp = new ConfigParser(); - cp.setDefinition(options); + cp.parseConfig(configFromEipServiceDotJson()); VpnProfile vp = cp.convertProfile(); mVpnProfile = vp; Log.v(TAG,"Created VPNProfile"); } catch (ConfigParseError e) { // FIXME We didn't get a VpnProfile! Error handling! and log level - Log.v(TAG,"Error createing VPNProfile"); + Log.v(TAG,"Error creating VPNProfile"); + e.printStackTrace(); + } catch (IOException e) { + // FIXME We didn't get a VpnProfile! Error handling! and log level + Log.v(TAG,"Error creating VPNProfile"); e.printStackTrace(); } } -- cgit v1.2.3 From a7408bea88dc5eedecaba0ef430e63c6cca9ec20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 20 Jun 2014 03:34:50 +0200 Subject: Removed the authentication bits from VpnProfile. Now we embed the openvpn cert, the corresponding ca cert and the user key directly from EIP, while creating a vpn profile. We leave VpnProfile untouched. --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 69 +++++++++++++++++++++--- 1 file changed, 63 insertions(+), 6 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index c340467c..21a573fe 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.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 java.io.StringReader; import java.io.IOException; @@ -33,6 +33,9 @@ import org.json.JSONException; import org.json.JSONObject; import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.Dashboard; +import se.leap.bitmaskclient.Provider; + import de.blinkt.openvpn.activities.DisconnectVPN; import de.blinkt.openvpn.core.ConfigParser; import de.blinkt.openvpn.core.ConfigParser.ConfigParseError; @@ -42,12 +45,14 @@ import de.blinkt.openvpn.core.OpenVpnService; import de.blinkt.openvpn.core.OpenVpnService.LocalBinder; import de.blinkt.openvpn.core.ProfileManager; import de.blinkt.openvpn.VpnProfile; + 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; @@ -62,6 +67,7 @@ import android.util.Log; * gateways, and controlling {@link de.blinkt.openvpn.core.OpenVpnService} connections. * * @author Sean Leonard + * @author Parménides GV */ public final class EIP extends IntentService { @@ -512,7 +518,7 @@ public final class EIP extends IntentService { /** * Parses data from eip-service.json to a section of the openvpn config file */ - private StringReader configFromEipServiceDotJson() { + private String configFromEipServiceDotJson() { String parsed_configuration = ""; String common_options = "openvpn_configuration"; @@ -582,19 +588,70 @@ public final class EIP extends IntentService { // arg.clear(); // args.clear(); - Log.d("EIP", "parsed configuration"); - Log.d("EIP", parsed_configuration); - return new StringReader(parsed_configuration.trim()); + return parsed_configuration; } + + + private String caSecretFromSharedPreferences() { + String secret_lines = ""; + SharedPreferences preferences = context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, context.MODE_PRIVATE); + System.getProperty("line.separator"); + secret_lines += ""; + secret_lines += System.getProperty("line.separator"); + secret_lines += preferences.getString(Provider.CA_CERT, ""); + secret_lines += System.getProperty("line.separator"); + secret_lines += ""; + + return secret_lines; + } + + private String keySecretFromSharedPreferences() { + String secret_lines = ""; + SharedPreferences preferences = context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, context.MODE_PRIVATE); + + secret_lines += System.getProperty("line.separator"); + secret_lines +=""; + secret_lines += System.getProperty("line.separator"); + secret_lines += preferences.getString(EIP.PRIVATE_KEY, ""); + secret_lines += System.getProperty("line.separator"); + secret_lines += ""; + secret_lines += System.getProperty("line.separator"); + + return secret_lines; + } + + private String certSecretFromSharedPreferences() { + String secret_lines = ""; + SharedPreferences preferences = context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, context.MODE_PRIVATE); + + secret_lines += System.getProperty("line.separator"); + secret_lines +=""; + secret_lines += System.getProperty("line.separator"); + secret_lines += preferences.getString(EIP.CERTIFICATE, ""); + secret_lines += System.getProperty("line.separator"); + secret_lines += ""; + secret_lines += System.getProperty("line.separator"); + + return secret_lines; + } + /** * Create and attach the VpnProfile to our gateway object */ protected void createVPNProfile(){ try { ConfigParser cp = new ConfigParser(); - cp.parseConfig(configFromEipServiceDotJson()); + Log.d(TAG, configFromEipServiceDotJson()); + Log.d(TAG, caSecretFromSharedPreferences()); + Log.d(TAG, keySecretFromSharedPreferences()); + Log.d(TAG, certSecretFromSharedPreferences()); + cp.parseConfig(new StringReader(configFromEipServiceDotJson())); + cp.parseConfig(new StringReader(caSecretFromSharedPreferences())); + cp.parseConfig(new StringReader(keySecretFromSharedPreferences())); + cp.parseConfig(new StringReader(certSecretFromSharedPreferences())); VpnProfile vp = cp.convertProfile(); + //vp.mAuthenticationType=VpnProfile.TYPE_STATICKEYS; mVpnProfile = vp; Log.v(TAG,"Created VPNProfile"); } catch (ConfigParseError e) { -- cgit v1.2.3 From 55e9c0c60b94c09f8321dccd2971b32d92ec72a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 24 Jun 2014 10:29:09 +0200 Subject: We don't predict future certificate. --- app/src/main/java/se/leap/bitmaskclient/Dashboard.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index f2763d84..66c305e6 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -507,9 +507,9 @@ 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.CORRECTLY_DOWNLOADED_CERTIFICATE: eipStatus.setText(R.string.future_authed_secured_status); 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.future_anonymous_secured_status); break; + case ProviderAPI.LOGOUT_SUCCESSFUL: break; case ProviderAPI.LOGOUT_FAILED: eipStatus.setText(R.string.log_out_failed_message); break; } } -- cgit v1.2.3 From b5c84602ebb9bf2f593d4352dfe51029f44731b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 25 Jun 2014 19:44:14 +0200 Subject: Show "Logged out." message. --- app/src/main/java/se/leap/bitmaskclient/Dashboard.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index 66c305e6..cb451b86 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -496,7 +496,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf case ProviderAPI.SRP_AUTHENTICATION_FAILED: eipStatus.setText(R.string.authentication_failed_message); break; case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE: eipStatus.setText(R.string.authed_secured_status); break; case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: eipStatus.setText(R.string.incorrectly_downloaded_certificate_message); break; - case ProviderAPI.LOGOUT_SUCCESSFUL: eipStatus.setText(R.string.anonymous_secured_status); break; + case ProviderAPI.LOGOUT_SUCCESSFUL: eipStatus.setText(R.string.logged_out_message); break; case ProviderAPI.LOGOUT_FAILED: eipStatus.setText(R.string.log_out_failed_message); break; } @@ -509,7 +509,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf case ProviderAPI.SRP_AUTHENTICATION_FAILED: eipStatus.setText(R.string.authentication_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: break; + case ProviderAPI.LOGOUT_SUCCESSFUL: eipStatus.setText(R.string.logged_out_message); break; case ProviderAPI.LOGOUT_FAILED: eipStatus.setText(R.string.log_out_failed_message); break; } } -- cgit v1.2.3 From f8932f11321fe2fac70edc9827f6a3517ee990c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 27 Jun 2014 19:51:57 +0200 Subject: Download certificate if expired. --- .../main/java/se/leap/bitmaskclient/Dashboard.java | 17 +++++++++- app/src/main/java/se/leap/bitmaskclient/EIP.java | 25 +++++++++++++++ .../se/leap/bitmaskclient/EipServiceFragment.java | 36 +++++++++++++++++++--- 3 files changed, 72 insertions(+), 6 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java index cb451b86..117e45d8 100644 --- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java +++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java @@ -472,9 +472,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf } else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) { setResult(RESULT_OK); changeStatusMessage(resultCode); - mProgressBar.setVisibility(ProgressBar.GONE); + if(mProgressBar != null) + mProgressBar.setVisibility(ProgressBar.GONE); if(EipServiceFragment.isEipSwitchChecked()) eipStart(); + else + eipStatus.setText(R.string.eip_state_not_connected); } else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { setResult(RESULT_CANCELED); changeStatusMessage(resultCode); @@ -570,4 +573,16 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf startService(eip_intent); } + + protected void setProgressBarVisibility(int visibility) { + if(mProgressBar == null) + mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); + mProgressBar.setVisibility(visibility); + } + + protected void setEipStatus(int status) { + if(eipStatus == null) + eipStatus = (TextView) findViewById(R.id.eipStatus); + eipStatus.setText(status); + } } diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 21a573fe..ea5d7ab6 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -27,6 +27,9 @@ import java.util.NoSuchElementException; import java.util.Set; import java.util.TreeMap; import java.util.Vector; +import java.security.cert.X509Certificate; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateNotYetValidException; import org.json.JSONArray; import org.json.JSONException; @@ -72,6 +75,7 @@ import android.util.Log; public final class EIP extends IntentService { public final static String AUTHED_EIP = "authed eip"; + public final static String ACTION_CHECK_CERT_VALIDITY = "se.leap.bitmaskclient.CHECK_CERT_VALIDITY"; public final static String ACTION_START_EIP = "se.leap.bitmaskclient.START_EIP"; public final static String ACTION_STOP_EIP = "se.leap.bitmaskclient.STOP_EIP"; public final static String ACTION_UPDATE_EIP_SERVICE = "se.leap.bitmaskclient.UPDATE_EIP_SERVICE"; @@ -138,6 +142,8 @@ public final class EIP extends IntentService { this.startEIP(); else if ( action == ACTION_STOP_EIP ) this.stopEIP(); + else if ( action == ACTION_CHECK_CERT_VALIDITY ) + this.checkCertValidity(); } /** @@ -408,6 +414,25 @@ public final class EIP extends IntentService { getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putInt(PARSED_SERIAL, eipDefinition.optInt(Provider.API_RETURN_SERIAL)).commit(); } + private void checkCertValidity() { + Log.d(TAG, "check cert validity"); + String certificate_string = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(CERTIFICATE, ""); + X509Certificate certificate_x509 = ConfigHelper.parseX509CertificateFromString(certificate_string); + // Fetch a new certificate if the current one is going to expire in less than 7 days + Calendar offset_date = Calendar.getInstance(); + offset_date.add(Calendar.DATE, 10); + Bundle result_data = new Bundle(); + result_data.putString(REQUEST_TAG, ACTION_CHECK_CERT_VALIDITY); + try { + certificate_x509.checkValidity(offset_date.getTime()); + mReceiver.send(Activity.RESULT_OK, result_data); + } catch(CertificateExpiredException e) { + mReceiver.send(Activity.RESULT_CANCELED, result_data); + } catch(CertificateNotYetValidException e) { + mReceiver.send(Activity.RESULT_CANCELED, result_data); + } + } + /** * OVPNGateway provides objects defining gateways and their options and metadata. * Each instance contains a VpnProfile for OpenVPN specific data and member diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 299d89a4..ef367a17 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -1,6 +1,10 @@ package se.leap.bitmaskclient; import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.ProviderAPIResultReceiver; +import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver; +import se.leap.bitmaskclient.Dashboard; + import de.blinkt.openvpn.activities.LogWindow; import de.blinkt.openvpn.core.VpnStatus; import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; @@ -21,6 +25,7 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.CompoundButton; +import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.Switch; import android.widget.TextView; @@ -37,7 +42,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe private boolean eipAutoSwitched = true; - private boolean mEipStartPending = false; + private boolean mEipStartPending = false; private boolean set_switch_off = false; @@ -100,6 +105,8 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe eipSwitch.setChecked(false); set_switch_off = false; } + + eipCommand(EIP.ACTION_CHECK_CERT_VALIDITY); } protected void setSwitchOff(boolean value) { @@ -198,9 +205,10 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe */ private void eipCommand(String action){ // TODO validate "action"...how do we get the list of intent-filters for a class via Android API? - Intent vpnIntent = new Intent(action); - vpnIntent.putExtra(EIP.RECEIVER_TAG, mEIPReceiver); - getActivity().startService(vpnIntent); + Intent vpn_intent = new Intent(getActivity().getApplicationContext(), EIP.class); + vpn_intent.setAction(action); + vpn_intent.putExtra(EIP.RECEIVER_TAG, mEIPReceiver); + getActivity().startService(vpn_intent); } @Override @@ -256,7 +264,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe @Override protected void onReceiveResult(int resultCode, Bundle resultData) { super.onReceiveResult(resultCode, resultData); - + String request = resultData.getString(EIP.REQUEST_TAG); boolean checked = false; @@ -298,6 +306,24 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe checked = false; break; } + } else if (request == EIP.ACTION_CHECK_CERT_VALIDITY) { + switch (resultCode) { + case Activity.RESULT_OK: + break; + case Activity.RESULT_CANCELED: + Dashboard dashboard = (Dashboard) getActivity(); + dashboard.setProgressBarVisibility(ProgressBar.VISIBLE); + dashboard.setEipStatus(R.string.updating_certificate_message); + ProviderAPIResultReceiver providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); + providerAPI_result_receiver.setReceiver((Receiver)getActivity()); + + Intent provider_API_command = new Intent(getActivity(), ProviderAPI.class); + provider_API_command.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); + provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); + + getActivity().startService(provider_API_command); + break; + } } eipAutoSwitched = true; -- cgit v1.2.3 From ca9952b324d153d1580f73ce8c999542ec1883c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 2 Jul 2014 19:48:34 +0200 Subject: Fetch new certificate and restart EIP. --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 8 ++++--- .../se/leap/bitmaskclient/EipServiceFragment.java | 26 +++++++++------------- 2 files changed, 15 insertions(+), 19 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index ea5d7ab6..19625ba1 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -279,7 +279,7 @@ public final class EIP extends IntentService { disconnect_vpn.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(disconnect_vpn); } - + if (mReceiver != null){ Bundle resultData = new Bundle(); resultData.putString(REQUEST_TAG, ACTION_STOP_EIP); @@ -415,19 +415,21 @@ public final class EIP extends IntentService { } private void checkCertValidity() { - Log.d(TAG, "check cert validity"); String certificate_string = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(CERTIFICATE, ""); X509Certificate certificate_x509 = ConfigHelper.parseX509CertificateFromString(certificate_string); // Fetch a new certificate if the current one is going to expire in less than 7 days Calendar offset_date = Calendar.getInstance(); - offset_date.add(Calendar.DATE, 10); + offset_date.add(Calendar.DATE, 7); + Bundle result_data = new Bundle(); result_data.putString(REQUEST_TAG, ACTION_CHECK_CERT_VALIDITY); try { certificate_x509.checkValidity(offset_date.getTime()); mReceiver.send(Activity.RESULT_OK, result_data); + Log.d(TAG, "Valid certificate"); } catch(CertificateExpiredException e) { mReceiver.send(Activity.RESULT_CANCELED, result_data); + Log.d(TAG, "Updating certificate"); } catch(CertificateNotYetValidException e) { mReceiver.send(Activity.RESULT_CANCELED, result_data); } diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index ef367a17..200e25e6 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -44,8 +44,6 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe private boolean mEipStartPending = false; - private boolean set_switch_off = false; - private static EIPReceiver mEIPReceiver; @@ -101,17 +99,9 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe super.onResume(); VpnStatus.addStateListener(this); - if(set_switch_off) { - eipSwitch.setChecked(false); - set_switch_off = false; - } eipCommand(EIP.ACTION_CHECK_CERT_VALIDITY); } - - protected void setSwitchOff(boolean value) { - set_switch_off = value; - } @Override public void onPause() { @@ -138,8 +128,7 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe } @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - Log.d("bitmask", "onCheckChanged"); - if (buttonView.equals(eipSwitch) && !eipAutoSwitched){ + if (buttonView.equals(eipSwitch) && !eipAutoSwitched){ boolean allowed_anon = getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE).getBoolean(EIP.ALLOWED_ANON, false); String certificate = getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE).getString(EIP.CERTIFICATE, ""); if(allowed_anon || !certificate.isEmpty()) { @@ -307,20 +296,25 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe break; } } else if (request == EIP.ACTION_CHECK_CERT_VALIDITY) { + checked = eipSwitch.isChecked(); + switch (resultCode) { case Activity.RESULT_OK: break; case Activity.RESULT_CANCELED: Dashboard dashboard = (Dashboard) getActivity(); + dashboard.setProgressBarVisibility(ProgressBar.VISIBLE); dashboard.setEipStatus(R.string.updating_certificate_message); - ProviderAPIResultReceiver providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); - providerAPI_result_receiver.setReceiver((Receiver)getActivity()); 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, providerAPI_result_receiver); - + provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, dashboard.providerAPI_result_receiver); getActivity().startService(provider_API_command); break; } -- cgit v1.2.3 From 70aa1258b34bf277595a7e5178e6fb914d10f13b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 2 Jul 2014 20:19:36 +0200 Subject: If authentication fails, restart eip. This happens when we update the openvpn certificate, in the first connection attempt. --- app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java index 200e25e6..5a5bb568 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java @@ -169,8 +169,12 @@ public class EipServiceFragment extends Fragment implements StateListener, OnChe } } else { - if(!eipSwitch.isChecked()) - eipStatus.setText(R.string.state_noprocess); + if(!eipSwitch.isChecked()) { + if(getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE).getString(EIP.STATUS, "").equalsIgnoreCase(ConnectionStatus.LEVEL_AUTH_FAILED.toString())) + startEipFromScratch(); + else + eipStatus.setText(R.string.state_noprocess); + } } eipAutoSwitched = true; saveEipStatus(); -- cgit v1.2.3 From a23c12674abd836b3abd4feeaf057236cfd0ca27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 7 Jul 2014 19:28:13 +0200 Subject: New certificate if half of its lifetime passed. It takes for granted that the certificate is valid from the very same date it's downloaded. --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 80 ++++++++++++++---------- 1 file changed, 47 insertions(+), 33 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 19625ba1..75c6ada8 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -16,38 +16,9 @@ */ package se.leap.bitmaskclient; -import java.io.StringReader; -import java.io.IOException; -import java.util.Calendar; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.TreeMap; -import java.util.Vector; -import java.security.cert.X509Certificate; -import java.security.cert.CertificateExpiredException; -import java.security.cert.CertificateNotYetValidException; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.Dashboard; -import se.leap.bitmaskclient.Provider; -import de.blinkt.openvpn.activities.DisconnectVPN; -import de.blinkt.openvpn.core.ConfigParser; -import de.blinkt.openvpn.core.ConfigParser.ConfigParseError; -import de.blinkt.openvpn.LaunchVPN; -import de.blinkt.openvpn.core.OpenVpnManagementThread; -import de.blinkt.openvpn.core.OpenVpnService; -import de.blinkt.openvpn.core.OpenVpnService.LocalBinder; -import de.blinkt.openvpn.core.ProfileManager; -import de.blinkt.openvpn.VpnProfile; import android.app.Activity; import android.app.IntentService; @@ -61,6 +32,38 @@ 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.OpenVpnService.LocalBinder; +import de.blinkt.openvpn.core.OpenVpnService; +import de.blinkt.openvpn.core.ProfileManager; +import java.io.IOException; +import java.io.StringReader; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.X509Certificate; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Locale; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.TreeMap; +import java.util.Vector; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import se.leap.bitmaskclient.Dashboard; +import se.leap.bitmaskclient.Provider; +import se.leap.bitmaskclient.R; /** * EIP is the abstract base class for interacting with and managing the Encrypted @@ -82,6 +85,7 @@ public final class EIP extends IntentService { public final static String ACTION_IS_EIP_RUNNING = "se.leap.bitmaskclient.IS_RUNNING"; public final static String EIP_NOTIFICATION = "EIP_NOTIFICATION"; public final static String STATUS = "eip status"; + public final static String DATE_FROM_CERTIFICATE = "date from certificate"; public final static String ALLOWED_ANON = "allow_anonymous"; public final static String CERTIFICATE = "cert"; public final static String PRIVATE_KEY = "private_key"; @@ -91,8 +95,9 @@ 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 = "se.leap.bitmaskclient.EIP"; - - + + 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 OpenVpnService mVpnService; @@ -416,14 +421,23 @@ public final class EIP extends IntentService { private void checkCertValidity() { String certificate_string = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(CERTIFICATE, ""); + String date_from_certificate_string = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(DATE_FROM_CERTIFICATE, Calendar.getInstance().getTime().toString()); X509Certificate certificate_x509 = ConfigHelper.parseX509CertificateFromString(certificate_string); - // Fetch a new certificate if the current one is going to expire in less than 7 days + Calendar offset_date = Calendar.getInstance(); - offset_date.add(Calendar.DATE, 7); + try { + long difference = Math.abs(certificate_date_format.parse(date_from_certificate_string).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); try { + Log.d(TAG, "offset_date = " + offset_date.getTime().toString()); certificate_x509.checkValidity(offset_date.getTime()); mReceiver.send(Activity.RESULT_OK, result_data); Log.d(TAG, "Valid certificate"); -- cgit v1.2.3 From 8ebea084e117365c4b7a9c10e56aaaceabcd43b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 4 Jul 2014 10:33:27 +0200 Subject: Change the name of the gateway to its location. This way, the notification shows the city of the gateway rather than the hostname :) --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 75c6ada8..01b7d827 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -369,7 +369,7 @@ public final class EIP extends IntentService { for (int i = 0; i < gateways.length(); i++) { JSONObject gw = gateways.getJSONObject(i); if ( gw.getString("location").equalsIgnoreCase(closestLocation) || closestLocation.isEmpty()){ - chosenHost = gw.getString("host"); + chosenHost = eipDefinition.getJSONObject("locations").getJSONObject(gw.getString("location")).getString("name"); break; } } @@ -480,7 +480,6 @@ public final class EIP extends IntentService { private void loadVpnProfile() { ProfileManager vpl = ProfileManager.getInstance(context); - try { if ( mName == null ) mVpnProfile = vpl.getProfiles().iterator().next(); @@ -510,8 +509,10 @@ public final class EIP extends IntentService { Collection profiles = vpl.getProfiles(); for (Iterator it = profiles.iterator(); it.hasNext(); ){ VpnProfile p = it.next(); + try { - if ( p.mName.equalsIgnoreCase( gateway.getString("host") ) ){ + String name = eipDefinition.getJSONObject("locations").getJSONObject(mGateway.getString("location")).getString("name"); + if ( p.mName.equalsIgnoreCase( name ) ) { it.remove(); vpl.removeProfile(context, p); } @@ -548,7 +549,9 @@ public final class EIP extends IntentService { newname = getString(R.string.converted_profile_i,i); } + newname = eipDefinition.getJSONObject("locations").getJSONObject(mGateway.getString("location")).getString("name"); mVpnProfile.mName=newname; + mName = newname; } catch (JSONException e) { // TODO Auto-generated catch block Log.v(TAG,"Couldn't read gateway name for profile creation!"); -- cgit v1.2.3 From e4c9c72dac9c7e3ffc257ba1c7d3803e7173a868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 4 Jul 2014 11:33:43 +0200 Subject: Extracted methods from some chunks of code. This is a first step for a refactoring of the EIP class. --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 275 +++++++++++------------ 1 file changed, 126 insertions(+), 149 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 01b7d827..5cac9825 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -260,26 +260,28 @@ public final class EIP extends IntentService { activeGateway = selectGateway(); if(activeGateway != null && activeGateway.mVpnProfile != null) { - Intent intent = new Intent(this,LaunchVPN.class); - intent.setAction(Intent.ACTION_MAIN); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(LaunchVPN.EXTRA_KEY, activeGateway.mVpnProfile.getUUID().toString() ); - intent.putExtra(LaunchVPN.EXTRA_NAME, activeGateway.mVpnProfile.getName() ); - intent.putExtra(LaunchVPN.EXTRA_HIDELOG, true); - intent.putExtra(RECEIVER_TAG, mReceiver); - startActivity(intent); - mPending = ACTION_START_EIP; + launchVpn(); } } + + private void launchVpn() { + Intent intent = new Intent(this,LaunchVPN.class); + intent.setAction(Intent.ACTION_MAIN); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(LaunchVPN.EXTRA_KEY, activeGateway.mVpnProfile.getUUID().toString() ); + intent.putExtra(LaunchVPN.EXTRA_NAME, activeGateway.mVpnProfile.getName() ); + 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 (mBound) - mVpnService.onRevoke(); - else if(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(STATUS, "").startsWith("LEVEL_CONNECT")){ + if(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(STATUS, "").startsWith("LEVEL_CONNECT")){ Intent disconnect_vpn = new Intent(this, DisconnectVPN.class); disconnect_vpn.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(disconnect_vpn); @@ -306,62 +308,27 @@ public final class EIP extends IntentService { e.printStackTrace(); } if(parsedEipSerial == 0) { - // Delete all vpn profiles - 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]); - } + deleteAllVpnProfiles(); } if (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]); + } + } /** * Choose a gateway to connect to based on timezone from system locale data * * @return The gateway to connect to */ private OVPNGateway selectGateway() { - // TODO Remove String arg constructor in favor of findGatewayByName(String) - - 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(); - } - } - + String closestLocation = closestGateway(); - String closestLocation = offsets.isEmpty() ? "" : offsets.firstEntry().getValue().iterator().next(); JSONArray gateways = null; String chosenHost = null; try { @@ -380,6 +347,44 @@ public final class EIP extends IntentService { 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 @@ -390,32 +395,19 @@ public final class EIP extends IntentService { JSONArray gatewaysDefined = null; try { - gatewaysDefined = eipDefinition.getJSONArray("gateways"); - } catch (JSONException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - for ( int i=0 ; i < gatewaysDefined.length(); i++ ){ - - JSONObject gw = null; + gatewaysDefined = eipDefinition.getJSONArray("gateways"); + for ( int i=0 ; i < gatewaysDefined.length(); i++ ){ + JSONObject gw = null; + gw = gatewaysDefined.getJSONObject(i); - try { - gw = gatewaysDefined.getJSONObject(i); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - try { - if ( gw.getJSONObject("capabilities").getJSONArray("transport").toString().contains("openvpn") ){ - new OVPNGateway(gw); - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + if ( gw.getJSONObject("capabilities").getJSONArray("transport").toString().contains("openvpn") ) + new OVPNGateway(gw); } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putInt(PARSED_SERIAL, eipDefinition.optInt(Provider.API_RETURN_SERIAL)).commit(); } @@ -538,18 +530,8 @@ public final class EIP extends IntentService { private void setUniqueProfileName(ProfileManager profileManager) { int i=0; - String newname; try { - newname = mGateway.getString("host"); - while(profileManager.getProfileByName(newname)!=null) { - i++; - if(i==1) - newname = getString(R.string.converted_profile); - else - newname = getString(R.string.converted_profile_i,i); - } - - newname = eipDefinition.getJSONObject("locations").getJSONObject(mGateway.getString("location")).getString("name"); + String newname = eipDefinition.getJSONObject("locations").getJSONObject(mGateway.getString("location")).getString("name"); mVpnProfile.mName=newname; mName = newname; } catch (JSONException e) { @@ -558,25 +540,55 @@ public final class EIP extends IntentService { e.printStackTrace(); } } + + /** + * Create and attach the VpnProfile to our gateway object + */ + protected void createVPNProfile(){ + try { + ConfigParser cp = new ConfigParser(); + Log.d(TAG, configFromEipServiceDotJson()); + Log.d(TAG, caSecretFromSharedPreferences()); + Log.d(TAG, keySecretFromSharedPreferences()); + Log.d(TAG, certSecretFromSharedPreferences()); + cp.parseConfig(new StringReader(configFromEipServiceDotJson())); + cp.parseConfig(new StringReader(caSecretFromSharedPreferences())); + cp.parseConfig(new StringReader(keySecretFromSharedPreferences())); + cp.parseConfig(new StringReader(certSecretFromSharedPreferences())); + VpnProfile vp = cp.convertProfile(); + //vp.mAuthenticationType=VpnProfile.TYPE_STATICKEYS; + mVpnProfile = vp; + Log.v(TAG,"Created VPNProfile"); + } catch (ConfigParseError e) { + // FIXME We didn't get a VpnProfile! Error handling! and log level + Log.v(TAG,"Error creating VPNProfile"); + e.printStackTrace(); + } catch (IOException e) { + // FIXME We didn't get a VpnProfile! Error handling! and log level + Log.v(TAG,"Error creating VPNProfile"); + e.printStackTrace(); + } + } /** * Parses data from eip-service.json to a section of the openvpn config file */ private String configFromEipServiceDotJson() { String parsed_configuration = ""; - - String common_options = "openvpn_configuration"; - String remote = "ip_address"; - String ports = "ports"; - String protos = "protocols"; - String capabilities = "capabilities"; + String location_key = "location"; String locations = "locations"; - - Vector arg = new Vector(); - Vector> args = new Vector>(); - + + parsed_configuration += extractCommonOptionsFromEipServiceDotJson(); + parsed_configuration += extractRemotesFromEipServiceDotJson(); + + return parsed_configuration; + } + + private String extractCommonOptionsFromEipServiceDotJson() { + String parsed_configuration = ""; try { + String common_options = "openvpn_configuration"; JSONObject openvpn_configuration = eipDefinition.getJSONObject(common_options); Iterator keys = openvpn_configuration.keys(); Vector> value = new Vector>(); @@ -596,7 +608,19 @@ public final class EIP extends IntentService { parsed_configuration += "client" + System.getProperty("line.separator"); - try { + return parsed_configuration; + } + + + private String extractRemotesFromEipServiceDotJson() { + String parsed_configuration = ""; + + String remote = "ip_address"; + String ports = "ports"; + String protos = "protocols"; + String capabilities = "capabilities"; + + try { JSONArray protocolsJSON = mGateway.getJSONObject(capabilities).getJSONArray(protos); String remote_line = "remote"; for ( int i=0; i>) args.clone() ); - - // arg.clear(); - // args.clear(); - return parsed_configuration; } - private String caSecretFromSharedPreferences() { String secret_lines = ""; SharedPreferences preferences = context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, context.MODE_PRIVATE); @@ -679,35 +685,6 @@ public final class EIP extends IntentService { return secret_lines; } - - /** - * Create and attach the VpnProfile to our gateway object - */ - protected void createVPNProfile(){ - try { - ConfigParser cp = new ConfigParser(); - Log.d(TAG, configFromEipServiceDotJson()); - Log.d(TAG, caSecretFromSharedPreferences()); - Log.d(TAG, keySecretFromSharedPreferences()); - Log.d(TAG, certSecretFromSharedPreferences()); - cp.parseConfig(new StringReader(configFromEipServiceDotJson())); - cp.parseConfig(new StringReader(caSecretFromSharedPreferences())); - cp.parseConfig(new StringReader(keySecretFromSharedPreferences())); - cp.parseConfig(new StringReader(certSecretFromSharedPreferences())); - VpnProfile vp = cp.convertProfile(); - //vp.mAuthenticationType=VpnProfile.TYPE_STATICKEYS; - mVpnProfile = vp; - Log.v(TAG,"Created VPNProfile"); - } catch (ConfigParseError e) { - // FIXME We didn't get a VpnProfile! Error handling! and log level - Log.v(TAG,"Error creating VPNProfile"); - e.printStackTrace(); - } catch (IOException e) { - // FIXME We didn't get a VpnProfile! Error handling! and log level - Log.v(TAG,"Error creating VPNProfile"); - e.printStackTrace(); - } - } } } -- cgit v1.2.3 From d4f006df65c03c75cda327d10073cd5cd27634bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 4 Jul 2014 12:06:26 +0200 Subject: Removed retrieveVpnService, it seems unuseful. I've tested autostart, on+off repeated times, and switch provider. It works. The ServiceConnection is managed by DisconnectVPN from ics-openvpn, it's not useful. --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 110 ++++------------------- 1 file changed, 16 insertions(+), 94 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 5cac9825..434b5121 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -121,13 +121,11 @@ public final class EIP extends IntentService { context = getApplicationContext(); updateEIPService(); - - this.retreiveVpnService(); } @Override public void onDestroy() { - unbindService(mVpnServiceConn); + mBound = false; super.onDestroy(); @@ -152,101 +150,25 @@ public final class EIP extends IntentService { } /** - * Sends an Intent to bind OpenVpnService. - * Used when OpenVpnService isn't bound but might be running. - */ - private boolean retreiveVpnService() { - Intent bindIntent = new Intent(this,OpenVpnService.class); - bindIntent.setAction(OpenVpnService.START_SERVICE); - return bindService(bindIntent, mVpnServiceConn, BIND_AUTO_CREATE); - } - - private ServiceConnection mVpnServiceConn = new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - LocalBinder binder = (LocalBinder) service; - mVpnService = binder.getService(); - mBound = true; - - if (mReceiver != null && mPending != null) { - - boolean running = isConnected(); - - int resultCode = Activity.RESULT_CANCELED; - - if (mPending.equals(ACTION_IS_EIP_RUNNING)){ - resultCode = (running) ? Activity.RESULT_OK : Activity.RESULT_CANCELED; - - } - else if (mPending.equals(ACTION_START_EIP)){ - resultCode = (running) ? Activity.RESULT_OK : Activity.RESULT_CANCELED; - } - else if (mPending.equals(ACTION_STOP_EIP)){ - resultCode = (running) ? Activity.RESULT_CANCELED - : Activity.RESULT_OK; - } - Bundle resultData = new Bundle(); - resultData.putString(REQUEST_TAG, ACTION_IS_EIP_RUNNING); - mReceiver.send(resultCode, resultData); - - mPending = null; - } - } - - @Override - public void onServiceDisconnected(ComponentName name) { - mBound = false; - - if (mReceiver != null){ - Bundle resultData = new Bundle(); - resultData.putString(REQUEST_TAG, EIP_NOTIFICATION); - mReceiver.send(Activity.RESULT_CANCELED, resultData); - } - } - - - }; - - /** - * Attempts to determine if OpenVpnService has an established VPN connection - * through the bound ServiceConnection. If there is no bound service, this - * method will attempt to bind a running OpenVpnService and send - * Activity.RESULT_CANCELED to the ResultReceiver that made the - * request. - * Note: If the request to bind OpenVpnService is successful, the ResultReceiver - * will be notified in {@link onServiceConnected()} + * 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(); - if (mBound) { - resultCode = (is_connected) ? Activity.RESULT_OK : Activity.RESULT_CANCELED; + 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); - } - } else { - mPending = ACTION_IS_EIP_RUNNING; - boolean retrieved_vpn_service = retreiveVpnService(); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - boolean running = is_connected; - - if (retrieved_vpn_service && running && mReceiver != null){ - mReceiver.send(Activity.RESULT_OK, resultData); - } - else{ - mReceiver.send(Activity.RESULT_CANCELED, resultData); - } - } - } + if (mReceiver != null){ + mReceiver.send(resultCode, resultData); + } + + Log.d(TAG, "isRunning() = " + is_connected); + } private boolean isConnected() { return getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(STATUS, "").equalsIgnoreCase("LEVEL_CONNECTED"); -- cgit v1.2.3 From 5749b7ec95d9bb68548f6a002b5c5e91cb8a8f7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 4 Jul 2014 12:41:27 +0200 Subject: Udp as default transport + minor refactoring. I've also added a check for a nullpointer when eipDefinition is null. --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 44 +++++++++++++----------- 1 file changed, 23 insertions(+), 21 deletions(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 434b5121..5c1336a1 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -182,11 +182,11 @@ public final class EIP extends IntentService { activeGateway = selectGateway(); if(activeGateway != null && activeGateway.mVpnProfile != null) { - launchVpn(); + launchActiveGateway(); } } - private void launchVpn() { + private void launchActiveGateway() { Intent intent = new Intent(this,LaunchVPN.class); intent.setAction(Intent.ACTION_MAIN); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -203,12 +203,12 @@ public final class EIP extends IntentService { * if there is no bound service. Sends a message to the requesting ResultReceiver. */ private void stopEIP() { - if(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(STATUS, "").startsWith("LEVEL_CONNECT")){ + if(isConnected()) { Intent disconnect_vpn = new Intent(this, DisconnectVPN.class); disconnect_vpn.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(disconnect_vpn); } - + if (mReceiver != null){ Bundle resultData = new Bundle(); resultData.putString(REQUEST_TAG, ACTION_STOP_EIP); @@ -232,7 +232,7 @@ public final class EIP extends IntentService { if(parsedEipSerial == 0) { deleteAllVpnProfiles(); } - if (eipDefinition.optInt("serial") > parsedEipSerial) + if (eipDefinition != null && eipDefinition.optInt("serial") > parsedEipSerial) updateGateways(); } @@ -508,19 +508,19 @@ public final class EIP extends IntentService { } private String extractCommonOptionsFromEipServiceDotJson() { - String parsed_configuration = ""; + String common_options = ""; try { - String common_options = "openvpn_configuration"; - JSONObject openvpn_configuration = eipDefinition.getJSONObject(common_options); + 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(); - parsed_configuration += key + " "; + common_options += key + " "; for ( String word : openvpn_configuration.getString(key).split(" ") ) - parsed_configuration += word + " "; - parsed_configuration += System.getProperty("line.separator"); + common_options += word + " "; + common_options += System.getProperty("line.separator"); } } catch (JSONException e) { @@ -528,40 +528,42 @@ public final class EIP extends IntentService { e.printStackTrace(); } - parsed_configuration += "client" + System.getProperty("line.separator"); + common_options += "client" + System.getProperty("line.separator"); - return parsed_configuration; + return common_options; } private String extractRemotesFromEipServiceDotJson() { - String parsed_configuration = ""; + 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); - String remote_line = "remote"; for ( int i=0; i Date: Thu, 10 Jul 2014 12:40:26 +0200 Subject: We don't need support library from Robotium. I've also fixed a simple test that wasn't letting the suite to finish correctly. --- app/src/main/java/se/leap/bitmaskclient/EIP.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/src/main/java/se') diff --git a/app/src/main/java/se/leap/bitmaskclient/EIP.java b/app/src/main/java/se/leap/bitmaskclient/EIP.java index 0b43f9e1..7374d5ed 100644 --- a/app/src/main/java/se/leap/bitmaskclient/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/EIP.java @@ -445,7 +445,7 @@ public final class EIP extends IntentService { } catch (JSONException e) { Log.v(TAG,"Couldn't read gateway name for profile creation! Returning original name = " + mName); e.printStackTrace(); - return mName; + return (mName != null) ? mName : ""; } } -- cgit v1.2.3