From 68d3a1dc12f55f0ec37bb90767642d9c03c1767a Mon Sep 17 00:00:00 2001 From: emanuele-f Date: Mon, 21 Aug 2023 07:08:09 +0200 Subject: [PATCH] Show notice when loading a PCAP without UID mappings --- .../remote_capture/CaptureService.java | 1 + .../activities/MainActivity.java | 39 ++++++++++++++----- .../fragments/prefs/Socks5Settings.java | 1 + .../emanuelef/remote_capture/model/Prefs.java | 6 +++ app/src/main/jni/core/capture_libpcap.c | 4 +- app/src/main/jni/core/jni_impl.c | 10 ++++- app/src/main/jni/core/pcapdroid.c | 2 + app/src/main/jni/core/pcapdroid.h | 1 + app/src/main/res/values/strings.xml | 1 + 9 files changed, 53 insertions(+), 12 deletions(-) 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 0d69dee0..3072ec3b 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/CaptureService.java +++ b/app/src/main/java/com/emanuelef/remote_capture/CaptureService.java @@ -1574,4 +1574,5 @@ public class CaptureService extends VpnService implements Runnable { public static native void setPayloadMode(int mode); public static native List getL7Protocols(); public static native void dumpMasterSecret(byte[] secret); + public static native boolean hasSeenPcapdroidTrailer(); } 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 e6ea0f7e..6b16c7f2 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 @@ -59,6 +59,7 @@ import com.emanuelef.remote_capture.AppsResolver; import com.emanuelef.remote_capture.Billing; import com.emanuelef.remote_capture.BuildConfig; import com.emanuelef.remote_capture.CaptureHelper; +import com.emanuelef.remote_capture.ConnectionsRegister; import com.emanuelef.remote_capture.Log; import com.emanuelef.remote_capture.MitmReceiver; import com.emanuelef.remote_capture.activities.prefs.SettingsActivity; @@ -538,16 +539,8 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig mState = AppState.ready; notifyAppState(); - if(mPcapLoadDialog != null) { - mPcapLoadDialog.dismiss(); - mPcapLoadDialog = null; - - if(!CaptureService.hasError()) { - // pcap file loaded successfully - Utils.showToastLong(this, R.string.pcap_load_success); - mPager.setCurrentItem(POS_CONNECTIONS); - } - } + if(mPcapLoadDialog != null) + checkLoadedPcap(); } public void appStateStarting() { @@ -568,6 +561,32 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig notifyAppState(); } + private void checkLoadedPcap() { + if(mPcapLoadDialog != null) { + mPcapLoadDialog.dismiss(); + mPcapLoadDialog = null; + } + + if(!CaptureService.hasError()) { + // pcap file loaded successfully + ConnectionsRegister reg = CaptureService.getConnsRegister(); + + if((reg != null) && (reg.getConnCount() > 0) + && !CaptureService.hasSeenPcapdroidTrailer() + && !Prefs.trailerNoticeShown(mPrefs) + ) { + new AlertDialog.Builder(this) + .setMessage(getString(R.string.pcapdroid_trailer_notice, + getString(R.string.unknown_app), getString(R.string.pcapdroid_trailer))) + .setPositiveButton(R.string.ok, (d, whichButton) -> Prefs.setTrailerNoticeShown(mPrefs)) + .show(); + } else + Utils.showToastLong(this, R.string.pcap_load_success); + + mPager.setCurrentItem(POS_CONNECTIONS); + } + } + @RequiresApi(api = Build.VERSION_CODES.Q) private void checkVpnLockdownNotice() { if(!Prefs.lockdownVpnNoticeShown(mPrefs) && Prefs.isFirewallEnabled(this, mPrefs) && !CaptureService.isLockdownVPN()) { diff --git a/app/src/main/java/com/emanuelef/remote_capture/fragments/prefs/Socks5Settings.java b/app/src/main/java/com/emanuelef/remote_capture/fragments/prefs/Socks5Settings.java index a7c8ed4d..7a350dd0 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/fragments/prefs/Socks5Settings.java +++ b/app/src/main/java/com/emanuelef/remote_capture/fragments/prefs/Socks5Settings.java @@ -46,6 +46,7 @@ public class Socks5Settings extends PreferenceFragmentCompat { /* SOCKS5 Proxy IP validation */ mProxyHost = Objects.requireNonNull(findPreference(Prefs.PREF_SOCKS5_PROXY_IP_KEY)); mProxyHost.setOnPreferenceChangeListener((preference, newValue) -> Utils.validateHost(newValue.toString())); + mProxyHost.setOnBindEditTextListener(editText -> editText.setInputType(InputType.TYPE_TEXT_VARIATION_URI)); /* SOCKS5 Proxy port validation */ mProxyPort = Objects.requireNonNull(findPreference(Prefs.PREF_SOCKS5_PROXY_PORT_KEY)); 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 d097f278..474434d3 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 @@ -87,6 +87,7 @@ public class Prefs { 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 static final String PREF_PCAPDROID_TRAILER_NOTICE_SHOWN = "trailer_notice_shown"; public static final String PREF_VPN_EXCEPTIONS = "vpn_exceptions"; public static final String PREF_PORT_MAPPING = "port_mapping"; public static final String PREF_PORT_MAPPING_ENABLED = "port_mapping_enabled"; @@ -155,6 +156,10 @@ public class Prefs { p.edit().putBoolean(PREF_LOCKDOWN_VPN_NOTICE_SHOWN, true).apply(); } + public static void setTrailerNoticeShown(SharedPreferences p) { + p.edit().putBoolean(PREF_PCAPDROID_TRAILER_NOTICE_SHOWN, true).apply(); + } + public static void setFirewallWhitelistInitialized(SharedPreferences p) { p.edit().putInt(PREF_FIREWALL_WHITELIST_INIT_VER, FIREWALL_WHITELIST_INIT_VER).apply(); } @@ -200,6 +205,7 @@ public class Prefs { 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)); } public static boolean blockNewApps(SharedPreferences p) { return(p.getBoolean(PREF_BLOCK_NEW_APPS, false)); } public static boolean isFirewallWhitelistMode(SharedPreferences p) { return(p.getBoolean(PREF_FIREWALL_WHITELIST_MODE, false)); } public static boolean isFirewallWhitelistInitialized(SharedPreferences p) { return(p.getInt(PREF_FIREWALL_WHITELIST_INIT_VER, 0) == FIREWALL_WHITELIST_INIT_VER); } diff --git a/app/src/main/jni/core/capture_libpcap.c b/app/src/main/jni/core/capture_libpcap.c index 0b3c9528..1f19f253 100644 --- a/app/src/main/jni/core/capture_libpcap.c +++ b/app/src/main/jni/core/capture_libpcap.c @@ -360,8 +360,10 @@ static bool handle_packet(pcapdroid_t *pd, pcapd_hdr_t *hdr, const char *buffer, const struct pcapdroid_trailer* trailer = (const struct pcapdroid_trailer*) (buffer + hdr->len - sizeof(pcapdroid_trailer_t)); - if(ntohl(trailer->magic) == PCAPDROID_TRAILER_MAGIC) + if(ntohl(trailer->magic) == PCAPDROID_TRAILER_MAGIC) { hdr->uid = ntohl(trailer->uid); + has_seen_pcapdroid_trailer = true; + } } } diff --git a/app/src/main/jni/core/jni_impl.c b/app/src/main/jni/core/jni_impl.c index b011aa16..f330c6a9 100644 --- a/app/src/main/jni/core/jni_impl.c +++ b/app/src/main/jni/core/jni_impl.c @@ -1248,4 +1248,12 @@ Java_com_emanuelef_remote_1capture_CaptureService_dumpMasterSecret(JNIEnv *env, (*env)->ReleaseByteArrayElements(env, secret, sec_data, 0); } -#endif // ANDROID \ No newline at end of file +/* ******************************************************* */ + +JNIEXPORT jboolean JNICALL +Java_com_emanuelef_remote_1capture_CaptureService_hasSeenPcapdroidTrailer(JNIEnv *env, + jclass clazz) { + return has_seen_pcapdroid_trailer; +} + +#endif // ANDROID diff --git a/app/src/main/jni/core/pcapdroid.c b/app/src/main/jni/core/pcapdroid.c index 7c382fec..eba8be20 100644 --- a/app/src/main/jni/core/pcapdroid.c +++ b/app/src/main/jni/core/pcapdroid.c @@ -36,6 +36,7 @@ extern void vpn_process_ndpi(pcapdroid_t *pd, const zdtun_5tuple_t *tuple, pd_co bool running = false; uint32_t new_dns_server = 0; bool block_private_dns = false; +bool has_seen_pcapdroid_trailer = false; bool dump_capture_stats_now = false; bool reload_blacklists_now = false; @@ -1153,6 +1154,7 @@ void pd_account_stats(pcapdroid_t *pd, pkt_context_t *pctx) { int pd_run(pcapdroid_t *pd) { /* Important: init global state every time. Android may reuse the service. */ running = true; + has_seen_pcapdroid_trailer = false; netd_resolve_waiting = 0; /* nDPI */ diff --git a/app/src/main/jni/core/pcapdroid.h b/app/src/main/jni/core/pcapdroid.h index 3f904de6..6875b925 100644 --- a/app/src/main/jni/core/pcapdroid.h +++ b/app/src/main/jni/core/pcapdroid.h @@ -364,6 +364,7 @@ extern uint32_t new_dns_server; extern bool block_private_dns; extern bool dump_capture_stats_now; extern bool reload_blacklists_now; +extern bool has_seen_pcapdroid_trailer; extern int bl_num_checked_connections; extern int fw_num_checked_connections; extern char *pd_appver; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 66167556..0fe99e82 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -488,4 +488,5 @@ PCAP read error PCAP file loading aborted "Could not resolve host %1$s + To show the actual apps instead of \"%1$s\", be sure to enable the \"%2$s\" option before exporting the PCAP file