diff --git a/app/src/main/java/com/emanuelef/remote_capture/CaptureService.java b/app/src/main/java/com/emanuelef/remote_capture/CaptureService.java
index 28c3923b..56bf99ea 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/CaptureService.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/CaptureService.java
@@ -767,6 +767,11 @@ public class CaptureService extends VpnService implements Runnable {
return((INSTANCE != null) && INSTANCE.mIsAlwaysOnVPN);
}
+ @RequiresApi(api = Build.VERSION_CODES.Q)
+ public static boolean isLockdownVPN() {
+ return ((INSTANCE != null) && INSTANCE.isLockdownEnabled());
+ }
+
private void checkBlacklistsUpdates() {
if(!mMalwareDetectionEnabled || (mBlacklistsUpdateThread != null))
return;
@@ -915,6 +920,9 @@ public class CaptureService extends VpnService implements Runnable {
if((fd > 0) && (fd < fd_setsize)) {
Log.d(TAG, "VPN fd: " + fd + " - FD_SETSIZE: " + fd_setsize);
runPacketLoop(fd, this, Build.VERSION.SDK_INT);
+
+ // if always-on VPN is stopped, it's not an always-on anymore
+ mIsAlwaysOnVPN = false;
} else
Log.e(TAG, "Invalid VPN fd: " + fd);
}
diff --git a/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java b/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java
index fb426082..134b4229 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/activities/MainActivity.java
@@ -36,6 +36,7 @@ import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission;
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
@@ -446,6 +447,9 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
public void appStateRunning() {
mState = AppState.running;
notifyAppState();
+
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
+ checkVpnLockdownNotice();
}
public void appStateStopping() {
@@ -453,6 +457,19 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
notifyAppState();
}
+ @RequiresApi(api = Build.VERSION_CODES.Q)
+ private void checkVpnLockdownNotice() {
+ if(!Prefs.lockdownVpnNoticeShown(mPrefs) && Prefs.isFirewallEnabled(this, mPrefs) && !CaptureService.isLockdownVPN()) {
+ new AlertDialog.Builder(this)
+ .setMessage(R.string.vpn_lockdown_notice)
+ .setPositiveButton(R.string.yes, (dialog, whichButton) -> Utils.startActivity(this, new Intent("android.net.vpn.SETTINGS")))
+ .setNegativeButton(R.string.no, (dialog, whichButton) -> {})
+ .show();
+
+ Prefs.setLockdownVpnNoticeShown(mPrefs);
+ }
+ }
+
private void openTelegram() {
Intent intent;
diff --git a/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java b/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java
index f1d3b4cb..11b9ddb7 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java
@@ -68,6 +68,7 @@ public class Prefs {
public static final String PREF_BLOCK_QUIC = "block_quic";
public static final String PREF_AUTO_BLOCK_PRIVATE_DNS = "auto_block_private_dns";
public static final String PREF_APP_VERSION = "appver";
+ public static final String PREF_LOCKDOWN_VPN_NOTICE_SHOWN = "vpn_lockdown_notice";
public enum DumpMode {
NONE,
@@ -107,6 +108,10 @@ public class Prefs {
p.edit().putInt(PREF_APP_VERSION, BuildConfig.VERSION_CODE).apply();
}
+ public static void setLockdownVpnNoticeShown(SharedPreferences p) {
+ p.edit().putBoolean(PREF_LOCKDOWN_VPN_NOTICE_SHOWN, true).apply();
+ }
+
/* Prefs with defaults */
public static String getCollectorIp(SharedPreferences p) { return(p.getString(PREF_COLLECTOR_IP_KEY, "127.0.0.1")); }
public static int getCollectorPort(SharedPreferences p) { return(Integer.parseInt(p.getString(PREF_COLLECTOR_PORT_KEY, "1234"))); }
@@ -137,4 +142,5 @@ public class Prefs {
public static boolean getFullPayloadMode(SharedPreferences p) { return(p.getBoolean(PREF_FULL_PAYLOAD, false)); }
public static boolean blockQuic(SharedPreferences p) { return(getTlsDecryptionEnabled(p) && p.getBoolean(PREF_BLOCK_QUIC, false)); }
public static boolean isPrivateDnsBlockingEnabled(SharedPreferences p) { return(p.getBoolean(PREF_AUTO_BLOCK_PRIVATE_DNS, true)); }
+ public static boolean lockdownVpnNoticeShown(SharedPreferences p) { return(p.getBoolean(PREF_LOCKDOWN_VPN_NOTICE_SHOWN, false)); }
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5e95fb94..2293d6aa 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -368,4 +368,5 @@
Capture has been stopped
Heap usage
Memory usage
+ To prevent apps from accessing the Internet when PCAPdroid is not running (e.g. after a reboot) you can set PCAPdroid as an always-on VPN in lockdown mode.\n\nDo you want to open the VPN settings now?