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() { | 
