summaryrefslogtreecommitdiff
path: root/app/src/main/java/de
diff options
context:
space:
mode:
authorcyBerta <cyberta@riseup.net>2019-07-05 17:18:30 +0200
committercyBerta <cyberta@riseup.net>2019-07-12 16:59:26 +0200
commitf5b8dae753448ed698486af8b49b977a58d4fcdc (patch)
tree06358a7d4e70903b6ce235f16c7e22a4800b8f99 /app/src/main/java/de
parent962e6261e4024cd8191cf2b0c64fc8a34ea3b425 (diff)
better support for android 8.X always-on killswitch (#8945 & #8928)
Diffstat (limited to 'app/src/main/java/de')
-rw-r--r--app/src/main/java/de/blinkt/openvpn/VpnProfile.java52
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java74
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java10
3 files changed, 82 insertions, 54 deletions
diff --git a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
index bd28ae16..7028bf62 100644
--- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
+++ b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
@@ -5,9 +5,6 @@
package de.blinkt.openvpn;
-import se.leap.bitmaskclient.R;
-import se.leap.bitmaskclient.BuildConfig;
-
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
@@ -15,7 +12,6 @@ import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
-import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.security.KeyChain;
import android.security.KeyChainException;
@@ -24,7 +20,8 @@ import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Base64;
-import de.blinkt.openvpn.core.*;
+import com.google.gson.Gson;
+
import org.spongycastle.util.io.pem.PemObject;
import org.spongycastle.util.io.pem.PemWriter;
@@ -37,7 +34,11 @@ import java.io.Serializable;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.security.*;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
@@ -52,6 +53,21 @@ import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
+import de.blinkt.openvpn.core.Connection;
+import de.blinkt.openvpn.core.ExtAuthHelper;
+import de.blinkt.openvpn.core.NativeUtils;
+import de.blinkt.openvpn.core.OpenVPNService;
+import de.blinkt.openvpn.core.OrbotHelper;
+import de.blinkt.openvpn.core.PasswordCache;
+import de.blinkt.openvpn.core.Preferences;
+import de.blinkt.openvpn.core.VPNLaunchHelper;
+import de.blinkt.openvpn.core.VpnStatus;
+import de.blinkt.openvpn.core.X509Utils;
+import se.leap.bitmaskclient.BuildConfig;
+import se.leap.bitmaskclient.R;
+
+import static se.leap.bitmaskclient.Constants.PROVIDER_PROFILE;
+
public class VpnProfile implements Serializable, Cloneable {
// Note that this class cannot be moved to core where it belongs since
// the profile loading depends on it being here
@@ -755,11 +771,8 @@ public class VpnProfile implements Serializable, Cloneable {
}
public Intent getStartServiceIntent(Context context) {
- String prefix = context.getPackageName();
-
Intent intent = new Intent(context, OpenVPNService.class);
- intent.putExtra(prefix + ".profileUUID", mUuid.toString());
- intent.putExtra(prefix + ".profileVersion", mVersion);
+ intent.putExtra(PROVIDER_PROFILE, this);
return intent;
}
@@ -1113,6 +1126,25 @@ public class VpnProfile implements Serializable, Cloneable {
return mName;
}
+ public String toJson() {
+ Gson gson = new Gson();
+ try {
+ return gson.toJson(this);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public static VpnProfile fromJson(String json) {
+ try {
+ Gson gson = new Gson();
+ return gson.fromJson(json, VpnProfile.class);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
public String getUUIDString() {
return mUuid.toString().toLowerCase(Locale.ENGLISH);
}
diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
index af31e977..ea782e00 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
@@ -44,10 +44,12 @@ import de.blinkt.openvpn.core.VpnStatus.ByteCountListener;
import de.blinkt.openvpn.core.VpnStatus.StateListener;
import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.VpnNotificationManager;
+import se.leap.bitmaskclient.utils.PreferenceHelper;
import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_CONNECTED;
import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT;
import static de.blinkt.openvpn.core.NetworkSpace.IpAddress;
+import static se.leap.bitmaskclient.Constants.PROVIDER_PROFILE;
public class OpenVPNService extends VpnService implements StateListener, Callback, ByteCountListener, IOpenVPNServiceInternal, VpnNotificationManager.VpnServiceCallback {
@@ -61,6 +63,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
public final static String ORBOT_PACKAGE_NAME = "org.torproject.android";
private static final String PAUSE_VPN = "de.blinkt.openvpn.PAUSE_VPN";
private static final String RESUME_VPN = "se.leap.bitmaskclient.RESUME_VPN";
+ private static final String TAG = OpenVPNService.class.getSimpleName();
private static boolean mNotificationAlwaysVisible = false;
private final Vector<String> mDnslist = new Vector<>();
private final NetworkSpace mRoutes = new NetworkSpace();
@@ -177,7 +180,6 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
}
VpnStatus.removeByteCountListener(this);
unregisterDeviceStateReceiver();
- ProfileManager.setConntectedVpnProfileDisconnected(this);
mOpenVPNThread = null;
if (!mStarting) {
stopForeground(!mNotificationAlwaysVisible);
@@ -312,47 +314,35 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
0,
NOTIFICATION_CHANNEL_NEWSTATUS_ID);
- if (intent != null && intent.hasExtra(getPackageName() + ".profileUUID")) {
- String profileUUID = intent.getStringExtra(getPackageName() + ".profileUUID");
- int profileVersion = intent.getIntExtra(getPackageName() + ".profileVersion", 0);
- // Try for 10s to get current version of the profile
- mProfile = ProfileManager.get(this, profileUUID, profileVersion, 100);
+ if (intent != null && intent.hasExtra(PROVIDER_PROFILE)) {
+ mProfile = (VpnProfile) intent.getSerializableExtra(PROVIDER_PROFILE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
updateShortCutUsage(mProfile);
}
-
+ PreferenceHelper.setAlwaysOn(this, false);
} else {
/* The intent is null when we are set as always-on or the service has been restarted. */
mProfile = ProfileManager.getLastConnectedProfile(this);
VpnStatus.logInfo(R.string.service_restarted);
- /* Got no profile, just stop */
- if (mProfile == null) {
- Log.d("OpenVPN", "Got no last connected profile on null intent. Assuming always on.");
- mProfile = ProfileManager.getAlwaysOnVPN(this);
-
- if (mProfile == null) {
- stopSelf(startId);
- return START_NOT_STICKY;
- }
+ if (mProfile != null) {
+ PreferenceHelper.setAlwaysOn(this, true);
}
- /* Do the asynchronous keychain certificate stuff */
- mProfile.checkForRestart(this);
}
if (mProfile == null) {
- stopSelf(startId);
+ stopService(startId);
+ Log.d(TAG, "Stopping service, no profile found");
return START_NOT_STICKY;
+ } else {
+ Log.d(TAG, "Found profile: " + mProfile.mName);
+ /* Do the asynchronous keychain certificate stuff */
+ mProfile.checkForRestart(this);
}
/* start the OpenVPN process itself in a background thread */
- new Thread(new Runnable() {
- @Override
- public void run() {
- startOpenVPN();
- }
- }).start();
+ new Thread(this::startOpenVPN).start();
ProfileManager.setConnectedVpnProfile(this, mProfile);
@@ -369,6 +359,11 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
shortcutManager.reportShortcutUsed(profile.getUUIDString());
}
+ private void stopService(int startId) {
+ VpnStatus.updateStateString("NOPROCESS", "VPN STOPPED", R.string.state_noprocess, ConnectionStatus.LEVEL_NOTCONNECTED);
+ stopSelf(startId);
+ }
+
private void startOpenVPN() {
/**
* see change above (l. 292 ff)
@@ -428,21 +423,17 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
}
synchronized (mProcessLock)
-
{
mProcessThread = new Thread(processThread, "OpenVPNProcessThread");
mProcessThread.start();
}
- new Handler(getMainLooper()).post(new Runnable() {
- @Override
- public void run() {
- if (mDeviceStateReceiver != null)
- unregisterDeviceStateReceiver();
-
- registerDeviceStateReceiver(mManagement);
- }
- }
+ new Handler(getMainLooper()).post(() -> {
+ if (mDeviceStateReceiver != null) {
+ unregisterDeviceStateReceiver();
+ }
+ registerDeviceStateReceiver(mManagement);
+ }
);
}
@@ -550,8 +541,17 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
VpnStatus.logInfo(R.string.last_openvpn_tun_config);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && mProfile.mAllowLocalLAN) {
- allowAllAFFamilies(builder);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ if (mProfile.mAllowLocalLAN) {
+ allowAllAFFamilies(builder);
+ }
+ if (PreferenceHelper.isAlwaysOn(this)) {
+ try {
+ builder.addDisallowedApplication(this.getPackageName());
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
}
if (mLocalIP == null && mLocalIPv6 == null) {
diff --git a/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java b/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java
index b9edc4b2..d897e91f 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/ProfileManager.java
@@ -75,7 +75,7 @@ public class ProfileManager {
SharedPreferences prefs = Preferences.getDefaultSharedPreferences(c);
Editor prefsedit = prefs.edit();
- prefsedit.putString(LAST_CONNECTED_PROFILE, connectedProfile.getUUIDString());
+ prefsedit.putString(LAST_CONNECTED_PROFILE, connectedProfile.toJson());
prefsedit.apply();
mLastConnectedVpn = connectedProfile;
@@ -87,11 +87,8 @@ public class ProfileManager {
public static VpnProfile getLastConnectedProfile(Context c) {
SharedPreferences prefs = Preferences.getDefaultSharedPreferences(c);
- String lastConnectedProfile = prefs.getString(LAST_CONNECTED_PROFILE, null);
- if (lastConnectedProfile != null)
- return get(c, lastConnectedProfile);
- else
- return null;
+ String lastConnectedProfileJson = prefs.getString(LAST_CONNECTED_PROFILE, null);
+ return VpnProfile.fromJson(lastConnectedProfileJson);
}
@@ -255,7 +252,6 @@ public class ProfileManager {
String uuid = prefs.getString("alwaysOnVpn", null);
return get(uuid);
-
}
public static void updateLRU(Context c, VpnProfile profile) {