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 7e104165..6d9fb267 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/CaptureService.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/CaptureService.java
@@ -1309,7 +1309,7 @@ public class CaptureService extends VpnService implements Runnable {
public int getVpnMTU() { return VPN_MTU; }
- public int blockQuick() { return(mSettings.block_quic ? 1 : 0); }
+ public int getBlockQuickMode() { return mSettings.block_quic_mode.ordinal(); }
// returns 1 if dumpPcapData should be called
public int pcapDumpEnabled() {
diff --git a/app/src/main/java/com/emanuelef/remote_capture/activities/prefs/SettingsActivity.java b/app/src/main/java/com/emanuelef/remote_capture/activities/prefs/SettingsActivity.java
index 223befad..240c5266 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/activities/prefs/SettingsActivity.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/activities/prefs/SettingsActivity.java
@@ -132,13 +132,13 @@ public class SettingsActivity extends BaseActivity implements PreferenceFragment
public static class SettingsFragment extends PreferenceFragmentCompat {
private SwitchPreference mTlsDecryption;
- private SwitchPreference mBlockQuic;
private SwitchPreference mFullPayloadEnabled;
private SwitchPreference mRootCaptureEnabled;
private SwitchPreference mAutoBlockPrivateDNS;
private EditTextPreference mMitmproxyOpts;
private DropDownPreference mIpMode;
private DropDownPreference mCapInterface;
+ private DropDownPreference mBlockQuic;
private Preference mVpnExceptions;
private Preference mSocks5Settings;
private Preference mDnsSettings;
@@ -167,7 +167,8 @@ public class SettingsActivity extends BaseActivity implements PreferenceFragment
setupSecurityPrefs();
setupOtherPrefs();
- socks5ProxyAndQuicHideShow(mTlsDecryption.isChecked(), rootCaptureEnabled());
+ socks5ProxyHideShow(mTlsDecryption.isChecked(), rootCaptureEnabled());
+ mBlockQuic.setVisible(!rootCaptureEnabled());
rootCaptureHideShow(rootCaptureEnabled());
Intent intent = requireActivity().getIntent();
@@ -309,7 +310,7 @@ public class SettingsActivity extends BaseActivity implements PreferenceFragment
mMitmWizard.setVisible((boolean) newValue);
mMitmproxyOpts.setVisible((boolean) newValue);
- socks5ProxyAndQuicHideShow((boolean) newValue, rootCaptureEnabled());
+ socks5ProxyHideShow((boolean) newValue, rootCaptureEnabled());
return true;
});
@@ -343,9 +344,8 @@ public class SettingsActivity extends BaseActivity implements PreferenceFragment
mSocks5Settings = requirePreference("socks5_settings");
}
- private void socks5ProxyAndQuicHideShow(boolean tlsDecryption, boolean rootEnabled) {
+ private void socks5ProxyHideShow(boolean tlsDecryption, boolean rootEnabled) {
mSocks5Settings.setVisible(!tlsDecryption && !rootEnabled);
- mBlockQuic.setVisible(tlsDecryption && !rootEnabled);
}
private void setupOtherPrefs() {
@@ -406,7 +406,7 @@ public class SettingsActivity extends BaseActivity implements PreferenceFragment
} else {
mAutoBlockPrivateDNS.setVisible(true);
mBlockQuic.setVisible(true);
- socks5ProxyAndQuicHideShow(mTlsDecryption.isChecked(), false);
+ socks5ProxyHideShow(mTlsDecryption.isChecked(), false);
}
mIpMode.setVisible(!enabled);
diff --git a/app/src/main/java/com/emanuelef/remote_capture/model/CaptureSettings.java b/app/src/main/java/com/emanuelef/remote_capture/model/CaptureSettings.java
index 5c752308..a7aa65d1 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/model/CaptureSettings.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/model/CaptureSettings.java
@@ -26,7 +26,7 @@ public class CaptureSettings implements Serializable {
public boolean root_capture;
public boolean pcapdroid_trailer;
public boolean full_payload;
- public boolean block_quic;
+ public Prefs.BlockQuicMode block_quic_mode;
public boolean auto_block_private_dns;
public boolean pcapng_format;
public String capture_interface;
@@ -54,7 +54,7 @@ public class CaptureSettings implements Serializable {
capture_interface = Prefs.getCaptureInterface(prefs);
tls_decryption = Prefs.getTlsDecryptionEnabled(prefs);
full_payload = Prefs.getFullPayloadMode(prefs);
- block_quic = Prefs.blockQuic(prefs);
+ block_quic_mode = Prefs.getBlockQuicMode(prefs);
auto_block_private_dns = Prefs.isPrivateDnsBlockingEnabled(prefs);
mitmproxy_opts = Prefs.getMitmproxyOpts(prefs);
pcapng_format = Prefs.isPcapngEnabled(ctx, prefs);
@@ -82,7 +82,7 @@ public class CaptureSettings implements Serializable {
max_dump_size = getInt(intent, Prefs.PREF_MAX_DUMP_SIZE, 0);
tls_decryption = getBool(intent, Prefs.PREF_TLS_DECRYPTION_KEY, false);
full_payload = false;
- block_quic = getBool(intent, Prefs.PREF_BLOCK_QUIC, false);
+ block_quic_mode = Prefs.getBlockQuicMode(getString(intent, Prefs.PREF_BLOCK_QUIC, Prefs.BLOCK_QUIC_MODE_DEFAULT));
auto_block_private_dns = getBool(intent, Prefs.PREF_AUTO_BLOCK_PRIVATE_DNS, true);
mitmproxy_opts = getString(intent, Prefs.PREF_MITMPROXY_OPTS, "");
pcapng_format = getBool(intent, Prefs.PREF_PCAPNG_ENABLED, false) && Billing.newInstance(ctx).isPurchased(Billing.PCAPNG_SKU);
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 474434d3..b9b7712c 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
@@ -41,6 +41,11 @@ public class Prefs {
public static final String IP_MODE_BOTH = "both";
public static final String IP_MODE_DEFAULT = IP_MODE_IPV4_ONLY;
+ public static final String BLOCK_QUIC_MODE_NEVER = "never";
+ public static final String BLOCK_QUIC_MODE_ALWAYS = "always";
+ public static final String BLOCK_QUIC_MODE_TO_DECRYPT = "to_decrypt";
+ public static final String BLOCK_QUIC_MODE_DEFAULT = BLOCK_QUIC_MODE_NEVER;
+
public static final String PAYLOAD_MODE_NONE = "none";
public static final String PAYLOAD_MODE_MINIMAL = "minimal";
public static final String PAYLOAD_MODE_FULL = "full";
@@ -83,7 +88,7 @@ public class Prefs {
public static final String PREF_TLS_DECRYPTION_SETUP_DONE = "tls_decryption_setup_ok";
public static final String PREF_CA_INSTALLATION_SKIPPED = "ca_install_skipped";
public static final String PREF_FULL_PAYLOAD = "full_payload";
- public static final String PREF_BLOCK_QUIC = "block_quic";
+ public static final String PREF_BLOCK_QUIC = "block_quic_mode";
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";
@@ -113,6 +118,12 @@ public class Prefs {
BOTH,
}
+ public enum BlockQuicMode {
+ NEVER,
+ ALWAYS,
+ TO_DECRYPT
+ }
+
public enum PayloadMode {
NONE,
MINIMAL,
@@ -136,6 +147,14 @@ public class Prefs {
}
}
+ public static BlockQuicMode getBlockQuicMode(String pref) {
+ switch (pref) {
+ case BLOCK_QUIC_MODE_ALWAYS: return BlockQuicMode.ALWAYS;
+ case BLOCK_QUIC_MODE_TO_DECRYPT: return BlockQuicMode.TO_DECRYPT;
+ default: return BlockQuicMode.NEVER;
+ }
+ }
+
public static PayloadMode getPayloadMode(String pref) {
switch (pref) {
case PAYLOAD_MODE_MINIMAL: return PayloadMode.MINIMAL;
@@ -182,6 +201,7 @@ public class Prefs {
public static String getSocks5Password(SharedPreferences p) { return(p.getString(PREF_SOCKS5_PASSWORD_KEY, "")); }
public static String getAppFilter(SharedPreferences p) { return(p.getString(PREF_APP_FILTER, "")); }
public static IpMode getIPMode(SharedPreferences p) { return(getIPMode(p.getString(PREF_IP_MODE, IP_MODE_DEFAULT))); }
+ public static BlockQuicMode getBlockQuicMode(SharedPreferences p) { return(getBlockQuicMode(p.getString(PREF_BLOCK_QUIC, BLOCK_QUIC_MODE_DEFAULT))); }
public static boolean useEnglishLanguage(SharedPreferences p){ return("english".equals(p.getString(PREF_APP_LANGUAGE, "system")));}
public static boolean isRootCaptureEnabled(SharedPreferences p) { return(Utils.isRootAvailable() && p.getBoolean(PREF_ROOT_CAPTURE, false)); }
public static boolean isPcapdroidTrailerEnabled(SharedPreferences p) { return(p.getBoolean(PREF_PCAPDROID_TRAILER, false)); }
@@ -202,7 +222,6 @@ public class Prefs {
public static boolean startAtBoot(SharedPreferences p) { return(p.getBoolean(PREF_START_AT_BOOT, false)); }
public static boolean isTLSDecryptionSetupDone(SharedPreferences p) { return(p.getBoolean(PREF_TLS_DECRYPTION_SETUP_DONE, false)); }
public static boolean getFullPayloadMode(SharedPreferences p) { return(p.getBoolean(PREF_FULL_PAYLOAD, false)); }
- public static boolean blockQuic(SharedPreferences p) { return(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)); }
public static boolean trailerNoticeShown(SharedPreferences p) { return(p.getBoolean(PREF_PCAPDROID_TRAILER_NOTICE_SHOWN, false)); }
@@ -224,7 +243,7 @@ public class Prefs {
"\nTLSDecryption: " + getTlsDecryptionEnabled(p) +
"\nTLSSetupOk: " + isTLSDecryptionSetupDone(p) +
"\nCAInstallSkipped: " + MitmAddon.isCAInstallationSkipped(ctx) +
- "\nBlockQuic: " + blockQuic(p) +
+ "\nBlockQuic: " + getBlockQuicMode(p) +
"\nRootCapture: " + isRootCaptureEnabled(p) +
"\nSocks5: " + getSocks5Enabled(p) +
"\nBlockPrivateDns: " + isPrivateDnsBlockingEnabled(p) +
diff --git a/app/src/main/jni/core/capture_vpn.c b/app/src/main/jni/core/capture_vpn.c
index 1ca852c1..e653a228 100644
--- a/app/src/main/jni/core/capture_vpn.c
+++ b/app/src/main/jni/core/capture_vpn.c
@@ -385,10 +385,14 @@ static bool should_proxify(pcapdroid_t *pd, const zdtun_5tuple_t *tuple, pd_conn
/* ******************************************************* */
void vpn_process_ndpi(pcapdroid_t *pd, const zdtun_5tuple_t *tuple, pd_conn_t *data) {
- if(pd->vpn.block_quic && (data->l7proto == NDPI_PROTOCOL_QUIC) &&
- pd->tls_decryption.enabled && matches_decryption_whitelist(pd, tuple, data)) {
- data->blacklisted_internal = true;
- data->to_block = true;
+ if(data->l7proto == NDPI_PROTOCOL_QUIC) {
+ block_quic_mode_t block_mode = pd->vpn.block_quic_mode;
+
+ if ((block_mode == BLOCK_QUIC_MODE_ALWAYS) ||
+ ((block_mode == BLOCK_QUIC_MODE_TO_DECRYPT) && matches_decryption_whitelist(pd, tuple, data))) {
+ data->blacklisted_internal = true;
+ data->to_block = true;
+ }
}
if(block_private_dns && !data->to_block &&
@@ -449,7 +453,7 @@ int run_vpn(pcapdroid_t *pd) {
#if ANDROID
pd->vpn.resolver = init_uid_resolver(pd->sdk_ver, pd->env, pd->capture_service);
pd->vpn.known_dns_servers = blacklist_init();
- pd->vpn.block_quic = getIntPref(pd->env, pd->capture_service, "blockQuick");
+ pd->vpn.block_quic_mode = getIntPref(pd->env, pd->capture_service, "getBlockQuickMode");
pd->vpn.ipv4.enabled = (bool) getIntPref(pd->env, pd->capture_service, "getIPv4Enabled");
pd->vpn.ipv4.dns_server = getIPv4Pref(pd->env, pd->capture_service, "getDnsServer");
diff --git a/app/src/main/jni/core/pcapdroid.h b/app/src/main/jni/core/pcapdroid.h
index 045b3078..c90badb0 100644
--- a/app/src/main/jni/core/pcapdroid.h
+++ b/app/src/main/jni/core/pcapdroid.h
@@ -65,6 +65,13 @@ typedef enum {
PAYLOAD_MODE_FULL
} payload_mode_t;
+// NOTE: sync with Prefs.BlockQuicMode
+typedef enum {
+ BLOCK_QUIC_MODE_NEVER = 0,
+ BLOCK_QUIC_MODE_ALWAYS,
+ BLOCK_QUIC_MODE_TO_DECRYPT
+} block_quic_mode_t;
+
typedef struct {
jint incr_id; // an incremental number which identifies a specific connection
@@ -205,7 +212,7 @@ typedef struct pcapdroid {
union {
struct {
int tunfd;
- bool block_quic;
+ block_quic_mode_t block_quic_mode;
blacklist_t *known_dns_servers;
uid_resolver_t *resolver;
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index 122ce756..d33152e2 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -49,4 +49,15 @@
- @string/theme_light
- @string/theme_dark
+
+
+ - never
+ - always
+ - to_decrypt
+
+
+ - @string/never
+ - @string/always
+ - @string/for_connections_to_decrypt
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8e21871a..7c7dc3ad 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -497,4 +497,7 @@
redirected
This connection has been redirected due to a port mapping rule
How to use DoH / DNSCrypt with PCAPdroid
+ Never
+ Always
+ Only for connections to decrypt
diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml
index 38d2865e..3923a96f 100644
--- a/app/src/main/res/xml/root_preferences.xml
+++ b/app/src/main/res/xml/root_preferences.xml
@@ -94,12 +94,14 @@
app:summary="@string/pcapng_format_summary"
app:defaultValue="true" />
-
+ app:defaultValue="never"
+ app:useSimpleSummaryProvider="true" />