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?