From b9615a4f42421b24b2a393cb08cd262975c8393c Mon Sep 17 00:00:00 2001 From: emanuele-f Date: Mon, 30 May 2022 11:16:08 +0200 Subject: [PATCH] Improve mitm addon setup wizard help messages --- .../emanuelef/remote_capture/MitmAddon.java | 3 +- .../com/emanuelef/remote_capture/Utils.java | 23 +++++++++++ .../activities/MainActivity.java | 1 + .../activities/SettingsActivity.java | 6 --- .../fragments/mitmwizard/Done.java | 41 +++++++++++++++++++ .../fragments/mitmwizard/InstallAddon.java | 2 +- .../mitmwizard/InstallCertificate.java | 6 +-- .../fragments/mitmwizard/Intro.java | 41 +++++++++++++++++++ .../main/res/navigation/mitm_wizard_graph.xml | 28 ++++++++++++- app/src/main/res/values/strings.xml | 12 +++--- app/src/main/res/xml/root_preferences.xml | 8 ---- 11 files changed, 146 insertions(+), 25 deletions(-) create mode 100644 app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/Done.java create mode 100644 app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/Intro.java diff --git a/app/src/main/java/com/emanuelef/remote_capture/MitmAddon.java b/app/src/main/java/com/emanuelef/remote_capture/MitmAddon.java index 1dee4027..470da8da 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/MitmAddon.java +++ b/app/src/main/java/com/emanuelef/remote_capture/MitmAddon.java @@ -51,6 +51,7 @@ import java.lang.ref.WeakReference; public class MitmAddon { public static final long PACKAGE_VERSION_CODE = 7; public static final String PACKAGE_VERSION_NAME = "v0.7"; + public static final String REPOSITORY = "https://github.com/emanuele-f/PCAPdroid-mitm"; private static final String TAG = "MitmAddon"; private final Context mContext; private final MitmListener mReceiver; @@ -113,7 +114,7 @@ public class MitmAddon { } public static String getGithubReleaseUrl() { - return "https://github.com/emanuele-f/PCAPdroid-mitm/releases/download/" + + return REPOSITORY + "/releases/download/" + PACKAGE_VERSION_NAME + "/PCAPdroid-mitm_" + PACKAGE_VERSION_NAME + "_" + Build.SUPPORTED_ABIS[0] + ".apk"; } diff --git a/app/src/main/java/com/emanuelef/remote_capture/Utils.java b/app/src/main/java/com/emanuelef/remote_capture/Utils.java index 75367dc4..02fd6e2f 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/Utils.java +++ b/app/src/main/java/com/emanuelef/remote_capture/Utils.java @@ -55,7 +55,11 @@ import android.os.Handler; import android.os.Looper; import android.provider.MediaStore; import android.provider.OpenableColumns; +import android.text.Html; import android.text.SpannableString; +import android.text.SpannedString; +import android.text.TextUtils; +import android.text.method.LinkMovementMethod; import android.text.style.StyleSpan; import android.util.Log; import android.view.View; @@ -1157,4 +1161,23 @@ public class Utils { public static boolean isPrintable(byte c) { return ((c >= 32) && (c <= 126)) || (c == '\r') || (c == '\n') || (c == '\t'); } + + // Get a CharSequence which properly displays clickable links obtained by formatting a parametric + // string resource with the provided args. See setTextUrls + // https://stackoverflow.com/questions/23503642/how-to-use-formatted-strings-together-with-placeholders-in-android + public static CharSequence getText(Context context, int resid, String... args) { + for(int i = 0; i < args.length; ++i) + args[i] = TextUtils.htmlEncode(args[i]); + + String htmlOnly = String.format(Html.toHtml(new SpannedString(context.getText(resid))), (Object[]) args); + //Log.d(TAG, htmlOnly); + return Html.fromHtml(htmlOnly); + } + + // Format a resource containing URLs and display it in a TextView, making URls clickable + public static void setTextUrls(TextView tv, int resid, String... args) { + CharSequence text = getText(tv.getContext(), resid, args); + tv.setText(text); + tv.setMovementMethod(LinkMovementMethod.getInstance()); + } } 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 d67005e8..ad6e23d6 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 @@ -110,6 +110,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig public static final String DONATE_URL = "https://emanuele-f.github.io/PCAPdroid/donate"; public static final String FIREWALL_DOCS_URL = DOCS_URL + "/paid_features#51-firewall"; public static final String MALWARE_DETECTION_DOCS_URL = DOCS_URL + "/paid_features#52-malware-detection"; + public static final String TLS_DECRYPTION_DOCS_URL = DOCS_URL + "/tls_decryption"; private final ActivityResultLauncher pcapFileLauncher = registerForActivityResult(new StartActivityForResult(), this::pcapFileResult); diff --git a/app/src/main/java/com/emanuelef/remote_capture/activities/SettingsActivity.java b/app/src/main/java/com/emanuelef/remote_capture/activities/SettingsActivity.java index caf8407a..85804878 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/activities/SettingsActivity.java +++ b/app/src/main/java/com/emanuelef/remote_capture/activities/SettingsActivity.java @@ -128,7 +128,6 @@ public class SettingsActivity extends BaseActivity implements PreferenceFragment private SwitchPreference mAutoBlockPrivateDNS; private EditTextPreference mSocks5ProxyIp; private EditTextPreference mSocks5ProxyPort; - private Preference mTlsHelp; private Preference mIpv6Enabled; private DropDownPreference mCapInterface; private SwitchPreference mMalwareDetectionEnabled; @@ -251,7 +250,6 @@ public class SettingsActivity extends BaseActivity implements PreferenceFragment @SuppressWarnings("deprecation") private void setupTrafficInspectionPrefs() { - mTlsHelp = requirePreference("tls_how_to"); mAutoBlockPrivateDNS = requirePreference("auto_block_private_dns"); mTlsDecryption = requirePreference(Prefs.PREF_TLS_DECRYPTION_KEY); @@ -305,9 +303,6 @@ public class SettingsActivity extends BaseActivity implements PreferenceFragment mSocks5Enabled.setVisible(!tlsDecryption); mSocks5ProxyIp.setVisible(socks5Enabled && !tlsDecryption); mSocks5ProxyPort.setVisible(socks5Enabled && !tlsDecryption); - - //mTlsHelp.setVisible(decryptionEnabled); - mTlsHelp.setVisible(true); } private void setupOtherPrefs() { @@ -371,7 +366,6 @@ public class SettingsActivity extends BaseActivity implements PreferenceFragment mSocks5Enabled.setVisible(false); mSocks5ProxyIp.setVisible(false); mSocks5ProxyPort.setVisible(false); - mTlsHelp.setVisible(false); mFullPayloadEnabled.setVisible(true); mBlockQuic.setVisible(false); } else { diff --git a/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/Done.java b/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/Done.java new file mode 100644 index 00000000..6433a5d6 --- /dev/null +++ b/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/Done.java @@ -0,0 +1,41 @@ +/* + * This file is part of PCAPdroid. + * + * PCAPdroid is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PCAPdroid is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with PCAPdroid. If not, see . + * + * Copyright 2022 - Emanuele Faranda + */ + +package com.emanuelef.remote_capture.fragments.mitmwizard; + +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.emanuelef.remote_capture.MitmAddon; +import com.emanuelef.remote_capture.R; + +public class Done extends StepFragment { + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + mStepIcon.setVisibility(View.GONE); + mStepLabel.setText(R.string.mitm_setup_wizard_done); + + MitmAddon.setDecryptionSetupDone(requireContext(), true); + nextStep(0); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/InstallAddon.java b/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/InstallAddon.java index 45007561..851ed8a1 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/InstallAddon.java +++ b/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/InstallAddon.java @@ -35,7 +35,7 @@ public class InstallAddon extends StepFragment { @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - mStepLabel.setText(R.string.install_mitm_addon); + Utils.setTextUrls(mStepLabel, R.string.install_mitm_addon, MitmAddon.REPOSITORY); if(MitmAddon.isInstalled(requireContext())) addonOk(); diff --git a/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/InstallCertificate.java b/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/InstallCertificate.java index 250be083..01855535 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/InstallCertificate.java +++ b/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/InstallCertificate.java @@ -88,13 +88,13 @@ public class InstallCertificate extends StepFragment implements MitmListener { } private void certOk() { - MitmAddon.setDecryptionSetupDone(requireContext(), true); mStepLabel.setText(R.string.cert_installed_correctly); - nextStep(0); + nextStep(R.id.navto_done); } private void certFail() { - mStepLabel.setText(R.string.ca_installation_failed); + mStepLabel.setText(R.string.ca_cert_export_failed); + Utils.setTextUrls(mStepLabel, R.string.ca_cert_export_failed, "https://www.vivo.com/en/support/questionByTitle?title=How%20to%20turn%20on/off%20Autostart%20for%20my%20apps"); mStepIcon.setColorFilter(mDangerColor); MitmAddon.setDecryptionSetupDone(requireContext(), false); } diff --git a/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/Intro.java b/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/Intro.java new file mode 100644 index 00000000..8a89c01a --- /dev/null +++ b/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/Intro.java @@ -0,0 +1,41 @@ +/* + * This file is part of PCAPdroid. + * + * PCAPdroid is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PCAPdroid is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with PCAPdroid. If not, see . + * + * Copyright 2022 - Emanuele Faranda + */ + +package com.emanuelef.remote_capture.fragments.mitmwizard; + +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.emanuelef.remote_capture.R; +import com.emanuelef.remote_capture.Utils; +import com.emanuelef.remote_capture.activities.MainActivity; + +public class Intro extends StepFragment { + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + mStepIcon.setVisibility(View.GONE); + Utils.setTextUrls(mStepLabel, R.string.mitm_setup_wizard_intro, MainActivity.TLS_DECRYPTION_DOCS_URL); + + nextStep(R.id.navto_install_addon); + } +} \ No newline at end of file diff --git a/app/src/main/res/navigation/mitm_wizard_graph.xml b/app/src/main/res/navigation/mitm_wizard_graph.xml index be608897..a6bc63b3 100644 --- a/app/src/main/res/navigation/mitm_wizard_graph.xml +++ b/app/src/main/res/navigation/mitm_wizard_graph.xml @@ -3,7 +3,20 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/mitm_wizard_graph" - app:startDestination="@id/installMitmApp"> + app:startDestination="@id/intro"> + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fe9b6e08..069f5d0c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -258,7 +258,7 @@ Saved TLS decryption Decrypt the SSL/TLS traffic by performing mitm. This may now work with some apps, check out the user guide - TLS decryption is starting + TLS decryption is starting… TLS decryption is running Traffic inspection Could not start the mitm service. Reinstall the mitm addon and retry @@ -266,13 +266,13 @@ Next Install Export - Install the PCAPdroid mitm addon + Install the PCAPdroid mitm addon.\n\nNOTE: The addon depends on closed source software Configure - Give PCAPdroid the ability to decrypt the network traffic + Give PCAPdroid the permission to control the mitm addon Export the PCAPdroid CA certificate, then open the Android \"Encryption & Credentials\" settings and choose install it as a \"CA certificate\" Install the PCAPdroid CA certificate, choosing \"VPN and apps\". Android will ask for your lockscreen or password Checking the certificate… - CA certificate installation failed + An error occurred while exporting the CA certificate\n\nIf your device implements Autostart or similar software to limit background services execution, be sure to whitelist PCAPdroid Certificate exported, now install it from the Android settings The CA certificate is installed The CA certificate is not installed, run the mitm setup wizard @@ -341,7 +341,9 @@ Block internet access to apps, configure rules for specific domains and IP addresses. Only works with the non-root capture No-root firewall Block QUIC - Block QUIC connections to possibly fallback to TLS. Some apps may stop working + Block QUIC connections to possibly fall back to decryptable TLS. Some apps may stop working Block private DNS Detect and possibly block private DNS to inspect DNS traffic. Disabling this can hinder detection + This wizard will guide you through the installation of the PCAPdroid mitm addon and certification authority, which are needed to perform the TLS decryption + PCAPdroid is now ready to decrypt TLS traffic\n\nCheck out the user guide to know more about the security measures which may prevent decryption and how to bypass them diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index 280621f0..71a4ac43 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -66,14 +66,6 @@ app:summary="@string/tls_decryption_summary" app:defaultValue="false" /> - - - -