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 +- app/src/main/res/values/untranslatable.xml | 78 +++++++++++++++++++++++- 2 files changed, 80 insertions(+), 2 deletions(-) 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; + } } /** diff --git a/app/src/main/res/values/untranslatable.xml b/app/src/main/res/values/untranslatable.xml index 50e598ac..4212cec2 100644 --- a/app/src/main/res/values/untranslatable.xml +++ b/app/src/main/res/values/untranslatable.xml @@ -777,4 +777,80 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From 65fb5a54be48e2664f1e4ef1faf1c36f881be09f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 16 Jun 2014 22:39:53 +0200 Subject: Bump version code for hotfix. --- app/src/main/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a2c2a82f..74af659a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,7 +17,7 @@ -- 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/build.gradle | 2 +- app/src/main/java/se/leap/bitmaskclient/EipServiceFragment.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 8c60eb0f..a57a2763 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -144,4 +144,4 @@ task mergeUntranslatable( type: Copy, dependsOn: 'removeDuplicatedStrings') { delete ics_openvpn_untranslatable } -build.dependsOn ':app:mergeUntranslatable' \ No newline at end of file +//build.dependsOn ':app:mergeUntranslatable' \ No newline at end of file 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 6ac43e5e95046308815581abf3189f12df841923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 19 Jun 2014 16:39:27 +0200 Subject: Provider name in Dashboard is ellipsized correctly --- app/src/main/res/layout/client_dashboard.xml | 58 ++++++++++------------------ app/src/main/res/values/untranslatable.xml | 3 +- 2 files changed, 23 insertions(+), 38 deletions(-) diff --git a/app/src/main/res/layout/client_dashboard.xml b/app/src/main/res/layout/client_dashboard.xml index a5387efd..0103e7bc 100644 --- a/app/src/main/res/layout/client_dashboard.xml +++ b/app/src/main/res/layout/client_dashboard.xml @@ -10,44 +10,28 @@ android:layout_width="match_parent" android:layout_height="40dp" android:background="?android:attr/selectableItemBackground" > - - - - - - - - - - + + + + - + + \ No newline at end of file -- cgit v1.2.3 From f721df21a6fd1f3bb2588e67298ae33993041779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 19 Jun 2014 16:41:53 +0200 Subject: Reordered introduced lines in textviews --- app/src/main/res/layout/client_dashboard.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/client_dashboard.xml b/app/src/main/res/layout/client_dashboard.xml index 0103e7bc..f33ac285 100644 --- a/app/src/main/res/layout/client_dashboard.xml +++ b/app/src/main/res/layout/client_dashboard.xml @@ -12,9 +12,9 @@ android:background="?android:attr/selectableItemBackground" > 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. --- .../java/se/leap/bitmaskclient/ProviderAPI.java | 32 ++++++---- .../main/java/se/leap/bitmaskclient/Provider.java | 1 + .../java/se/leap/bitmaskclient/ProviderAPI.java | 70 ++++++++++++---------- 3 files changed, 61 insertions(+), 42 deletions(-) diff --git a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java index dd7af633..2029a2f5 100644 --- a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java @@ -426,7 +426,7 @@ public class ProviderAPI extends IntentService { parameters.put("user[password_verifier]", password_verifier); Log.d(TAG, server_url); Log.d(TAG, parameters.toString()); - return sendToServer(server_url + "/users", "POST", parameters); + return sendToServer(server_url + "/users.json", "POST", parameters); } /** @@ -538,16 +538,16 @@ public class ProviderAPI extends IntentService { CA_CERT_DOWNLOADED = PROVIDER_JSON_DOWNLOADED = EIP_SERVICE_JSON_DOWNLOADED = false; } - if(!CA_CERT_DOWNLOADED) - current_download = downloadCACert(last_provider_main_url, last_danger_on); - if(CA_CERT_DOWNLOADED || (current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY))) { - broadcast_progress(progress++); - CA_CERT_DOWNLOADED = true; if(!PROVIDER_JSON_DOWNLOADED) current_download = getAndSetProviderJson(last_provider_main_url, last_danger_on); if(PROVIDER_JSON_DOWNLOADED || (current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY))) { + broadcast_progress(progress++); + PROVIDER_JSON_DOWNLOADED = true; + current_download = downloadCACert(last_danger_on); + + if(CA_CERT_DOWNLOADED || (current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY))) { broadcast_progress(progress++); - PROVIDER_JSON_DOWNLOADED = true; + CA_CERT_DOWNLOADED = true; current_download = getAndSetEipServiceJson(); if(current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY)) { broadcast_progress(progress++); @@ -559,17 +559,25 @@ public class ProviderAPI extends IntentService { return current_download; } - private Bundle downloadCACert(String provider_main_url, boolean danger_on) { + private Bundle downloadCACert(boolean danger_on) { Bundle result = new Bundle(); - String cert_string = downloadWithCommercialCA(provider_main_url + "/ca.crt", danger_on); + try { + JSONObject provider_json = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, "")); + String ca_cert_url = provider_json.getString(Provider.CA_CERT_URI); + String cert_string = downloadWithCommercialCA(ca_cert_url, danger_on); - if(validCertificate(cert_string) && setting_up_provider) { - getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(Provider.CA_CERT, cert_string).commit(); + if(validCertificate(cert_string) && setting_up_provider) { + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(Provider.CA_CERT, cert_string).commit(); result.putBoolean(RESULT_KEY, true); - } else { + } else { String reason_to_fail = pickErrorMessage(cert_string); result.putString(ERRORS, reason_to_fail); result.putBoolean(RESULT_KEY, false); + } + } catch (JSONException e) { + String reason_to_fail = formatErrorMessage(R.string.malformed_url); + result.putString(ERRORS, reason_to_fail); + result.putBoolean(RESULT_KEY, false); } return result; 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", diff --git a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java index 6d1ff879..a328dacc 100644 --- a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java @@ -421,7 +421,7 @@ public class ProviderAPI extends IntentService { parameters.put("user[password_verifier]", password_verifier); Log.d(TAG, server_url); Log.d(TAG, parameters.toString()); - return sendToServer(server_url + "/users", "POST", parameters); + return sendToServer(server_url + "/users.json", "POST", parameters); } /** @@ -530,47 +530,57 @@ public class ProviderAPI extends IntentService { * @param task containing a boolean meaning if the provider is custom or not, another boolean meaning if the user completely trusts this provider, the provider name and its provider.json url. * @return a bundle with a boolean value mapped to a key named RESULT_KEY, and which is true if the update was successful. */ - private Bundle setUpProvider(Bundle task) { - int progress = 0; - Bundle current_download = new Bundle(); + private Bundle setUpProvider(Bundle task) { + int progress = 0; + Bundle current_download = new Bundle(); - if(task != null && task.containsKey(Provider.MAIN_URL)) { - last_provider_main_url = task.getString(Provider.MAIN_URL); - CA_CERT_DOWNLOADED = PROVIDER_JSON_DOWNLOADED = EIP_SERVICE_JSON_DOWNLOADED = false; - } + if(task != null && task.containsKey(Provider.MAIN_URL)) { + last_provider_main_url = task.getString(Provider.MAIN_URL); + CA_CERT_DOWNLOADED = PROVIDER_JSON_DOWNLOADED = EIP_SERVICE_JSON_DOWNLOADED = false; + } - if(!CA_CERT_DOWNLOADED) - current_download = downloadCACert(last_provider_main_url); - if(CA_CERT_DOWNLOADED || (current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY))) { - broadcast_progress(progress++); - CA_CERT_DOWNLOADED = true; - if(!PROVIDER_JSON_DOWNLOADED) - current_download = getAndSetProviderJson(last_provider_main_url); - if(PROVIDER_JSON_DOWNLOADED || (current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY))) { - broadcast_progress(progress++); - PROVIDER_JSON_DOWNLOADED = true; - current_download = getAndSetEipServiceJson(); - if(current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY)) { - broadcast_progress(progress++); - EIP_SERVICE_JSON_DOWNLOADED = true; - } - } + if(!PROVIDER_JSON_DOWNLOADED) + current_download = getAndSetProviderJson(last_provider_main_url); + if(PROVIDER_JSON_DOWNLOADED || (current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY))) { + broadcast_progress(progress++); + PROVIDER_JSON_DOWNLOADED = true; + + if(!CA_CERT_DOWNLOADED) + current_download = downloadCACert(); + if(CA_CERT_DOWNLOADED || (current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY))) { + broadcast_progress(progress++); + CA_CERT_DOWNLOADED = true; + current_download = getAndSetEipServiceJson(); + if(current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY)) { + broadcast_progress(progress++); + EIP_SERVICE_JSON_DOWNLOADED = true; } + } + } - return current_download; + return current_download; } - private Bundle downloadCACert(String provider_main_url) { + private Bundle downloadCACert() { Bundle result = new Bundle(); - String cert_string = downloadWithCommercialCA(provider_main_url + "/ca.crt"); + try { + JSONObject provider_json = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, "")); + String ca_cert_url = provider_json.getString(Provider.CA_CERT_URI); + String cert_string = downloadWithCommercialCA(ca_cert_url); + result.putBoolean(RESULT_KEY, true); - if(validCertificate(cert_string) && setting_up_provider) { - getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(Provider.CA_CERT, cert_string).commit(); + if(validCertificate(cert_string) && setting_up_provider) { + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(Provider.CA_CERT, cert_string).commit(); result.putBoolean(RESULT_KEY, true); - } else { + } else { String reason_to_fail = pickErrorMessage(cert_string); result.putString(ERRORS, reason_to_fail); result.putBoolean(RESULT_KEY, false); + } + } catch (JSONException e) { + String reason_to_fail = formatErrorMessage(R.string.malformed_url); + result.putString(ERRORS, reason_to_fail); + result.putBoolean(RESULT_KEY, false); } return result; -- cgit v1.2.3 From 0bf036dae1cc8d2be7129cd8f39474af8cdb9f30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 20 Jun 2014 12:29:56 +0200 Subject: Service is down message correctly shown. I've also fixed another message: if a file to be downloaded is not found, we say the entered provider isn't a LEAP provider. This is based on the fact that if provider.json doesn't exist/contain valid information, then the url isn't pointing to a LEAP provider. --- .../java/se/leap/bitmaskclient/ProviderAPI.java | 31 ++++++++++++---------- app/src/main/res/values/strings.xml | 1 + .../java/se/leap/bitmaskclient/ProviderAPI.java | 12 +++++++-- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java index 2029a2f5..1a812e7c 100644 --- a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java @@ -16,12 +16,20 @@ */ package se.leap.bitmaskclient; +import android.app.IntentService; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.ResultReceiver; +import android.util.Base64; +import android.util.Log; import java.io.DataOutputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.math.BigInteger; +import java.net.ConnectException; import java.net.CookieHandler; import java.net.CookieManager; import java.net.CookiePolicy; @@ -45,30 +53,21 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Scanner; - import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; - import org.apache.http.client.ClientProtocolException; import org.jboss.security.srp.SRPParameters; import org.json.JSONException; import org.json.JSONObject; - -import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.ProviderListContent.ProviderItem; -import android.app.IntentService; -import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; -import android.os.ResultReceiver; -import android.util.Base64; -import android.util.Log; +import se.leap.bitmaskclient.R; /** @@ -705,12 +704,16 @@ public class ProviderAPI extends IntentService { json_file_content = formatErrorMessage(R.string.malformed_url); } catch(SocketTimeoutException e) { json_file_content = formatErrorMessage(R.string.server_unreachable_message); - } catch (IOException e) { + } catch (SSLHandshakeException e) { if(provider_url != null) { - json_file_content = downloadWithProviderCA(string_url, danger_on); + json_file_content = downloadWithProviderCA(string_url, danger_on); } else { json_file_content = formatErrorMessage(R.string.certificate_error); } + } catch(ConnectException e) { + json_file_content = formatErrorMessage(R.string.service_is_down_error); + } catch (FileNotFoundException e) { + json_file_content = formatErrorMessage(R.string.malformed_url); } catch (Exception e) { if(provider_url != null && danger_on) { json_file_content = downloadWithProviderCA(string_url, danger_on); @@ -825,7 +828,7 @@ public class ProviderAPI extends IntentService { System.out.println("String ignoring certificate = " + string); } catch (FileNotFoundException e) { e.printStackTrace(); - string = formatErrorMessage(R.string.server_unreachable_message); + string = formatErrorMessage(R.string.malformed_url); } catch (IOException e) { // The downloaded certificate doesn't validate our https connection. e.printStackTrace(); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d7114b73..62d54981 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -52,6 +52,7 @@ Server is unreachable, please try again. It doesn\'t seem to be a Bitmask provider. This is not a trusted Bitmask provider. + Service is down. Configuring provider Your anon cert was not downloaded Logging in diff --git a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java index a328dacc..fa96fffa 100644 --- a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java @@ -25,6 +25,7 @@ import java.math.BigInteger; import java.net.CookieHandler; import java.net.CookieManager; import java.net.CookiePolicy; +import java.net.ConnectException; import java.net.MalformedURLException; import java.net.SocketTimeoutException; import java.net.URISyntaxException; @@ -32,6 +33,7 @@ import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; import java.net.UnknownHostException; +import javax.net.ssl.SSLHandshakeException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; @@ -705,14 +707,20 @@ public class ProviderAPI extends IntentService { } catch (MalformedURLException e) { json_file_content = formatErrorMessage(R.string.malformed_url); } catch(SocketTimeoutException e) { + e.printStackTrace(); json_file_content = formatErrorMessage(R.string.server_unreachable_message); - } catch (IOException e) { + } catch (SSLHandshakeException e) { if(provider_url != null) { json_file_content = downloadWithProviderCA(string_url); } else { json_file_content = formatErrorMessage(R.string.certificate_error); } + } catch(ConnectException e) { + json_file_content = formatErrorMessage(R.string.service_is_down_error); + } catch (FileNotFoundException e) { + json_file_content = formatErrorMessage(R.string.malformed_url); } catch (Exception e) { + e.printStackTrace(); if(provider_url != null) { json_file_content = downloadWithProviderCA(string_url); } @@ -821,7 +829,7 @@ public class ProviderAPI extends IntentService { System.out.println("String ignoring certificate = " + string); } catch (FileNotFoundException e) { e.printStackTrace(); - string = formatErrorMessage(R.string.server_unreachable_message); + string = formatErrorMessage(R.string.malformed_url); } catch (IOException e) { // The downloaded certificate doesn't validate our https connection. e.printStackTrace(); -- 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/de/blinkt/openvpn/core/OpenVpnService.java | 7 ------- app/src/main/java/se/leap/bitmaskclient/EIP.java | 10 +++++++--- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java index b5bba5d4..f08684b6 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java @@ -72,13 +72,6 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac private String mLastTunCfg; private String mRemoteGW; - //TODO We should know if this is running or not without this method - public boolean isRunning() { - if (mStarting == true || mProcessThread != null) - return true; - else - return false; - } // From: http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java public static String humanReadableByteCount(long bytes, boolean mbit) { if (mbit) 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. --- .../java/de/blinkt/openvpn/core/ConfigParser.java | 8 - app/src/main/java/se/leap/bitmaskclient/EIP.java | 181 +++++++++------------ 2 files changed, 79 insertions(+), 110 deletions(-) diff --git a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java index 4fbbe165..5d5b3471 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java @@ -25,14 +25,6 @@ public class ConfigParser { private boolean extraRemotesAsCustom=false; - - /* - * TODO: We shouldn't be using this method. - * We need to figure out how to use just parseConfig, probably removing parseOptions. - */ - public void setDefinition(HashMap>> args) { - options = args; - } public void parseConfig(Reader reader) throws IOException, ConfigParseError { 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. --- .../main/java/de/blinkt/openvpn/VpnProfile.java | 23 +++----- app/src/main/java/se/leap/bitmaskclient/EIP.java | 69 ++++++++++++++++++++-- 2 files changed, 72 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java index d21a085f..d351610d 100644 --- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -2,12 +2,6 @@ package de.blinkt.openvpn; import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.R; - -import se.leap.bitmaskclient.EIP; -import se.leap.bitmaskclient.Dashboard; -import se.leap.bitmaskclient.Provider; - import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -95,7 +89,7 @@ public class VpnProfile implements Serializable { // but needs to keep wrong name to guarante loading of old // profiles public transient boolean profileDleted = false; - public int mAuthenticationType = TYPE_CERTIFICATES; + public int mAuthenticationType = TYPE_KEYSTORE; public String mName; public String mAlias; public String mClientCertFilename; @@ -281,13 +275,14 @@ public class VpnProfile implements Serializable { switch (mAuthenticationType) { case VpnProfile.TYPE_USERPASS_CERTIFICATES: cfg += "auth-user-pass\n"; - case VpnProfile.TYPE_CERTIFICATES: - // FIXME This is all we need...The whole switch statement can go... - SharedPreferences preferences = context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, context.MODE_PRIVATE); - cfg+="\n"+preferences.getString(Provider.CA_CERT, "")+"\n\n"; - cfg+="\n"+preferences.getString(EIP.PRIVATE_KEY, "")+"\n\n"; - cfg+="\n"+preferences.getString(EIP.CERTIFICATE, "")+"\n\n"; - + case VpnProfile.TYPE_CERTIFICATES: + // Ca + cfg += insertFileData("ca", mCaFilename); + + // Client Cert + Key + cfg += insertFileData("key", mClientKeyFilename); + cfg += insertFileData("cert", mClientCertFilename); + break; case VpnProfile.TYPE_USERPASS_PKCS12: cfg += "auth-user-pass\n"; 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 e53c1b281014e584e6ad92593863870afe26499a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 20 Jun 2014 13:55:54 +0200 Subject: Updated ics-openvpn-upstream: less patches of ours. --- app/src/main/java/de/blinkt/openvpn/LaunchVPN.java | 30 +++---- .../main/java/de/blinkt/openvpn/VpnProfile.java | 2 + .../java/de/blinkt/openvpn/core/ConfigParser.java | 2 +- .../de/blinkt/openvpn/core/OpenVpnService.java | 5 +- .../de/blinkt/openvpn/fragments/LogFragment.java | 93 ++++++++++++---------- app/src/main/res/menu/logmenu.xml | 5 +- app/src/main/res/values-de/strings-icsopenvpn.xml | 6 +- app/src/main/res/values/untranslatable.xml | 38 +++++++++ .../src/main/java/de/blinkt/openvpn/LaunchVPN.java | 30 +++---- .../main/java/de/blinkt/openvpn/VpnProfile.java | 21 +++-- .../java/de/blinkt/openvpn/core/ConfigParser.java | 8 -- .../de/blinkt/openvpn/core/OpenVpnService.java | 12 +-- .../de/blinkt/openvpn/fragments/LogFragment.java | 93 ++++++++++++---------- .../main/src/main/res/menu/logmenu.xml | 5 +- .../main/src/main/res/values-de/strings.xml | 6 +- 15 files changed, 200 insertions(+), 156 deletions(-) diff --git a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java index f8487891..a39e780a 100644 --- a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java +++ b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java @@ -110,28 +110,28 @@ public class LaunchVPN extends Activity { } } - + + @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode==START_VPN_PROFILE) { - if(resultCode == Activity.RESULT_OK) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - boolean showlogwindow = prefs.getBoolean("showlogwindow", true); - - if(!mhideLog && showlogwindow) - showLogWindow(); - new startOpenVpnThread().start(); - } else if (resultCode == Activity.RESULT_CANCELED) { - // User does not want us to start, so we just vanish - VpnStatus.updateStateString("USER_VPN_PERMISSION_CANCELLED", "", R.string.state_user_vpn_permission_cancelled, - ConnectionStatus.LEVEL_NOTCONNECTED); - - finish(); - } + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + boolean showlogwindow = prefs.getBoolean("showlogwindow", true); + + if(!mhideLog && showlogwindow) + showLogWindow(); + new startOpenVpnThread().start(); + } else if (resultCode == Activity.RESULT_CANCELED) { + // User does not want us to start, so we just vanish + VpnStatus.updateStateString("USER_VPN_PERMISSION_CANCELLED", "", R.string.state_user_vpn_permission_cancelled, + ConnectionStatus.LEVEL_NOTCONNECTED); + + finish(); } } + void showLogWindow() { Intent startLW = new Intent(getBaseContext(),LogWindow.class); diff --git a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java index d351610d..0166eb98 100644 --- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -2,6 +2,8 @@ package de.blinkt.openvpn; import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.R; + import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; diff --git a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java index 5d5b3471..378b6b92 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java +++ b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java @@ -25,7 +25,7 @@ public class ConfigParser { private boolean extraRemotesAsCustom=false; - + public void parseConfig(Reader reader) throws IOException, ConfigParseError { diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java index f08684b6..43b27212 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java @@ -34,7 +34,6 @@ import se.leap.bitmaskclient.BuildConfig; import se.leap.bitmaskclient.R; import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.activities.DisconnectVPN; -import de.blinkt.openvpn.activities.LogWindow; import de.blinkt.openvpn.core.VpnStatus.ByteCountListener; import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; import de.blinkt.openvpn.core.VpnStatus.StateListener; @@ -44,6 +43,8 @@ import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_CONNECTED; import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET; import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT; +import se.leap.bitmaskclient.Dashboard; + public class OpenVpnService extends VpnService implements StateListener, Callback, ByteCountListener { public static final String START_SERVICE = "de.blinkt.openvpn.START_SERVICE"; public static final String START_SERVICE_STICKY = "de.blinkt.openvpn.START_SERVICE_STICKY"; @@ -236,7 +237,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac PendingIntent getLogPendingIntent() { // Let the configure Button show the Log - Intent intent = new Intent(getBaseContext(), se.leap.bitmaskclient.Dashboard.class); + Intent intent = new Intent(getBaseContext(), Dashboard.class); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); PendingIntent startLW = PendingIntent.getActivity(this, 0, intent, 0); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); diff --git a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java b/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java index 2f04d235..6e592121 100644 --- a/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java +++ b/app/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java @@ -7,33 +7,39 @@ import se.leap.bitmaskclient.R; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; -import android.app.*; -import android.content.*; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.ListFragment; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; import android.database.DataSetObserver; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.os.Handler.Callback; -import android.os.IBinder; import android.os.Message; import android.text.SpannableString; import android.text.format.DateFormat; import android.text.style.ImageSpan; -import android.view.*; -import android.widget.*; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; import android.widget.AdapterView.OnItemLongClickListener; -import de.blinkt.openvpn.*; -import de.blinkt.openvpn.activities.DisconnectVPN; -import se.leap.bitmaskclient.Dashboard; -import de.blinkt.openvpn.core.OpenVPNManagement; -import de.blinkt.openvpn.core.VpnStatus; -import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; -import de.blinkt.openvpn.core.VpnStatus.LogItem; -import de.blinkt.openvpn.core.VpnStatus.LogListener; -import de.blinkt.openvpn.core.VpnStatus.StateListener; -import de.blinkt.openvpn.core.OpenVpnService; -import de.blinkt.openvpn.core.OpenVpnService.LocalBinder; -import de.blinkt.openvpn.core.ProfileManager; +import android.widget.LinearLayout; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.RadioGroup; +import android.widget.SeekBar; +import android.widget.TextView; +import android.widget.Toast; + import org.jetbrains.annotations.Nullable; import java.text.SimpleDateFormat; @@ -42,31 +48,29 @@ import java.util.Date; import java.util.Locale; import java.util.Vector; +import de.blinkt.openvpn.LaunchVPN; +import se.leap.bitmaskclient.R; +import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.activities.DisconnectVPN; +import de.blinkt.openvpn.core.OpenVPNManagement; +import de.blinkt.openvpn.core.OpenVpnService; +import de.blinkt.openvpn.core.ProfileManager; +import de.blinkt.openvpn.core.VpnStatus; +import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; +import de.blinkt.openvpn.core.VpnStatus.LogItem; +import de.blinkt.openvpn.core.VpnStatus.LogListener; +import de.blinkt.openvpn.core.VpnStatus.StateListener; + import static de.blinkt.openvpn.core.OpenVpnService.humanReadableByteCount; +import se.leap.bitmaskclient.Dashboard; + public class LogFragment extends ListFragment implements StateListener, SeekBar.OnSeekBarChangeListener, RadioGroup.OnCheckedChangeListener, VpnStatus.ByteCountListener { private static final String LOGTIMEFORMAT = "logtimeformat"; private static final int START_VPN_CONFIG = 0; private static final String VERBOSITYLEVEL = "verbositylevel"; - protected OpenVpnService mService; - private ServiceConnection mConnection = new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName className, - IBinder service) { - // We've bound to LocalService, cast the IBinder and get LocalService instance - LocalBinder binder = (LocalBinder) service; - mService = binder.getService(); - } - - @Override - public void onServiceDisconnected(ComponentName arg0) { - mService =null; - } - - }; - private SeekBar mLogLevelSlider; private LinearLayout mOptionsLayout; private RadioGroup mTimeRadioGroup; @@ -425,8 +429,18 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. Intent intent = new Intent(getActivity(),DisconnectVPN.class); startActivity(intent); return true; - } else if(item.getItemId()==R.id.send) { + } else if(item.getItemId()==R.id.send) { ladapter.shareLog(); + } else if(item.getItemId()==R.id.edit_vpn) { + VpnProfile lastConnectedprofile = ProfileManager.getLastConnectedVpn(); + + if(lastConnectedprofile!=null) { + Intent vprefintent = new Intent(getActivity(),Dashboard.class) + .putExtra(VpnProfile.EXTRA_PROFILEUUID,lastConnectedprofile.getUUIDString()); + startActivityForResult(vprefintent,START_VPN_CONFIG); + } else { + Toast.makeText(getActivity(), R.string.log_no_last_vpn, Toast.LENGTH_LONG).show(); + } } else if(item.getItemId() == R.id.toggle_time) { showHideOptionsPanel(); } else if(item.getItemId() == android.R.id.home) { @@ -492,10 +506,6 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. Intent intent = new Intent(getActivity(), OpenVpnService.class); intent.setAction(OpenVpnService.START_SERVICE); - getActivity().bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - - - } @@ -531,14 +541,13 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. super.onActivityResult(requestCode, resultCode, data); } - @Override + + @Override public void onStop() { super.onStop(); VpnStatus.removeStateListener(this); VpnStatus.removeByteCountListener(this); - if(mService!=null) - getActivity().unbindService(mConnection); getActivity().getPreferences(0).edit().putInt(LOGTIMEFORMAT, ladapter.mTimeFormat) .putInt(VERBOSITYLEVEL, ladapter.mLogLevel).apply(); diff --git a/app/src/main/res/menu/logmenu.xml b/app/src/main/res/menu/logmenu.xml index c498eefc..c8c9e815 100644 --- a/app/src/main/res/menu/logmenu.xml +++ b/app/src/main/res/menu/logmenu.xml @@ -33,6 +33,7 @@ android:alphabeticShortcut="e" android:icon="@android:drawable/ic_menu_edit" android:showAsAction="withText|ifRoom" - android:title="@string/edit_vpn"/> + android:title="@string/edit_vpn" + android:visible="false"/> - \ No newline at end of file + diff --git a/app/src/main/res/values-de/strings-icsopenvpn.xml b/app/src/main/res/values-de/strings-icsopenvpn.xml index 9bf58685..bf115be5 100755 --- a/app/src/main/res/values-de/strings-icsopenvpn.xml +++ b/app/src/main/res/values-de/strings-icsopenvpn.xml @@ -62,7 +62,7 @@ VPN löschen Überprüfe, ob der Server ein Zertifikat mit TLS-Servererweiterungen verwendet (--remote-cert-tls server) TLS-Serverzertifikat erwarten - Server Zertifikatssubjekt überprüfen + Server Zertifikatssubjekt DN überprüfen Zertifikat Namen überprüfen Spezifizieren Sie die Methode mit welcher der DN des Serverzertifikates (z. B. C=DE, L=Paderborn, OU=Avian IP-Carrier, CN=openvpn.blinkt.de) überprüft wird.\n\nSie können den vollständigen DN oder den RDN (openvpn.blinkt.de im Beispiel) oder ein RDN-Präfix angeben.\n\nDer RDN Präfix \"Server\" erlaubt z.B. \"Server-1\" und \"Server-2\" \n\nWenn Sie das Eingabefeld leer lassen, wird der RDN gegen den Servernamen geprüft.\n\n Für weitere Details sehen Sie die Manpage von OpenVPN 2.3.1+ unter —verify-x509-name Serverzertifikat Subject @@ -84,7 +84,7 @@ Leitet allen Internet Verkehr über das VPN Benutze Default Route Benutze eigene Routen. Geben Sie Zielnetzwerk im CIDR Format an. Z.b. \"10.0.0.0/8 2002::/16\" würde die Netzwerke 10.0.0.0/8 und 2002::/16 über das VPN routen. - Netze, die nicht über das VPN weitergeleitet werden sollen. Nutzt die gleiche Syntax wie die eigenen Routen. + Netze, die nicht über das VPN geleitet werden sollen. Nutzt die gleiche Syntax wie die eigenen Routen. Eigene Routen Ausgeschlossene Netze Log Detail Level @@ -312,7 +312,7 @@ %3$s: %1$s\n\n%2$s Wenn Sie ihr Gerät gerootet haben können Sie das <a href=\"http://xposed.info/\">Xposed Framework</a> und das <a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\">VPN Dialog confirm Modul</a> auf eigene Gefahr installieren. Komplette Lizenzen - Netze, die direkt über ein lokales Interfaces erreicht werden können werden nicht über das VPN gerottet. Deaktivieren dieser Option leitet allen Verkehr, der für lokale Netzwerke bestimmt ist, über das VPN. + Netze, die direkt über ein lokales Interfaces erreicht werden können werden nicht über das VPN geroutet. Deaktivieren dieser Option leitet allen Verkehr, der für lokale Netzwerke bestimmt ist, über das VPN. VPN für lokale Netzwerke umgehen Datei mit Benutzername und Passwort [Importiert aus %s] diff --git a/app/src/main/res/values/untranslatable.xml b/app/src/main/res/values/untranslatable.xml index de355720..cc39df3d 100644 --- a/app/src/main/res/values/untranslatable.xml +++ b/app/src/main/res/values/untranslatable.xml @@ -833,6 +833,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java index eead600c..16519418 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java @@ -108,28 +108,28 @@ public class LaunchVPN extends Activity { } } - + + @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode==START_VPN_PROFILE) { - if(resultCode == Activity.RESULT_OK) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - boolean showlogwindow = prefs.getBoolean("showlogwindow", true); - - if(!mhideLog && showlogwindow) - showLogWindow(); - new startOpenVpnThread().start(); - } else if (resultCode == Activity.RESULT_CANCELED) { - // User does not want us to start, so we just vanish - VpnStatus.updateStateString("USER_VPN_PERMISSION_CANCELLED", "", R.string.state_user_vpn_permission_cancelled, - ConnectionStatus.LEVEL_NOTCONNECTED); - - finish(); - } + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + boolean showlogwindow = prefs.getBoolean("showlogwindow", true); + + if(!mhideLog && showlogwindow) + showLogWindow(); + new startOpenVpnThread().start(); + } else if (resultCode == Activity.RESULT_CANCELED) { + // User does not want us to start, so we just vanish + VpnStatus.updateStateString("USER_VPN_PERMISSION_CANCELLED", "", R.string.state_user_vpn_permission_cancelled, + ConnectionStatus.LEVEL_NOTCONNECTED); + + finish(); } } + void showLogWindow() { Intent startLW = new Intent(getBaseContext(),LogWindow.class); diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/VpnProfile.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/VpnProfile.java index 9eed03f1..d351610d 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -2,10 +2,6 @@ package de.blinkt.openvpn; import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.EIP; -import se.leap.bitmaskclient.Dashboard; -import se.leap.bitmaskclient.Provider; - import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -93,7 +89,7 @@ public class VpnProfile implements Serializable { // but needs to keep wrong name to guarante loading of old // profiles public transient boolean profileDleted = false; - public int mAuthenticationType = TYPE_CERTIFICATES; + public int mAuthenticationType = TYPE_KEYSTORE; public String mName; public String mAlias; public String mClientCertFilename; @@ -279,13 +275,14 @@ public class VpnProfile implements Serializable { switch (mAuthenticationType) { case VpnProfile.TYPE_USERPASS_CERTIFICATES: cfg += "auth-user-pass\n"; - case VpnProfile.TYPE_CERTIFICATES: - // FIXME This is all we need...The whole switch statement can go... - SharedPreferences preferences = context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, context.MODE_PRIVATE); - cfg+="\n"+preferences.getString(Provider.CA_CERT, "")+"\n\n"; - cfg+="\n"+preferences.getString(EIP.PRIVATE_KEY, "")+"\n\n"; - cfg+="\n"+preferences.getString(EIP.CERTIFICATE, "")+"\n\n"; - + case VpnProfile.TYPE_CERTIFICATES: + // Ca + cfg += insertFileData("ca", mCaFilename); + + // Client Cert + Key + cfg += insertFileData("key", mClientKeyFilename); + cfg += insertFileData("cert", mClientCertFilename); + break; case VpnProfile.TYPE_USERPASS_PKCS12: cfg += "auth-user-pass\n"; diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java index 4fbbe165..378b6b92 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java @@ -26,14 +26,6 @@ public class ConfigParser { private boolean extraRemotesAsCustom=false; - /* - * TODO: We shouldn't be using this method. - * We need to figure out how to use just parseConfig, probably removing parseOptions. - */ - public void setDefinition(HashMap>> args) { - options = args; - } - public void parseConfig(Reader reader) throws IOException, ConfigParseError { diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java index b5bba5d4..43b27212 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java @@ -34,7 +34,6 @@ import se.leap.bitmaskclient.BuildConfig; import se.leap.bitmaskclient.R; import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.activities.DisconnectVPN; -import de.blinkt.openvpn.activities.LogWindow; import de.blinkt.openvpn.core.VpnStatus.ByteCountListener; import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; import de.blinkt.openvpn.core.VpnStatus.StateListener; @@ -44,6 +43,8 @@ import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_CONNECTED; import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET; import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT; +import se.leap.bitmaskclient.Dashboard; + public class OpenVpnService extends VpnService implements StateListener, Callback, ByteCountListener { public static final String START_SERVICE = "de.blinkt.openvpn.START_SERVICE"; public static final String START_SERVICE_STICKY = "de.blinkt.openvpn.START_SERVICE_STICKY"; @@ -72,13 +73,6 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac private String mLastTunCfg; private String mRemoteGW; - //TODO We should know if this is running or not without this method - public boolean isRunning() { - if (mStarting == true || mProcessThread != null) - return true; - else - return false; - } // From: http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java public static String humanReadableByteCount(long bytes, boolean mbit) { if (mbit) @@ -243,7 +237,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac PendingIntent getLogPendingIntent() { // Let the configure Button show the Log - Intent intent = new Intent(getBaseContext(), se.leap.bitmaskclient.Dashboard.class); + Intent intent = new Intent(getBaseContext(), Dashboard.class); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); PendingIntent startLW = PendingIntent.getActivity(this, 0, intent, 0); intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); diff --git a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java index 1abcc54d..d96a66a0 100644 --- a/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java +++ b/ics-openvpn-stripped/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java @@ -5,33 +5,39 @@ import se.leap.bitmaskclient.R; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; -import android.app.*; -import android.content.*; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.ListFragment; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; import android.database.DataSetObserver; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.os.Handler.Callback; -import android.os.IBinder; import android.os.Message; import android.text.SpannableString; import android.text.format.DateFormat; import android.text.style.ImageSpan; -import android.view.*; -import android.widget.*; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; import android.widget.AdapterView.OnItemLongClickListener; -import de.blinkt.openvpn.*; -import de.blinkt.openvpn.activities.DisconnectVPN; -import se.leap.bitmaskclient.Dashboard; -import de.blinkt.openvpn.core.OpenVPNManagement; -import de.blinkt.openvpn.core.VpnStatus; -import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; -import de.blinkt.openvpn.core.VpnStatus.LogItem; -import de.blinkt.openvpn.core.VpnStatus.LogListener; -import de.blinkt.openvpn.core.VpnStatus.StateListener; -import de.blinkt.openvpn.core.OpenVpnService; -import de.blinkt.openvpn.core.OpenVpnService.LocalBinder; -import de.blinkt.openvpn.core.ProfileManager; +import android.widget.LinearLayout; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.RadioGroup; +import android.widget.SeekBar; +import android.widget.TextView; +import android.widget.Toast; + import org.jetbrains.annotations.Nullable; import java.text.SimpleDateFormat; @@ -40,31 +46,29 @@ import java.util.Date; import java.util.Locale; import java.util.Vector; +import de.blinkt.openvpn.LaunchVPN; +import se.leap.bitmaskclient.R; +import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.activities.DisconnectVPN; +import de.blinkt.openvpn.core.OpenVPNManagement; +import de.blinkt.openvpn.core.OpenVpnService; +import de.blinkt.openvpn.core.ProfileManager; +import de.blinkt.openvpn.core.VpnStatus; +import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; +import de.blinkt.openvpn.core.VpnStatus.LogItem; +import de.blinkt.openvpn.core.VpnStatus.LogListener; +import de.blinkt.openvpn.core.VpnStatus.StateListener; + import static de.blinkt.openvpn.core.OpenVpnService.humanReadableByteCount; +import se.leap.bitmaskclient.Dashboard; + public class LogFragment extends ListFragment implements StateListener, SeekBar.OnSeekBarChangeListener, RadioGroup.OnCheckedChangeListener, VpnStatus.ByteCountListener { private static final String LOGTIMEFORMAT = "logtimeformat"; private static final int START_VPN_CONFIG = 0; private static final String VERBOSITYLEVEL = "verbositylevel"; - protected OpenVpnService mService; - private ServiceConnection mConnection = new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName className, - IBinder service) { - // We've bound to LocalService, cast the IBinder and get LocalService instance - LocalBinder binder = (LocalBinder) service; - mService = binder.getService(); - } - - @Override - public void onServiceDisconnected(ComponentName arg0) { - mService =null; - } - - }; - private SeekBar mLogLevelSlider; private LinearLayout mOptionsLayout; private RadioGroup mTimeRadioGroup; @@ -423,8 +427,18 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. Intent intent = new Intent(getActivity(),DisconnectVPN.class); startActivity(intent); return true; - } else if(item.getItemId()==R.id.send) { + } else if(item.getItemId()==R.id.send) { ladapter.shareLog(); + } else if(item.getItemId()==R.id.edit_vpn) { + VpnProfile lastConnectedprofile = ProfileManager.getLastConnectedVpn(); + + if(lastConnectedprofile!=null) { + Intent vprefintent = new Intent(getActivity(),Dashboard.class) + .putExtra(VpnProfile.EXTRA_PROFILEUUID,lastConnectedprofile.getUUIDString()); + startActivityForResult(vprefintent,START_VPN_CONFIG); + } else { + Toast.makeText(getActivity(), R.string.log_no_last_vpn, Toast.LENGTH_LONG).show(); + } } else if(item.getItemId() == R.id.toggle_time) { showHideOptionsPanel(); } else if(item.getItemId() == android.R.id.home) { @@ -490,10 +504,6 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. Intent intent = new Intent(getActivity(), OpenVpnService.class); intent.setAction(OpenVpnService.START_SERVICE); - getActivity().bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - - - } @@ -529,14 +539,13 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. super.onActivityResult(requestCode, resultCode, data); } - @Override + + @Override public void onStop() { super.onStop(); VpnStatus.removeStateListener(this); VpnStatus.removeByteCountListener(this); - if(mService!=null) - getActivity().unbindService(mConnection); getActivity().getPreferences(0).edit().putInt(LOGTIMEFORMAT, ladapter.mTimeFormat) .putInt(VERBOSITYLEVEL, ladapter.mLogLevel).apply(); diff --git a/ics-openvpn-stripped/main/src/main/res/menu/logmenu.xml b/ics-openvpn-stripped/main/src/main/res/menu/logmenu.xml index c498eefc..c8c9e815 100644 --- a/ics-openvpn-stripped/main/src/main/res/menu/logmenu.xml +++ b/ics-openvpn-stripped/main/src/main/res/menu/logmenu.xml @@ -33,6 +33,7 @@ android:alphabeticShortcut="e" android:icon="@android:drawable/ic_menu_edit" android:showAsAction="withText|ifRoom" - android:title="@string/edit_vpn"/> + android:title="@string/edit_vpn" + android:visible="false"/> - \ No newline at end of file + diff --git a/ics-openvpn-stripped/main/src/main/res/values-de/strings.xml b/ics-openvpn-stripped/main/src/main/res/values-de/strings.xml index ef9fb9d6..eb6ef36e 100755 --- a/ics-openvpn-stripped/main/src/main/res/values-de/strings.xml +++ b/ics-openvpn-stripped/main/src/main/res/values-de/strings.xml @@ -62,7 +62,7 @@ VPN löschen Überprüfe, ob der Server ein Zertifikat mit TLS-Servererweiterungen verwendet (--remote-cert-tls server) TLS-Serverzertifikat erwarten - Server Zertifikatssubjekt überprüfen + Server Zertifikatssubjekt DN überprüfen Zertifikat Namen überprüfen Spezifizieren Sie die Methode mit welcher der DN des Serverzertifikates (z. B. C=DE, L=Paderborn, OU=Avian IP-Carrier, CN=openvpn.blinkt.de) überprüft wird.\n\nSie können den vollständigen DN oder den RDN (openvpn.blinkt.de im Beispiel) oder ein RDN-Präfix angeben.\n\nDer RDN Präfix \"Server\" erlaubt z.B. \"Server-1\" und \"Server-2\" \n\nWenn Sie das Eingabefeld leer lassen, wird der RDN gegen den Servernamen geprüft.\n\n Für weitere Details sehen Sie die Manpage von OpenVPN 2.3.1+ unter —verify-x509-name Serverzertifikat Subject @@ -84,7 +84,7 @@ Leitet allen Internet Verkehr über das VPN Benutze Default Route Benutze eigene Routen. Geben Sie Zielnetzwerk im CIDR Format an. Z.b. \"10.0.0.0/8 2002::/16\" würde die Netzwerke 10.0.0.0/8 und 2002::/16 über das VPN routen. - Netze, die nicht über das VPN weitergeleitet werden sollen. Nutzt die gleiche Syntax wie die eigenen Routen. + Netze, die nicht über das VPN geleitet werden sollen. Nutzt die gleiche Syntax wie die eigenen Routen. Eigene Routen Ausgeschlossene Netze Log Detail Level @@ -312,7 +312,7 @@ %3$s: %1$s\n\n%2$s Wenn Sie ihr Gerät gerootet haben können Sie das <a href=\"http://xposed.info/\">Xposed Framework</a> und das <a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\">VPN Dialog confirm Modul</a> auf eigene Gefahr installieren. Komplette Lizenzen - Netze, die direkt über ein lokales Interfaces erreicht werden können werden nicht über das VPN gerottet. Deaktivieren dieser Option leitet allen Verkehr, der für lokale Netzwerke bestimmt ist, über das VPN. + Netze, die direkt über ein lokales Interfaces erreicht werden können werden nicht über das VPN geroutet. Deaktivieren dieser Option leitet allen Verkehr, der für lokale Netzwerke bestimmt ist, über das VPN. VPN für lokale Netzwerke umgehen Datei mit Benutzername und Passwort [Importiert aus %s] -- cgit v1.2.3 From c66aa1bf6aea82e78d684d549113ed44639fb400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 20 Jun 2014 14:12:06 +0200 Subject: Bump build number and version - 0.5.3-RC1 --- app/src/main/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 74af659a..8f78cd97 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,8 +17,8 @@ + android:versionCode="81" + android:versionName="0.5.3-RC1" > -- cgit v1.2.3 From 49aee8dd5fe884eabdc291d758bb8a635f9d1271 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 24 Jun 2014 09:32:06 +0200 Subject: LEAP copyright updated until 2014. --- .gitignore | 1 + app/src/main/res/values/untranslatable.xml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 81972b83..b5067c60 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,4 @@ G* *.dot /ics-openvpn/ /TAGS +/ics-openvpn diff --git a/app/src/main/res/values/untranslatable.xml b/app/src/main/res/values/untranslatable.xml index cc39df3d..6bffb192 100644 --- a/app/src/main/res/values/untranslatable.xml +++ b/app/src/main/res/values/untranslatable.xml @@ -3,7 +3,7 @@ Bitmask Bitmask - Copyright 2012\nLEAP Encryption Access Project <info@leap.se> + Copyright 2012-2014\nLEAP Encryption Access Project <info@leap.se> Copyright © 2002–2010 OpenVPN Technologies, Inc. <sales@openvpn.net>\n "OpenVPN" is a trademark of OpenVPN Technologies, Inc. @@ -892,4 +892,4 @@ - \ No newline at end of file + -- cgit v1.2.3 From c228f481090a468106b57593117d95d9e3dda3f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 24 Jun 2014 10:00:31 +0200 Subject: Tracker link pointing to chili --- app/src/main/res/layout/about.xml | 6 ++++++ app/src/main/res/values-es/strings.xml | 2 ++ app/src/main/res/values/strings.xml | 3 ++- app/src/main/res/values/untranslatable.xml | 3 ++- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/about.xml b/app/src/main/res/layout/about.xml index 4b3f16e0..ccb1ea26 100644 --- a/app/src/main/res/layout/about.xml +++ b/app/src/main/res/layout/about.xml @@ -37,6 +37,12 @@ android:autoLink="all" android:text="@string/repository_url_text" /> + + diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 6a9cce29..ec8c21ff 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -6,4 +6,6 @@ Rutas IPv6: %s El nombre de usuario no debe estar vacío. Conseguido el certificado de \'%s\' de almacén de claves + Código fuente disponible en https://github.com/leapcode/bitmask_android/ + Tracker disponible en https://leap.se/code diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 62d54981..bb68b942 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,7 +2,8 @@ Retry - Source code and issue tracker available at https://github.com/leapcode/bitmask_android/ + Source code available at https://github.com/leapcode/bitmask_android/ + Tracker available at https://leap.se/code Translations welcome and appreciated. See our Transifex project at https://www.transifex.com/projects/p/bitmask-android/ Switch provider info diff --git a/app/src/main/res/values/untranslatable.xml b/app/src/main/res/values/untranslatable.xml index 6bffb192..f956b6bd 100644 --- a/app/src/main/res/values/untranslatable.xml +++ b/app/src/main/res/values/untranslatable.xml @@ -892,4 +892,5 @@ - + + \ No newline at end of file -- 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 ++-- app/src/main/res/values/strings.xml | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) 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; } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bb68b942..6db6962f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -17,9 +17,7 @@ No provider configured Access EIP connection settings Status unknown. - Connection will be secure using an anonymous certificate. Connection secure using an anonymous certificate. - Connection will be secure using your own certificate. Connection secure using your own certificate. Encrypted Internet Select a service provider -- cgit v1.2.3 From 58785d184e4acf5f60f3b40f7387c233777b5c8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 25 Jun 2014 18:55:13 +0200 Subject: Update notification icons. If the connection is being established, the key with a clock icon is shown. If the connection has been established, the key without the clock icon is shown. I've also added all some icons to more resolutions. --- app/src/main/res/drawable-hdpi/ic_stat_vpn.png | Bin 0 -> 539 bytes .../main/res/drawable-hdpi/ic_stat_vpn_empty_halo.png | Bin 816 -> 721 bytes app/src/main/res/drawable-hdpi/ic_stat_vpn_offline.png | Bin 637 -> 801 bytes app/src/main/res/drawable-hdpi/ic_stat_vpn_outline.png | Bin 863 -> 28 bytes app/src/main/res/drawable-hdpi/ic_vpn_disconnected.png | Bin 801 -> 0 bytes app/src/main/res/drawable-ldpi/ic_stat_vpn.png | Bin 461 -> 757 bytes .../main/res/drawable-ldpi/ic_stat_vpn_empty_halo.png | Bin 0 -> 404 bytes app/src/main/res/drawable-ldpi/ic_stat_vpn_offline.png | Bin 0 -> 455 bytes app/src/main/res/drawable-ldpi/ic_stat_vpn_outline.png | 1 + app/src/main/res/drawable-mdpi/ic_stat_vpn.png | Bin 0 -> 502 bytes .../main/res/drawable-mdpi/ic_stat_vpn_empty_halo.png | Bin 545 -> 504 bytes app/src/main/res/drawable-mdpi/ic_stat_vpn_offline.png | Bin 451 -> 586 bytes app/src/main/res/drawable-mdpi/ic_stat_vpn_outline.png | Bin 609 -> 28 bytes app/src/main/res/drawable-xhdpi/ic_stat_vpn.png | Bin 0 -> 688 bytes .../main/res/drawable-xhdpi/ic_stat_vpn_empty_halo.png | Bin 1033 -> 902 bytes .../main/res/drawable-xhdpi/ic_stat_vpn_offline.png | Bin 834 -> 1091 bytes .../main/res/drawable-xhdpi/ic_stat_vpn_outline.png | Bin 1151 -> 28 bytes app/src/main/res/values/untranslatable.xml | 3 ++- 18 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/drawable-hdpi/ic_stat_vpn.png mode change 100644 => 120000 app/src/main/res/drawable-hdpi/ic_stat_vpn_outline.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_vpn_disconnected.png create mode 100644 app/src/main/res/drawable-ldpi/ic_stat_vpn_empty_halo.png create mode 100644 app/src/main/res/drawable-ldpi/ic_stat_vpn_offline.png create mode 120000 app/src/main/res/drawable-ldpi/ic_stat_vpn_outline.png create mode 100644 app/src/main/res/drawable-mdpi/ic_stat_vpn.png mode change 100644 => 120000 app/src/main/res/drawable-mdpi/ic_stat_vpn_outline.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_stat_vpn.png mode change 100644 => 120000 app/src/main/res/drawable-xhdpi/ic_stat_vpn_outline.png diff --git a/app/src/main/res/drawable-hdpi/ic_stat_vpn.png b/app/src/main/res/drawable-hdpi/ic_stat_vpn.png new file mode 100644 index 00000000..c3547e85 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_stat_vpn.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_stat_vpn_empty_halo.png b/app/src/main/res/drawable-hdpi/ic_stat_vpn_empty_halo.png index 7df5b670..25f82a95 100644 Binary files a/app/src/main/res/drawable-hdpi/ic_stat_vpn_empty_halo.png and b/app/src/main/res/drawable-hdpi/ic_stat_vpn_empty_halo.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_stat_vpn_offline.png b/app/src/main/res/drawable-hdpi/ic_stat_vpn_offline.png index 8aa48803..dfb962b9 100644 Binary files a/app/src/main/res/drawable-hdpi/ic_stat_vpn_offline.png and b/app/src/main/res/drawable-hdpi/ic_stat_vpn_offline.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_stat_vpn_outline.png b/app/src/main/res/drawable-hdpi/ic_stat_vpn_outline.png deleted file mode 100644 index b5583d99..00000000 Binary files a/app/src/main/res/drawable-hdpi/ic_stat_vpn_outline.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_stat_vpn_outline.png b/app/src/main/res/drawable-hdpi/ic_stat_vpn_outline.png new file mode 120000 index 00000000..96d8d34d --- /dev/null +++ b/app/src/main/res/drawable-hdpi/ic_stat_vpn_outline.png @@ -0,0 +1 @@ +./ic_stat_vpn_empty_halo.png \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/ic_vpn_disconnected.png b/app/src/main/res/drawable-hdpi/ic_vpn_disconnected.png deleted file mode 100644 index dfb962b9..00000000 Binary files a/app/src/main/res/drawable-hdpi/ic_vpn_disconnected.png and /dev/null differ diff --git a/app/src/main/res/drawable-ldpi/ic_stat_vpn.png b/app/src/main/res/drawable-ldpi/ic_stat_vpn.png index f973015c..65fc6db7 100644 Binary files a/app/src/main/res/drawable-ldpi/ic_stat_vpn.png and b/app/src/main/res/drawable-ldpi/ic_stat_vpn.png differ diff --git a/app/src/main/res/drawable-ldpi/ic_stat_vpn_empty_halo.png b/app/src/main/res/drawable-ldpi/ic_stat_vpn_empty_halo.png new file mode 100644 index 00000000..2df0a9bd Binary files /dev/null and b/app/src/main/res/drawable-ldpi/ic_stat_vpn_empty_halo.png differ diff --git a/app/src/main/res/drawable-ldpi/ic_stat_vpn_offline.png b/app/src/main/res/drawable-ldpi/ic_stat_vpn_offline.png new file mode 100644 index 00000000..22f3497e Binary files /dev/null and b/app/src/main/res/drawable-ldpi/ic_stat_vpn_offline.png differ diff --git a/app/src/main/res/drawable-ldpi/ic_stat_vpn_outline.png b/app/src/main/res/drawable-ldpi/ic_stat_vpn_outline.png new file mode 120000 index 00000000..482dafd3 --- /dev/null +++ b/app/src/main/res/drawable-ldpi/ic_stat_vpn_outline.png @@ -0,0 +1 @@ +./ic_stat_vpn_offline.png \ No newline at end of file diff --git a/app/src/main/res/drawable-mdpi/ic_stat_vpn.png b/app/src/main/res/drawable-mdpi/ic_stat_vpn.png new file mode 100644 index 00000000..7e167f84 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_stat_vpn.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_stat_vpn_empty_halo.png b/app/src/main/res/drawable-mdpi/ic_stat_vpn_empty_halo.png index fc039a82..a658d9e9 100644 Binary files a/app/src/main/res/drawable-mdpi/ic_stat_vpn_empty_halo.png and b/app/src/main/res/drawable-mdpi/ic_stat_vpn_empty_halo.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_stat_vpn_offline.png b/app/src/main/res/drawable-mdpi/ic_stat_vpn_offline.png index f31387a4..f8b02bfb 100644 Binary files a/app/src/main/res/drawable-mdpi/ic_stat_vpn_offline.png and b/app/src/main/res/drawable-mdpi/ic_stat_vpn_offline.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_stat_vpn_outline.png b/app/src/main/res/drawable-mdpi/ic_stat_vpn_outline.png deleted file mode 100644 index 052aef9d..00000000 Binary files a/app/src/main/res/drawable-mdpi/ic_stat_vpn_outline.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_stat_vpn_outline.png b/app/src/main/res/drawable-mdpi/ic_stat_vpn_outline.png new file mode 120000 index 00000000..96d8d34d --- /dev/null +++ b/app/src/main/res/drawable-mdpi/ic_stat_vpn_outline.png @@ -0,0 +1 @@ +./ic_stat_vpn_empty_halo.png \ No newline at end of file diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_vpn.png b/app/src/main/res/drawable-xhdpi/ic_stat_vpn.png new file mode 100644 index 00000000..1f46be2c Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_stat_vpn.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_vpn_empty_halo.png b/app/src/main/res/drawable-xhdpi/ic_stat_vpn_empty_halo.png index 2f61e890..f4f28ef7 100644 Binary files a/app/src/main/res/drawable-xhdpi/ic_stat_vpn_empty_halo.png and b/app/src/main/res/drawable-xhdpi/ic_stat_vpn_empty_halo.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_vpn_offline.png b/app/src/main/res/drawable-xhdpi/ic_stat_vpn_offline.png index e9411518..7f44c46f 100644 Binary files a/app/src/main/res/drawable-xhdpi/ic_stat_vpn_offline.png and b/app/src/main/res/drawable-xhdpi/ic_stat_vpn_offline.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_vpn_outline.png b/app/src/main/res/drawable-xhdpi/ic_stat_vpn_outline.png deleted file mode 100644 index 5d27240d..00000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_stat_vpn_outline.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_vpn_outline.png b/app/src/main/res/drawable-xhdpi/ic_stat_vpn_outline.png new file mode 120000 index 00000000..96d8d34d --- /dev/null +++ b/app/src/main/res/drawable-xhdpi/ic_stat_vpn_outline.png @@ -0,0 +1 @@ +./ic_stat_vpn_empty_halo.png \ No newline at end of file diff --git a/app/src/main/res/values/untranslatable.xml b/app/src/main/res/values/untranslatable.xml index 6bffb192..f956b6bd 100644 --- a/app/src/main/res/values/untranslatable.xml +++ b/app/src/main/res/values/untranslatable.xml @@ -892,4 +892,5 @@ - + + \ No newline at end of file -- 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 ++-- app/src/main/res/values/strings.xml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) 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; } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6db6962f..c928f001 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -57,6 +57,7 @@ Logging in Signing up Logging out from this session. + Logged out. Didn\'t logged out. Authentication succeeded. Authentication failed. -- cgit v1.2.3 From adfcb7f7a0586cb1ea21c531b5560ff20e0e486b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 26 Jun 2014 00:18:51 +0200 Subject: Bump build number and version for 0.5.3 RC2 --- app/src/main/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8f78cd97..a98ede86 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,8 +17,8 @@ + android:versionCode="82" + android:versionName="0.5.3-RC2" > -- cgit v1.2.3 From 7788fcbee03e18d9633723347156b9386b6b2fc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 26 Jun 2014 09:54:11 +0200 Subject: New openvpn cert -> create a vpn profile. --- .../debug/java/se/leap/bitmaskclient/ProviderAPI.java | 16 ++++++++++++---- .../release/java/se/leap/bitmaskclient/ProviderAPI.java | 17 +++++++++++++---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java index 1a812e7c..b17d6bb4 100644 --- a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java @@ -192,7 +192,7 @@ public class ProviderAPI extends IntentService { receiver.send(LOGOUT_FAILED, Bundle.EMPTY); } } else if (action.equalsIgnoreCase(DOWNLOAD_CERTIFICATE)) { - if(getNewCert(parameters)) { + if(updateVpnCertificate()) { receiver.send(CORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); } else { receiver.send(INCORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); @@ -889,16 +889,24 @@ public class ProviderAPI extends IntentService { return true; } + private boolean updateVpnCertificate() { + getNewCert(); + + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putInt(EIP.PARSED_SERIAL, 0).commit(); + Intent updateEIP = new Intent(getApplicationContext(), EIP.class); + updateEIP.setAction(EIP.ACTION_UPDATE_EIP_SERVICE); + startService(updateEIP); + + return true; + } /** * Downloads a new OpenVPN certificate, attaching authenticated cookie for authenticated certificate. * - * @param task containing the type of the certificate to be downloaded * @return true if certificate was downloaded correctly, false if provider.json or danger_on flag are not present in SharedPreferences, or if the certificate url could not be parsed as a URI, or if there was an SSL error. */ - private boolean getNewCert(Bundle task) { + private boolean getNewCert() { try { - String type_of_certificate = task.getString(ConfigurationWizard.TYPE_OF_CERTIFICATE); JSONObject provider_json = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, "")); String provider_main_url = provider_json.getString(Provider.API_URL); diff --git a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java index fa96fffa..cdac8197 100644 --- a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java @@ -190,7 +190,7 @@ public class ProviderAPI extends IntentService { receiver.send(LOGOUT_FAILED, Bundle.EMPTY); } } else if (action.equalsIgnoreCase(DOWNLOAD_CERTIFICATE)) { - if(getNewCert(parameters)) { + if(updateVpnCertificate()) { receiver.send(CORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); } else { receiver.send(INCORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); @@ -890,16 +890,25 @@ public class ProviderAPI extends IntentService { return true; } + private boolean updateVpnCertificate() { + getNewCert(); + + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putInt(EIP.PARSED_SERIAL, 0).commit(); + Intent updateEIP = new Intent(getApplicationContext(), EIP.class); + updateEIP.setAction(EIP.ACTION_UPDATE_EIP_SERVICE); + startService(updateEIP); + + return true; + } + /** * Downloads a new OpenVPN certificate, attaching authenticated cookie for authenticated certificate. * - * @param task containing the type of the certificate to be downloaded * @return true if certificate was downloaded correctly, false if provider.json is not present in SharedPreferences, or if the certificate url could not be parsed as a URI, or if there was an SSL error. */ - private boolean getNewCert(Bundle task) { + private boolean getNewCert() { try { - String type_of_certificate = task.getString(ConfigurationWizard.TYPE_OF_CERTIFICATE); JSONObject provider_json = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, "")); String provider_main_url = provider_json.getString(Provider.API_URL); -- cgit v1.2.3 From 1d73097f06dd6b9d3ef55c59877b9b6551847dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 27 Jun 2014 19:53:18 +0200 Subject: Bump version and build number for 0.5.3 RC3. Forgot to commit before uploading actual APK. --- app/src/main/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a98ede86..040d03b9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,8 +17,8 @@ + android:versionCode="83" + android:versionName="0.5.3-RC3" > -- cgit v1.2.3 From 64b3bcab6ae951282e474aed05f36ee09588f5f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 27 Jun 2014 20:01:30 +0200 Subject: Changelog for 0.5.3 --- CHANGELOG | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 460d1971..2f42267e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,14 @@ +0.5.3 June 27 2014- the "beautiful oak" release +Features +- Updated ics-openvpn (again). +- Support for riseup leap provider +- Always use latests certificate +Bugs Fixed +- UI inconsistencies (notification, messages) +- About text contains correct tracker +- Long provider names are shown correctly +- Fewer glue code for ics-openvpn customizations + 0.5.2 June 13 2014 - the "new beginning" release Features - Updated ics-openvpn codebase! -- cgit v1.2.3 From 3292c43a77f5be07e110452a332797169a90b345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 27 Jun 2014 20:01:46 +0200 Subject: Bump version and build number for 0.5.3 --- app/src/main/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 040d03b9..f73d59cb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,8 +17,8 @@ + android:versionCode="84" + android:versionName="0.5.3" > -- 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 +++++++++++++++++++--- app/src/main/res/values/strings.xml | 1 + 4 files changed, 73 insertions(+), 6 deletions(-) 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; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c928f001..1dbe8fee 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -54,6 +54,7 @@ Service is down. Configuring provider Your anon cert was not downloaded + Updating EIP certificate Logging in Signing up Logging out from this session. -- 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 +++++++++------------- .../java/se/leap/bitmaskclient/ProviderAPI.java | 1 + 3 files changed, 16 insertions(+), 19 deletions(-) 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; } diff --git a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java index cdac8197..8baaacc7 100644 --- a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java @@ -190,6 +190,7 @@ public class ProviderAPI extends IntentService { receiver.send(LOGOUT_FAILED, Bundle.EMPTY); } } else if (action.equalsIgnoreCase(DOWNLOAD_CERTIFICATE)) { + Log.d(TAG, "action.equalsIgnoreCase(DOWNLOAD_CERTIFICATE)"); if(updateVpnCertificate()) { receiver.send(CORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); } else { -- 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(-) 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. --- .../java/se/leap/bitmaskclient/ProviderAPI.java | 2 + app/src/main/java/se/leap/bitmaskclient/EIP.java | 80 +++++++++++++--------- .../java/se/leap/bitmaskclient/ProviderAPI.java | 3 +- 3 files changed, 51 insertions(+), 34 deletions(-) diff --git a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java index b17d6bb4..5549252e 100644 --- a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java @@ -49,6 +49,7 @@ import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; +import java.util.Calendar; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -943,6 +944,7 @@ public class ProviderAPI extends IntentService { X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(certificateString); certificateString = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT); getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.CERTIFICATE, "-----BEGIN CERTIFICATE-----\n"+certificateString+"-----END CERTIFICATE-----").commit(); + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.DATE_FROM_CERTIFICATE, EIP.certificate_date_format.format(Calendar.getInstance().getTime())).commit(); return true; } catch (CertificateException e) { 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"); diff --git a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java index 8baaacc7..625125d8 100644 --- a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java +++ b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java @@ -43,6 +43,7 @@ import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateKey; +import java.util.Calendar; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -944,7 +945,7 @@ public class ProviderAPI extends IntentService { X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(certificateString); certificateString = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT); getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.CERTIFICATE, "-----BEGIN CERTIFICATE-----\n"+certificateString+"-----END CERTIFICATE-----").commit(); - + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.DATE_FROM_CERTIFICATE, EIP.certificate_date_format.format(Calendar.getInstance().getTime())).commit(); return true; } catch (CertificateException e) { // TODO Auto-generated catch block -- 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(-) 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(-) 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(-) 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(-) 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 11:05:58 +0200 Subject: Minor gradle updates, due to Android L. - Build tools update to latest version (20). - testPackageName is correctly calculated by default, doing nothing. - support library needs some tweaks to support pre Android L versions. --- app/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index a57a2763..82f71bc8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,13 +2,12 @@ apply plugin: 'android' android { compileSdkVersion 19 - buildToolsVersion "19.1.0" + buildToolsVersion "20" defaultConfig { minSdkVersion 14 targetSdkVersion 19 - testPackageName "se.leap.bitmaskclient.test" testInstrumentationRunner "android.test.InstrumentationTestRunner" } @@ -47,7 +46,8 @@ android { } dependencies { - androidTestCompile 'com.android.support:support-v4:+' + androidTestCompile 'com.android.support:support-v4:20+' + androidTestCompile 'com.android.support:appcompat-v7:20.+' androidTestCompile 'com.jayway.android.robotium:robotium-solo:4.3.1' compile 'com.intellij:annotations:12.0' } -- cgit v1.2.3 From 629a0b279a80938212b01c096e55c402d91739d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= 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/build.gradle | 6 +++--- .../java/se/leap/bitmaskclient/test/testConfigurationWizard.java | 2 +- .../androidTest/java/se/leap/bitmaskclient/test/testDashboard.java | 4 +--- app/src/main/java/se/leap/bitmaskclient/EIP.java | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 82f71bc8..c4fdc44b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -46,9 +46,9 @@ android { } dependencies { - androidTestCompile 'com.android.support:support-v4:20+' - androidTestCompile 'com.android.support:appcompat-v7:20.+' - androidTestCompile 'com.jayway.android.robotium:robotium-solo:4.3.1' + // androidTestCompile 'com.android.support:support-v4:20+' + // androidTestCompile 'com.android.support:appcompat-v7:20.+' + androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.2.1' compile 'com.intellij:annotations:12.0' } 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 8ddfbc57..229c3452 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/testConfigurationWizard.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/testConfigurationWizard.java @@ -2,7 +2,7 @@ package se.leap.bitmaskclient.test; import android.test.ActivityInstrumentationTestCase2; import android.widget.ListView; -import com.jayway.android.robotium.solo.Solo; +import com.robotium.solo.Solo; import java.io.IOException; import se.leap.bitmaskclient.AboutActivity; import se.leap.bitmaskclient.ConfigurationWizard; diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/testDashboard.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/testDashboard.java index bbc3e97d..85197493 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/testDashboard.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/testDashboard.java @@ -7,7 +7,7 @@ import android.content.IntentFilter; import android.provider.Settings; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; -import com.jayway.android.robotium.solo.Solo; +import com.robotium.solo.Solo; import se.leap.bitmaskclient.ConfigurationWizard; import se.leap.bitmaskclient.Dashboard; import se.leap.bitmaskclient.R; @@ -39,8 +39,6 @@ public class testDashboard extends ActivityInstrumentationTestCase2 { */ public void testOnOffOpenVpn() { solo.clickOnView(solo.getView(R.id.eipSwitch)); - if(!solo.waitForText(getActivity().getString(R.string.eip_status_start_pending))) - fail(); if(!solo.waitForText(getActivity().getString(R.string.state_auth))) fail(); if(!solo.waitForText(getActivity().getString(R.string.eip_state_connected), 1, 30*1000)) 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 From 98f2fcedc3c645b38ecf168d57e28287c4a7a76e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 10 Jul 2014 18:32:55 +0200 Subject: Simulate network down. The tests say they failed, but it's because the adb server is no longer able to communicate with the emulator due to switching network connectivity off (and being the adb server connected to a local tcp port of the emulator, this port dissapears once connectivity is down). To see if all tests passed, take a look at the logcat. Once tests are finished, issue "adb kill-server" from the development machine, and then "adb logcat". --- .../androidTest/java/se/leap/bitmaskclient/test/testDashboard.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/testDashboard.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/testDashboard.java index 85197493..66ef6565 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/testDashboard.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/testDashboard.java @@ -48,14 +48,13 @@ public class testDashboard extends ActivityInstrumentationTestCase2 { if(!solo.waitForText(getActivity().getString(R.string.eip_state_not_connected))) fail(); - /*ConnectionManager.setMobileDataEnabled(false, solo.getCurrentActivity().getApplicationContext()); + ConnectionManager.setMobileDataEnabled(false, solo.getCurrentActivity().getApplicationContext()); solo.clickOnView(solo.getView(R.id.eipSwitch)); - if(!solo.waitForText(getActivity().getString(R.string.eip_status_start_pending))) - fail(); + // if(!solo.waitForText(getActivity().getString(R.string.eip_status_start_pending))) + // fail(); if(!solo.waitForText(getActivity().getString(R.string.state_nonetwork))) fail(); - */ } public void testLogInAndOut() { -- cgit v1.2.3 From 623f81b5e52a5155549731e4afe35ca054f97a3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 10 Jul 2014 20:55:55 +0200 Subject: network up & down 3 times: sometimes fails I simulate removing the network at the end of the test. Sometimes, the test fails because a openvpn tries to close a bad file descriptor. --- .../se/leap/bitmaskclient/test/testDashboard.java | 71 ++++++++++++++++------ 1 file changed, 53 insertions(+), 18 deletions(-) diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/test/testDashboard.java b/app/src/androidTest/java/se/leap/bitmaskclient/test/testDashboard.java index 66ef6565..fdf4f135 100644 --- a/app/src/androidTest/java/se/leap/bitmaskclient/test/testDashboard.java +++ b/app/src/androidTest/java/se/leap/bitmaskclient/test/testDashboard.java @@ -8,6 +8,8 @@ import android.provider.Settings; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; import com.robotium.solo.Solo; + +import de.blinkt.openvpn.activities.DisconnectVPN; import se.leap.bitmaskclient.ConfigurationWizard; import se.leap.bitmaskclient.Dashboard; import se.leap.bitmaskclient.R; @@ -38,25 +40,58 @@ public class testDashboard extends ActivityInstrumentationTestCase2 { * I cannot automate that dialog. */ public void testOnOffOpenVpn() { - solo.clickOnView(solo.getView(R.id.eipSwitch)); - if(!solo.waitForText(getActivity().getString(R.string.state_auth))) - fail(); - if(!solo.waitForText(getActivity().getString(R.string.eip_state_connected), 1, 30*1000)) - fail(); - - solo.clickOnView(solo.getView(R.id.eipSwitch)); - if(!solo.waitForText(getActivity().getString(R.string.eip_state_not_connected))) - fail(); - - ConnectionManager.setMobileDataEnabled(false, solo.getCurrentActivity().getApplicationContext()); - - solo.clickOnView(solo.getView(R.id.eipSwitch)); - // if(!solo.waitForText(getActivity().getString(R.string.eip_status_start_pending))) - // fail(); - if(!solo.waitForText(getActivity().getString(R.string.state_nonetwork))) - fail(); + solo.clickOnView(solo.getView(R.id.eipSwitch)); + testEipTurningOn(); + + solo.clickOnView(solo.getView(R.id.eipSwitch)); + testEipTurningOff(); + + solo.clickOnView(solo.getView(R.id.eipSwitch)); + testEipTurningOn(); + + solo.clickOnView(solo.getView(R.id.eipSwitch)); + testEipTurningOff(); + + solo.clickOnView(solo.getView(R.id.eipSwitch)); + testEipTurningOn(); + + solo.clickOnView(solo.getView(R.id.eipSwitch)); + testEipTurningOff(); + + solo.clickOnView(solo.getView(R.id.eipSwitch)); + testEipTurningOn(); + + testEipIsOnNoNetwork(); + } - + + private void testEipTurningOn() { + if(!solo.waitForText(getActivity().getString(R.string.state_auth))) + fail(); + if(!solo.waitForText(getActivity().getString(R.string.eip_state_connected), 1, 30*1000)) + fail(); + solo.sleep(2*1000); + } + + private void testEipTurningOff() { + sayOkToDisconnect(); + if(!solo.waitForText(getActivity().getString(R.string.eip_state_not_connected))) + fail(); + solo.sleep(2*1000); + } + + private void sayOkToDisconnect() { + if(!solo.waitForActivity(DisconnectVPN.class)) + fail(); + solo.clickOnText(getActivity().getString(android.R.string.yes)); + } + + private void testEipIsOnNoNetwork() { + ConnectionManager.setMobileDataEnabled(false, solo.getCurrentActivity().getApplicationContext()); + if(!solo.waitForText(getActivity().getString(R.string.eip_state_not_connected), 1, 15*1000)) + fail(); + } + public void testLogInAndOut() { long miliseconds_to_log_in = 40 * 1000; solo.clickOnActionBarItem(R.id.login_button); -- cgit v1.2.3 From 1d6c26020a8ecc71a97cbbd313c776984afd903a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 15 Jul 2014 18:27:02 +0200 Subject: Some instructions to run the tests. --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 68cc075a..37ef3bde 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,21 @@ The resulting apk(s) will be in `app/build/apk`. * `Import project` => select bitmask_android top folder +## Running tests + +To run the automated tests: + 1. Run an emulator + 2. Unlock Android + 3. Issue the command ./gradlew connectedCheck + 4. Pay attention and check the "Trust this app" checkbox, if you don't do so tests won't run. + +Due to the nature of some tests, adb will lose its connectivity and you won't receive any tests results. To look for failed tests, do the following: + 1. adb kill-server + 2. adb logcat | less + 3. Look for: "failed: test" + +We'll polish this process soon, but right now that's what we're doing (well, in fact, we run "adb logcat" in Emacs and then search "failed: test" in the corresponding buffer ;) ). + ## Acknowledgements This project bases its work in [ics-openvpn project](https://code.google.com/p/ics-openvpn/). -- cgit v1.2.3 From b8165c50328beca82efc93fadfc69a3ac18123dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 15 Jul 2014 18:29:37 +0200 Subject: Bump build number and version for 0.6.0-RC1 --- app/src/main/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f73d59cb..8018f7e8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,8 +17,8 @@ + android:versionCode="85" + android:versionName="0.6.0-RC1" > -- cgit v1.2.3 From a572fbf2a1f69fbba80d28f3c425defdcf5dc633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 21 Jul 2014 17:09:34 +0200 Subject: Changelog for 0.5.4 --- CHANGELOG | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 2f42267e..35ad2918 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +0.5.4 July 21 2014 - the "meetup" release +Features +- Renewal of the certificate soon enough +- After signing up, eip restarts to use the new certificate +- EIP profiles are named according to their locations +- Developers: tests run, and network tests are more intensive + 0.5.3 June 27 2014- the "beautiful oak" release Features - Updated ics-openvpn (again). -- cgit v1.2.3 From dce7064c35a903c7b13e97181c07058e143df621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 21 Jul 2014 17:10:31 +0200 Subject: Bump version number for the "meetup" release --- app/src/main/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8018f7e8..a90d6396 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,8 +17,8 @@ + android:versionCode="86" + android:versionName="0.5.4" > -- cgit v1.2.3