diff --git a/app/src/main/java/com/emanuelef/remote_capture/MitmAddon.java b/app/src/main/java/com/emanuelef/remote_capture/MitmAddon.java
new file mode 100644
index 00000000..0cde76d0
--- /dev/null
+++ b/app/src/main/java/com/emanuelef/remote_capture/MitmAddon.java
@@ -0,0 +1,225 @@
+/*
+ * 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;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceManager;
+
+import com.emanuelef.remote_capture.interfaces.MitmListener;
+import com.emanuelef.remote_capture.model.Prefs;
+
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+
+public class MitmAddon {
+ /* API */
+ public static final String PACKAGE_NAME = "com.pcapdroid.mitm";
+ public static final String MITM_PERMISSION = "com.pcapdroid.permission.MITM";
+ public static final String MITM_SERVICE = PACKAGE_NAME + ".MitmService";
+
+ public static final int MSG_START_MITM = 1;
+ public static final int MSG_GET_CA_CERTIFICATE = 2;
+ public static final String CERTIFICATE_RESULT = "certificate";
+ /* END API */
+
+ private static final String TAG = "MitmAddon";
+ private final Context mContext;
+ private final MitmListener mReceiver;
+ private final Messenger mMessenger;
+ private Messenger mService;
+
+ public MitmAddon(Context ctx, MitmListener receiver) {
+ // Important: the application context is required here, otherwise bind/unbind will not work properly
+ mContext = ctx.getApplicationContext();
+ mReceiver = receiver;
+ mMessenger = new Messenger(new ReplyHandler(receiver));
+ }
+
+ private final ServiceConnection mConnection = new ServiceConnection() {
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ Log.d(TAG, "Service connected");
+ mService = new Messenger(service);
+ mReceiver.onMitmServiceConnect();
+ }
+
+ public void onServiceDisconnected(ComponentName className) {
+ Log.d(TAG, "Service disconnected");
+ disconnect(); // call unbind to prevent new connections
+ mReceiver.onMitmServiceDisconnect();
+ }
+ };
+
+ public static boolean isInstalled(Context ctx) {
+ try {
+ ctx.getPackageManager().getPackageInfo(PACKAGE_NAME, 0);
+ return true;
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ public static boolean hasMitmPermission(Context ctx) {
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
+ return ctx.checkSelfPermission(MitmAddon.MITM_PERMISSION) == PackageManager.PERMISSION_GRANTED;
+
+ return true;
+ }
+
+ public static void setDecryptionSetupDone(Context ctx, boolean done) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
+ prefs.edit()
+ .putBoolean(Prefs.PREF_TLS_DECRYPTION_SETUP_DONE, done)
+ .apply();
+ }
+
+ public static boolean needsSetup(Context ctx) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
+
+ if(!Prefs.isTLSDecryptionSetupDone(prefs))
+ return true;
+
+ // Perform some other quick checks just in case the env has changed
+ if(!isInstalled(ctx) || !hasMitmPermission(ctx)) {
+ setDecryptionSetupDone(ctx, false);
+ return true;
+ }
+
+ return false;
+ }
+
+ private static class ReplyHandler extends Handler {
+ private final WeakReference mReceiver;
+
+ ReplyHandler(MitmListener receiver) {
+ mReceiver = new WeakReference<>(receiver);
+ }
+
+ @Override
+ public void handleMessage(@NonNull Message msg) {
+ Log.d(TAG, "Message: " + msg.what);
+
+ MitmListener receiver = mReceiver.get();
+ if(receiver == null)
+ return;
+
+ if(msg.what == MitmAddon.MSG_GET_CA_CERTIFICATE) {
+ String ca_pem = null;
+
+ if(msg.getData() != null) {
+ Bundle res = msg.getData();
+ ca_pem = res.getString(MitmAddon.CERTIFICATE_RESULT);
+ }
+
+ receiver.onMitmGetCaCertificateResult(ca_pem);
+ }
+ }
+ }
+
+ // Asynchronously connect to the service. The onConnect callback will be called.
+ public boolean connect(int extra_flags) {
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(MitmAddon.PACKAGE_NAME, MitmAddon.MITM_SERVICE));
+
+ if(!mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE | extra_flags)) {
+ mContext.unbindService(mConnection);
+ return false;
+ }
+ return true;
+ }
+
+ // This must be always called after connect, e.g. in the OnDestroy
+ public void disconnect() {
+ if(mService != null) {
+ Log.d(TAG, "Unbinding service...");
+ mContext.unbindService(mConnection);
+ mService = null;
+ }
+ }
+
+ public boolean isConnected() {
+ return (mService != null);
+ }
+
+ public boolean requestCaCertificate() {
+ if(mService == null) {
+ Log.e(TAG, "Not connected");
+ return false;
+ }
+
+ Message msg = Message.obtain(null, MitmAddon.MSG_GET_CA_CERTIFICATE);
+ msg.replyTo = mMessenger;
+ try {
+ mService.send(msg);
+ return true;
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ // Start the mitm proxy and returns a ParcelFileDescriptor for the data communication.
+ // The proxy can be stopped by closing the descriptor and then calling disconnect().
+ public ParcelFileDescriptor startProxy(int port) {
+ if(mService == null) {
+ Log.e(TAG, "Not connected");
+ return null;
+ }
+
+ ParcelFileDescriptor[] pair;
+ try {
+ pair = ParcelFileDescriptor.createReliableSocketPair();
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+
+ Message msg = Message.obtain(null, MitmAddon.MSG_START_MITM, port, 0, pair[0]);
+
+ try {
+ mService.send(msg);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ Utils.safeClose(pair[0]);
+ Utils.safeClose(pair[1]);
+ return null;
+ }
+
+ // The other end of the pipe is sent, close it locally
+ Utils.safeClose(pair[0]);
+
+ return pair[1];
+ }
+}
diff --git a/app/src/main/java/com/emanuelef/remote_capture/MitmReceiver.java b/app/src/main/java/com/emanuelef/remote_capture/MitmReceiver.java
index 10f01d17..89bbe29c 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/MitmReceiver.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/MitmReceiver.java
@@ -22,22 +22,21 @@ package com.emanuelef.remote_capture;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
import android.util.Log;
import android.util.LruCache;
+import com.emanuelef.remote_capture.activities.MitmSetupWizard;
import com.emanuelef.remote_capture.interfaces.ConnectionsListener;
+import com.emanuelef.remote_capture.interfaces.MitmListener;
import com.emanuelef.remote_capture.model.ConnectionDescriptor;
-import com.emanuelef.remote_capture.model.MitmAddon;
+
+import org.jetbrains.annotations.Nullable;
import java.io.DataInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.security.cert.X509Certificate;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
@@ -53,70 +52,23 @@ import java.util.StringTokenizer;
*
* The raw payload data follows the header.
*/
-public class MitmReceiver implements Runnable, ConnectionsListener {
+public class MitmReceiver implements Runnable, ConnectionsListener, MitmListener {
private static final String TAG = "MitmReceiver";
public static final int MAX_PLAINTEXT_LENGTH = 1024; // sync with pcapdroid.h
public static final int TLS_DECRYPTION_PROXY_PORT = 7780;
private Thread mThread;
private final ConnectionsRegister mReg;
private final Context mContext;
- private Messenger mService;
- private boolean bound;
+ private final MitmAddon mAddon;
private ParcelFileDescriptor mSocketFd;
- private final ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- Log.d(TAG, "Service connected");
- mService = new Messenger(service);
-
- ParcelFileDescriptor[] pair;
- try {
- // Create a pair of connected fds
- pair = ParcelFileDescriptor.createReliableSocketPair();
- } catch (IOException e) {
- e.printStackTrace();
- return;
- }
- mSocketFd = pair[1];
-
- Message msg = Message.obtain(null, MitmAddon.MSG_START_MITM, TLS_DECRYPTION_PROXY_PORT, 0, pair[0]);
-
- try {
- mService.send(msg);
- } catch (RemoteException e) {
- e.printStackTrace();
- Utils.safeClose(pair[0]);
- Utils.safeClose(pair[1]);
- return;
- }
- bound = true;
-
- // Sent, close here
- Utils.safeClose(pair[0]);
-
- if(mThread != null)
- mThread.interrupt();
-
- mThread = new Thread(MitmReceiver.this);
- mThread.start();
- }
-
- public void onServiceDisconnected(ComponentName className) {
- Log.d(TAG, "Service disconnected");
- mService = null;
- Utils.safeClose(mSocketFd);
- mSocketFd = null;
- bound = false;
- }
- };
-
// Shared state
private final LruCache mPortToConnId = new LruCache<>(64);
public MitmReceiver(Context ctx) {
- // Important: the application context is required here, otherwise bind/unbind will not work properly
- mContext = ctx.getApplicationContext();
+ mContext = ctx;
mReg = CaptureService.requireConnsRegister();
+ mAddon = new MitmAddon(mContext, this);
}
public boolean start() throws IOException {
@@ -125,8 +77,7 @@ public class MitmReceiver implements Runnable, ConnectionsListener {
Intent intent = new Intent();
intent.setComponent(new ComponentName(MitmAddon.PACKAGE_NAME, MitmAddon.MITM_SERVICE));
- if(!mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT)) {
- mContext.unbindService(mConnection);
+ if(!mAddon.connect(Context.BIND_IMPORTANT)) {
Utils.showToastLong(mContext, R.string.mitm_start_failed);
return false;
}
@@ -152,19 +103,17 @@ public class MitmReceiver implements Runnable, ConnectionsListener {
}
mThread = null;
- if(bound) {
- Log.d(TAG, "Unbinding service...");
- mContext.unbindService(mConnection);
- bound = false;
- }
+ mAddon.disconnect();
Log.d(TAG, "stop done");
}
@Override
public void run() {
+ Log.d(TAG, "Receiving data...");
+
try(DataInputStream istream = new DataInputStream(new ParcelFileDescriptor.AutoCloseInputStream(mSocketFd))) {
- while(bound) {
+ while(mAddon.isConnected()) {
String payload_type;
int port;
int payload_len;
@@ -214,6 +163,8 @@ public class MitmReceiver implements Runnable, ConnectionsListener {
if(mSocketFd != null) // ignore termination
e.printStackTrace();
}
+
+ Log.d(TAG, "End receiving data");
}
@Override
@@ -232,6 +183,47 @@ public class MitmReceiver implements Runnable, ConnectionsListener {
}
}
+ @Override
+ public void onMitmServiceConnect() {
+ // when connected, verify that the certificate is installed before starting the proxy.
+ // will continue on onMitmGetCaCertificateResult.
+ if(!mAddon.requestCaCertificate())
+ mAddon.disconnect();
+ }
+
+ @Override
+ public void onMitmGetCaCertificateResult(@Nullable String ca_pem) {
+ if(!Utils.isCAInstalled(ca_pem)) {
+ // The certificate has been uninstalled from the system
+ Utils.showToastLong(mContext, R.string.cert_reinstall_required);
+ MitmAddon.setDecryptionSetupDone(mContext, false);
+ CaptureService.stopService();
+ return;
+ }
+
+ // Certificate installation verified, start the proxy
+ mSocketFd = mAddon.startProxy(TLS_DECRYPTION_PROXY_PORT);
+ if(mSocketFd == null) {
+ mAddon.disconnect();
+ return;
+ }
+
+ if(mThread != null)
+ mThread.interrupt();
+
+ mThread = new Thread(MitmReceiver.this);
+ mThread.start();
+ }
+
+ @Override
+ public void onMitmServiceDisconnect() {
+ Utils.safeClose(mSocketFd);
+ mSocketFd = null;
+
+ // Stop the capture if running
+ CaptureService.stopService();
+ }
+
ConnectionDescriptor getConnByLocalPort(int local_port) {
Integer conn_id;
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 352e3e82..4f1a9f61 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/Utils.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/Utils.java
@@ -975,4 +975,15 @@ public class Utils {
return false;
}
}
+
+ public static boolean isCAInstalled(String ca_pem) {
+ if(ca_pem == null)
+ return false;
+
+ X509Certificate ca_cert = x509FromPem(ca_pem);
+ if(ca_cert == null)
+ return false;
+
+ return isCAInstalled(ca_cert);
+ }
}
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 99e07fe7..ce497a5d 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
@@ -70,7 +70,7 @@ import com.emanuelef.remote_capture.model.AppState;
import com.emanuelef.remote_capture.CaptureService;
import com.emanuelef.remote_capture.model.CaptureSettings;
import com.emanuelef.remote_capture.model.ListInfo;
-import com.emanuelef.remote_capture.model.MitmAddon;
+import com.emanuelef.remote_capture.MitmAddon;
import com.emanuelef.remote_capture.model.Prefs;
import com.emanuelef.remote_capture.R;
import com.emanuelef.remote_capture.Utils;
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 c91626a1..7a5a8803 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
@@ -42,7 +42,7 @@ import androidx.preference.SwitchPreference;
import com.emanuelef.remote_capture.Billing;
import com.emanuelef.remote_capture.PCAPdroid;
import com.emanuelef.remote_capture.Utils;
-import com.emanuelef.remote_capture.model.MitmAddon;
+import com.emanuelef.remote_capture.MitmAddon;
import com.emanuelef.remote_capture.model.Prefs;
import com.emanuelef.remote_capture.R;
diff --git a/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/GrantPermission.java b/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/GrantPermission.java
index b8124840..20f957c7 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/GrantPermission.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/GrantPermission.java
@@ -30,7 +30,7 @@ import androidx.annotation.Nullable;
import com.emanuelef.remote_capture.R;
import com.emanuelef.remote_capture.Utils;
-import com.emanuelef.remote_capture.model.MitmAddon;
+import com.emanuelef.remote_capture.MitmAddon;
public class GrantPermission extends StepFragment {
private final ActivityResultLauncher requestPermissionLauncher =
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 4af5afdd..e5f4e188 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
@@ -26,7 +26,7 @@ import androidx.annotation.Nullable;
import android.view.View;
import com.emanuelef.remote_capture.R;
-import com.emanuelef.remote_capture.model.MitmAddon;
+import com.emanuelef.remote_capture.MitmAddon;
public class InstallAddon extends StepFragment {
@Override
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 fbe59898..3c19cff7 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
@@ -25,6 +25,7 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
+import android.util.Log;
import android.view.View;
import androidx.activity.result.ActivityResult;
@@ -35,18 +36,19 @@ import androidx.annotation.Nullable;
import com.emanuelef.remote_capture.R;
import com.emanuelef.remote_capture.Utils;
-import com.emanuelef.remote_capture.model.MitmAddon;
+import com.emanuelef.remote_capture.interfaces.MitmListener;
+import com.emanuelef.remote_capture.MitmAddon;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.cert.X509Certificate;
-public class InstallCertificate extends StepFragment {
+public class InstallCertificate extends StepFragment implements MitmListener {
+ private static final String TAG = "InstallCertificate";
+ private MitmAddon mAddon;
private String mCaPem;
private X509Certificate mCaCert;
- private final ActivityResultLauncher mitmCtrlLauncher =
- registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), this::mitmCtrlResult);
private final ActivityResultLauncher certFileLauncher =
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), this::certFileResult);
@@ -57,15 +59,15 @@ public class InstallCertificate extends StepFragment {
mStepButton.setText(R.string.export_action);
mStepButton.setEnabled(false);
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setClassName(MitmAddon.PACKAGE_NAME, MitmAddon.CONTROL_ACTIVITY);
- intent.putExtra(MitmAddon.ACTION_EXTRA, MitmAddon.ACTION_GET_CA_CERTIFICATE);
+ mAddon = new MitmAddon(requireContext(), this);
+ if(!mAddon.connect(0))
+ certFail();
+ }
- try {
- mitmCtrlLauncher.launch(intent);
- } catch (ActivityNotFoundException e) {
- mStepLabel.setText(R.string.no_intent_handler_found);
- }
+ @Override
+ public void onDestroyView() {
+ mAddon.disconnect();
+ super.onDestroyView();
}
@Override
@@ -76,28 +78,6 @@ public class InstallCertificate extends StepFragment {
super.onResume();
}
- private void mitmCtrlResult(final ActivityResult result) {
- if((result.getResultCode() == Activity.RESULT_OK) && (result.getData() != null)) {
- Intent res = result.getData();
- mCaPem = res.getStringExtra(MitmAddon.CERTIFICATE_RESULT);
-
- if(mCaPem != null) {
- //Log.d(TAG, "certificate: " + cert_str);
- mCaCert = Utils.x509FromPem(mCaPem);
-
- if(mCaCert != null) {
- if(Utils.isCAInstalled(mCaCert))
- certOk();
- else {
- MitmAddon.setDecryptionSetupDone(requireContext(), false);
- installCaCertificate();
- }
- } else
- certFail();
- }
- }
- }
-
private void certOk() {
MitmAddon.setDecryptionSetupDone(requireContext(), true);
mStepLabel.setText(R.string.cert_installed_correctly);
@@ -154,4 +134,38 @@ public class InstallCertificate extends StepFragment {
Utils.showToastLong(ctx, R.string.cert_exported_now_installed);
}
}
+
+ @Override
+ public void onMitmGetCaCertificateResult(@Nullable String ca_pem) {
+ mAddon.disconnect();
+ mCaPem = ca_pem;
+
+ if(mCaPem != null) {
+ Log.d(TAG, "Got certificate");
+ //Log.d(TAG, "certificate: " + cert_str);
+ mCaCert = Utils.x509FromPem(mCaPem);
+
+ if(mCaCert != null) {
+ if(Utils.isCAInstalled(mCaCert))
+ certOk();
+ else {
+ MitmAddon.setDecryptionSetupDone(requireContext(), false);
+ installCaCertificate();
+ }
+ } else
+ certFail();
+ }
+ }
+
+ @Override
+ public void onMitmServiceConnect() {
+ if(!mAddon.requestCaCertificate())
+ certFail();
+ }
+
+ @Override
+ public void onMitmServiceDisconnect() {
+ if(mCaPem == null)
+ certFail();
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/emanuelef/remote_capture/interfaces/MitmListener.java b/app/src/main/java/com/emanuelef/remote_capture/interfaces/MitmListener.java
new file mode 100644
index 00000000..f0d7ce0d
--- /dev/null
+++ b/app/src/main/java/com/emanuelef/remote_capture/interfaces/MitmListener.java
@@ -0,0 +1,28 @@
+/*
+ * 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 2020-21 - Emanuele Faranda
+ */
+
+package com.emanuelef.remote_capture.interfaces;
+
+import org.jetbrains.annotations.Nullable;
+
+public interface MitmListener {
+ void onMitmGetCaCertificateResult(@Nullable String ca_pem);
+ void onMitmServiceConnect();
+ void onMitmServiceDisconnect();
+}
diff --git a/app/src/main/java/com/emanuelef/remote_capture/model/MitmAddon.java b/app/src/main/java/com/emanuelef/remote_capture/model/MitmAddon.java
deleted file mode 100644
index 579bf254..00000000
--- a/app/src/main/java/com/emanuelef/remote_capture/model/MitmAddon.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.model;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.os.Build;
-
-import androidx.preference.PreferenceManager;
-
-public class MitmAddon {
- public static final String PACKAGE_NAME = "com.pcapdroid.mitm";
- public static final String MITM_PERMISSION = "com.pcapdroid.permission.MITM";
-
- public static final String MITM_SERVICE = PACKAGE_NAME + ".MitmService";
- public static final int MSG_START_MITM = 1;
-
- public static final String CONTROL_ACTIVITY = PACKAGE_NAME + ".MitmCtrl";
- public static final String ACTION_EXTRA = "action";
- public static final String ACTION_GET_CA_CERTIFICATE = "getCAcert";
- public static final String CERTIFICATE_RESULT = "certificate";
-
- public static boolean isInstalled(Context ctx) {
- try {
- ctx.getPackageManager().getPackageInfo(PACKAGE_NAME, 0);
- return true;
- } catch (PackageManager.NameNotFoundException e) {
- return false;
- }
- }
-
- public static boolean hasMitmPermission(Context ctx) {
- if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
- return ctx.checkSelfPermission(MitmAddon.MITM_PERMISSION) == PackageManager.PERMISSION_GRANTED;
-
- return true;
- }
-
- public static void setDecryptionSetupDone(Context ctx, boolean done) {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
- prefs.edit()
- .putBoolean(Prefs.PREF_TLS_DECRYPTION_SETUP_DONE, done)
- .apply();
- }
-
- public static boolean needsSetup(Context ctx) {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
-
- if(!Prefs.isTLSDecryptionSetupDone(prefs))
- return true;
-
- // Perform some other quick checks just in case the env has changed
- if(!isInstalled(ctx) || !hasMitmPermission(ctx)) {
- setDecryptionSetupDone(ctx, false);
- return true;
- }
-
- return false;
- }
-}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0767248a..fd48cec0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -279,5 +279,6 @@
CA certificate installation failed
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
Done
\ No newline at end of file