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 edaa90fe..223befad 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 @@ -167,8 +167,7 @@ public class SettingsActivity extends BaseActivity implements PreferenceFragment setupSecurityPrefs(); setupOtherPrefs(); - socks5ProxyHideShow(mTlsDecryption.isChecked(), rootCaptureEnabled()); - mBlockQuic.setVisible(!rootCaptureEnabled()); + socks5ProxyAndQuicHideShow(mTlsDecryption.isChecked(), rootCaptureEnabled()); rootCaptureHideShow(rootCaptureEnabled()); Intent intent = requireActivity().getIntent(); @@ -310,7 +309,7 @@ public class SettingsActivity extends BaseActivity implements PreferenceFragment mMitmWizard.setVisible((boolean) newValue); mMitmproxyOpts.setVisible((boolean) newValue); - socks5ProxyHideShow((boolean) newValue, rootCaptureEnabled()); + socks5ProxyAndQuicHideShow((boolean) newValue, rootCaptureEnabled()); return true; }); @@ -344,8 +343,9 @@ public class SettingsActivity extends BaseActivity implements PreferenceFragment mSocks5Settings = requirePreference("socks5_settings"); } - private void socks5ProxyHideShow(boolean tlsDecryption, boolean rootEnabled) { + private void socks5ProxyAndQuicHideShow(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); - socks5ProxyHideShow(mTlsDecryption.isChecked(), false); + socks5ProxyAndQuicHideShow(mTlsDecryption.isChecked(), false); } mIpMode.setVisible(!enabled); diff --git a/app/src/main/java/com/emanuelef/remote_capture/fragments/EditListFragment.java b/app/src/main/java/com/emanuelef/remote_capture/fragments/EditListFragment.java index e41f3f1f..8e887dd8 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/fragments/EditListFragment.java +++ b/app/src/main/java/com/emanuelef/remote_capture/fragments/EditListFragment.java @@ -77,7 +77,7 @@ public class EditListFragment extends Fragment implements MatchList.ListChangeLi private boolean mIsOwnUpdate; private ActionMode mActionMode; private AppSelectDialog mAppSelDialog; - private int MAX_RULES_BEFORE_WARNING = 5000; + private static final int MAX_RULES_BEFORE_WARNING = 5000; private static final String TAG = "EditListFragment"; private static final String LIST_TYPE_ARG = "list_type"; diff --git a/app/src/main/jni/core/capture_vpn.c b/app/src/main/jni/core/capture_vpn.c index 2f62d869..1c19f487 100644 --- a/app/src/main/jni/core/capture_vpn.c +++ b/app/src/main/jni/core/capture_vpn.c @@ -348,22 +348,31 @@ static void update_conn_status(zdtun_t *zdt, const zdtun_pkt_t *pkt, uint8_t fro /* ******************************************************* */ +static bool matches_decryption_whitelist(pcapdroid_t *pd, const zdtun_5tuple_t *tuple, pd_conn_t *data) { + zdtun_ip_t dst_ip = tuple->dst_ip; + + if(!pd->tls_decryption.list) + return false; + + // NOTE: domain matching only works if a prior DNS reply is seen (see ip_lru_find in pd_new_connection) + return blacklist_match_ip(pd->tls_decryption.list, &dst_ip, tuple->ipver) || + blacklist_match_uid(pd->tls_decryption.list, data->uid) || + (data->info && blacklist_match_domain(pd->tls_decryption.list, data->info)); +} + +/* ******************************************************* */ + static bool should_proxify(pcapdroid_t *pd, const zdtun_5tuple_t *tuple, pd_conn_t *data) { // NOTE: connections must be proxified as soon as the first packet arrives. // In case of TLS decryption, since we cannot reliably determine TLS connections with 1 packet, - // we must proxy all the TCP connections. + // we must proxify all the TCP connections. if(!pd->socks5.enabled || (tuple->ipproto != IPPROTO_TCP)) { data->decryption_ignored = true; return false; } if(pd->tls_decryption.list) { - zdtun_ip_t dst_ip = tuple->dst_ip; - - // NOTE: domain matching only works if a prior DNS reply is seen (see ip_lru_find in pd_new_connection) - if(blacklist_match_ip(pd->tls_decryption.list, &dst_ip, tuple->ipver) || - blacklist_match_uid(pd->tls_decryption.list, data->uid) || - (data->info && blacklist_match_domain(pd->tls_decryption.list, data->info))) + if(matches_decryption_whitelist(pd, tuple, data)) return true; data->decryption_ignored = true; @@ -376,7 +385,8 @@ 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)) { + 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; } diff --git a/docs/app_api.md b/docs/app_api.md index 8912f126..862edd3b 100644 --- a/docs/app_api.md +++ b/docs/app_api.md @@ -94,7 +94,7 @@ As shown above, the capture settings can be specified by using intent extras. Th | max_pkts_per_flow | int | 43 | | only dump the first max_pkts_per_flow packets per flow | | max_dump_size | int | 43 | | max size in bytes for the PCAP dump | | tls_decryption | bool | 49 | vpn | true to enable the built-in TLS decryption | -| block_quic | bool | 51 | vpn | true to block QUIC traffic | +| block_quic | bool | 51 | vpn | true to block QUIC traffic (73+: matching the decryption whitelist)| | auto_block_private_dns | bool | 51 | vpn | true to detect and possibly block private DNS to inspect traffic | | ip_mode | string | 56 | vpn | which IP addresses to use for the VPN: ipv4 \| ipv6 \| both | | mitmproxy_opts | string | 62 | | additional options to provide to mitmproxy in decryption mode |