summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.project2
-rw-r--r--Building_from_eclipse.md24
l---------README2
-rw-r--r--README.md44
-rw-r--r--README.txt65
-rw-r--r--build.xml2
-rwxr-xr-xcompile-native-openvpn.sh14
-rwxr-xr-xcompile.sh10
-rwxr-xr-xdebug.sh2
-rw-r--r--hosts-for-tests (renamed from hosts-for-android-emulator)0
-rwxr-xr-xres/values/strings.xml1
-rwxr-xr-xrun.sh2
-rw-r--r--src/se/leap/bitmaskclient/ConfigHelper.java13
-rw-r--r--src/se/leap/bitmaskclient/ConfigurationWizard.java28
-rw-r--r--src/se/leap/bitmaskclient/Dashboard.java12
-rw-r--r--src/se/leap/bitmaskclient/DownloadFailedDialog.java59
-rw-r--r--src/se/leap/bitmaskclient/EIP.java10
-rw-r--r--src/se/leap/bitmaskclient/ProviderAPI.java188
-rw-r--r--src/se/leap/openvpn/OpenVPN.java4
-rw-r--r--src/se/leap/openvpn/OpenVpnManagementThread.java12
-rw-r--r--src/se/leap/openvpn/VpnProfile.java4
-rw-r--r--tests/.project34
22 files changed, 332 insertions, 200 deletions
diff --git a/.project b/.project
index 3fb41079..fbbe869b 100644
--- a/.project
+++ b/.project
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
- <name>bitmask_android</name>
+ <name>bitmask_for_android</name>
<comment></comment>
<projects>
</projects>
diff --git a/Building_from_eclipse.md b/Building_from_eclipse.md
new file mode 100644
index 00000000..827ba778
--- /dev/null
+++ b/Building_from_eclipse.md
@@ -0,0 +1,24 @@
+# Download Eclipse ADT environment
+
+# Download Android SDK for Bitmask Android
+
+- From the Android SDK Manager, install API 17 (Android 4.2.2) SDK Platform and ARM EABI v7a System Image
+- Restart Eclipse
+
+# Setup an AVD
+
+- Leave default settings
+- Set the name (api_17 for example)
+- Device 4.0 WVGA
+- API level 17
+- SD card size = 100 MiB
+
+# Import project
+## Import repository from Git
+
+File -> Import -> Git -> Projects from Git
+Uri -> https://github.com/leapcode/bitmask_android.git -> leave develop and master checked -> initial branch = develop -> leave "Import existing projects" -> deselect leap_androidTest -> Finish
+
+## Build OpenVPN
+
+- From the project directory, execute "./compile-native-openvpn.sh"
diff --git a/README b/README
index c3ca0746..42061c01 120000
--- a/README
+++ b/README
@@ -1 +1 @@
-README.txt \ No newline at end of file
+README.md \ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..1609d0ce
--- /dev/null
+++ b/README.md
@@ -0,0 +1,44 @@
+# Bitmask Android App
+
+This repository contains the source code for the [Bitmask][https://bitmask.net/] Android app.
+
+Please see the [issues](https://github.com/leapcode/bitmask_android/issues) section to
+report any bugs or feature requests and to see the list of known issues.
+
+## License
+
+* [See LICENSE file](https://github.com/leapcode/bitmask_android/blob/master/LICENSE.txt)
+
+## Building
+
+The build requires [Ant](https://ant.apache.org/) v1.6+, the [Android SDK](http://developer.android.com/sdk/index.html) API 17 and the [Android NDK](http://developer.android.com/tools/sdk/ndk/index.html) r8b
+to be installed in your development environment.
+
+In addition you'll need ant/bin, android/tools, 'platforms-tools' and 'android-ndk-r8b' in your enviroment path.
+
+After satisfying those requirements, the build is pretty simple:
+
+* Run `./compile.sh` from the project directory to build the APK only
+
+You might find that your device doesn't let you install your build if you
+already have the version from the Android Market installed. This is standard
+Android security as it it won't let you directly replace an app that's been
+signed with a different key. Manually uninstall Bitmask Android from your device and
+you will then be able to install your own built version.
+To uninstall it, do: adb uninstall se.leap.bitmaskclient
+
+See [here](https://github.com/parmegv/bitmask_android/blob/feature/docs/Building_from_eclipse.md) for
+instructions on building from [Eclipse](http://eclipse.org).
+
+## Acknowledgements
+
+This project uses code from [ics-openvpn project](https://code.google.com/p/ics-openvpn/).
+
+## Contributing
+
+Please fork this repository and contribute back using
+[pull requests](https://github.com/leapcode/leap_android/pulls).
+
+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/README.txt b/README.txt
deleted file mode 100644
index c7dd933b..00000000
--- a/README.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-Compiling
-=========
-
-Preconditions
-----------------
-
-1. Android SDK installed (follow instructions from http://developer.android.com/sdk/index.html)
-2. API version 16 or version installed.
-2. Ant 1.6 or greater
-
-Instructions to compile
------------------------
-
-1. cd $PROJECT_LOCATION/leap_android
-2. ./compile.sh
-
-Postconditions
---------------
-
-1. $PROJECT_LOCATION/leap_android/bin/Bitmask Android-debug.apk exists
-
-Running on the emulator
-=========================
-
-Preconditions
------------------
-
-1. Android SDK is installed, and its tools are in the PATH.
-2. Bitmask Android has been compiled.
-3. An avd exists in ~/.android/avd/ (if you do not have one, follow instructions from http://developer.android.com/tools/devices/managing-avds-cmdline.html)
-
-Instructions to run on the emulator
------------------------------------
-
-1. cd $PROJECT_LOCATION/leap_android
-1. Run script: ./run.sh @AVD-NAME . (avd names are the names of the files in ~/.android/avd with extension .avd).
-
-Postconditions
---------------
-
-1. Bitmask Android is running.
-
-Debugging from console
-======================
-
-Preconditions
------------------
-
-1. Android SDK is installed, and its tools are in the PATH.
-2. Bitmask Android has been compiled.
-3. An avd exists in ~/.android/avd/ (if you do not have one, follow instructions from http://developer.android.com/tools/devices/managing-avds-cmdline.html).
-4. jdb is installed (this program is part of OpenJDK 7)
-
-Instructions to debug from the console
------------------------------------
-
-1. cd $PROJECT_LOCATION/leap_android
-2. Run script: ./debug.sh @AVD-NAME . (avd names are the names of the files in ~/.android/avd with extension .avd).
-
-Postconditions
---------------
-
-1. Bitmask Android is running.
-2. Bitmask Android does not show the message "Application Bitmask for Android (process se.leap.bitmaskclient) is waiting for the debugger to attach".
-3. You are in a jdb debuggin session.
diff --git a/build.xml b/build.xml
index 56cf179f..9942754f 100644
--- a/build.xml
+++ b/build.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project name="Bitmask Android" default="help">
+<project name="Bitmask for Android" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
diff --git a/compile-native-openvpn.sh b/compile-native-openvpn.sh
new file mode 100755
index 00000000..7b512631
--- /dev/null
+++ b/compile-native-openvpn.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+function compile() {
+ svn co http://google-breakpad.googlecode.com/svn/trunk/ google-breakpad
+ ./build-native.sh
+}
+
+if command -v $(head -n 1 build-native.sh | column | cut -d ' ' -f 1); then
+ compile
+elif command -v ndk-build; then
+ sed -i 's/.*ndk-build/ndk-build/g' build-native.sh
+ compile
+else
+ echo "Install ndk, or modify build-native script to point to your ndk-build executable"
+fi
diff --git a/compile.sh b/compile.sh
index 77bd6caa..c557e371 100755
--- a/compile.sh
+++ b/compile.sh
@@ -1,3 +1,11 @@
#!/bin/bash
-android update project --path . --name "Bitmask Android" --target android-17
+libopenvpn_so_files=`find libs -name libopenvpn.so | wc --lines`
+libopvnutil_so_files=`find libs -name libopvpnutil.so | wc --lines`
+minivpn_files=`find libs -name minivpn | wc --lines`
+if [ $libopenvpn_so_files -lt 4 ] || [ $libopvnutil_so_files -lt 4 ] || [ $minivpn_files -lt 4 ];
+then
+ ./compile-native-openvpn.sh
+fi
+
+android update project --path . --name "Bitmask for Android" --target android-17
ant debug
diff --git a/debug.sh b/debug.sh
index 04e0fed0..9a19bf31 100755
--- a/debug.sh
+++ b/debug.sh
@@ -22,7 +22,7 @@ wait_until_booted() {
echo "Emulator booted!"
}
-emulator -wipe-data @$avd_name & # If you want to test the app from scratch
+emulator @$avd_name & # If you want to test the app from scratch
wait_until_booted
adb install -r $PROJECT_FOLDER/bin/LEAP\ Android-debug.apk # Install the new version of the application
adb shell am start -D se.leap.bitmaskclient/.Dashboard # Run app
diff --git a/hosts-for-android-emulator b/hosts-for-tests
index ab0cf906..ab0cf906 100644
--- a/hosts-for-android-emulator
+++ b/hosts-for-tests
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 39c82d40..1abd85cd 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -10,6 +10,7 @@
<string name="cant_read_folder">Unable to read directory</string>
<string name="select">Select</string>
<string name="cancel">Cancel</string>
+ <string name="ok">OK</string>
<string name="no_data">No Data</string>
<string name="useLZO">LZO Compression</string>
<string name="client_no_certificate">No Certificate</string>
diff --git a/run.sh b/run.sh
index 77dc7c6c..60258c44 100755
--- a/run.sh
+++ b/run.sh
@@ -34,5 +34,5 @@ else
fi
wait_until_booted
-adb install -r $PROJECT_FOLDER/bin/Bitmask\ Android-debug.apk # Install the new version of the application
+adb install -r $PROJECT_FOLDER/bin/Bitmask\ for\ Android-debug.apk # Install the new version of the application
adb shell am start se.leap.bitmaskclient/.Dashboard # Run app
diff --git a/src/se/leap/bitmaskclient/ConfigHelper.java b/src/se/leap/bitmaskclient/ConfigHelper.java
index b916a9ac..97a62bb2 100644
--- a/src/se/leap/bitmaskclient/ConfigHelper.java
+++ b/src/se/leap/bitmaskclient/ConfigHelper.java
@@ -50,7 +50,6 @@ 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");
@@ -178,6 +177,18 @@ public class ConfigHelper {
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()) {
+ return true;
+ } else {
+ return false;
+ }
+ } catch(JSONException e) {
+ return false;
+ }
+ }
/**
* Treat the input as the MSB representation of a number,
diff --git a/src/se/leap/bitmaskclient/ConfigurationWizard.java b/src/se/leap/bitmaskclient/ConfigurationWizard.java
index a0ac1bc2..c03d7c9e 100644
--- a/src/se/leap/bitmaskclient/ConfigurationWizard.java
+++ b/src/se/leap/bitmaskclient/ConfigurationWizard.java
@@ -124,8 +124,10 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn
//Toast.makeText(this, getResources().getString(R.string.config_error_parsing), Toast.LENGTH_LONG);
setResult(RESULT_CANCELED, mConfigState);
}
- }
+ }
else if(resultCode == ProviderAPI.INCORRECTLY_UPDATED_PROVIDER_DOT_JSON) {
+ String reason_to_fail = resultData.getString(ProviderAPI.ERRORS);
+ showDownloadFailedDialog(getCurrentFocus(), reason_to_fail);
mProgressDialog.dismiss();
setResult(RESULT_CANCELED, mConfigState);
}
@@ -142,8 +144,9 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn
}
}
else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_JSON_FILES) {
- //Toast.makeText(getApplicationContext(), R.string.incorrectly_downloaded_json_files_message, Toast.LENGTH_LONG).show();
- mProgressDialog.dismiss();
+ //Toast.makeText(getApplicationContext(), R.string.incorrectly_downloaded_json_files_message, Toast.LENGTH_LONG).show();
+ String reason_to_fail = resultData.getString(ProviderAPI.ERRORS);
+ showDownloadFailedDialog(getCurrentFocus(), reason_to_fail);
setResult(RESULT_CANCELED, mConfigState);
}
else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) {
@@ -319,6 +322,25 @@ implements ProviderListFragment.Callbacks, NewProviderDialog.NewProviderDialogIn
* use it anonymously (if possible)
* or cancel his/her election pressing the back button.
* @param view
+ * @param reason_to_fail
+ */
+ public void showDownloadFailedDialog(View view, String reason_to_fail) {
+ FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction();
+ Fragment previous_provider_details_dialog = getFragmentManager().findFragmentByTag(DownloadFailedDialog.TAG);
+ if (previous_provider_details_dialog != null) {
+ fragment_transaction.remove(previous_provider_details_dialog);
+ }
+ fragment_transaction.addToBackStack(null);
+
+ DialogFragment newFragment = DownloadFailedDialog.newInstance(reason_to_fail);
+ newFragment.show(fragment_transaction, DownloadFailedDialog.TAG);
+ }
+
+ /**
+ * Once selected a provider, this fragment offers the user to log in,
+ * use it anonymously (if possible)
+ * or cancel his/her election pressing the back button.
+ * @param view
*/
public void showProviderDetails(View view) {
FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction();
diff --git a/src/se/leap/bitmaskclient/Dashboard.java b/src/se/leap/bitmaskclient/Dashboard.java
index b452189a..fd8d6be6 100644
--- a/src/se/leap/bitmaskclient/Dashboard.java
+++ b/src/se/leap/bitmaskclient/Dashboard.java
@@ -66,7 +66,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
private TextView providerNameTV;
- private boolean authed = false;
+ private boolean authed_eip = false;
public ProviderAPIResultReceiver providerAPI_result_receiver;
@@ -80,6 +80,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
ConfigHelper.setSharedPreferences(getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE));
preferences = ConfigHelper.shared_preferences;
+ authed_eip = ConfigHelper.getBoolFromSharedPref(EIP.AUTHED_EIP);
if (ConfigHelper.getStringFromSharedPref(Provider.KEY).isEmpty())
startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP);
else
@@ -90,6 +91,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if ( requestCode == CONFIGURE_LEAP ) {
if ( resultCode == RESULT_OK ){
+ ConfigHelper.saveSharedPref(EIP.AUTHED_EIP, authed_eip);
startService( new Intent(EIP.ACTION_UPDATE_EIP_SERVICE) );
buildDashboard();
if(data != null && data.hasExtra(LogInDialog.VERB)) {
@@ -158,7 +160,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
provider_json = ConfigHelper.getJsonFromSharedPref(Provider.KEY);
JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE);
if(service_description.getBoolean(Provider.ALLOW_REGISTRATION)) {
- if(authed) {
+ if(authed_eip) {
menu.findItem(R.id.login_button).setVisible(false);
menu.findItem(R.id.logout_button).setVisible(true);
} else {
@@ -314,7 +316,8 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
String session_id_cookie_key = resultData.getString(ProviderAPI.SESSION_ID_COOKIE_KEY);
String session_id_string = resultData.getString(ProviderAPI.SESSION_ID_KEY);
setResult(RESULT_OK);
- authed = true;
+ authed_eip = true;
+ ConfigHelper.saveSharedPref(EIP.AUTHED_EIP, authed_eip);
invalidateOptionsMenu();
//Cookie session_id = new BasicClientCookie(session_id_cookie_key, session_id_string);
@@ -323,7 +326,8 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
mProgressDialog.dismiss();
logInDialog(getCurrentFocus(), resultData);
} else if(resultCode == ProviderAPI.LOGOUT_SUCCESSFUL) {
- authed = false;
+ authed_eip = false;
+ ConfigHelper.saveSharedPref(EIP.AUTHED_EIP, authed_eip);
invalidateOptionsMenu();
setResult(RESULT_OK);
mProgressDialog.dismiss();
diff --git a/src/se/leap/bitmaskclient/DownloadFailedDialog.java b/src/se/leap/bitmaskclient/DownloadFailedDialog.java
new file mode 100644
index 00000000..3ce101a6
--- /dev/null
+++ b/src/se/leap/bitmaskclient/DownloadFailedDialog.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2013 LEAP Encryption Access Project and contributers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+ package se.leap.bitmaskclient;
+
+import se.leap.bitmaskclient.R;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+
+/**
+ * Implements a dialog to show why a download failed.
+ *
+ * @author parmegv
+ *
+ */
+public class DownloadFailedDialog extends DialogFragment {
+
+ public static String TAG = "downloaded_failed_dialog";
+ private String reason_to_fail;
+ /**
+ * @return a new instance of this DialogFragment.
+ */
+ public static DialogFragment newInstance(String reason_to_fail) {
+ DownloadFailedDialog dialog_fragment = new DownloadFailedDialog();
+ dialog_fragment.reason_to_fail = reason_to_fail;
+ return dialog_fragment;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+
+ builder.setMessage(reason_to_fail)
+ .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ dialog.dismiss();
+ }
+ });
+
+ // Create the AlertDialog object and return it
+ return builder.create();
+ }
+}
diff --git a/src/se/leap/bitmaskclient/EIP.java b/src/se/leap/bitmaskclient/EIP.java
index c643d501..e059f1c1 100644
--- a/src/se/leap/bitmaskclient/EIP.java
+++ b/src/se/leap/bitmaskclient/EIP.java
@@ -58,10 +58,11 @@ import android.util.Log;
*/
public final class EIP extends IntentService {
- 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";
- public final static String ACTION_IS_EIP_RUNNING = "se.leap.bitmaskclient.IS_RUNNING";
+ public final static String ACTION_START_EIP = "se.leap.leapclient.START_EIP";
+ public final static String ACTION_STOP_EIP = "se.leap.leapclient.STOP_EIP";
+ public final static String ACTION_UPDATE_EIP_SERVICE = "se.leap.leapclient.UPDATE_EIP_SERVICE";
+ public final static String AUTHED_EIP = "authed_eip";
+ public final static String ACTION_IS_EIP_RUNNING = "se.leap.leapclient.IS_RUNNING";
public final static String EIP_NOTIFICATION = "EIP_NOTIFICATION";
public final static String ALLOWED_ANON = "allow_anonymous";
public final static String CERTIFICATE = "cert";
@@ -72,6 +73,7 @@ public final class EIP extends IntentService {
public final static String RECEIVER_TAG = "receiverTag";
public final static String REQUEST_TAG = "requestTag";
+
private static Context context;
private static ResultReceiver mReceiver;
private static OpenVpnService mVpnService;
diff --git a/src/se/leap/bitmaskclient/ProviderAPI.java b/src/se/leap/bitmaskclient/ProviderAPI.java
index 39b44e24..1408efc8 100644
--- a/src/se/leap/bitmaskclient/ProviderAPI.java
+++ b/src/se/leap/bitmaskclient/ProviderAPI.java
@@ -57,6 +57,7 @@ import org.apache.http.client.ClientProtocolException;
import org.jboss.security.srp.SRPParameters;
import org.json.JSONException;
import org.json.JSONObject;
+import org.json.JSONStringer;
import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.ProviderListContent.ProviderItem;
@@ -128,14 +129,8 @@ public class ProviderAPI extends IntentService {
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER) );
}
- private void displayToast(final int toast_string_id) {
- mHandler.post(new Runnable() {
-
- @Override
- public void run() {
- Toast.makeText(ProviderAPI.this, toast_string_id, Toast.LENGTH_LONG).show();
- }
- });
+ private String formatErrorMessage(final int toast_string_id) {
+ return "{ \"" + ERRORS + "\" : \""+getResources().getString(toast_string_id)+"\" }";
}
@Override
@@ -145,10 +140,11 @@ public class ProviderAPI extends IntentService {
Bundle parameters = command.getBundleExtra(PARAMETERS);
if(action.equalsIgnoreCase(DOWNLOAD_JSON_FILES_BUNDLE_EXTRA)) {
- if(!downloadJsonFiles(parameters)) {
- receiver.send(INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY);
- } else {
+ Bundle result = downloadJsonFiles(parameters);
+ if(result.getBoolean(RESULT_KEY)) {
receiver.send(CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY);
+ } else {
+ receiver.send(INCORRECTLY_DOWNLOADED_JSON_FILES, result);
}
} else if(action.equalsIgnoreCase(UPDATE_PROVIDER_DOTJSON)) {
Bundle result = updateProviderDotJSON(parameters);
@@ -162,7 +158,7 @@ public class ProviderAPI extends IntentService {
if(result.getBoolean(RESULT_KEY)) {
receiver.send(CORRECTLY_UPDATED_PROVIDER_DOT_JSON, result);
} else {
- receiver.send(INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY);
+ receiver.send(INCORRECTLY_DOWNLOADED_JSON_FILES, result);
}
} else if (action.equalsIgnoreCase(SRP_AUTH)) {
Bundle session_id_bundle = authenticateBySRP(parameters);
@@ -191,28 +187,53 @@ public class ProviderAPI extends IntentService {
* @param task
* @return true if eip-service.json was parsed as a JSON object correctly.
*/
- private boolean downloadJsonFiles(Bundle task) {
+ private Bundle downloadJsonFiles(Bundle task) {
+ Bundle result = new Bundle();
String cert_url = task.getString(Provider.CA_CERT);
String eip_service_json_url = task.getString(EIP.KEY);
boolean danger_on = task.getBoolean(ProviderItem.DANGER_ON);
try {
String cert_string = downloadWithCommercialCA(cert_url, danger_on);
- if(cert_string.isEmpty()) return false;
- X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(cert_string);
- cert_string = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT);
- ConfigHelper.saveSharedPref(Provider.CA_CERT, "-----BEGIN CERTIFICATE-----\n"+cert_string+"-----END CERTIFICATE-----");
-
- String eip_service_string = downloadWithCommercialCA(eip_service_json_url, danger_on);
- ConfigHelper.saveSharedPref(EIP.KEY, new JSONObject(eip_service_string));
-
- return true;
+
+ if(ConfigHelper.checkErroneousDownload(cert_string)) {
+ JSONObject possible_errors = new JSONObject(cert_string);
+ String reason_to_fail = "";
+ if(cert_string.isEmpty())
+ reason_to_fail = "Empty certificate downloaded";
+ else
+ reason_to_fail = possible_errors.getString(ERRORS);
+ result.putString(ERRORS, reason_to_fail);
+ result.putBoolean(RESULT_KEY, false);
+ } else {
+ X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(cert_string);
+ cert_string = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT);
+ ConfigHelper.saveSharedPref(Provider.CA_CERT, "-----BEGIN CERTIFICATE-----\n"+cert_string+"-----END CERTIFICATE-----");
+ }
} catch (JSONException e) {
- return false;
+ e.printStackTrace();
+ result.putBoolean(RESULT_KEY, false);
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
- return false;
+ result.putBoolean(RESULT_KEY, false);
+ }
+
+ try {
+ String eip_service_string = downloadWithCommercialCA(eip_service_json_url, danger_on);
+ JSONObject eip_service_json = new JSONObject(eip_service_string);
+ if(eip_service_json.has(ERRORS)) {
+ String reason_to_fail = eip_service_json.getString(ERRORS);
+ result.putString(ERRORS, reason_to_fail);
+ result.putBoolean(RESULT_KEY, false);
+ }
+ else ConfigHelper.saveSharedPref(EIP.KEY, eip_service_json);
+
+ result.putBoolean(RESULT_KEY, true);
+ } catch (JSONException e) {
+ result.putBoolean(RESULT_KEY, false);
}
+
+ return result;
}
/**
@@ -452,12 +473,18 @@ public class ProviderAPI extends IntentService {
result.putBoolean(RESULT_KEY, false);
} else {
JSONObject provider_json = new JSONObject(provider_dot_json_string);
- ConfigHelper.saveSharedPref(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON));
+ if(provider_json.has(ERRORS)) {
+ String reason_to_fail = provider_json.getString(ERRORS);
+ result.putString(ERRORS, reason_to_fail);
+ result.putBoolean(RESULT_KEY, false);
+ } else {
+ ConfigHelper.saveSharedPref(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON));
- //ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on));
- result.putBoolean(RESULT_KEY, true);
- result.putString(Provider.KEY, provider_json.toString());
- result.putBoolean(ProviderItem.DANGER_ON, danger_on);
+ //ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on));
+ result.putBoolean(RESULT_KEY, true);
+ result.putString(Provider.KEY, provider_json.toString());
+ result.putBoolean(ProviderItem.DANGER_ON, danger_on);
+ }
}
} catch (JSONException e) {
result.putBoolean(RESULT_KEY, false);
@@ -487,19 +514,26 @@ public class ProviderAPI extends IntentService {
} else {
JSONObject provider_json = new JSONObject(provider_json_string);
- ConfigHelper.saveSharedPref(Provider.KEY, provider_json);
- ConfigHelper.saveSharedPref(ProviderItem.DANGER_ON, danger_on);
- ConfigHelper.saveSharedPref(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON));
- ProviderItem added_provider = new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on);
- ProviderListContent.addItem(added_provider);
-
- result.putString(Provider.NAME, added_provider.getName());
- result.putBoolean(RESULT_KEY, true);
- result.putString(Provider.KEY, provider_json.toString());
- result.putBoolean(ProviderItem.DANGER_ON, danger_on);
+ if(provider_json.has(ERRORS)) {
+ String reason_to_fail = provider_json.getString(ERRORS);
+ result.putString(ERRORS, reason_to_fail);
+ result.putBoolean(RESULT_KEY, false);
+ } else {
+ ConfigHelper.saveSharedPref(Provider.KEY, provider_json);
+ ConfigHelper.saveSharedPref(ProviderItem.DANGER_ON, danger_on);
+ ConfigHelper.saveSharedPref(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON));
+ ProviderItem added_provider = new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on);
+ ProviderListContent.addItem(added_provider);
+
+ result.putString(Provider.NAME, added_provider.getName());
+ result.putBoolean(RESULT_KEY, true);
+ result.putString(Provider.KEY, provider_json.toString());
+ result.putBoolean(ProviderItem.DANGER_ON, danger_on);
+ }
}
} catch (JSONException e) {
result.putBoolean(RESULT_KEY, false);
+ result.putString(ERRORS, "Corrupt download");
}
return result;
@@ -525,17 +559,14 @@ public class ProviderAPI extends IntentService {
url_connection.setConnectTimeout(seconds_of_timeout*1000);
json_file_content = new Scanner(url_connection.getInputStream()).useDelimiter("\\A").next();
} catch (MalformedURLException e) {
- displayToast(R.string.malformed_url);
+ json_file_content = formatErrorMessage(R.string.malformed_url);
} catch(SocketTimeoutException e) {
- displayToast(R.string.server_is_down_message);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- displayToast(R.string.server_is_down_message);
+ json_file_content = formatErrorMessage(R.string.server_is_down_message);
} catch (IOException e) {
if(provider_url != null) {
json_file_content = downloadWithProviderCA(provider_url, danger_on);
} else {
- displayToast(R.string.certificate_error);
+ json_file_content = formatErrorMessage(R.string.certificate_error);
}
} catch (Exception e) {
if(provider_url != null && danger_on) {
@@ -547,7 +578,7 @@ public class ProviderAPI extends IntentService {
}
/**
- * Tries to download the contents of the provided url using not commercially validated CA certificate from chosen provider.
+ * Tries to download the contents of the provided url using not commercially validated CA certificate from chosen provider.
* @param url
* @param danger_on true to download CA certificate in case it has not been downloaded.
* @return an empty string if it fails, the url content if not.
@@ -565,16 +596,13 @@ public class ProviderAPI extends IntentService {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
- displayToast(R.string.server_is_down_message);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- displayToast(R.string.server_is_down_message);
+ json_file_content = formatErrorMessage(R.string.server_is_down_message);
} catch (IOException e) {
// The downloaded certificate doesn't validate our https connection.
if(danger_on) {
json_file_content = downloadWithoutCA(url);
} else {
- displayToast(R.string.certificate_error);
+ json_file_content = formatErrorMessage(R.string.certificate_error);
}
} catch (KeyStoreException e) {
// TODO Auto-generated catch block
@@ -650,11 +678,11 @@ public class ProviderAPI extends IntentService {
System.out.println("String ignoring certificate = " + string);
} catch (FileNotFoundException e) {
e.printStackTrace();
- displayToast(R.string.server_is_down_message);
+ string = formatErrorMessage(R.string.server_is_down_message);
} catch (IOException e) {
// The downloaded certificate doesn't validate our https connection.
e.printStackTrace();
- displayToast(R.string.certificate_error);
+ string = formatErrorMessage(R.string.certificate_error);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@@ -734,32 +762,40 @@ public class ProviderAPI extends IntentService {
boolean danger_on = ConfigHelper.getBoolFromSharedPref(ProviderItem.DANGER_ON);
String cert_string = downloadWithCommercialCA(new_cert_string_url, danger_on);
if(!cert_string.isEmpty()) {
- // API returns concatenated cert & key. Split them for OpenVPN options
- String certificateString = null, keyString = null;
- String[] certAndKey = cert_string.split("(?<=-\n)");
- for (int i=0; i < certAndKey.length-1; i++){
- if ( certAndKey[i].contains("KEY") ) {
- keyString = certAndKey[i++] + certAndKey[i];
+ if(ConfigHelper.checkErroneousDownload(cert_string)) {
+ String reason_to_fail = provider_json.getString(ERRORS);
+ //result.putString(ConfigHelper.ERRORS_KEY, reason_to_fail);
+ //result.putBoolean(ConfigHelper.RESULT_KEY, false);
+ return false;
+ } else {
+
+ // API returns concatenated cert & key. Split them for OpenVPN options
+ String certificateString = null, keyString = null;
+ String[] certAndKey = cert_string.split("(?<=-\n)");
+ for (int i=0; i < certAndKey.length-1; i++){
+ if ( certAndKey[i].contains("KEY") ) {
+ keyString = certAndKey[i++] + certAndKey[i];
+ }
+ else if ( certAndKey[i].contains("CERTIFICATE") ) {
+ certificateString = certAndKey[i++] + certAndKey[i];
+ }
}
- else if ( certAndKey[i].contains("CERTIFICATE") ) {
- certificateString = certAndKey[i++] + certAndKey[i];
+ 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-----");
+
+ X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(certificateString);
+ certificateString = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT);
+ ConfigHelper.saveSharedPref(EIP.CERTIFICATE, "-----BEGIN CERTIFICATE-----\n"+certificateString+"-----END CERTIFICATE-----");
+
+ return true;
+ } catch (CertificateException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return false;
}
}
- 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-----");
-
- X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(certificateString);
- certificateString = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT);
- ConfigHelper.saveSharedPref(EIP.CERTIFICATE, "-----BEGIN CERTIFICATE-----\n"+certificateString+"-----END CERTIFICATE-----");
-
- return true;
- } catch (CertificateException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- return false;
- }
} else {
return false;
}
diff --git a/src/se/leap/openvpn/OpenVPN.java b/src/se/leap/openvpn/OpenVPN.java
index c6055abd..d7d17b4f 100644
--- a/src/se/leap/openvpn/OpenVPN.java
+++ b/src/se/leap/openvpn/OpenVPN.java
@@ -9,6 +9,7 @@ import se.leap.bitmaskclient.R;
import android.content.Context;
import android.os.Build;
+import android.util.Log;
public class OpenVPN {
@@ -57,6 +58,7 @@ public class OpenVPN {
public LogItem(String message) {
+
mMessage = message;
}
@@ -113,7 +115,7 @@ public class OpenVPN {
synchronized static void logMessage(int level,String prefix, String message)
{
newlogItem(new LogItem(prefix + message));
-
+ Log.d("OpenVPN log item", message);
}
synchronized static void clearLog() {
diff --git a/src/se/leap/openvpn/OpenVpnManagementThread.java b/src/se/leap/openvpn/OpenVpnManagementThread.java
index 028c6ec7..78ce5a2b 100644
--- a/src/se/leap/openvpn/OpenVpnManagementThread.java
+++ b/src/se/leap/openvpn/OpenVpnManagementThread.java
@@ -182,7 +182,6 @@ public class OpenVpnManagementThread implements Runnable {
String cmd = parts[0].substring(1);
String argument = parts[1];
-
if(cmd.equals("INFO")) {
// Ignore greeting from mgmt
//logStatusMessage(command);
@@ -273,13 +272,14 @@ public class OpenVpnManagementThread implements Runnable {
private void processState(String argument) {
String[] args = argument.split(",",3);
String currentstate = args[1];
+ Log.d("OpenVPN log", argument);
if(args[2].equals(",,"))
OpenVPN.updateStateString(currentstate,"");
else
OpenVPN.updateStateString(currentstate,args[2]);
}
-
+ private static int repeated_byte_counts = 0;
private void processByteCount(String argument) {
// >BYTECOUNT:{BYTES_IN},{BYTES_OUT}
int comma = argument.indexOf(',');
@@ -288,7 +288,10 @@ public class OpenVpnManagementThread implements Runnable {
long diffin = in - mLastIn;
long diffout = out - mLastOut;
-
+ if(diffin == 0 && diffout == 0)
+ repeated_byte_counts++;
+ if(repeated_byte_counts > 3)
+ Log.d("OpenVPN log", "Repeated byte count = " + repeated_byte_counts);
mLastIn=in;
mLastOut=out;
@@ -330,7 +333,8 @@ public class OpenVpnManagementThread implements Runnable {
mOpenVPNService.setDomain(extra);
} else if (needed.equals("ROUTE")) {
String[] routeparts = extra.split(" ");
- mOpenVPNService.addRoute(routeparts[0], routeparts[1]);
+ if(!mOpenVPNService.isRunning()) // We cannot add routes to an existing openvpn session
+ mOpenVPNService.addRoute(routeparts[0], routeparts[1]);
} else if (needed.equals("ROUTE6")) {
mOpenVPNService.addRoutev6(extra);
} else if (needed.equals("IFCONFIG")) {
diff --git a/src/se/leap/openvpn/VpnProfile.java b/src/se/leap/openvpn/VpnProfile.java
index 8eebb763..41cf574b 100644
--- a/src/se/leap/openvpn/VpnProfile.java
+++ b/src/se/leap/openvpn/VpnProfile.java
@@ -108,7 +108,7 @@ public class VpnProfile implements Serializable{
public String mKeyPassword="";
public boolean mPersistTun = false;
public String mConnectRetryMax="5";
- public String mConnectRetry="5";
+ public String mConnectRetry="10";
public boolean mUserEditable=true;
static final String MINIVPN = "miniopenvpn";
@@ -211,7 +211,7 @@ public class VpnProfile implements Serializable{
cfg+="connect-retry-max " + mConnectRetryMax+ "\n";
if(mConnectRetry==null)
- mConnectRetry="5";
+ mConnectRetry="10";
cfg+="connect-retry " + mConnectRetry + "\n";
diff --git a/tests/.project b/tests/.project
deleted file mode 100644
index 851db452..00000000
--- a/tests/.project
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>leap_androidTest</name>
- <comment></comment>
- <projects>
- <project>leap_android</project>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>com.android.ide.eclipse.adt.ApkBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>