diff options
-rw-r--r-- | .tx/config | 10 | ||||
-rw-r--r-- | AndroidManifest.xml | 4 | ||||
-rw-r--r-- | CHANGELOG | 16 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | res/menu/client_dashboard.xml | 4 | ||||
-rwxr-xr-x | res/values/values-nl/arrays.xml | 27 | ||||
-rwxr-xr-x | res/values/values-nl/strings.xml | 64 | ||||
-rw-r--r-- | src/se/leap/bitmaskclient/ConfigHelper.java | 139 | ||||
-rw-r--r-- | src/se/leap/bitmaskclient/ConfigurationWizard.java | 39 | ||||
-rw-r--r-- | src/se/leap/bitmaskclient/Dashboard.java | 28 | ||||
-rw-r--r-- | src/se/leap/bitmaskclient/EIP.java | 89 | ||||
-rw-r--r-- | src/se/leap/bitmaskclient/LeapHttpClient.java | 9 | ||||
-rw-r--r-- | src/se/leap/bitmaskclient/ProviderAPI.java | 46 | ||||
-rw-r--r-- | src/se/leap/bitmaskclient/ProviderDetailFragment.java | 11 | ||||
-rw-r--r-- | src/se/leap/openvpn/VpnProfile.java | 8 | ||||
-rw-r--r-- | tests/src/se/leap/bitmaskclient/test/testConfigurationWizard.java | 4 |
16 files changed, 155 insertions, 345 deletions
diff --git a/.tx/config b/.tx/config new file mode 100644 index 00000000..08f7fd2b --- /dev/null +++ b/.tx/config @@ -0,0 +1,10 @@ +[main] +host = https://www.transifex.com + +[bitmask-android.strings] +source_lang = en +source_file = res/values/strings.xml +file_filter = res/values-<lang>/strings.xml +trans.zh_CN = res/values-zh-rCN/strings.xml +trans.zh_TW = res/values-zh-rTW/strings.xml + diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 25b78bd6..815ddf87 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -17,8 +17,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="se.leap.bitmaskclient" - android:versionCode="64" - android:versionName="0.2.3" > + android:versionCode="67" + android:versionName="0.4" > <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> @@ -1,4 +1,18 @@ -0.2.3-rc1 Nov 29 2013 +0.4 Feb 10 2014 +Features +- Use token based authentication +- UI Improvements +- Show location of VPN gateway +- About view is now an Activity +- Removed ics-openvpn references and unused code +Bugs Fixed +- Improved handling of Configuration Wizard errors +- Use strong cert pinning for provider +- Progress bars layout +- References to "LEAP Android" changed to Bitmask +- Login/logout messages clear when complete + +0.2.3 Nov 29 2013 Features - Begin integrating tests into repository - Clearer wording in some places @@ -39,6 +39,8 @@ This project uses code from [ics-openvpn project](https://code.google.com/p/ics- Please fork this repository and contribute back using [pull requests](https://github.com/leapcode/leap_android/pulls). +Our preferred method for receiving translations is our [Transifex project](https://www.transifex.com/projects/p/bitmask-android). + Any contributions, large or small, major features, bug fixes, additional language translations, unit/integration tests are welcomed and appreciated but will be thoroughly reviewed and discussed. diff --git a/res/menu/client_dashboard.xml b/res/menu/client_dashboard.xml index bdd49ab9..676c07c7 100644 --- a/res/menu/client_dashboard.xml +++ b/res/menu/client_dashboard.xml @@ -1,8 +1,4 @@ <menu xmlns:android="http://schemas.android.com/apk/res/android" > - - <item - android:orderInCategory="100" - android:title="@string/menu_settings"/> <item android:id="@+id/about_leap" android:orderInCategory="110" diff --git a/res/values/values-nl/arrays.xml b/res/values/values-nl/arrays.xml deleted file mode 100755 index 9be2a9d4..00000000 --- a/res/values/values-nl/arrays.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!--Generated by crowdin.net--> -<resources> - <string-array name="vpn_types"> - <item>Certificaten</item> - <item>PKCS12 Bestand</item> - <item>Android Certificaat</item> - <item>Gebruikersnaam/Wachtwoord</item> - <item>Statische Sleutels</item> - <item>Gebruiker/WW + Certificaten</item> - <item>Gebruiker/WW + PKCS12 </item> - <item>Gebruiker/WW + Android</item> - </string-array> - <string-array name="tls_directions_entries"> - <item>0</item> - <item>1</item> - <item>Niet-gespecificeerd</item> - </string-array> - <string-array name="verb_entries"> - <item>0 - Geen logboek</item> - <item>1 - Standaard logboek</item> - <item>2 - Uitgebreid logboek</item> - <item>3</item> - <item>4</item> - <item>5 - Debug logboek</item> - </string-array> -</resources> diff --git a/res/values/values-nl/strings.xml b/res/values/values-nl/strings.xml deleted file mode 100755 index 64f43469..00000000 --- a/res/values/values-nl/strings.xml +++ /dev/null @@ -1,64 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!--Generated by crowdin.net--> -<resources> - <string name="app">LEAP voor Android</string> - <string name="address">Server Adres:</string> - <string name="port">Server Poort:</string> - <string name="location">Locatie</string> - <string name="select">Selecteer</string> - <string name="cancel">Annuleer</string> - <string name="no_data">Geen Gegevens</string> - <string name="useLZO">LZO Compressie</string> - <string name="client_no_certificate">Geen Certificaat</string> - <string name="client_certificate_title">Client Certificaat</string> - <string name="client_key_title">Client Certificaat Sleutel</string> - <string name="client_pkcs12_title">PKCS12 Bestand</string> - <string name="ca_title">CA Certificaat</string> - <string name="about">Over</string> - <string name="about_summary">Over LEAP voor Android</string> - <string name="vpn_list_summary">Lijst van alle geconfigureerde VPN verbindingen</string> - <string name="vpn_list_title">VPN Profielen</string> - <string name="vpn_type">Type</string> - <string name="pkcs12pwquery">PKCS12 Wachtwoord</string> - <string name="file_select">Selecteer…</string> - <string name="useTLSAuth">Gebruik TLS autentificatie</string> - <string name="tls_direction">TLS Richting</string> - <string name="ipv6_dialog_tile">Voer een IPv6 Adres/Netmask in met het CIDR Formaat (v.b. 2000:dd::23/64)</string> - <string name="ipv4_dialog_title">Voer een IPv4 Adres/Netmask in met het CIDR Formaat (v.b. 1.2.3.4/24)</string> - <string name="ipv4_address">IPv4 Adres</string> - <string name="ipv6_address">IPv4 Adres</string> - <string name="auth_username">Gebruikersnaam</string> - <string name="auth_pwquery">wachtwoord</string> - <string name="configure_the_vpn">VPN configureren</string> - <string name="menu_add_profile">Profiel toevoegen</string> - <string name="no_error_found">Geen fout.</string> - <string name="config_error_found">Fout in de configuratie</string> - <string name="vpn_launch_title">Met VPN verbinden</string> - <string name="shortcut_profile_notfound">Het profiel zoals aangegeven in de snelkoppeling kon niet gevonden worden.</string> - <string name="route_rejected">Route geweigert door Android</string> - <string name="cancel_connection">Verbinding verbreken</string> - <string name="clear_log">logboek wissen</string> - <string name="title_cancel">Annuleer bevestiging</string> - <string name="cancel_connection_query">Sluit de verbonden VPN af/annuleer de verbindingspoging?</string> - <string name="edit_vpn">VPN Instellingen Bewerken</string> - <string name="error">"Fout:"</string> - <string name="clear">Leeg maken</string> - <string name="info">info</string> - <string name="show_connection_details">Details van de verbinding weergeven</string> - <string name="last_openvpn_tun_config">Laatste interfaceconfiguratie van OpenVPN:</string> - <string name="local_ip_info">Lokaal IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> - <string name="dns_server_info">DNS Server: %s</string> - <string name="dns_domain_info">DNS Domein: %s</string> - <string name="routes_info">Routes: %s</string> - <string name="routes_info6">Routes IPv6: %s</string> - <string name="version_info">%1$s %2$s</string> - <string name="send_logfile">Logboek verzenden</string> - <string name="send">Verzenden</string> - <string name="speed_waiting">Wachten op status bericht…</string> - <string name="converted_profile">Geïmporteerd profiel</string> - <string name="converted_profile_i">Geïmporteerd profiel %d</string> - <string name="error_empty_username">De gebruikersnaam moet niet leeg zijn.</string> - <string name="pkcs12_file_encryption_key">PKCS12 Bestand Encryptie Sleutel</string> - <string name="private_key_password">Privé Sleutel Wachtwoord</string> - <string name="password">Wachtwoord</string> -</resources> diff --git a/src/se/leap/bitmaskclient/ConfigHelper.java b/src/se/leap/bitmaskclient/ConfigHelper.java index 6b49d7d7..a8bd3b7a 100644 --- a/src/se/leap/bitmaskclient/ConfigHelper.java +++ b/src/se/leap/bitmaskclient/ConfigHelper.java @@ -47,142 +47,12 @@ import android.util.Base64; * */ public class ConfigHelper { - - public static SharedPreferences shared_preferences; private static KeyStore keystore_trusted; final public static String NG_1024 = "eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3"; final public static BigInteger G = new BigInteger("2"); - - private static boolean checkSharedPrefs() { - try { - if(shared_preferences == null) - shared_preferences = Dashboard.getAppContext().getSharedPreferences(Dashboard.SHARED_PREFERENCES,Context.MODE_PRIVATE); - } catch (Exception e) { - return false; - } - - return true; - } - - /** - * Saves a JSON object into class scope Shared Preferences - * @param shared_preferences_key - * @param content - */ - public static void saveSharedPref(String shared_preferences_key, JSONObject content) { - - SharedPreferences.Editor shared_preferences_editor = shared_preferences - .edit(); - shared_preferences_editor.putString(shared_preferences_key, - content.toString()); - shared_preferences_editor.commit(); - } - - /** - * Saves a String object into class scope Shared Preferences - * @param shared_preferences_key - * @param content - */ - public static void saveSharedPref(String shared_preferences_key, String content) { - - SharedPreferences.Editor shared_preferences_editor = shared_preferences - .edit(); - shared_preferences_editor.putString(shared_preferences_key, - content); - shared_preferences_editor.commit(); - } - - /** - * Saves a boolean object into class scope Shared Preferences - * @param shared_preferences_key - * @param content - */ - public static void saveSharedPref(String shared_preferences_key, boolean content) { - - SharedPreferences.Editor shared_preferences_editor = shared_preferences - .edit(); - shared_preferences_editor.putBoolean(shared_preferences_key, content); - shared_preferences_editor.commit(); - } - - /** - * Saves an int into class scope Shared Preferences - * - * @param shared_preferences_key - * @param value - */ - protected static void saveSharedPref(String shared_preferences_key, int value) { - SharedPreferences.Editor shared_preferences_editor = shared_preferences.edit(); - shared_preferences_editor.putInt(shared_preferences_key, value).commit(); - } - - /** - * Gets String object from class scope Shared Preferences - * @param shared_preferences_key - * @return the string correspondent to the key parameter - */ - public static String getStringFromSharedPref(String shared_preferences_key) { - String content = null; - content = shared_preferences.getString(shared_preferences_key, ""); - return content; - } - - /** - * Gets JSON object from class scope Shared Preferences - * @param shared_preferences_key - * @return the JSON object correspondent to the key parameter - */ - public static JSONObject getJsonFromSharedPref(String shared_preferences_key) throws JSONException { - JSONObject content = null; - if ( checkSharedPrefs() ) { - String json_string = shared_preferences.getString(shared_preferences_key, ""); - content = new JSONObject(json_string); - } - - return content; - } - - /* - * This method defaults to false. - * If you use this method, be sure to fail-closed on false! - * TODO This is obviously less than ideal...solve it! - */ - public static boolean getBoolFromSharedPref(String shared_preferences_key) { - boolean value = false; - if ( checkSharedPrefs() ) { - value = shared_preferences.getBoolean(shared_preferences_key, false); - } - return value; - } - - /** - * Get an int from SharedPreferences - * - * @param shared_preferences_key Key to retrieve - * @return The value for the key or 0 - */ - protected static int getIntFromSharedPref(String shared_preferences_key) { - return shared_preferences.getInt(shared_preferences_key, 0); - } - - protected static boolean sharedPrefContainsKey(String shared_preferences_key) { - return shared_preferences.contains(shared_preferences_key); - } - /* - * This method defaults to false. - * If you use this method, be sure to fail-closed on false! - * TODO This is obviously less than ideal...solve it! - */ - public static boolean removeFromSharedPref(String shared_preferences_key) { - SharedPreferences.Editor shared_preferences_editor = shared_preferences - .edit(); - shared_preferences_editor.remove(shared_preferences_key); - return shared_preferences_editor.commit(); - } - public static boolean checkErroneousDownload(String downloaded_string) { try { if(new JSONObject(downloaded_string).has(ProviderAPI.ERRORS) || downloaded_string.isEmpty()) { @@ -214,15 +84,6 @@ public class ConfigHelper { System.arraycopy(in, i, ret, 0, len - i); return ret; } - - /** - * Sets class scope Shared Preferences - * @param shared_preferences - */ - public static void setSharedPreferences( - SharedPreferences shared_preferences) { - ConfigHelper.shared_preferences = shared_preferences; - } public static X509Certificate parseX509CertificateFromString(String certificate_string) { java.security.cert.Certificate certificate = null; diff --git a/src/se/leap/bitmaskclient/ConfigurationWizard.java b/src/se/leap/bitmaskclient/ConfigurationWizard.java index cf027660..e5ad5b3d 100644 --- a/src/se/leap/bitmaskclient/ConfigurationWizard.java +++ b/src/se/leap/bitmaskclient/ConfigurationWizard.java @@ -40,6 +40,7 @@ import android.content.BroadcastReceiver; import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.os.Handler;
@@ -85,10 +86,12 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD public ProviderAPIResultReceiver providerAPI_result_receiver;
private ProviderAPIBroadcastReceiver_Update providerAPI_broadcast_receiver_update;
+ private static SharedPreferences preferences; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE);
setContentView(R.layout.configuration_wizard_activity);
mProgressBar = (ProgressBar) findViewById(R.id.progressbar_configuration_wizard);
@@ -101,10 +104,8 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD IntentFilter update_intent_filter = new IntentFilter(ProviderAPI.UPDATE_PROGRESSBAR);
update_intent_filter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(providerAPI_broadcast_receiver_update, update_intent_filter);
-
- ConfigHelper.setSharedPreferences(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE));
-
- loadPreseededProviders();
+
+ loadPreseededProviders();
// Only create our fragments if we're not restoring a saved instance
if ( savedInstanceState == null ){
@@ -150,7 +151,7 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD if(resultCode == ProviderAPI.PROVIDER_OK) {
mConfigState.setAction(PROVIDER_SET);
- if (ConfigHelper.getBoolFromSharedPref(EIP.ALLOWED_ANON)){
+ if (preferences.getBoolean(EIP.ALLOWED_ANON, false)){
mConfigState.putExtra(SERVICES_RETRIEVED, true);
downloadAnonCert();
} else {
@@ -166,7 +167,7 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD showDownloadFailedDialog(getCurrentFocus(), reason_to_fail);
mProgressBar.setVisibility(ProgressBar.GONE);
progressbar_description.setVisibility(TextView.GONE);
- ConfigHelper.removeFromSharedPref(Provider.KEY); + preferences.edit().remove(Provider.KEY).commit(); setResult(RESULT_CANCELED, mConfigState);
}
else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) {
@@ -204,15 +205,17 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD provider_list_fragment.hideAllBut(provider_index); boolean danger_on = true; - if(ConfigHelper.sharedPrefContainsKey(ProviderItem.DANGER_ON)) - danger_on = ConfigHelper.getBoolFromSharedPref(ProviderItem.DANGER_ON); + if(preferences.contains(ProviderItem.DANGER_ON)) + danger_on = preferences.getBoolean(ProviderItem.DANGER_ON, false); setUpProvider(selected_provider.providerMainUrl(), danger_on); }
@Override
public void onBackPressed() {
try {
- if(ConfigHelper.getJsonFromSharedPref(Provider.KEY) == null || ConfigHelper.getJsonFromSharedPref(Provider.KEY).length() == 0) {
+ boolean is_provider_set_up = new JSONObject(preferences.getString(Provider.KEY, "no provider")) != null ? true : false;
+ boolean is_provider_set_up_truly = new JSONObject(preferences.getString(Provider.KEY, "no provider")).length() != 0 ? true : false;
+ if(!is_provider_set_up || !is_provider_set_up_truly) {
askDashboardToQuitApp();
} else {
setResult(RESULT_OK);
@@ -275,12 +278,7 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD ProviderItem provider = providers_iterator.next();
if(provider.name().equalsIgnoreCase(id)) {
break;
-//<<<<<<< HEAD -// }
-// index++;
-//======= - } else index++;
-//>>>>>>> bug/more-detailed-response-to-CW-errors + } else index++; }
return index;
}
@@ -432,8 +430,7 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD }
private void autoSelectProvider(String provider_main_url, boolean danger_on) {
- - ConfigHelper.saveSharedPref(ProviderItem.DANGER_ON, danger_on);
+ getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putBoolean(ProviderItem.DANGER_ON, danger_on).commit();
onItemSelected(getId(provider_main_url));
}
@@ -498,14 +495,10 @@ implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderD public void cancelSettingUpProvider() {
provider_list_fragment = (ProviderListFragment) getFragmentManager().findFragmentByTag(ProviderListFragment.TAG);
- if(provider_list_fragment != null && ConfigHelper.sharedPrefContainsKey(ProviderItem.DANGER_ON)) {
+ if(provider_list_fragment != null && preferences.contains(ProviderItem.DANGER_ON)) {
provider_list_fragment.removeLastItem();
}
-
- ConfigHelper.removeFromSharedPref(Provider.KEY);
- ConfigHelper.removeFromSharedPref(ProviderItem.DANGER_ON);
- ConfigHelper.removeFromSharedPref(EIP.ALLOWED_ANON);
- ConfigHelper.removeFromSharedPref(EIP.KEY);
+ preferences.edit().remove(Provider.KEY).remove(ProviderItem.DANGER_ON).remove(EIP.ALLOWED_ANON).remove(EIP.KEY).commit();
}
@Override
diff --git a/src/se/leap/bitmaskclient/Dashboard.java b/src/se/leap/bitmaskclient/Dashboard.java index d50aa7e0..b4d06f23 100644 --- a/src/se/leap/bitmaskclient/Dashboard.java +++ b/src/se/leap/bitmaskclient/Dashboard.java @@ -85,11 +85,10 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - ConfigHelper.setSharedPreferences(getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE)); - preferences = ConfigHelper.shared_preferences; + preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); - authed_eip = ConfigHelper.getBoolFromSharedPref(EIP.AUTHED_EIP); - if (ConfigHelper.getStringFromSharedPref(Provider.KEY).isEmpty()) + authed_eip = preferences.getBoolean(EIP.AUTHED_EIP, false); + if (preferences.getString(Provider.KEY, "").isEmpty()) startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP); else buildDashboard(); @@ -105,10 +104,11 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf if ( requestCode == CONFIGURE_LEAP || requestCode == SWITCH_PROVIDER) { // It should be equivalent: if ( (requestCode == CONFIGURE_LEAP) || (data!= null && data.hasExtra(STOP_FIRST))) { if ( resultCode == RESULT_OK ){ - ConfigHelper.saveSharedPref(EIP.PARSED_SERIAL, 0); - ConfigHelper.saveSharedPref(EIP.AUTHED_EIP, authed_eip); - - startService( new Intent(EIP.ACTION_UPDATE_EIP_SERVICE) ); + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putInt(EIP.PARSED_SERIAL, 0).commit(); + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); + Intent updateEIP = new Intent(getApplicationContext(), EIP.class); + updateEIP.setAction(EIP.ACTION_UPDATE_EIP_SERVICE); + startService(updateEIP); buildDashboard(); if(data != null && data.hasExtra(LogInDialog.VERB)) { @@ -176,8 +176,9 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf public boolean onPrepareOptionsMenu(Menu menu) { JSONObject provider_json; try { - provider_json = ConfigHelper.getJsonFromSharedPref(Provider.KEY); + provider_json = new JSONObject(getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, "")); JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE); + if(service_description.getBoolean(Provider.ALLOW_REGISTRATION)) { if(authed_eip) { menu.findItem(R.id.login_button).setVisible(false); @@ -210,12 +211,12 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf return true; case R.id.switch_provider: if (Provider.getInstance().hasEIP()){ - if (ConfigHelper.getBoolFromSharedPref(EIP.AUTHED_EIP)){ + if (getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getBoolean(EIP.AUTHED_EIP, false)){ logOut(); } eipStop(); } - ConfigHelper.removeFromSharedPref(Provider.KEY); + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().remove(Provider.KEY).commit(); startActivityForResult(new Intent(this,ConfigurationWizard.class), SWITCH_PROVIDER); return true; case R.id.login_button: @@ -347,7 +348,8 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf setResult(RESULT_OK); authed_eip = true; - ConfigHelper.saveSharedPref(EIP.AUTHED_EIP, authed_eip); + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); + invalidateOptionsMenu(); mProgressBar.setVisibility(ProgressBar.GONE); changeStatusMessage(resultCode); @@ -358,7 +360,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf logInDialog(getCurrentFocus(), resultData); } else if(resultCode == ProviderAPI.LOGOUT_SUCCESSFUL) { authed_eip = false; - ConfigHelper.saveSharedPref(EIP.AUTHED_EIP, authed_eip); + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); mProgressBar.setVisibility(ProgressBar.GONE); mProgressBar.setProgress(0); invalidateOptionsMenu(); diff --git a/src/se/leap/bitmaskclient/EIP.java b/src/se/leap/bitmaskclient/EIP.java index ecb7498f..169178d1 100644 --- a/src/se/leap/bitmaskclient/EIP.java +++ b/src/se/leap/bitmaskclient/EIP.java @@ -16,10 +16,14 @@ */ package se.leap.bitmaskclient; +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 org.json.JSONArray; @@ -97,13 +101,7 @@ public final class EIP extends IntentService { context = getApplicationContext(); - try { - eipDefinition = ConfigHelper.getJsonFromSharedPref(KEY); - parsedEipSerial = ConfigHelper.getIntFromSharedPref(PARSED_SERIAL); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + updateEIPService(); this.retreiveVpnService(); } @@ -273,8 +271,8 @@ public final class EIP extends IntentService { */ private void updateEIPService() { try { - eipDefinition = ConfigHelper.getJsonFromSharedPref(EIP.KEY); - parsedEipSerial = ConfigHelper.getIntFromSharedPref(PARSED_SERIAL); + eipDefinition = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(KEY, "")); + parsedEipSerial = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getInt(PARSED_SERIAL, 0); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -297,10 +295,61 @@ public final class EIP extends IntentService { * @return The gateway to connect to */ private OVPNGateway selectGateway() { - // TODO Implement gateway selection logic based on TZ or preferences - // TODO Implement search through gateways loaded from SharedPreferences // TODO Remove String arg constructor in favor of findGatewayByName(String) - return new OVPNGateway("first"); + + Calendar cal = Calendar.getInstance(); + int localOffset = cal.get(Calendar.ZONE_OFFSET) / 3600000; + TreeMap<Integer, Set<String>> offsets = new TreeMap<Integer, Set<String>>(); + JSONObject locationsObjects = null; + Iterator<String> 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<String> set = offsets.get(dist); + if (set == null) set = new HashSet<String>(); + set.add(locationName); + offsets.put(dist, set); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + String closestLocation = offsets.firstEntry().getValue().iterator().next(); + JSONArray gateways = null; + String chosenHost = null; + try { + gateways = eipDefinition.getJSONArray("gateways"); + for (int i = 0; i < gateways.length(); i++) { + JSONObject gw = gateways.getJSONObject(i); + if ( gw.getString("location").equalsIgnoreCase(closestLocation) ){ + chosenHost = gw.getString("host"); + break; + } + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return new OVPNGateway(chosenHost); } /** @@ -338,8 +387,7 @@ public final class EIP extends IntentService { e.printStackTrace(); } } - - ConfigHelper.saveSharedPref(PARSED_SERIAL, eipDefinition.optInt(Provider.API_RETURN_SERIAL)); + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putInt(PARSED_SERIAL, eipDefinition.optInt(Provider.API_RETURN_SERIAL)).commit(); } /** @@ -375,12 +423,10 @@ public final class EIP extends IntentService { ProfileManager vpl = ProfileManager.getInstance(context); try { - if ( mName == "first" ) { - mName = vpl.getProfiles().iterator().next().mName; - } - - mVpnProfile = vpl.getProfileByName(mName); - + if ( mName == null ) + mVpnProfile = vpl.getProfiles().iterator().next(); + else + mVpnProfile = vpl.getProfileByName(mName); } catch (NoSuchElementException e) { updateEIPService(); this.loadVpnProfile(); // FIXME catch infinite loops @@ -406,9 +452,10 @@ public final class EIP extends IntentService { for (Iterator<VpnProfile> it = profiles.iterator(); it.hasNext(); ){ VpnProfile p = it.next(); try { - if ( p.mName.contains( gateway.getString("host") ) ) + if ( p.mName.equalsIgnoreCase( gateway.getString("host") ) ){ it.remove(); vpl.removeProfile(context, p); + } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); diff --git a/src/se/leap/bitmaskclient/LeapHttpClient.java b/src/se/leap/bitmaskclient/LeapHttpClient.java index 837da236..885b5105 100644 --- a/src/se/leap/bitmaskclient/LeapHttpClient.java +++ b/src/se/leap/bitmaskclient/LeapHttpClient.java @@ -34,7 +34,6 @@ import android.content.Context; * */ public class LeapHttpClient extends DefaultHttpClient { - final Context context; private static LeapHttpClient client; @@ -43,10 +42,8 @@ public class LeapHttpClient extends DefaultHttpClient { * @param context * @return the new client. */ - public static LeapHttpClient getInstance(Context context) { + public static LeapHttpClient getInstance(String cert_string) { if(client == null) { - client = new LeapHttpClient(context); - String cert_string = ConfigHelper.getStringFromSharedPref(Provider.CA_CERT); if(cert_string != null) { ConfigHelper.addTrustedCertificate("provider_ca_certificate", cert_string); } @@ -77,8 +74,4 @@ public class LeapHttpClient extends DefaultHttpClient { throw new AssertionError(e); } } - - public LeapHttpClient(Context context) { - this.context = context; - } } diff --git a/src/se/leap/bitmaskclient/ProviderAPI.java b/src/se/leap/bitmaskclient/ProviderAPI.java index 8116f244..5344e471 100644 --- a/src/se/leap/bitmaskclient/ProviderAPI.java +++ b/src/se/leap/bitmaskclient/ProviderAPI.java @@ -444,25 +444,6 @@ public class ProviderAPI extends IntentService { * @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) { -//<<<<<<< HEAD -// Bundle result = new Bundle(); -// int progress = 0; -// boolean danger_on = task.getBoolean(ProviderItem.DANGER_ON); -// String provider_main_url = task.getString(Provider.MAIN_URL); -// if(downloadCACert(provider_main_url, danger_on)) { -// broadcast_progress(progress++); -// result.putBoolean(RESULT_KEY, true); -// if(getAndSetProviderJson(provider_main_url)) { -// broadcast_progress(progress++); -// if(getAndSetEipServiceJson()) -// broadcast_progress(progress++); -// } -// } -// return result; -// } -// -// -//======= int progress = 0; Bundle current_download = new Bundle(); @@ -496,8 +477,8 @@ public class ProviderAPI extends IntentService { private Bundle downloadCACert(String provider_main_url, boolean danger_on) { Bundle result = new Bundle(); String cert_string = downloadWithCommercialCA(provider_main_url + "/ca.crt", danger_on); - if(validCertificate(cert_string)) { - ConfigHelper.saveSharedPref(Provider.CA_CERT, cert_string); + if(validCertificate(cert_string)) { + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(Provider.CA_CERT, cert_string).commit(); result.putBoolean(RESULT_KEY, true); } else { String reason_to_fail = pickErrorMessage(cert_string); @@ -538,8 +519,8 @@ public class ProviderAPI extends IntentService { String name = provider_json.getString(Provider.NAME); //TODO setProviderName(name); - ConfigHelper.saveSharedPref(Provider.KEY, provider_json); - ConfigHelper.saveSharedPref(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON)); + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(Provider.KEY, provider_json.toString()).commit(); + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putBoolean(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON)).commit(); result.putBoolean(RESULT_KEY, true); } catch (JSONException e) { @@ -561,13 +542,13 @@ public class ProviderAPI extends IntentService { Bundle result = new Bundle(); String eip_service_json_string = ""; try { - JSONObject provider_json = ConfigHelper.getJsonFromSharedPref(Provider.KEY); + JSONObject provider_json = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, "")); String eip_service_url = provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.SERVICE_API_PATH; eip_service_json_string = downloadWithProviderCA(eip_service_url, true); JSONObject eip_service_json = new JSONObject(eip_service_json_string); eip_service_json.getInt(Provider.API_RETURN_SERIAL); - - ConfigHelper.saveSharedPref(EIP.KEY, eip_service_json); + + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.KEY, eip_service_json.toString()).commit(); result.putBoolean(RESULT_KEY, true); } catch (JSONException e) { @@ -685,7 +666,7 @@ public class ProviderAPI extends IntentService { } private javax.net.ssl.SSLSocketFactory getProviderSSLSocketFactory() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException { - String provider_cert_string = ConfigHelper.getStringFromSharedPref(Provider.CA_CERT); + String provider_cert_string = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.CA_CERT,""); java.security.cert.Certificate provider_certificate = ConfigHelper.parseX509CertificateFromString(provider_cert_string); @@ -817,11 +798,12 @@ public class ProviderAPI extends IntentService { try { String type_of_certificate = task.getString(ConfigurationWizard.TYPE_OF_CERTIFICATE); - JSONObject provider_json = ConfigHelper.getJsonFromSharedPref(Provider.KEY); + JSONObject provider_json = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, "")); + String provider_main_url = provider_json.getString(Provider.API_URL); URL new_cert_string_url = new URL(provider_main_url + "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.CERTIFICATE); - boolean danger_on = ConfigHelper.getBoolFromSharedPref(ProviderItem.DANGER_ON); + boolean danger_on = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getBoolean(ProviderItem.DANGER_ON, false); String cert_string = downloadWithProviderCA(new_cert_string_url.toString(), danger_on); @@ -847,12 +829,12 @@ public class ProviderAPI extends IntentService { try { RSAPrivateKey keyCert = ConfigHelper.parseRsaKeyFromString(keyString); keyString = Base64.encodeToString( keyCert.getEncoded(), Base64.DEFAULT ); - ConfigHelper.saveSharedPref(EIP.PRIVATE_KEY, "-----BEGIN RSA PRIVATE KEY-----\n"+keyString+"-----END RSA PRIVATE KEY-----"); + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.PRIVATE_KEY, "-----BEGIN RSA PRIVATE KEY-----\n"+keyString+"-----END RSA PRIVATE KEY-----").commit(); X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(certificateString); certificateString = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT); - ConfigHelper.saveSharedPref(EIP.CERTIFICATE, "-----BEGIN CERTIFICATE-----\n"+certificateString+"-----END CERTIFICATE-----"); - + getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.CERTIFICATE, "-----BEGIN CERTIFICATE-----\n"+certificateString+"-----END CERTIFICATE-----").commit(); + return true; } catch (CertificateException e) { // TODO Auto-generated catch block diff --git a/src/se/leap/bitmaskclient/ProviderDetailFragment.java b/src/se/leap/bitmaskclient/ProviderDetailFragment.java index fd8b29d9..3ed04184 100644 --- a/src/se/leap/bitmaskclient/ProviderDetailFragment.java +++ b/src/se/leap/bitmaskclient/ProviderDetailFragment.java @@ -11,6 +11,7 @@ import android.app.AlertDialog; import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
+import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@@ -28,7 +29,7 @@ public class ProviderDetailFragment extends DialogFragment { LayoutInflater inflater = getActivity().getLayoutInflater();
View provider_detail_view = inflater.inflate(R.layout.provider_detail_fragment, null);
- JSONObject provider_json = ConfigHelper.getJsonFromSharedPref(Provider.KEY);
+ JSONObject provider_json = new JSONObject(getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, getActivity().MODE_PRIVATE).getString(Provider.KEY, ""));
final TextView domain = (TextView)provider_detail_view.findViewById(R.id.provider_detail_domain);
domain.setText(provider_json.getString(Provider.DOMAIN));
@@ -82,11 +83,9 @@ public class ProviderDetailFragment extends DialogFragment { @Override
public void onCancel(DialogInterface dialog) {
- super.onCancel(dialog); - ConfigHelper.removeFromSharedPref(Provider.KEY);
- ConfigHelper.removeFromSharedPref(ProviderItem.DANGER_ON);
- ConfigHelper.removeFromSharedPref(EIP.ALLOWED_ANON);
- ConfigHelper.removeFromSharedPref(EIP.KEY); + super.onCancel(dialog);
+ SharedPreferences.Editor editor = getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE).edit();
+ editor.remove(Provider.KEY).remove(ProviderItem.DANGER_ON).remove(EIP.ALLOWED_ANON).remove(EIP.KEY).commit(); interface_with_configuration_wizard.showAllProviders(); }
diff --git a/src/se/leap/openvpn/VpnProfile.java b/src/se/leap/openvpn/VpnProfile.java index 99e1c676..481819ad 100644 --- a/src/se/leap/openvpn/VpnProfile.java +++ b/src/se/leap/openvpn/VpnProfile.java @@ -22,6 +22,7 @@ import org.spongycastle.util.io.pem.PemObject; import org.spongycastle.util.io.pem.PemWriter; import se.leap.bitmaskclient.ConfigHelper; +import se.leap.bitmaskclient.Dashboard; import se.leap.bitmaskclient.EIP; import se.leap.bitmaskclient.Provider; import se.leap.bitmaskclient.R; @@ -249,9 +250,10 @@ public class VpnProfile implements Serializable{ cfg+=insertFileData("cert",mClientCertFilename); */ // FIXME This is all we need...The whole switch statement can go... - cfg+="<ca>\n"+ConfigHelper.getStringFromSharedPref(Provider.CA_CERT)+"\n</ca>\n"; - cfg+="<key>\n"+ConfigHelper.getStringFromSharedPref(EIP.PRIVATE_KEY)+"\n</key>\n"; - cfg+="<cert>\n"+ConfigHelper.getStringFromSharedPref(EIP.CERTIFICATE)+"\n</cert>\n"; + SharedPreferences preferences = context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, context.MODE_PRIVATE); + cfg+="<ca>\n"+preferences.getString(Provider.CA_CERT, "")+"\n</ca>\n"; + cfg+="<key>\n"+preferences.getString(EIP.PRIVATE_KEY, "")+"\n</key>\n"; + cfg+="<cert>\n"+preferences.getString(EIP.CERTIFICATE, "")+"\n</cert>\n"; break; case VpnProfile.TYPE_USERPASS_PKCS12: diff --git a/tests/src/se/leap/bitmaskclient/test/testConfigurationWizard.java b/tests/src/se/leap/bitmaskclient/test/testConfigurationWizard.java index 34d2ae26..55fd87ae 100644 --- a/tests/src/se/leap/bitmaskclient/test/testConfigurationWizard.java +++ b/tests/src/se/leap/bitmaskclient/test/testConfigurationWizard.java @@ -2,7 +2,7 @@ package se.leap.bitmaskclient.test; import java.io.IOException; -import se.leap.bitmaskclient.AboutFragment; +import se.leap.bitmaskclient.AboutActivity; import se.leap.bitmaskclient.ConfigurationWizard; import se.leap.bitmaskclient.ProviderDetailFragment; import se.leap.bitmaskclient.R; @@ -56,7 +56,7 @@ public class testConfigurationWizard extends ActivityInstrumentationTestCase2<Co public void testShowAbout() { solo.clickOnMenuItem(solo.getString(R.string.about)); - assertTrue("Provider details dialog did not appear", solo.waitForFragmentByTag(AboutFragment.TAG)); + assertTrue("Provider details dialog did not appear", solo.waitForActivity(AboutActivity.class)); } public void testShowSettings() { |