summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/src/main/AndroidManifest.xml4
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/EipFragment.java14
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/MainActivity.java8
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/MainActivityErrorDialog.java4
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderAPI.java5
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java11
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EIP.java563
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java2
8 files changed, 287 insertions, 324 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6f6feebb..4e1a9406 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -26,6 +26,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18"/>
@@ -102,7 +103,8 @@
<service
android:name=".eip.EIP"
- android:exported="false">
+ android:exported="false"
+ android:permission="android.permission.BIND_JOB_SERVICE">
<intent-filter>
<action android:name="se.leap.bitmaskclient.EIP.UPDATE"/>
<action android:name="se.leap.bitmaskclient.EIP.START"/>
diff --git a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java
index 098418a9..5dbec7b0 100644
--- a/app/src/main/java/se/leap/bitmaskclient/EipFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/EipFragment.java
@@ -29,7 +29,6 @@ import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
-import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.AppCompatTextView;
@@ -56,17 +55,12 @@ import se.leap.bitmaskclient.views.VpnStateImage;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_NONETWORK;
-import static se.leap.bitmaskclient.Constants.BROADCAST_EIP_EVENT;
-import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_CODE;
-import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY;
-import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP;
-import static se.leap.bitmaskclient.Constants.EIP_REQUEST;
import static se.leap.bitmaskclient.Constants.EIP_RESTART_ON_BOOT;
import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.Constants.REQUEST_CODE_LOG_IN;
import static se.leap.bitmaskclient.Constants.REQUEST_CODE_SWITCH_PROVIDER;
import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES;
-import static se.leap.bitmaskclient.ProviderAPI.DOWNLOAD_VPN_CERTIFICATE;
+import static se.leap.bitmaskclient.ProviderAPI.UPDATE_INVALID_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.ProviderAPI.USER_MESSAGE;
import static se.leap.bitmaskclient.R.string.vpn_certificate_user_message;
@@ -240,7 +234,7 @@ public class EipFragment extends Fragment implements Observer {
askUserToLogIn(getString(vpn_certificate_user_message));
} else {
// provider has no VpnCertificate but user is logged in
- downloadVpnCertificate();
+ updateInvalidVpnCertificate();
}
}
@@ -449,8 +443,8 @@ public class EipFragment extends Fragment implements Observer {
background.setImageAlpha(210);
}
- private void downloadVpnCertificate() {
- ProviderAPICommand.execute(getContext(), DOWNLOAD_VPN_CERTIFICATE, provider);
+ private void updateInvalidVpnCertificate() {
+ ProviderAPICommand.execute(getContext(), UPDATE_INVALID_VPN_CERTIFICATE, provider);
}
private void askUserToLogIn(String userMessage) {
diff --git a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
index 33ecf85a..868d2876 100644
--- a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
@@ -54,10 +54,10 @@ import static se.leap.bitmaskclient.Constants.REQUEST_CODE_SWITCH_PROVIDER;
import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES;
import static se.leap.bitmaskclient.EipFragment.ASK_TO_CANCEL_VPN;
import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE;
-import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_VPN_CERTIFICATE;
+import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.ProviderAPI.ERRORS;
import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_DOWNLOADED_EIP_SERVICE;
-import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE;
+import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.ProviderAPI.USER_MESSAGE;
import static se.leap.bitmaskclient.R.string.downloading_vpn_certificate_failed;
import static se.leap.bitmaskclient.R.string.vpn_certificate_user_message;
@@ -294,12 +294,12 @@ public class MainActivity extends AppCompatActivity {
// TODO CATCH ME IF YOU CAN - WHAT DO WE WANT TO DO?
break;
- case CORRECTLY_DOWNLOADED_VPN_CERTIFICATE:
+ case CORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE:
provider = resultData.getParcelable(PROVIDER_KEY);
ConfigHelper.storeProviderInPreferences(preferences, provider);
EipCommand.startVPN(this, true);
break;
- case INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE:
+ case INCORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE:
if (LeapSRPSession.loggedIn() || provider.allowsAnonymous()) {
showMainActivityErrorDialog(getString(downloading_vpn_certificate_failed));
} else {
diff --git a/app/src/main/java/se/leap/bitmaskclient/MainActivityErrorDialog.java b/app/src/main/java/se/leap/bitmaskclient/MainActivityErrorDialog.java
index 23bc8427..1065503b 100644
--- a/app/src/main/java/se/leap/bitmaskclient/MainActivityErrorDialog.java
+++ b/app/src/main/java/se/leap/bitmaskclient/MainActivityErrorDialog.java
@@ -28,7 +28,7 @@ import org.json.JSONObject;
import static se.leap.bitmaskclient.MainActivityErrorDialog.DOWNLOAD_ERRORS.DEFAULT;
import static se.leap.bitmaskclient.MainActivityErrorDialog.DOWNLOAD_ERRORS.valueOf;
-import static se.leap.bitmaskclient.ProviderAPI.DOWNLOAD_VPN_CERTIFICATE;
+import static se.leap.bitmaskclient.ProviderAPI.UPDATE_INVALID_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.eip.EIP.ERRORS;
import static se.leap.bitmaskclient.eip.EIP.ERROR_ID;
@@ -107,7 +107,7 @@ public class MainActivityErrorDialog extends DialogFragment {
builder.setPositiveButton(R.string.update_certificate, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- ProviderAPICommand.execute(getContext(), DOWNLOAD_VPN_CERTIFICATE, provider);
+ ProviderAPICommand.execute(getContext(), UPDATE_INVALID_VPN_CERTIFICATE, provider);
}
});
break;
diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/ProviderAPI.java
index f1f474d7..0e27592b 100644
--- a/app/src/main/java/se/leap/bitmaskclient/ProviderAPI.java
+++ b/app/src/main/java/se/leap/bitmaskclient/ProviderAPI.java
@@ -45,6 +45,7 @@ public class ProviderAPI extends IntentService implements ProviderApiManagerBase
LOG_IN = "srpAuth",
LOG_OUT = "logOut",
DOWNLOAD_VPN_CERTIFICATE = "downloadUserAuthedVPNCertificate",
+ UPDATE_INVALID_VPN_CERTIFICATE = "ProviderAPI.UPDATE_INVALID_VPN_CERTIFICATE",
PARAMETERS = "parameters",
RECEIVER_KEY = "receiver",
ERRORS = "errors",
@@ -67,7 +68,9 @@ public class ProviderAPI extends IntentService implements ProviderApiManagerBase
PROVIDER_OK = 11,
PROVIDER_NOK = 12,
CORRECTLY_DOWNLOADED_EIP_SERVICE = 13,
- INCORRECTLY_DOWNLOADED_EIP_SERVICE = 14;
+ INCORRECTLY_DOWNLOADED_EIP_SERVICE = 14,
+ CORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE = 15,
+ INCORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE = 16;
ProviderApiManager providerApiManager;
diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java
index 2cde431e..753172e6 100644
--- a/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java
+++ b/app/src/main/java/se/leap/bitmaskclient/ProviderApiManagerBase.java
@@ -66,6 +66,7 @@ import static se.leap.bitmaskclient.ProviderAPI.BACKEND_ERROR_KEY;
import static se.leap.bitmaskclient.ProviderAPI.BACKEND_ERROR_MESSAGE;
import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_EIP_SERVICE;
import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_DOWNLOADED_VPN_CERTIFICATE;
+import static se.leap.bitmaskclient.ProviderAPI.CORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.ProviderAPI.DOWNLOAD_SERVICE_JSON;
import static se.leap.bitmaskclient.ProviderAPI.DOWNLOAD_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.ProviderAPI.ERRORID;
@@ -74,6 +75,7 @@ import static se.leap.bitmaskclient.ProviderAPI.FAILED_LOGIN;
import static se.leap.bitmaskclient.ProviderAPI.FAILED_SIGNUP;
import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_DOWNLOADED_EIP_SERVICE;
import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE;
+import static se.leap.bitmaskclient.ProviderAPI.INCORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.ProviderAPI.LOGOUT_FAILED;
import static se.leap.bitmaskclient.ProviderAPI.LOG_IN;
import static se.leap.bitmaskclient.ProviderAPI.LOG_OUT;
@@ -87,6 +89,7 @@ import static se.leap.bitmaskclient.ProviderAPI.SIGN_UP;
import static se.leap.bitmaskclient.ProviderAPI.SUCCESSFUL_LOGIN;
import static se.leap.bitmaskclient.ProviderAPI.SUCCESSFUL_LOGOUT;
import static se.leap.bitmaskclient.ProviderAPI.SUCCESSFUL_SIGNUP;
+import static se.leap.bitmaskclient.ProviderAPI.UPDATE_INVALID_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.ProviderAPI.UPDATE_PROVIDER_DETAILS;
import static se.leap.bitmaskclient.ProviderAPI.USER_MESSAGE;
import static se.leap.bitmaskclient.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_CERTIFICATE_PINNING;
@@ -197,6 +200,14 @@ public abstract class ProviderApiManagerBase {
sendToReceiverOrBroadcast(receiver, INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE, result, provider);
}
break;
+ case UPDATE_INVALID_VPN_CERTIFICATE:
+ result = updateVpnCertificate(provider);
+ if (result.getBoolean(BROADCAST_RESULT_KEY)) {
+ sendToReceiverOrBroadcast(receiver, CORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE, result, provider);
+ } else {
+ sendToReceiverOrBroadcast(receiver, INCORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE, result, provider);
+ }
+ break;
case DOWNLOAD_SERVICE_JSON:
result = getAndSetEipServiceJson(provider);
if (result.getBoolean(BROADCAST_RESULT_KEY)) {
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
index 92bd5929..159bc9a7 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
@@ -17,7 +17,6 @@
package se.leap.bitmaskclient.eip;
import android.annotation.SuppressLint;
-import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -27,10 +26,10 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ResultReceiver;
-import android.os.SystemClock;
-import android.support.annotation.Nullable;
+import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.annotation.WorkerThread;
+import android.support.v4.app.JobIntentService;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
@@ -43,7 +42,6 @@ import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.atomic.AtomicInteger;
import de.blinkt.openvpn.LaunchVPN;
import de.blinkt.openvpn.core.IOpenVPNServiceInternal;
@@ -84,7 +82,8 @@ import static se.leap.bitmaskclient.R.string.vpn_certificate_is_invalid;
* @author Sean Leonard <meanderingcode@aetherislands.net>
* @author Parménides GV <parmegv@sdf.org>
*/
-public final class EIP extends Service implements Observer {
+public final class EIP extends JobIntentService implements Observer {
+
public final static String TAG = EIP.class.getSimpleName(),
SERVICE_API_PATH = "config/eip-service.json",
@@ -92,17 +91,21 @@ public final class EIP extends Service implements Observer {
ERROR_ID = "errorID";
private volatile SharedPreferences preferences;
- private AtomicInteger processCounter;
private volatile EipStatus eipStatus;
- private final Object lock = new Object();
-
// Service connection to OpenVpnService, shared between threads
- private volatile OpenvpnServiceConnection openvpnServiceConnection;
+ private volatile OpenVpnServiceConnection openVpnServiceConnection;
+ private WeakReference<ResultReceiver> mResultRef = new WeakReference<>(null);
- @Nullable
- @Override
- public IBinder onBind(Intent intent) {
- return null;
+ /**
+ * Unique job ID for this service.
+ */
+ static final int JOB_ID = 1312;
+
+ /**
+ * Convenience method for enqueuing work in to this service.
+ */
+ static void enqueueWork(Context context, Intent work) {
+ enqueueWork(context, EIP.class, JOB_ID, work);
}
@Override
@@ -110,7 +113,6 @@ public final class EIP extends Service implements Observer {
super.onCreate();
eipStatus = EipStatus.getInstance();
eipStatus.addObserver(this);
- processCounter = new AtomicInteger(0);
preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
}
@@ -118,9 +120,9 @@ public final class EIP extends Service implements Observer {
public void onDestroy() {
super.onDestroy();
eipStatus.deleteObserver(this);
- if (openvpnServiceConnection != null) {
- openvpnServiceConnection.close();
- openvpnServiceConnection = null;
+ if (openVpnServiceConnection != null) {
+ openVpnServiceConnection.close();
+ openVpnServiceConnection = null;
}
}
@@ -135,330 +137,284 @@ public final class EIP extends Service implements Observer {
}
/**
- * register new process with processCounter and start it
+ *
* @param intent the intent that started this EIP call
*/
@Override
- public int onStartCommand(final Intent intent, int flags, int startId) {
- Log.d(TAG, "new process counter: " + processCounter.incrementAndGet());
+ protected void onHandleWork(@NonNull Intent intent) {
final String action = intent.getAction();
- if (action != null) {
- ResultReceiver resultReceiver = intent.getParcelableExtra(EIP_RECEIVER);
- new EipThread(this, action, intent, resultReceiver).start();
- } else {
- processCounter.decrementAndGet();
+ if (action == null) {
+ return;
}
- return START_STICKY;
- }
- /**
- * Thread to handle the requests to this service
- */
- class EipThread extends Thread {
- EipThread(EIP eipReference, String action, Intent startIntent, ResultReceiver resultReceiver) {
- super(new EipRunnable(eipReference, action, startIntent, resultReceiver));
+ if (intent.getParcelableExtra(EIP_RECEIVER) != null) {
+ mResultRef = new WeakReference<>((ResultReceiver) intent.getParcelableExtra(EIP_RECEIVER));
+ }
+ switch (action) {
+ case EIP_ACTION_START:
+ boolean earlyRoutes = intent.getBooleanExtra(EIP_EARLY_ROUTES, true);
+ startEIP(earlyRoutes);
+ break;
+ case EIP_ACTION_START_ALWAYS_ON_VPN:
+ startEIPAlwaysOnVpn();
+ break;
+ case EIP_ACTION_STOP:
+ stopEIP();
+ break;
+ case EIP_ACTION_IS_RUNNING:
+ isRunning();
+ break;
+ case EIP_ACTION_CHECK_CERT_VALIDITY:
+ checkVPNCertificateValidity();
+ break;
}
}
/**
- * Runnable to be used in the EipThread class
+ * Initiates an EIP connection by selecting a gateway and preparing and sending an
+ * Intent to {@link de.blinkt.openvpn.LaunchVPN}.
+ * It also sets up early routes.
*/
- class EipRunnable implements Runnable {
- private String action;
- private EIP eipReference;
- private Intent intent;
-
- private WeakReference<ResultReceiver> mReceiverRef = new WeakReference<>(null);
-
-
- EipRunnable(EIP eipReference, String action, Intent startIntent, ResultReceiver resultReceiver) {
- super();
- this.action = action;
- this.eipReference = eipReference;
- this.intent = startIntent;
- this.mReceiverRef = new WeakReference<ResultReceiver>(resultReceiver);
+ @SuppressLint("ApplySharedPref")
+ private void startEIP(boolean earlyRoutes) {
+ if (!eipStatus.isBlockingVpnEstablished() && earlyRoutes) {
+ earlyRoutes();
}
- /**
- * select correct function to call based upon transmitted action
- * after completing check if no other thread is running
- * if no other thread is running terminate the EIP service
- */
- @Override
- public void run() {
- Log.d(TAG, "new EIP thread started!");
- switch (action) {
- case EIP_ACTION_START:
- boolean earlyRoutes = intent.getBooleanExtra(EIP_EARLY_ROUTES, true);
- startEIP(earlyRoutes);
- break;
- case EIP_ACTION_START_ALWAYS_ON_VPN:
- startEIPAlwaysOnVpn();
- break;
- case EIP_ACTION_STOP:
- stopEIP();
- break;
- case EIP_ACTION_IS_RUNNING:
- isRunning();
- break;
- case EIP_ACTION_CHECK_CERT_VALIDITY:
- checkVPNCertificateValidity();
- break;
- }
- if (processCounter.decrementAndGet() == 0) {
- Log.d(TAG, "no more running EIP threads!");
- eipReference.stopSelf();
- }
+ Bundle result = new Bundle();
+ if (!preferences.getBoolean(EIP_RESTART_ON_BOOT, false)) {
+ preferences.edit().putBoolean(EIP_RESTART_ON_BOOT, true).commit();
}
- /**
- * Initiates an EIP connection by selecting a gateway and preparing and sending an
- * Intent to {@link de.blinkt.openvpn.LaunchVPN}.
- * It also sets up early routes.
- */
- @SuppressLint("ApplySharedPref")
- private void startEIP(boolean earlyRoutes) {
- if (!eipStatus.isBlockingVpnEstablished() && earlyRoutes) {
- earlyRoutes();
- }
-
- Bundle result = new Bundle();
- if (!preferences.getBoolean(EIP_RESTART_ON_BOOT, false)) {
- preferences.edit().putBoolean(EIP_RESTART_ON_BOOT, true).commit();
- }
-
- GatewaysManager gatewaysManager = gatewaysFromPreferences();
- if (!isVPNCertificateValid()) {
- setErrorResult(result, vpn_certificate_is_invalid, ERROR_INVALID_VPN_CERTIFICATE.toString());
- tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_CANCELED, result);
- return;
- }
-
- Gateway gateway = gatewaysManager.select();
- if (gateway != null && gateway.getProfile() != null) {
- launchActiveGateway(gateway);
- tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_OK);
- } else
- tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_CANCELED);
+ GatewaysManager gatewaysManager = gatewaysFromPreferences();
+ if (!isVPNCertificateValid()) {
+ setErrorResult(result, vpn_certificate_is_invalid, ERROR_INVALID_VPN_CERTIFICATE.toString());
+ tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_CANCELED);
+ return;
}
- /**
- * Tries to start the last used vpn profile when the OS was rebooted and always-on-VPN is enabled.
- * The {@link OnBootReceiver} will care if there is no profile.
- */
- private void startEIPAlwaysOnVpn() {
- Log.d(TAG, "startEIPAlwaysOnVpn vpn");
-
- GatewaysManager gatewaysManager = gatewaysFromPreferences();
- Gateway gateway = gatewaysManager.select();
-
- if (gateway != null && gateway.getProfile() != null) {
- Log.d(TAG, "startEIPAlwaysOnVpn eip launch avtive gateway vpn");
- launchActiveGateway(gateway);
- } else {
- Log.d(TAG, "startEIPAlwaysOnVpn no active profile available!");
- }
- }
+ Gateway gateway = gatewaysManager.select();
+ if (gateway != null && gateway.getProfile() != null) {
+ launchActiveGateway(gateway);
+ tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_OK);
+ } else
+ tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_CANCELED);
+ }
- /**
- * Early routes are routes that block traffic until a new
- * VpnService is started properly.
- */
- private void earlyRoutes() {
- Intent voidVpnLauncher = new Intent(getApplicationContext(), VoidVpnLauncher.class);
- voidVpnLauncher.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(voidVpnLauncher);
- }
+ /**
+ * Tries to start the last used vpn profile when the OS was rebooted and always-on-VPN is enabled.
+ * The {@link OnBootReceiver} will care if there is no profile.
+ */
+ private void startEIPAlwaysOnVpn() {
+ Log.d(TAG, "startEIPAlwaysOnVpn vpn");
- /**
- * starts the VPN and connects to the given gateway
- *
- * @param gateway to connect to
- */
- private void launchActiveGateway(Gateway gateway) {
- Intent intent = new Intent(eipReference, LaunchVPN.class);
- intent.setAction(Intent.ACTION_MAIN);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(LaunchVPN.EXTRA_HIDELOG, true);
- intent.putExtra(LaunchVPN.EXTRA_TEMP_VPN_PROFILE, gateway.getProfile());
- startActivity(intent);
- }
+ GatewaysManager gatewaysManager = gatewaysFromPreferences();
+ Gateway gateway = gatewaysManager.select();
- /**
- * Stop VPN
- * First checks if the OpenVpnConnection is open then
- * terminates EIP if currently connected or connecting
- */
- private void stopEIP() {
- int resultCode = stop() ? RESULT_OK : RESULT_CANCELED;
- tellToReceiverOrBroadcast(EIP_ACTION_STOP, resultCode);
+ if (gateway != null && gateway.getProfile() != null) {
+ Log.d(TAG, "startEIPAlwaysOnVpn eip launch avtive gateway vpn");
+ launchActiveGateway(gateway);
+ } else {
+ Log.d(TAG, "startEIPAlwaysOnVpn no active profile available!");
}
+ }
- /**
- * Checks the last stored status notified by ics-openvpn
- * Sends <code>Activity.RESULT_CANCELED</code> to the ResultReceiver that made the
- * request if it's not connected, <code>Activity.RESULT_OK</code> otherwise.
- */
- private void isRunning() {
- int resultCode = (eipStatus.isConnected()) ?
- RESULT_OK :
- RESULT_CANCELED;
- tellToReceiverOrBroadcast(EIP_ACTION_IS_RUNNING, resultCode);
- }
+ /**
+ * Early routes are routes that block traffic until a new
+ * VpnService is started properly.
+ */
+ private void earlyRoutes() {
+ Intent voidVpnLauncher = new Intent(getApplicationContext(), VoidVpnLauncher.class);
+ voidVpnLauncher.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(voidVpnLauncher);
+ }
- /**
- * read eipServiceJson from preferences and parse Gateways
- *
- * @return GatewaysManager
- */
- private GatewaysManager gatewaysFromPreferences() {
- GatewaysManager gatewaysManager = new GatewaysManager(eipReference, preferences);
- gatewaysManager.configureFromPreferences();
- return gatewaysManager;
- }
+ /**
+ * starts the VPN and connects to the given gateway
+ *
+ * @param gateway to connect to
+ */
+ private void launchActiveGateway(Gateway gateway) {
+ Intent intent = new Intent(this, LaunchVPN.class);
+ intent.setAction(Intent.ACTION_MAIN);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(LaunchVPN.EXTRA_HIDELOG, true);
+ intent.putExtra(LaunchVPN.EXTRA_TEMP_VPN_PROFILE, gateway.getProfile());
+ startActivity(intent);
+ }
- /**
- * read VPN certificate from preferences and check it
- * broadcast result
- */
- private void checkVPNCertificateValidity() {
- int resultCode = isVPNCertificateValid() ?
- RESULT_OK :
- RESULT_CANCELED;
- tellToReceiverOrBroadcast(EIP_ACTION_CHECK_CERT_VALIDITY, resultCode);
- }
+ /**
+ * Stop VPN
+ * First checks if the OpenVpnConnection is open then
+ * terminates EIP if currently connected or connecting
+ */
+ private void stopEIP() {
+ int resultCode = stop() ? RESULT_OK : RESULT_CANCELED;
+ tellToReceiverOrBroadcast(EIP_ACTION_STOP, resultCode);
+ }
- /**
- * read VPN certificate from preferences and check it
- *
- * @return true if VPN certificate is valid false otherwise
- */
- private boolean isVPNCertificateValid() {
- VpnCertificateValidator validator = new VpnCertificateValidator(preferences.getString(PROVIDER_VPN_CERTIFICATE, ""));
- return validator.isValid();
- }
+ /**
+ * Checks the last stored status notified by ics-openvpn
+ * Sends <code>Activity.RESULT_CANCELED</code> to the ResultReceiver that made the
+ * request if it's not connected, <code>Activity.RESULT_OK</code> otherwise.
+ */
+ private void isRunning() {
+ int resultCode = (eipStatus.isConnected()) ?
+ RESULT_OK :
+ RESULT_CANCELED;
+ tellToReceiverOrBroadcast(EIP_ACTION_IS_RUNNING, resultCode);
+ }
- /**
- * send resultCode and resultData to receiver or
- * broadcast the result if no receiver is defined
- *
- * @param action the action that has been performed
- * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise
- * @param resultData other data to broadcast or return to receiver
- */
- private void tellToReceiverOrBroadcast(String action, int resultCode, Bundle resultData) {
- resultData.putString(EIP_REQUEST, action);
- if (mReceiverRef.get() != null) {
- mReceiverRef.get().send(resultCode, resultData);
- } else {
- broadcastEvent(resultCode, resultData);
- }
- }
+ /**
+ * read eipServiceJson from preferences and parse Gateways
+ *
+ * @return GatewaysManager
+ */
+ private GatewaysManager gatewaysFromPreferences() {
+ GatewaysManager gatewaysManager = new GatewaysManager(this, preferences);
+ gatewaysManager.configureFromPreferences();
+ return gatewaysManager;
+ }
- /**
- * send resultCode and resultData to receiver or
- * broadcast the result if no receiver is defined
- *
- * @param action the action that has been performed
- * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise
- */
- private void tellToReceiverOrBroadcast(String action, int resultCode) {
- tellToReceiverOrBroadcast(action, resultCode, new Bundle());
- }
+ /**
+ * read VPN certificate from preferences and check it
+ * broadcast result
+ */
+ private void checkVPNCertificateValidity() {
+ int resultCode = isVPNCertificateValid() ?
+ RESULT_OK :
+ RESULT_CANCELED;
+ tellToReceiverOrBroadcast(EIP_ACTION_CHECK_CERT_VALIDITY, resultCode);
+ }
- /**
- * broadcast result
- *
- * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise
- * @param resultData other data to broadcast or return to receiver
- */
- private void broadcastEvent(int resultCode, Bundle resultData) {
- Intent intentUpdate = new Intent(BROADCAST_EIP_EVENT);
- intentUpdate.addCategory(CATEGORY_DEFAULT);
- intentUpdate.putExtra(BROADCAST_RESULT_CODE, resultCode);
- intentUpdate.putExtra(BROADCAST_RESULT_KEY, resultData);
- Log.d(TAG, "sending broadcast");
- LocalBroadcastManager.getInstance(eipReference).sendBroadcast(intentUpdate);
+ /**
+ * read VPN certificate from preferences and check it
+ *
+ * @return true if VPN certificate is valid false otherwise
+ */
+ private boolean isVPNCertificateValid() {
+ VpnCertificateValidator validator = new VpnCertificateValidator(preferences.getString(PROVIDER_VPN_CERTIFICATE, ""));
+ return validator.isValid();
+ }
+
+ /**
+ * send resultCode and resultData to receiver or
+ * broadcast the result if no receiver is defined
+ *
+ * @param action the action that has been performed
+ * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise
+ * @param resultData other data to broadcast or return to receiver
+ */
+ private void tellToReceiverOrBroadcast(String action, int resultCode, Bundle resultData) {
+ resultData.putString(EIP_REQUEST, action);
+ if (mResultRef.get() != null) {
+ mResultRef.get().send(resultCode, resultData);
+ } else {
+ broadcastEvent(resultCode, resultData);
}
+ }
+ /**
+ * send resultCode and resultData to receiver or
+ * broadcast the result if no receiver is defined
+ *
+ * @param action the action that has been performed
+ * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise
+ */
+ private void tellToReceiverOrBroadcast(String action, int resultCode) {
+ tellToReceiverOrBroadcast(action, resultCode, new Bundle());
+ }
- /**
- * helper function to add error to result bundle
- *
- * @param result - result of an action
- * @param errorMessageId - id of string resource describing the error
- * @param errorId - MainActivityErrorDialog DownloadError id
- */
- void setErrorResult(Bundle result, @StringRes int errorMessageId, String errorId) {
- JSONObject errorJson = new JSONObject();
- try {
- errorJson.put(ERRORS, getResources().getString(errorMessageId));
- errorJson.put(ERROR_ID, errorId);
- } catch (JSONException e) {
- e.printStackTrace();
- }
- result.putString(ERRORS, errorJson.toString());
- result.putBoolean(BROADCAST_RESULT_KEY, false);
- }
+ /**
+ * broadcast result
+ *
+ * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise
+ * @param resultData other data to broadcast or return to receiver
+ */
+ private void broadcastEvent(int resultCode, Bundle resultData) {
+ Intent intentUpdate = new Intent(BROADCAST_EIP_EVENT);
+ intentUpdate.addCategory(CATEGORY_DEFAULT);
+ intentUpdate.putExtra(BROADCAST_RESULT_CODE, resultCode);
+ intentUpdate.putExtra(BROADCAST_RESULT_KEY, resultData);
+ Log.d(TAG, "sending broadcast");
+ LocalBroadcastManager.getInstance(this).sendBroadcast(intentUpdate);
+ }
- /**
- * disable Bitmask starting on after phone reboot
- * then stop VPN
- */
- private boolean stop() {
- preferences.edit().putBoolean(EIP_RESTART_ON_BOOT, false).apply();
- if (eipStatus.isBlockingVpnEstablished()) {
- stopBlockingVpn();
- }
- return disconnect();
+ /**
+ * helper function to add error to result bundle
+ *
+ * @param result - result of an action
+ * @param errorMessageId - id of string resource describing the error
+ * @param errorId - MainActivityErrorDialog DownloadError id
+ */
+ void setErrorResult(Bundle result, @StringRes int errorMessageId, String errorId) {
+ JSONObject errorJson = new JSONObject();
+ try {
+ errorJson.put(ERRORS, getResources().getString(errorMessageId));
+ errorJson.put(ERROR_ID, errorId);
+ } catch (JSONException e) {
+ e.printStackTrace();
}
+ result.putString(ERRORS, errorJson.toString());
+ result.putBoolean(BROADCAST_RESULT_KEY, false);
+ }
- /**
- * stop void vpn from blocking internet
- */
- private void stopBlockingVpn() {
- Log.d(TAG, "stop VoidVpn!");
- Intent stopVoidVpnIntent = new Intent(eipReference, VoidVpnService.class);
- stopVoidVpnIntent.setAction(EIP_ACTION_STOP_BLOCKING_VPN);
- startService(stopVoidVpnIntent);
+
+ /**
+ * disable Bitmask starting on after phone reboot
+ * then stop VPN
+ */
+ private boolean stop() {
+ preferences.edit().putBoolean(EIP_RESTART_ON_BOOT, false).apply();
+ if (eipStatus.isBlockingVpnEstablished()) {
+ stopBlockingVpn();
}
+ return disconnect();
+ }
+
+ /**
+ * stop void vpn from blocking internet
+ */
+ private void stopBlockingVpn() {
+ Log.d(TAG, "stop VoidVpn!");
+ Intent stopVoidVpnIntent = new Intent(this, VoidVpnService.class);
+ stopVoidVpnIntent.setAction(EIP_ACTION_STOP_BLOCKING_VPN);
+ startService(stopVoidVpnIntent);
+ }
- /**
- * creates a OpenVpnServiceConnection if necessary
- * then terminates OpenVPN
- */
- private boolean disconnect() {
- try {
- initOpenVpnServiceConnection();
- } catch (InterruptedException | IllegalStateException e) {
- return false;
- }
-
- ProfileManager.setConntectedVpnProfileDisconnected(eipReference);
- try {
- return openvpnServiceConnection.getService().stopVPN(false);
- } catch (RemoteException e) {
- VpnStatus.logException(e);
- }
+ /**
+ * creates a OpenVpnServiceConnection if necessary
+ * then terminates OpenVPN
+ */
+ private boolean disconnect() {
+ try {
+ initOpenVpnServiceConnection();
+ } catch (InterruptedException | IllegalStateException e) {
return false;
}
- /**
- * Assigns a new OpenvpnServiceConnection to EIP's member variable openvpnServiceConnection.
- * Only one thread at a time can create the service connection, that will be shared between threads
- *
- * @throws InterruptedException thrown if thread gets interrupted
- * @throws IllegalStateException thrown if this method was not called from a background thread
- */
- private void initOpenVpnServiceConnection() throws InterruptedException, IllegalStateException {
- synchronized (lock) {
- if (openvpnServiceConnection == null) {
- Log.d(TAG, "serviceConnection is still null");
- openvpnServiceConnection = new OpenvpnServiceConnection(eipReference);
- }
- }
+ ProfileManager.setConntectedVpnProfileDisconnected(this);
+ try {
+ return openVpnServiceConnection.getService().stopVPN(false);
+ } catch (RemoteException e) {
+ VpnStatus.logException(e);
+ }
+ return false;
+ }
+
+ /**
+ * Assigns a new OpenVpnServiceConnection to EIP's member variable openVpnServiceConnection.
+ * Only one thread at a time can create the service connection, that will be shared between threads
+ *
+ * @throws InterruptedException thrown if thread gets interrupted
+ * @throws IllegalStateException thrown if this method was not called from a background thread
+ */
+ private void initOpenVpnServiceConnection() throws InterruptedException, IllegalStateException {
+ if (openVpnServiceConnection == null) {
+ Log.d(TAG, "serviceConnection is still null");
+ openVpnServiceConnection = new OpenVpnServiceConnection(this);
}
}
@@ -468,12 +424,12 @@ public final class EIP extends Service implements Observer {
* Pattern stolen from android.security.KeyChain.java
*/
@WorkerThread
- public static class OpenvpnServiceConnection implements Closeable {
+ public static class OpenVpnServiceConnection implements Closeable {
private final Context context;
private ServiceConnection serviceConnection;
private IOpenVPNServiceInternal service;
- protected OpenvpnServiceConnection(Context context) throws InterruptedException, IllegalStateException {
+ OpenVpnServiceConnection(Context context) throws InterruptedException, IllegalStateException {
this.context = context;
ensureNotOnMainThread(context);
Log.d(TAG, "initSynchronizedServiceConnection!");
@@ -488,7 +444,6 @@ public final class EIP extends Service implements Observer {
if (!mConnectedAtLeastOnce) {
mConnectedAtLeastOnce = true;
try {
- Log.d(TAG, "serviceConnection connected! ProcessCounter: " + ((EIP) context).processCounter.get());
blockingQueue.put(IOpenVPNServiceInternal.Stub.asInterface(service));
} catch (InterruptedException e) {
e.printStackTrace();
@@ -496,7 +451,6 @@ public final class EIP extends Service implements Observer {
}
}
@Override public void onServiceDisconnected(ComponentName name) {
- Log.d(TAG, "serviceConnection disconnected! ProcessCounter: " + ((EIP) context).processCounter.get());
}
};
@@ -516,4 +470,3 @@ public final class EIP extends Service implements Observer {
}
}
-
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java
index 5a6a98d8..19735483 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java
@@ -42,7 +42,7 @@ public class EipCommand {
vpnIntent.setAction(action);
if (resultReceiver != null)
vpnIntent.putExtra(EIP_RECEIVER, resultReceiver);
- context.startService(vpnIntent);
+ EIP.enqueueWork(context, vpnIntent);
}
public static void startVPN(@NonNull Context context, boolean earlyRoutes) {