From ca1cad6ec5b175a85b361c45e8d2c0cac0b405ec Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 7 Dec 2017 12:49:15 +0100 Subject: #8742 basic always-on implementation with blocking vpn if no profile is configured --- .../se/leap/bitmaskclient/eip/VoidVpnService.java | 100 ++++++++++++++++----- 1 file changed, 80 insertions(+), 20 deletions(-) (limited to 'app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java index cbf0fed2..46c010ca 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java @@ -1,41 +1,58 @@ package se.leap.bitmaskclient.eip; -import android.content.*; -import android.net.*; -import android.os.*; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.VpnService; +import android.os.Build; +import android.os.ParcelFileDescriptor; +import android.util.Log; + +import java.io.IOException; + +import de.blinkt.openvpn.core.ConnectionStatus; +import de.blinkt.openvpn.core.VpnStatus; +import se.leap.bitmaskclient.R; + +import static se.leap.bitmaskclient.Dashboard.SHARED_PREFERENCES; +import static se.leap.bitmaskclient.eip.Constants.ACTION_START_ALWAYS_ON_EIP; -import java.io.*; public class VoidVpnService extends VpnService { static final String TAG = VoidVpnService.class.getSimpleName(); static ParcelFileDescriptor fd; - static Thread thread; + private final int ALWAYS_ON_MIN_API_LEVEL = Build.VERSION_CODES.N; + private static final String STATE_ESTABLISH = "ESTABLISHVOIDVPN"; + private static final String STATE_STOP = "STOPVOIDVPN"; @Override - public int onStartCommand(Intent intent, int flags, int startId) { + public int onStartCommand(final Intent intent, int flags, int startId) { String action = intent != null ? intent.getAction() : ""; - if (action == Constants.START_BLOCKING_VPN_PROFILE) { + if (action.equals(Constants.START_BLOCKING_VPN_PROFILE)) { thread = new Thread(new Runnable() { public void run() { - Builder builder = new Builder(); - builder.setSession("Blocking until running"); - builder.addAddress("10.42.0.8", 16); - builder.addRoute("0.0.0.0", 1); - builder.addRoute("192.168.1.0", 24); - builder.addDnsServer("10.42.0.1"); - try { - fd = builder.establish(); - - } catch (Exception e) { - e.printStackTrace(); - } + establishBlockingVpn(); + SharedPreferences preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); + preferences.edit().putBoolean(Constants.IS_ALWAYS_ON, false).commit(); + Log.d(TAG, "start blocking vpn profile - always on = false"); + } + }); + thread.run(); + } else if (action.equals("android.net.VpnService") && Build.VERSION.SDK_INT >= ALWAYS_ON_MIN_API_LEVEL) { + //only always-on feature triggers this + thread = new Thread(new Runnable() { + public void run() { + establishBlockingVpn(); + SharedPreferences preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); + preferences.edit().putBoolean(Constants.IS_ALWAYS_ON, true).commit(); + requestVpnWithLastSelectedProfile(); + Log.d(TAG, "start blocking vpn profile - always on = true"); } }); thread.run(); } - return 0; + return START_STICKY; } @Override @@ -48,6 +65,8 @@ public class VoidVpnService extends VpnService { if (thread != null) thread.interrupt(); closeFd(); + VpnStatus.updateStateString(STATE_STOP, "", + R.string.void_vpn_stopped, ConnectionStatus.LEVEL_NOTCONNECTED); } public static boolean isRunning() throws NullPointerException { @@ -62,4 +81,45 @@ public class VoidVpnService extends VpnService { e.printStackTrace(); } } + + private Builder prepareBlockingVpnProfile() { + Builder builder = new Builder(); + builder.setSession("Blocking until running"); + builder.addRoute("0.0.0.0", 1); + builder.addRoute("192.168.1.0", 24); + builder.addDnsServer("10.42.0.1"); + builder.addAddress("10.42.0.8", 16); + return builder; + + } + + private void establishBlockingVpn() { + try { + VpnStatus.logInfo(getString(R.string.void_vpn_establish)); + VpnStatus.updateStateString(STATE_ESTABLISH, "", + R.string.void_vpn_establish, ConnectionStatus.LEVEL_BLOCKING); + Builder builder = prepareBlockingVpnProfile(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + builder.addDisallowedApplication(getPackageName()); + } + + fd = builder.establish(); + } catch (Exception e) { + // Catch any exception + e.printStackTrace(); + VpnStatus.logError(R.string.void_vpn_error_establish); + } + } + + private void requestVpnWithLastSelectedProfile() { + Intent startEIP = new Intent(getApplicationContext(), EIP.class); + startEIP.setAction(ACTION_START_ALWAYS_ON_EIP); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + //noinspection NewApi + getApplicationContext().startForegroundService(startEIP); + } else { + getApplicationContext().startService(startEIP); + } + } + } -- cgit v1.2.3