From 28aa153a3865200a2c9eb46fbedd7bda25583819 Mon Sep 17 00:00:00 2001 From: Nathaniel Smith Date: Tue, 13 Aug 2024 17:24:04 +0100 Subject: [PATCH 01/16] added base for dynamic config loading --- agent/src/main/AndroidManifest.xml | 5 +- .../java/com/WithSecure/dz/DzApplication.java | 15 ++++ .../dz/activities/AboutActivity.java | 4 +- .../dz/activities/BaseActivity.java | 16 ++++ .../dz/activities/BasePreferenceActivity.java | 15 ++++ .../dz/activities/ConnectorActivity.java | 2 +- .../activities/EndpointSettingsActivity.java | 2 +- .../dz/activities/MainActivity.java | 4 +- .../dz/activities/SettingsActivity.java | 2 +- .../dz/activities/StartBroadcastActivity.java | 2 +- .../WithSecure/dz/models/GlobalSettings.java | 86 +++++++++++++++++++ agent/src/main/res/raw/config.txt | 0 agent/src/main/res/values-v14/styles.xml | 15 +++- 13 files changed, 156 insertions(+), 12 deletions(-) create mode 100644 agent/src/main/java/com/WithSecure/dz/DzApplication.java create mode 100644 agent/src/main/java/com/WithSecure/dz/activities/BaseActivity.java create mode 100644 agent/src/main/java/com/WithSecure/dz/activities/BasePreferenceActivity.java create mode 100644 agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java create mode 100644 agent/src/main/res/raw/config.txt diff --git a/agent/src/main/AndroidManifest.xml b/agent/src/main/AndroidManifest.xml index 4232510..6bd9ccf 100644 --- a/agent/src/main/AndroidManifest.xml +++ b/agent/src/main/AndroidManifest.xml @@ -11,7 +11,8 @@ android:allowBackup="false" android:icon="@drawable/ic_launcher" android:label="@string/app_name" - android:theme="@style/AppTheme"> + android:theme="@style/AppTheme" + android:name=".DzApplication"> diff --git a/agent/src/main/java/com/WithSecure/dz/DzApplication.java b/agent/src/main/java/com/WithSecure/dz/DzApplication.java new file mode 100644 index 0000000..e92322b --- /dev/null +++ b/agent/src/main/java/com/WithSecure/dz/DzApplication.java @@ -0,0 +1,15 @@ +package com.WithSecure.dz; + +import android.app.Application; + +import com.WithSecure.dz.models.GlobalSettings; + +public class DzApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + + Agent.getInstance().setContext(this.getApplicationContext()); + GlobalSettings.Init(this.getApplicationContext()); + } +} diff --git a/agent/src/main/java/com/WithSecure/dz/activities/AboutActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/AboutActivity.java index 9936462..a83e5cf 100644 --- a/agent/src/main/java/com/WithSecure/dz/activities/AboutActivity.java +++ b/agent/src/main/java/com/WithSecure/dz/activities/AboutActivity.java @@ -8,7 +8,7 @@ import android.view.Menu; import android.widget.TextView; -public class AboutActivity extends Activity { +public class AboutActivity extends BaseActivity { private TextView description; @@ -22,7 +22,7 @@ private String getVersionName() { } @Override - protected void onCreate(Bundle savedInstanceState) { + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_about); diff --git a/agent/src/main/java/com/WithSecure/dz/activities/BaseActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/BaseActivity.java new file mode 100644 index 0000000..17fbe9f --- /dev/null +++ b/agent/src/main/java/com/WithSecure/dz/activities/BaseActivity.java @@ -0,0 +1,16 @@ +package com.WithSecure.dz.activities; + +import android.app.Activity; +import android.os.Bundle; + +import com.WithSecure.dz.models.GlobalSettings; + +public class BaseActivity extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(GlobalSettings.themeFromString(GlobalSettings.get("theme"))); + } +} + diff --git a/agent/src/main/java/com/WithSecure/dz/activities/BasePreferenceActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/BasePreferenceActivity.java new file mode 100644 index 0000000..aab011d --- /dev/null +++ b/agent/src/main/java/com/WithSecure/dz/activities/BasePreferenceActivity.java @@ -0,0 +1,15 @@ +package com.WithSecure.dz.activities; + +import android.os.Bundle; +import android.preference.PreferenceActivity; + +import com.WithSecure.dz.models.GlobalSettings; + +public class BasePreferenceActivity extends PreferenceActivity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(GlobalSettings.themeFromString(GlobalSettings.get("theme"))); + } +} diff --git a/agent/src/main/java/com/WithSecure/dz/activities/ConnectorActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/ConnectorActivity.java index 8208df0..cb1e8a9 100644 --- a/agent/src/main/java/com/WithSecure/dz/activities/ConnectorActivity.java +++ b/agent/src/main/java/com/WithSecure/dz/activities/ConnectorActivity.java @@ -17,7 +17,7 @@ import android.view.Menu; import android.view.MenuItem; -public abstract class ConnectorActivity extends Activity { +public abstract class ConnectorActivity extends BaseActivity { public static class IncomingFingerprintHandler extends Handler { diff --git a/agent/src/main/java/com/WithSecure/dz/activities/EndpointSettingsActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/EndpointSettingsActivity.java index 4ddb120..aa31992 100644 --- a/agent/src/main/java/com/WithSecure/dz/activities/EndpointSettingsActivity.java +++ b/agent/src/main/java/com/WithSecure/dz/activities/EndpointSettingsActivity.java @@ -17,7 +17,7 @@ import android.view.View; import android.widget.Button; -public class EndpointSettingsActivity extends PreferenceActivity { +public class EndpointSettingsActivity extends BasePreferenceActivity { public static final String ENDPOINT_SETTINGS_PREFERENCE = "endpoint_settings"; public static final String SECURITY_SETTINGS_PREFERENCE = "security_settings"; diff --git a/agent/src/main/java/com/WithSecure/dz/activities/MainActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/MainActivity.java index 811ba99..bc9a5b4 100644 --- a/agent/src/main/java/com/WithSecure/dz/activities/MainActivity.java +++ b/agent/src/main/java/com/WithSecure/dz/activities/MainActivity.java @@ -16,7 +16,7 @@ import android.view.View; import android.widget.Toast; -public class MainActivity extends Activity { +public class MainActivity extends BaseActivity { private EndpointListView endpoint_list_view = null; private ServerListRowView server_list_row_view = null; @@ -36,8 +36,6 @@ private void launchServerActivity() { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Agent.getInstance().setContext(this.getApplicationContext()); - setContentView(R.layout.activity_main); this.endpoint_list_view = (EndpointListView)this.findViewById(R.id.endpoint_list_view); diff --git a/agent/src/main/java/com/WithSecure/dz/activities/SettingsActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/SettingsActivity.java index cab20d6..9edf64b 100644 --- a/agent/src/main/java/com/WithSecure/dz/activities/SettingsActivity.java +++ b/agent/src/main/java/com/WithSecure/dz/activities/SettingsActivity.java @@ -14,7 +14,7 @@ import android.preference.PreferenceCategory; import android.widget.Toast; -public class SettingsActivity extends PreferenceActivity { +public class SettingsActivity extends BasePreferenceActivity { public static final String ABOUT_DROZER_PREFERENCE = "about_drozer"; public static final String ENDPOINT_SETTINGS_PREFERENCE = "endpoint_settings"; diff --git a/agent/src/main/java/com/WithSecure/dz/activities/StartBroadcastActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/StartBroadcastActivity.java index 00d3d43..43ae7c3 100644 --- a/agent/src/main/java/com/WithSecure/dz/activities/StartBroadcastActivity.java +++ b/agent/src/main/java/com/WithSecure/dz/activities/StartBroadcastActivity.java @@ -9,7 +9,7 @@ import java.util.ArrayList; -public class StartBroadcastActivity extends Activity { +public class StartBroadcastActivity extends BaseActivity { public void onCreate(Bundle bundle) { super.onCreate(bundle); diff --git a/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java b/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java new file mode 100644 index 0000000..370ebde --- /dev/null +++ b/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java @@ -0,0 +1,86 @@ +package com.WithSecure.dz.models; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.Resources; +import com.WithSecure.dz.Agent; +import com.WithSecure.dz.R; +import com.WithSecure.jsolar.api.connectors.Server; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Dictionary; + +public class GlobalSettings { + private GlobalSettings(Context ctx) { + // load settings from config file + try { + BufferedReader confFile = new BufferedReader(new InputStreamReader( + ctx.getResources().openRawResource(R.raw.config))); + String line; + + while ((line = confFile.readLine()) != null) { + String[] parts = line.split(":"); + if (parts.length != 2) { + continue; + } + + if (ensure(parts[0], parts[1])) { + // make additional changes on a per setting basis + switch (parts[0]) { + case "server-port": + try { + SharedPreferences.Editor e = Agent.getInstance().getSettings().edit(); + e.putString(Server.SERVER_PORT, parts[1]); + e.commit(); + } catch (NumberFormatException ignored) { + break; + } + break; + case "endpoint": + break; + } + } + } + } + catch (Resources.NotFoundException ignored) { } + catch (IOException ignored) { } + } + + private static boolean ensure(String key, String value) { + SharedPreferences p = Agent.getInstance().getSettings(); + + if (!p.contains(key)) { + SharedPreferences.Editor e = p.edit(); + e.putString(key, value); + e.commit(); + return true; + } + return false; + } + + public static String get(String key) { + return Agent.getInstance().getSettings().getString(key, null); + } + + public static int themeFromString(String s) { + if (s == null) { + return R.style.AppTheme; + } + + switch(s) { + case "red": return R.style.dzRed; + case "purple": return R.style.dzPurple; + case "blue": return R.style.dzBlue; + default: return R.style.AppTheme; + } + } + + public static void Init(Context ctx) { + if (instance == null) { + instance = new GlobalSettings(ctx); + } + } + + private static GlobalSettings instance = null; + private Dictionary data; +} diff --git a/agent/src/main/res/raw/config.txt b/agent/src/main/res/raw/config.txt new file mode 100644 index 0000000..e69de29 diff --git a/agent/src/main/res/values-v14/styles.xml b/agent/src/main/res/values-v14/styles.xml index 3da2d61..5a8dd4c 100644 --- a/agent/src/main/res/values-v14/styles.xml +++ b/agent/src/main/res/values-v14/styles.xml @@ -1,5 +1,18 @@ + - + + + + \ No newline at end of file From 5353c4be496726d24d91525a54f318d03dde4f99 Mon Sep 17 00:00:00 2001 From: Nathaniel Smith Date: Tue, 13 Aug 2024 20:14:30 +0100 Subject: [PATCH 02/16] request runtime perms on launch --- .../dz/activities/MainActivity.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/agent/src/main/java/com/WithSecure/dz/activities/MainActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/MainActivity.java index bc9a5b4..c2cdb60 100644 --- a/agent/src/main/java/com/WithSecure/dz/activities/MainActivity.java +++ b/agent/src/main/java/com/WithSecure/dz/activities/MainActivity.java @@ -7,6 +7,8 @@ import com.WithSecure.dz.views.ServerListRowView; import com.WithSecure.jsolar.api.connectors.Endpoint; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import android.os.Bundle; import android.os.RemoteException; import android.app.Activity; @@ -16,6 +18,13 @@ import android.view.View; import android.widget.Toast; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + public class MainActivity extends BaseActivity { private EndpointListView endpoint_list_view = null; @@ -78,6 +87,27 @@ public void onToggle(boolean toggle) { } }); + + // request all unrequested perms in manifest + try { + PackageInfo pi = getPackageManager().getPackageInfo(getApplicationContext().getPackageName(), PackageManager.GET_PERMISSIONS); + String[] requestedPermissions = pi.requestedPermissions; + + List toRequest = new ArrayList<>(); + for (String p : requestedPermissions) { + if (ContextCompat.checkSelfPermission(getApplicationContext(), p) != PackageManager.PERMISSION_GRANTED) { + toRequest.add(p); + } + } + + if (!toRequest.isEmpty()) { + String[] asArray = new String[toRequest.size()]; + toRequest.toArray(asArray); + ActivityCompat.requestPermissions(this, asArray, 1); + } + } catch (PackageManager.NameNotFoundException e) { + throw new RuntimeException(e); + } } @Override From 00fea8dd63d05b867606e5f17c864c115c23a79f Mon Sep 17 00:00:00 2001 From: Nathaniel Smith Date: Tue, 13 Aug 2024 20:54:04 +0100 Subject: [PATCH 03/16] display listening interfaces of server --- .../dz/activities/ServerActivity.java | 14 ++++++-- .../WithSecure/dz/models/ServerSettings.java | 35 +++++++++++++++++++ agent/src/main/res/layout/activity_server.xml | 17 ++++++++- agent/src/main/res/values/strings.xml | 1 + 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/agent/src/main/java/com/WithSecure/dz/activities/ServerActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/ServerActivity.java index fbc13ff..0355f9c 100644 --- a/agent/src/main/java/com/WithSecure/dz/activities/ServerActivity.java +++ b/agent/src/main/java/com/WithSecure/dz/activities/ServerActivity.java @@ -5,6 +5,7 @@ import com.WithSecure.dz.Agent; import com.WithSecure.dz.R; +import com.WithSecure.dz.models.ServerSettings; import com.WithSecure.dz.views.CheckListItemView; import com.WithSecure.dz.views.ConnectorStatusIndicator; import com.WithSecure.dz.views.logger.LogMessageAdapter; @@ -19,6 +20,7 @@ import android.app.ProgressDialog; import android.widget.CompoundButton; import android.widget.ListView; +import android.widget.TextView; import android.widget.Toast; public class ServerActivity extends ConnectorActivity implements Observer, Server.OnDetailedStatusListener { @@ -28,6 +30,8 @@ public class ServerActivity extends ConnectorActivity implements Observer, Serve private CompoundButton server_enabled = null; private ListView server_messages = null; private ConnectorStatusIndicator server_status_indicator = null; + + private TextView server_endpoint_text = null; private CheckListItemView status_enabled = null; private CheckListItemView status_listening = null; @@ -51,9 +55,12 @@ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.activity_server); - - this.server_status_indicator = (ConnectorStatusIndicator)this.findViewById(R.id.server_status_indicator); - + + this.server_status_indicator = (ConnectorStatusIndicator)this.findViewById(R.id.server_status_indicator); + + this.server_endpoint_text = (TextView)this.findViewById(R.id.server_endpoint); + server_endpoint_text.setText(ServerSettings.interfacesAsString()); + this.server_enabled = (CompoundButton)this.findViewById(R.id.server_enabled); this.server_enabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @@ -99,6 +106,7 @@ public void onDetailedStatus(Bundle status) { * Refresh the status indicators, to show the current status of the Endpoint. */ protected void refreshStatus() { + server_endpoint_text.setText(ServerSettings.interfacesAsString()); this.getDetailedServerStatus(); } diff --git a/agent/src/main/java/com/WithSecure/dz/models/ServerSettings.java b/agent/src/main/java/com/WithSecure/dz/models/ServerSettings.java index beb5944..f4b9b08 100644 --- a/agent/src/main/java/com/WithSecure/dz/models/ServerSettings.java +++ b/agent/src/main/java/com/WithSecure/dz/models/ServerSettings.java @@ -6,6 +6,12 @@ import com.WithSecure.dz.Agent; import com.WithSecure.jsolar.api.connectors.Server; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; + public class ServerSettings implements OnSharedPreferenceChangeListener { private Server server; @@ -88,4 +94,33 @@ public boolean save(Server server) { return editor.commit(); } + public static String interfacesAsString() { + try { + List ipAddrs = new ArrayList<>(); + + Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); + while (interfaces.hasMoreElements()) { + NetworkInterface i = interfaces.nextElement(); + + if (!i.isUp()) { + continue; + } + + Enumeration ips = i.getInetAddresses(); + while (ips.hasMoreElements()) { + InetAddress ip = ips.nextElement(); + + if (ip.isLinkLocalAddress() || ip.isLoopbackAddress()) { + continue; + } + + ipAddrs.add(ip.getHostAddress()); + } + } + + return String.join(", ", ipAddrs); + } catch (Exception ignored) { } + return "could not retrieve interfaces"; + } + } diff --git a/agent/src/main/res/layout/activity_server.xml b/agent/src/main/res/layout/activity_server.xml index 38a0b18..3e4369c 100644 --- a/agent/src/main/res/layout/activity_server.xml +++ b/agent/src/main/res/layout/activity_server.xml @@ -27,12 +27,27 @@ android:paddingTop="24dp" android:text="@string/embedded_server_details" android:textAppearance="?android:attr/textAppearanceLarge" /> + + Embedded Server Server Details + Server Interfaces: Messages Password Password Protected From 78d1a0b541a210a1bb7e9df3f8ff73d548ccf14a Mon Sep 17 00:00:00 2001 From: Nathaniel Smith Date: Thu, 15 Aug 2024 16:08:49 +0100 Subject: [PATCH 04/16] run dz services in foreground if possible --- .../java/com/WithSecure/dz/DzApplication.java | 2 + .../helpers/IntentProxyToContentProvider.java | 7 ++- .../models/ForegroundServiceNotification.java | 62 +++++++++++++++++++ .../WithSecure/dz/services/ClientService.java | 2 +- .../dz/services/ConnectorService.java | 28 ++++++++- .../WithSecure/dz/services/ServerService.java | 2 +- 6 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 agent/src/main/java/com/WithSecure/dz/models/ForegroundServiceNotification.java diff --git a/agent/src/main/java/com/WithSecure/dz/DzApplication.java b/agent/src/main/java/com/WithSecure/dz/DzApplication.java index e92322b..0ee65f0 100644 --- a/agent/src/main/java/com/WithSecure/dz/DzApplication.java +++ b/agent/src/main/java/com/WithSecure/dz/DzApplication.java @@ -2,6 +2,7 @@ import android.app.Application; +import com.WithSecure.dz.models.ForegroundServiceNotification; import com.WithSecure.dz.models.GlobalSettings; public class DzApplication extends Application { @@ -9,6 +10,7 @@ public class DzApplication extends Application { public void onCreate() { super.onCreate(); + ForegroundServiceNotification.Init(this.getApplicationContext()); Agent.getInstance().setContext(this.getApplicationContext()); GlobalSettings.Init(this.getApplicationContext()); } diff --git a/agent/src/main/java/com/WithSecure/dz/helpers/IntentProxyToContentProvider.java b/agent/src/main/java/com/WithSecure/dz/helpers/IntentProxyToContentProvider.java index 3841fa6..f98060d 100644 --- a/agent/src/main/java/com/WithSecure/dz/helpers/IntentProxyToContentProvider.java +++ b/agent/src/main/java/com/WithSecure/dz/helpers/IntentProxyToContentProvider.java @@ -1,15 +1,16 @@ package com.WithSecure.dz.helpers; -import android.app.Activity; import android.net.Uri; import android.os.Bundle; +import com.WithSecure.dz.activities.BaseActivity; + import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; -public class IntentProxyToContentProvider extends Activity { +public class IntentProxyToContentProvider extends BaseActivity { // This class is meant to help download files from unexported Content Providers // Assuming the unexported Content Provider has GrantURIPermissions set to True @@ -27,7 +28,7 @@ public class IntentProxyToContentProvider extends Activity { String filename = "yayoutputyay"; // save file as "yayoutputyay" - protected void onCreate(Bundle savedInstanceState) { + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Uri uri = Uri.parse(getIntent().getDataString()); // Get the Uri for the unexported content provider if (getIntent().getStringExtra("filename") != null) { diff --git a/agent/src/main/java/com/WithSecure/dz/models/ForegroundServiceNotification.java b/agent/src/main/java/com/WithSecure/dz/models/ForegroundServiceNotification.java new file mode 100644 index 0000000..f37264b --- /dev/null +++ b/agent/src/main/java/com/WithSecure/dz/models/ForegroundServiceNotification.java @@ -0,0 +1,62 @@ +package com.WithSecure.dz.models; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.os.Build; + +import androidx.core.app.NotificationCompat; + +import com.WithSecure.dz.R; +import com.WithSecure.dz.activities.MainActivity; + +public class ForegroundServiceNotification { + private static final String CHANNEL_ID = "ForegroundServiceChannel"; + private static final int NOTIFICATION_ID = 1; + + private Notification notification; + private static ForegroundServiceNotification instance = null; + + private ForegroundServiceNotification(Context ctx) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel channel = new NotificationChannel( + CHANNEL_ID, + "Foreground Service Channel", + NotificationManager.IMPORTANCE_HIGH + ); + channel.setDescription("Channel for foreground service"); + + NotificationManager manager = ctx.getSystemService(NotificationManager.class); + if (manager != null) { + manager.createNotificationChannel(channel); + } + + Intent notificationIntent = new Intent(ctx, MainActivity.class); + PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE); + + notification = new NotificationCompat.Builder(ctx, CHANNEL_ID) + .setContentTitle("Drozer") + .setContentText("Drozer is running in background") + .setSmallIcon(R.drawable.ic_notification) + .setContentIntent(pendingIntent) + .build(); + } + } + + public static void Init(Context ctx) { + if (instance == null) { + instance = new ForegroundServiceNotification(ctx); + } + } + + public static Notification getNotification() { + return instance.notification; + } + + public static int getId() { + return NOTIFICATION_ID; + } +} diff --git a/agent/src/main/java/com/WithSecure/dz/services/ClientService.java b/agent/src/main/java/com/WithSecure/dz/services/ClientService.java index 2d1477d..e1cfa0c 100644 --- a/agent/src/main/java/com/WithSecure/dz/services/ClientService.java +++ b/agent/src/main/java/com/WithSecure/dz/services/ClientService.java @@ -222,7 +222,7 @@ public void onDestroy() { public static void startAndBindToService(Context context, ServiceConnection serviceConnection) { if(!ClientService.running) - context.startService(new Intent(context, ClientService.class)); + ConnectorService.Start(context, ClientService.class); Intent intent = new Intent(context, ClientService.class); context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); diff --git a/agent/src/main/java/com/WithSecure/dz/services/ConnectorService.java b/agent/src/main/java/com/WithSecure/dz/services/ConnectorService.java index a57ff67..38862a0 100644 --- a/agent/src/main/java/com/WithSecure/dz/services/ConnectorService.java +++ b/agent/src/main/java/com/WithSecure/dz/services/ConnectorService.java @@ -3,14 +3,19 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; +import com.WithSecure.dz.Agent; +import com.WithSecure.dz.models.ForegroundServiceNotification; import com.WithSecure.jsolar.api.connectors.Connector; import com.WithSecure.jsolar.api.connectors.Endpoint; import com.WithSecure.jsolar.logger.LogMessage; import com.WithSecure.jsolar.logger.Logger; import com.WithSecure.jsolar.logger.OnLogMessageListener; +import android.Manifest; import android.app.Service; +import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -18,6 +23,8 @@ import android.os.Messenger; import android.os.RemoteException; +import androidx.core.content.ContextCompat; + public abstract class ConnectorService extends Service implements OnLogMessageListener { public static final int MSG_LOG_MESSAGE = 1; @@ -84,7 +91,16 @@ public void cacheMessenger(Messenger messenger) { public IBinder onBind(Intent intent) { return this.messenger.getBinder(); } - + + @Override + public void onCreate() { + super.onCreate(); + + if (ContextCompat.checkSelfPermission(Agent.getContext(), Manifest.permission.FOREGROUND_SERVICE) + == PackageManager.PERMISSION_GRANTED) + startForeground(ForegroundServiceNotification.getId(), ForegroundServiceNotification.getNotification()); + } + @Override public void onLogMessage(Logger logger, LogMessage message) { Bundle data = new Bundle(); @@ -115,4 +131,14 @@ protected void sendToAllMessengers(Message msg) { } } + public static void Start(Context ctx, Class c) { + Intent i = new Intent(ctx, c); + + if (ContextCompat.checkSelfPermission(ctx, Manifest.permission.FOREGROUND_SERVICE) + == PackageManager.PERMISSION_GRANTED) + ContextCompat.startForegroundService(ctx, new Intent(ctx, c)); + else + ctx.startService(i); + } + } diff --git a/agent/src/main/java/com/WithSecure/dz/services/ServerService.java b/agent/src/main/java/com/WithSecure/dz/services/ServerService.java index 18fa8f4..f44e705 100644 --- a/agent/src/main/java/com/WithSecure/dz/services/ServerService.java +++ b/agent/src/main/java/com/WithSecure/dz/services/ServerService.java @@ -193,7 +193,7 @@ public void onDestroy() { public static void startAndBindToService(Context context, ServiceConnection serviceConnection) { if(!ServerService.running) - context.startService(new Intent(context, ServerService.class)); + ConnectorService.Start(context, ServerService.class); Intent intent = new Intent(context, ServerService.class); context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); From 4bec4da9b659be64a23cbe77ac89ec4a2e252956 Mon Sep 17 00:00:00 2001 From: Nathaniel Smith Date: Thu, 15 Aug 2024 16:09:34 +0100 Subject: [PATCH 05/16] fixed requesting of ACTION_MANAGE_OVERLAY_PERMISSION on newer android versions --- .../WithSecure/dz/activities/MainActivity.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/agent/src/main/java/com/WithSecure/dz/activities/MainActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/MainActivity.java index c2cdb60..beb4cf3 100644 --- a/agent/src/main/java/com/WithSecure/dz/activities/MainActivity.java +++ b/agent/src/main/java/com/WithSecure/dz/activities/MainActivity.java @@ -7,12 +7,16 @@ import com.WithSecure.dz.views.ServerListRowView; import com.WithSecure.jsolar.api.connectors.Endpoint; +import android.Manifest; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.RemoteException; import android.app.Activity; import android.content.Intent; +import android.provider.Settings; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -96,7 +100,16 @@ public void onToggle(boolean toggle) { List toRequest = new ArrayList<>(); for (String p : requestedPermissions) { if (ContextCompat.checkSelfPermission(getApplicationContext(), p) != PackageManager.PERMISSION_GRANTED) { - toRequest.add(p); + if (p.equals(Manifest.permission.SYSTEM_ALERT_WINDOW)) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) { + Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, + Uri.parse("package:" + getPackageName())); + startActivity(intent); + } + } + else { + toRequest.add(p); + } } } From 845a15d993b3339f11c52c19db44ad387cf9dd29 Mon Sep 17 00:00:00 2001 From: Nathaniel Smith Date: Thu, 15 Aug 2024 16:10:49 +0100 Subject: [PATCH 06/16] added ability to reset all persistent preferences --- .../WithSecure/dz/activities/SettingsActivity.java | 11 +++++++++++ agent/src/main/res/values/strings.xml | 1 + agent/src/main/res/xml/preferences.xml | 3 +++ 3 files changed, 15 insertions(+) diff --git a/agent/src/main/java/com/WithSecure/dz/activities/SettingsActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/SettingsActivity.java index 9edf64b..6137c3a 100644 --- a/agent/src/main/java/com/WithSecure/dz/activities/SettingsActivity.java +++ b/agent/src/main/java/com/WithSecure/dz/activities/SettingsActivity.java @@ -18,11 +18,13 @@ public class SettingsActivity extends BasePreferenceActivity { public static final String ABOUT_DROZER_PREFERENCE = "about_drozer"; public static final String ENDPOINT_SETTINGS_PREFERENCE = "endpoint_settings"; + public static final String RESET_DROZER_PREFERENCE = "reset_preferences"; public static final int NEW_ENDPOINT = 1; public static final int EDIT_ENDPOINT = 2; private Preference about_preference = null; + private Preference reset = null; private PreferenceCategory endpoint_preferences = null; @Override @@ -105,6 +107,15 @@ public boolean onPreferenceClick(Preference arg0) { } }); + + this.reset = (Preference)this.findPreference(RESET_DROZER_PREFERENCE); + this.reset.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference arg0) { + Agent.getInstance().getSettings().edit().clear().apply(); + return true; + } + }); this.endpoint_preferences = (PreferenceCategory)this.getPreferenceManager().findPreference(ENDPOINT_SETTINGS_PREFERENCE); diff --git a/agent/src/main/res/values/strings.xml b/agent/src/main/res/values/strings.xml index adf94a1..63074c0 100644 --- a/agent/src/main/res/values/strings.xml +++ b/agent/src/main/res/values/strings.xml @@ -125,5 +125,6 @@ drozer Settings Restore after crash Restore state after an unexpected shutdown + Reset diff --git a/agent/src/main/res/xml/preferences.xml b/agent/src/main/res/xml/preferences.xml index cf09232..65326c8 100644 --- a/agent/src/main/res/xml/preferences.xml +++ b/agent/src/main/res/xml/preferences.xml @@ -64,6 +64,9 @@ android:title="@string/restore_after_crash" android:summary="@string/restore_summary" android:defaultValue="true"/> + From 8754ccdb0d0b7b78c9e2d83318e41df5196df68b Mon Sep 17 00:00:00 2001 From: Nathaniel Smith Date: Thu, 15 Aug 2024 16:11:13 +0100 Subject: [PATCH 07/16] fix to allow ':' char in config values --- .../src/main/java/com/WithSecure/dz/models/GlobalSettings.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java b/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java index 370ebde..741d17a 100644 --- a/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java +++ b/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java @@ -19,7 +19,8 @@ private GlobalSettings(Context ctx) { String line; while ((line = confFile.readLine()) != null) { - String[] parts = line.split(":"); + String[] parts = line.split(":", 2); + if (parts.length != 2) { continue; } From f900a376872165143465d7ea3df8d4edf4d25a72 Mon Sep 17 00:00:00 2001 From: Nathaniel Smith Date: Thu, 15 Aug 2024 16:21:11 +0100 Subject: [PATCH 08/16] suppress "deprecation" warning in BasePreferenceActivity --- .../com/WithSecure/dz/activities/BasePreferenceActivity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/agent/src/main/java/com/WithSecure/dz/activities/BasePreferenceActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/BasePreferenceActivity.java index aab011d..181eb98 100644 --- a/agent/src/main/java/com/WithSecure/dz/activities/BasePreferenceActivity.java +++ b/agent/src/main/java/com/WithSecure/dz/activities/BasePreferenceActivity.java @@ -7,6 +7,7 @@ public class BasePreferenceActivity extends PreferenceActivity { @Override + @SuppressWarnings("deprecation") public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); From 268918efc3495848a93fb237af5103c4022c42e8 Mon Sep 17 00:00:00 2001 From: Nathaniel Smith Date: Thu, 15 Aug 2024 16:40:35 +0100 Subject: [PATCH 09/16] custom Themes :D --- .../com/WithSecure/dz/activities/BaseActivity.java | 4 ++-- .../dz/activities/BasePreferenceActivity.java | 4 ++-- .../com/WithSecure/dz/models/GlobalSettings.java | 1 + agent/src/main/res/drawable/background_blue.xml | 13 +++++++++++++ agent/src/main/res/drawable/background_green.xml | 13 +++++++++++++ agent/src/main/res/drawable/background_purple.xml | 13 +++++++++++++ agent/src/main/res/drawable/background_red.xml | 12 ++++++++++++ agent/src/main/res/values-v14/styles.xml | 11 +++++++---- 8 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 agent/src/main/res/drawable/background_blue.xml create mode 100644 agent/src/main/res/drawable/background_green.xml create mode 100644 agent/src/main/res/drawable/background_purple.xml create mode 100644 agent/src/main/res/drawable/background_red.xml diff --git a/agent/src/main/java/com/WithSecure/dz/activities/BaseActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/BaseActivity.java index 17fbe9f..a8ebab0 100644 --- a/agent/src/main/java/com/WithSecure/dz/activities/BaseActivity.java +++ b/agent/src/main/java/com/WithSecure/dz/activities/BaseActivity.java @@ -8,9 +8,9 @@ public class BaseActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setTheme(GlobalSettings.themeFromString(GlobalSettings.get("theme"))); + + super.onCreate(savedInstanceState); } } diff --git a/agent/src/main/java/com/WithSecure/dz/activities/BasePreferenceActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/BasePreferenceActivity.java index 181eb98..962841b 100644 --- a/agent/src/main/java/com/WithSecure/dz/activities/BasePreferenceActivity.java +++ b/agent/src/main/java/com/WithSecure/dz/activities/BasePreferenceActivity.java @@ -9,8 +9,8 @@ public class BasePreferenceActivity extends PreferenceActivity { @Override @SuppressWarnings("deprecation") public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setTheme(GlobalSettings.themeFromString(GlobalSettings.get("theme"))); + + super.onCreate(savedInstanceState); } } diff --git a/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java b/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java index 741d17a..75075d9 100644 --- a/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java +++ b/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java @@ -70,6 +70,7 @@ public static int themeFromString(String s) { switch(s) { case "red": return R.style.dzRed; + case "green": return R.style.dzGreen; case "purple": return R.style.dzPurple; case "blue": return R.style.dzBlue; default: return R.style.AppTheme; diff --git a/agent/src/main/res/drawable/background_blue.xml b/agent/src/main/res/drawable/background_blue.xml new file mode 100644 index 0000000..b11dff5 --- /dev/null +++ b/agent/src/main/res/drawable/background_blue.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/agent/src/main/res/drawable/background_green.xml b/agent/src/main/res/drawable/background_green.xml new file mode 100644 index 0000000..83e98c9 --- /dev/null +++ b/agent/src/main/res/drawable/background_green.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/agent/src/main/res/drawable/background_purple.xml b/agent/src/main/res/drawable/background_purple.xml new file mode 100644 index 0000000..f40f9c9 --- /dev/null +++ b/agent/src/main/res/drawable/background_purple.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/agent/src/main/res/drawable/background_red.xml b/agent/src/main/res/drawable/background_red.xml new file mode 100644 index 0000000..48e229e --- /dev/null +++ b/agent/src/main/res/drawable/background_red.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/agent/src/main/res/values-v14/styles.xml b/agent/src/main/res/values-v14/styles.xml index 5a8dd4c..1c4959c 100644 --- a/agent/src/main/res/values-v14/styles.xml +++ b/agent/src/main/res/values-v14/styles.xml @@ -2,17 +2,20 @@ - + + \ No newline at end of file From 5aeb65cf0f0129dc980271b8389f6d462b38b563 Mon Sep 17 00:00:00 2001 From: Nathaniel Smith Date: Thu, 15 Aug 2024 16:44:02 +0100 Subject: [PATCH 10/16] added FOREGROUND_SERVICE to default perms --- agent/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/agent/src/main/AndroidManifest.xml b/agent/src/main/AndroidManifest.xml index 6bd9ccf..ca2c07b 100644 --- a/agent/src/main/AndroidManifest.xml +++ b/agent/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + Date: Tue, 27 Aug 2024 06:17:27 +0100 Subject: [PATCH 11/16] improved interface list --- .../dz/activities/ServerActivity.java | 23 +++++++--- .../dz/models/NetworkInterfaceModel.java | 16 +++++++ .../WithSecure/dz/models/ServerSettings.java | 36 ++++++++------- .../dz/views/NetworkInterfaceListAdapter.java | 45 +++++++++++++++++++ agent/src/main/res/layout/activity_server.xml | 9 ++-- .../layout/list_view_network_interface.xml | 18 ++++++++ 6 files changed, 123 insertions(+), 24 deletions(-) create mode 100644 agent/src/main/java/com/WithSecure/dz/models/NetworkInterfaceModel.java create mode 100644 agent/src/main/java/com/WithSecure/dz/views/NetworkInterfaceListAdapter.java create mode 100644 agent/src/main/res/layout/list_view_network_interface.xml diff --git a/agent/src/main/java/com/WithSecure/dz/activities/ServerActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/ServerActivity.java index 0355f9c..5af8093 100644 --- a/agent/src/main/java/com/WithSecure/dz/activities/ServerActivity.java +++ b/agent/src/main/java/com/WithSecure/dz/activities/ServerActivity.java @@ -1,13 +1,17 @@ package com.WithSecure.dz.activities; +import java.util.ArrayList; +import java.util.List; import java.util.Observable; import java.util.Observer; import com.WithSecure.dz.Agent; import com.WithSecure.dz.R; +import com.WithSecure.dz.models.NetworkInterfaceModel; import com.WithSecure.dz.models.ServerSettings; import com.WithSecure.dz.views.CheckListItemView; import com.WithSecure.dz.views.ConnectorStatusIndicator; +import com.WithSecure.dz.views.NetworkInterfaceListAdapter; import com.WithSecure.dz.views.logger.LogMessageAdapter; import com.WithSecure.jsolar.api.connectors.Connector; import com.WithSecure.jsolar.api.connectors.Endpoint; @@ -20,7 +24,6 @@ import android.app.ProgressDialog; import android.widget.CompoundButton; import android.widget.ListView; -import android.widget.TextView; import android.widget.Toast; public class ServerActivity extends ConnectorActivity implements Observer, Server.OnDetailedStatusListener { @@ -31,7 +34,9 @@ public class ServerActivity extends ConnectorActivity implements Observer, Serve private ListView server_messages = null; private ConnectorStatusIndicator server_status_indicator = null; - private TextView server_endpoint_text = null; + private ListView server_interface_list = null; + private NetworkInterfaceListAdapter server_interface_adapter = null; + private List server_interface_data; private CheckListItemView status_enabled = null; private CheckListItemView status_listening = null; @@ -58,8 +63,14 @@ public void onCreate(Bundle savedInstanceState) { this.server_status_indicator = (ConnectorStatusIndicator)this.findViewById(R.id.server_status_indicator); - this.server_endpoint_text = (TextView)this.findViewById(R.id.server_endpoint); - server_endpoint_text.setText(ServerSettings.interfacesAsString()); + this.server_interface_list = (ListView)this.findViewById(R.id.server_endpoint); + this.server_interface_data = new ArrayList<>(); + this.server_interface_adapter = new NetworkInterfaceListAdapter(this, server_interface_data); + server_interface_list.setAdapter(server_interface_adapter); + + server_interface_adapter.clear(); + server_interface_adapter.addAll(ServerSettings.getInterfaces()); + server_interface_adapter.notifyDataSetChanged(); this.server_enabled = (CompoundButton)this.findViewById(R.id.server_enabled); this.server_enabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @@ -106,7 +117,9 @@ public void onDetailedStatus(Bundle status) { * Refresh the status indicators, to show the current status of the Endpoint. */ protected void refreshStatus() { - server_endpoint_text.setText(ServerSettings.interfacesAsString()); + server_interface_adapter.clear(); + server_interface_adapter.addAll(ServerSettings.getInterfaces()); + server_interface_adapter.notifyDataSetChanged(); this.getDetailedServerStatus(); } diff --git a/agent/src/main/java/com/WithSecure/dz/models/NetworkInterfaceModel.java b/agent/src/main/java/com/WithSecure/dz/models/NetworkInterfaceModel.java new file mode 100644 index 0000000..3770713 --- /dev/null +++ b/agent/src/main/java/com/WithSecure/dz/models/NetworkInterfaceModel.java @@ -0,0 +1,16 @@ +package com.WithSecure.dz.models; + + +import java.util.List; + +public class NetworkInterfaceModel +{ + public NetworkInterfaceModel(String name, List ips) + { + this.name = name; + this.ips = ips; + } + + public final String name; + public final List ips; +} \ No newline at end of file diff --git a/agent/src/main/java/com/WithSecure/dz/models/ServerSettings.java b/agent/src/main/java/com/WithSecure/dz/models/ServerSettings.java index f4b9b08..e2e3aa8 100644 --- a/agent/src/main/java/com/WithSecure/dz/models/ServerSettings.java +++ b/agent/src/main/java/com/WithSecure/dz/models/ServerSettings.java @@ -62,21 +62,21 @@ public void load(Server server) { this.getSettings().registerOnSharedPreferenceChangeListener(this); } - + @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if(key.equals(Server.SERVER_PORT)) this.server.setPort(this.getPort()); if(key.equals(Server.SERVER_PASSWORD)) this.server.setPassword(this.getPassword()); - + if(key.equals(Server.SERVER_SSL)) { this.server.setSSL(this.isSSL()); server.setKeyStorePath(this.getKeyStorePath()); server.setKeyStorePassword(this.getKeyStorePassword()); server.setKeyPassword(this.getKeyPassword()); } - + if(key.equals(Server.SERVER_KEYSTORE_PATH)) server.setKeyStorePath(this.getKeyStorePath()); if(key.equals(Server.SERVER_KEYSTORE_PASSWORD)) @@ -84,7 +84,7 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin if(key.equals(Server.SERVER_KEY_PASSWORD)) server.setKeyPassword(this.getKeyPassword()); } - + public boolean save(Server server) { SharedPreferences.Editor editor = Agent.getInstance().getSettings().edit(); @@ -94,33 +94,39 @@ public boolean save(Server server) { return editor.commit(); } - public static String interfacesAsString() { - try { + public static List getInterfaces() { + List ret = new ArrayList<>(); + try { List ipAddrs = new ArrayList<>(); Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()) { - NetworkInterface i = interfaces.nextElement(); + NetworkInterface intr = interfaces.nextElement(); - if (!i.isUp()) { + if (!intr.isUp()) { continue; } - Enumeration ips = i.getInetAddresses(); + NetworkInterfaceModel inter_data = new NetworkInterfaceModel(intr.getName(), new ArrayList<>()); + + Enumeration ips = intr.getInetAddresses(); while (ips.hasMoreElements()) { InetAddress ip = ips.nextElement(); - if (ip.isLinkLocalAddress() || ip.isLoopbackAddress()) { + if (ip.isLinkLocalAddress()) { continue; } - ipAddrs.add(ip.getHostAddress()); + inter_data.ips.add(ip.getHostAddress()); } - } - return String.join(", ", ipAddrs); - } catch (Exception ignored) { } - return "could not retrieve interfaces"; + if (!inter_data.ips.isEmpty()) + { + ret.add(inter_data); + } + } + } catch (Exception ignored) { } + return ret; } } diff --git a/agent/src/main/java/com/WithSecure/dz/views/NetworkInterfaceListAdapter.java b/agent/src/main/java/com/WithSecure/dz/views/NetworkInterfaceListAdapter.java new file mode 100644 index 0000000..c5f1e0c --- /dev/null +++ b/agent/src/main/java/com/WithSecure/dz/views/NetworkInterfaceListAdapter.java @@ -0,0 +1,45 @@ +package com.WithSecure.dz.views; + +import android.app.Activity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.WithSecure.dz.R; +import com.WithSecure.dz.models.NetworkInterfaceModel; + +import java.util.List; + +public class NetworkInterfaceListAdapter extends ArrayAdapter +{ + private final Activity context; + + public NetworkInterfaceListAdapter(@NonNull Activity context, List interfaces) { + super(context, R.layout.list_view_network_interface, interfaces); + + this.context = context; + } + + @NonNull + @Override + public View getView(int position, View view, @NonNull ViewGroup parent) + { + LayoutInflater inflater=this.context.getLayoutInflater(); + View rowView=inflater.inflate(R.layout.list_view_network_interface, null,true); + + TextView name = rowView.findViewById(R.id.interface_name); + TextView ips = rowView.findViewById(R.id.ips); + + NetworkInterfaceModel data = this.getItem(position); + assert data != null; + + name.setText(data.name); + ips.setText(String.join("\n", data.ips)); + + return rowView; + } +} \ No newline at end of file diff --git a/agent/src/main/res/layout/activity_server.xml b/agent/src/main/res/layout/activity_server.xml index 3e4369c..41f5574 100644 --- a/agent/src/main/res/layout/activity_server.xml +++ b/agent/src/main/res/layout/activity_server.xml @@ -32,16 +32,17 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:layout_alignParentRight="true" android:layout_below="@+id/label_server_details" android:text="@string/embedded_server_interfaces"/> - + android:paddingLeft="10dp" + android:layout_below="@+id/server_endpoint_text"/> + + + + + + \ No newline at end of file From c2c88943ba0baab66a1a7b8fd1eb490250dcb717 Mon Sep 17 00:00:00 2001 From: Nathaniel Smith Date: Tue, 3 Sep 2024 20:39:38 +0100 Subject: [PATCH 12/16] Revert "added ability to reset all persistent preferences" This reverts commit fafbb23ae89c853accce62a3b6b36580ac719b8d. Funny button crashes the app oops :p was useful for testing but probably shouldn't have been pushed- --- .../WithSecure/dz/activities/SettingsActivity.java | 11 ----------- agent/src/main/res/values/strings.xml | 1 - agent/src/main/res/xml/preferences.xml | 3 --- 3 files changed, 15 deletions(-) diff --git a/agent/src/main/java/com/WithSecure/dz/activities/SettingsActivity.java b/agent/src/main/java/com/WithSecure/dz/activities/SettingsActivity.java index 6137c3a..9edf64b 100644 --- a/agent/src/main/java/com/WithSecure/dz/activities/SettingsActivity.java +++ b/agent/src/main/java/com/WithSecure/dz/activities/SettingsActivity.java @@ -18,13 +18,11 @@ public class SettingsActivity extends BasePreferenceActivity { public static final String ABOUT_DROZER_PREFERENCE = "about_drozer"; public static final String ENDPOINT_SETTINGS_PREFERENCE = "endpoint_settings"; - public static final String RESET_DROZER_PREFERENCE = "reset_preferences"; public static final int NEW_ENDPOINT = 1; public static final int EDIT_ENDPOINT = 2; private Preference about_preference = null; - private Preference reset = null; private PreferenceCategory endpoint_preferences = null; @Override @@ -107,15 +105,6 @@ public boolean onPreferenceClick(Preference arg0) { } }); - - this.reset = (Preference)this.findPreference(RESET_DROZER_PREFERENCE); - this.reset.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference arg0) { - Agent.getInstance().getSettings().edit().clear().apply(); - return true; - } - }); this.endpoint_preferences = (PreferenceCategory)this.getPreferenceManager().findPreference(ENDPOINT_SETTINGS_PREFERENCE); diff --git a/agent/src/main/res/values/strings.xml b/agent/src/main/res/values/strings.xml index 63074c0..adf94a1 100644 --- a/agent/src/main/res/values/strings.xml +++ b/agent/src/main/res/values/strings.xml @@ -125,6 +125,5 @@ drozer Settings Restore after crash Restore state after an unexpected shutdown - Reset diff --git a/agent/src/main/res/xml/preferences.xml b/agent/src/main/res/xml/preferences.xml index 65326c8..cf09232 100644 --- a/agent/src/main/res/xml/preferences.xml +++ b/agent/src/main/res/xml/preferences.xml @@ -64,9 +64,6 @@ android:title="@string/restore_after_crash" android:summary="@string/restore_summary" android:defaultValue="true"/> - From 24378430f8b697ef2762c04c2964bc71b3d997d8 Mon Sep 17 00:00:00 2001 From: Nathaniel Smith Date: Thu, 5 Sep 2024 17:24:50 +0100 Subject: [PATCH 13/16] modified config file loading to not use global preferences so changed or removed config items are registered properly --- .../WithSecure/dz/models/GlobalSettings.java | 47 +++++++++---------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java b/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java index 75075d9..8461a0e 100644 --- a/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java +++ b/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java @@ -9,6 +9,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.Dictionary; +import java.util.Hashtable; public class GlobalSettings { private GlobalSettings(Context ctx) { @@ -25,21 +26,21 @@ private GlobalSettings(Context ctx) { continue; } - if (ensure(parts[0], parts[1])) { - // make additional changes on a per setting basis - switch (parts[0]) { - case "server-port": - try { - SharedPreferences.Editor e = Agent.getInstance().getSettings().edit(); - e.putString(Server.SERVER_PORT, parts[1]); - e.commit(); + data.put(parts[0], parts[1]); + + // preform additional changes on a per setting basis + switch (parts[0]) { + case "server-port": + try { + SharedPreferences.Editor e = Agent.getInstance().getSettings().edit(); + e.putString(Server.SERVER_PORT, parts[1]); + e.commit(); } catch (NumberFormatException ignored) { break; } - break; - case "endpoint": - break; - } + break; + default: + break; } } } @@ -47,20 +48,16 @@ private GlobalSettings(Context ctx) { catch (IOException ignored) { } } - private static boolean ensure(String key, String value) { - SharedPreferences p = Agent.getInstance().getSettings(); - - if (!p.contains(key)) { - SharedPreferences.Editor e = p.edit(); - e.putString(key, value); - e.commit(); - return true; - } - return false; + public static String get(String key) { + return get(key, null); } - public static String get(String key) { - return Agent.getInstance().getSettings().getString(key, null); + public static String get(String key, String fallback) { + String value = instance.data.get(key); + + return value != null + ? value + : fallback; } public static int themeFromString(String s) { @@ -84,5 +81,5 @@ public static void Init(Context ctx) { } private static GlobalSettings instance = null; - private Dictionary data; + private final Dictionary data = new Hashtable<>(); } From 1ba47e65c43b353fe2c086e92225e940d6ea35e4 Mon Sep 17 00:00:00 2001 From: Nathaniel Smith Date: Fri, 6 Sep 2024 03:26:19 +0100 Subject: [PATCH 14/16] reindented GlobalSettings.java with tabs --- .../WithSecure/dz/models/GlobalSettings.java | 119 +++++++++--------- 1 file changed, 60 insertions(+), 59 deletions(-) diff --git a/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java b/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java index 8461a0e..ac5881f 100644 --- a/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java +++ b/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java @@ -12,74 +12,75 @@ import java.util.Hashtable; public class GlobalSettings { - private GlobalSettings(Context ctx) { - // load settings from config file - try { - BufferedReader confFile = new BufferedReader(new InputStreamReader( - ctx.getResources().openRawResource(R.raw.config))); - String line; + private GlobalSettings(Context ctx) { + // load settings from config file + try { + BufferedReader confFile = new BufferedReader(new InputStreamReader( + ctx.getResources().openRawResource(R.raw.config))); + String line; - while ((line = confFile.readLine()) != null) { - String[] parts = line.split(":", 2); + while ((line = confFile.readLine()) != null) { + String[] parts = line.split(":", 2); - if (parts.length != 2) { - continue; - } + if (parts.length != 2) { + continue; + } - data.put(parts[0], parts[1]); + data.put(parts[0], parts[1]); - // preform additional changes on a per setting basis - switch (parts[0]) { - case "server-port": - try { - SharedPreferences.Editor e = Agent.getInstance().getSettings().edit(); - e.putString(Server.SERVER_PORT, parts[1]); - e.commit(); - } catch (NumberFormatException ignored) { - break; - } - break; - default: - break; - } - } - } - catch (Resources.NotFoundException ignored) { } - catch (IOException ignored) { } - } + // preform additional changes on a per setting basis + switch (parts[0]) { + case "server-port": + try { + SharedPreferences.Editor e = Agent.getInstance().getSettings().edit(); + e.putString(Server.SERVER_PORT, parts[1]); + e.commit(); + } + catch (NumberFormatException ignored) { + break; + } + break; + default: + break; + } + } + } + catch (Resources.NotFoundException ignored) { } + catch (IOException ignored) { } + } - public static String get(String key) { - return get(key, null); - } + public static String get(String key) { + return get(key, null); + } - public static String get(String key, String fallback) { - String value = instance.data.get(key); + public static String get(String key, String fallback) { + String value = instance.data.get(key); - return value != null - ? value - : fallback; - } + return value != null + ? value + : fallback; + } - public static int themeFromString(String s) { - if (s == null) { - return R.style.AppTheme; - } + public static int themeFromString(String s) { + if (s == null) { + return R.style.AppTheme; + } - switch(s) { - case "red": return R.style.dzRed; - case "green": return R.style.dzGreen; - case "purple": return R.style.dzPurple; - case "blue": return R.style.dzBlue; - default: return R.style.AppTheme; - } - } + switch(s) { + case "red": return R.style.dzRed; + case "green": return R.style.dzGreen; + case "purple": return R.style.dzPurple; + case "blue": return R.style.dzBlue; + default: return R.style.AppTheme; + } + } - public static void Init(Context ctx) { - if (instance == null) { - instance = new GlobalSettings(ctx); - } - } + public static void Init(Context ctx) { + if (instance == null) { + instance = new GlobalSettings(ctx); + } + } - private static GlobalSettings instance = null; - private final Dictionary data = new Hashtable<>(); + private static GlobalSettings instance = null; + private final Dictionary data = new Hashtable<>(); } From c7d8beb00f85a47f14740e7e2c25129ca4b9ab4a Mon Sep 17 00:00:00 2001 From: Nathaniel Smith Date: Sat, 7 Sep 2024 03:02:19 +0100 Subject: [PATCH 15/16] adding settings option to disable loading of config file --- .../main/java/com/WithSecure/dz/models/GlobalSettings.java | 4 ++++ agent/src/main/res/values/strings.xml | 2 ++ agent/src/main/res/xml/preferences.xml | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java b/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java index ac5881f..9e8449a 100644 --- a/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java +++ b/agent/src/main/java/com/WithSecure/dz/models/GlobalSettings.java @@ -13,6 +13,10 @@ public class GlobalSettings { private GlobalSettings(Context ctx) { + // skip if config loading is disabled + if (Agent.getInstance().getSettings().getBoolean("disable_config_loading", false)) + return; + // load settings from config file try { BufferedReader confFile = new BufferedReader(new InputStreamReader( diff --git a/agent/src/main/res/values/strings.xml b/agent/src/main/res/values/strings.xml index adf94a1..8dda6d5 100644 --- a/agent/src/main/res/values/strings.xml +++ b/agent/src/main/res/values/strings.xml @@ -125,5 +125,7 @@ drozer Settings Restore after crash Restore state after an unexpected shutdown + Disable config file loading + Disable auto loading of custom agent settings diff --git a/agent/src/main/res/xml/preferences.xml b/agent/src/main/res/xml/preferences.xml index cf09232..cfd7570 100644 --- a/agent/src/main/res/xml/preferences.xml +++ b/agent/src/main/res/xml/preferences.xml @@ -64,6 +64,10 @@ android:title="@string/restore_after_crash" android:summary="@string/restore_summary" android:defaultValue="true"/> + From 1b14c09c8b5669d58044cdabf408744831064530 Mon Sep 17 00:00:00 2001 From: Nathaniel Smith Date: Sat, 7 Sep 2024 03:14:39 +0100 Subject: [PATCH 16/16] bump version number for agent compatibility reasons --- agent/src/main/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent/src/main/AndroidManifest.xml b/agent/src/main/AndroidManifest.xml index ca2c07b..3e1afaa 100644 --- a/agent/src/main/AndroidManifest.xml +++ b/agent/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + android:versionName="3.1.1" >