From 51641c5f134d55418564118217b5b6d8a448ef54 Mon Sep 17 00:00:00 2001 From: mayorow Date: Mon, 21 Oct 2024 12:24:47 +0400 Subject: [PATCH] v6.09: Plain HTTP traffic is enabled. Fixed a problem with Push notification polling in secure mode. Headwind MDM requests special permissions if can't grant it automatically. Fixed an error of setting easy password requirements. Library version changed to 1.1.6 --- app/build.gradle | 4 +-- .../hmdm/launcher/server/ServerService.java | 8 +++-- .../launcher/service/PluginApiService.java | 4 +-- .../service/PushLongPollingService.java | 30 +++++++++++++++++-- .../com/hmdm/launcher/ui/MainActivity.java | 18 +++++++---- .../java/com/hmdm/launcher/util/Utils.java | 4 +-- .../worker/PushNotificationWorker.java | 20 +++++++++++-- .../main/res/xml/network_security_config.xml | 2 +- 8 files changed, 71 insertions(+), 19 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d154a59..e456f17 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -38,8 +38,8 @@ android { // To avoid extra step during initial setup, let's keep the target SDK version as 29 as long as possible //noinspection ExpiredTargetSdkVersion targetSdkVersion 34 - versionCode 15050 - versionName "6.05" + versionCode 15090 + versionName "6.09" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" dataBinding { enabled = true diff --git a/app/src/main/java/com/hmdm/launcher/server/ServerService.java b/app/src/main/java/com/hmdm/launcher/server/ServerService.java index 55b9da1..1b2e462 100644 --- a/app/src/main/java/com/hmdm/launcher/server/ServerService.java +++ b/app/src/main/java/com/hmdm/launcher/server/ServerService.java @@ -78,10 +78,14 @@ Call getServerConfig(@Path("project") String project, Call sendDevice(@Path("project") String project, @Body DeviceInfo deviceInfo); @GET("{project}/rest/notifications/device/{number}") - Call queryPushNotifications(@Path("project") String project, @Path("number") String number); + Call queryPushNotifications(@Path("project") String project, + @Path("number") String number, + @Header(REQUEST_SIGNATURE_HEADER) String signature); @GET("{project}/rest/notification/polling/{number}") - Call queryPushLongPolling(@Path("project") String project, @Path("number") String number); + Call queryPushLongPolling(@Path("project") String project, + @Path("number") String number, + @Header(REQUEST_SIGNATURE_HEADER) String signature); @GET( "{project}/rest/plugins/devicelog/log/rules/{number}" ) Call getRemoteLogConfig(@Path("project") String project, @Path("number") String number); diff --git a/app/src/main/java/com/hmdm/launcher/service/PluginApiService.java b/app/src/main/java/com/hmdm/launcher/service/PluginApiService.java index 112cb9e..c9fc560 100644 --- a/app/src/main/java/com/hmdm/launcher/service/PluginApiService.java +++ b/app/src/main/java/com/hmdm/launcher/service/PluginApiService.java @@ -68,8 +68,8 @@ public IBinder onBind(Intent intent) { @Override public int getVersion() { - // 1.1.5 - return 115; + // 1.1.6 + return 116; } @Override diff --git a/app/src/main/java/com/hmdm/launcher/service/PushLongPollingService.java b/app/src/main/java/com/hmdm/launcher/service/PushLongPollingService.java index 67625c0..982e28c 100644 --- a/app/src/main/java/com/hmdm/launcher/service/PushLongPollingService.java +++ b/app/src/main/java/com/hmdm/launcher/service/PushLongPollingService.java @@ -20,6 +20,7 @@ import com.hmdm.launcher.BuildConfig; import com.hmdm.launcher.Const; import com.hmdm.launcher.R; +import com.hmdm.launcher.helper.CryptoHelper; import com.hmdm.launcher.helper.SettingsHelper; import com.hmdm.launcher.json.PushMessage; import com.hmdm.launcher.json.PushResponse; @@ -31,6 +32,8 @@ import org.eclipse.paho.android.service.MqttService; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; @@ -105,6 +108,19 @@ public int onStartCommand(Intent intent, int flags, int startId) { secondaryServerService = ServerServiceKeeper.createServerService(settingsHelper.getSecondaryBaseUrl(), Const.LONG_POLLING_READ_TIMEOUT); } + // Calculate request signature + String encodedDeviceId = settingsHelper.getDeviceId(); + try { + encodedDeviceId = URLEncoder.encode(encodedDeviceId, "utf8"); + } catch (UnsupportedEncodingException e) { + } + String path = settingsHelper.getServerProject() + "/rest/notification/polling/" + encodedDeviceId; + String signature = null; + try { + signature = CryptoHelper.getSHA1String(BuildConfig.REQUEST_SIGNATURE + path); + } catch (Exception e) { + } + threadActive = true; while (enabled) { Response response = null; @@ -113,7 +129,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { try { // This is the long operation response = serverService. - queryPushLongPolling(settingsHelper.getServerProject(), settingsHelper.getDeviceId()).execute(); + queryPushLongPolling(settingsHelper.getServerProject(), settingsHelper.getDeviceId(), signature).execute(); } catch (Exception e) { RemoteLogger.log(context, Const.LOG_WARN, "Failed to query push notifications from " + settingsHelper.getBaseUrl() + " : " + e.getMessage()); @@ -123,7 +139,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { try { if (response == null) { response = secondaryServerService. - queryPushLongPolling(settingsHelper.getServerProject(), settingsHelper.getDeviceId()).execute(); + queryPushLongPolling(settingsHelper.getServerProject(), settingsHelper.getDeviceId(), signature).execute(); } if ( response.isSuccessful() ) { @@ -140,6 +156,16 @@ public int onStartCommand(Intent intent, int flags, int startId) { PushNotificationProcessor.process(entry.getValue(), context); } } + } else if (response.code() >= 400 && response.code() < 500) { + // Response code 500 is fine (Timeout), so here we log only 4xx requests (403 Forbidden in particular) + RemoteLogger.log(context, Const.LOG_WARN, "Wrong response while querying push notifications from " + + settingsHelper.getSecondaryBaseUrl() + " : HTTP status " + response.code()); + try { + // On exception, we need to wait to avoid looping + Thread.sleep(DELAY_AFTER_EXCEPTION_MS); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } } // Avoid looping by adding some pause Thread.sleep(DELAY_AFTER_REQUEST_MS); diff --git a/app/src/main/java/com/hmdm/launcher/ui/MainActivity.java b/app/src/main/java/com/hmdm/launcher/ui/MainActivity.java index 34e7de7..23ac24d 100644 --- a/app/src/main/java/com/hmdm/launcher/ui/MainActivity.java +++ b/app/src/main/java/com/hmdm/launcher/ui/MainActivity.java @@ -1016,8 +1016,10 @@ private boolean needRequestUsageStats() { private boolean checkUsageStatistics() { if (!ProUtils.checkUsageStatistics(this)) { if (SystemUtils.autoSetUsageStatsPermission(this, getPackageName())) { - // Permission auto granted - return true; + // Permission auto granted, but we double check + if (ProUtils.checkUsageStatistics(this)) { + return true; + } } createAndShowHistorySettingsDialog(); return false; @@ -1029,8 +1031,10 @@ private boolean checkUsageStatistics() { private boolean checkManageStorage() { if (!Environment.isExternalStorageManager()) { if (SystemUtils.autoSetStoragePermission(this, getPackageName())) { - // Permission auto granted - return true; + // Permission auto granted, but we double check + if (Environment.isExternalStorageManager()) { + return true; + } } createAndShowManageStorageDialog(); return false; @@ -1060,8 +1064,10 @@ private boolean needRequestOverlay() { private boolean checkAlarmWindow() { if (ProUtils.isPro() && !Utils.canDrawOverlays(this)) { if (SystemUtils.autoSetOverlayPermission(this, getPackageName())) { - // Permission auto granted - return true; + // Permission auto granted, but we double check + if (Utils.canDrawOverlays(this)) { + return true; + } } createAndShowOverlaySettingsDialog(); return false; diff --git a/app/src/main/java/com/hmdm/launcher/util/Utils.java b/app/src/main/java/com/hmdm/launcher/util/Utils.java index 88af879..9d4d341 100644 --- a/app/src/main/java/com/hmdm/launcher/util/Utils.java +++ b/app/src/main/java/com/hmdm/launcher/util/Utils.java @@ -664,10 +664,10 @@ public static boolean setPasswordMode(String passwordMode, Context context) { if (passwordMode == null) { devicePolicyManager.setPasswordQuality(adminComponentName, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED); } else if (passwordMode.equals(Const.PASSWORD_QUALITY_PRESENT)) { - devicePolicyManager.setPasswordQuality(adminComponentName, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); + devicePolicyManager.setPasswordQuality(adminComponentName, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC); devicePolicyManager.setPasswordMinimumLength(adminComponentName, 1); } else if (passwordMode.equals(Const.PASSWORD_QUALITY_EASY)) { - devicePolicyManager.setPasswordQuality(adminComponentName, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); + devicePolicyManager.setPasswordQuality(adminComponentName, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC); devicePolicyManager.setPasswordMinimumLength(adminComponentName, 6); } else if (passwordMode.equals(Const.PASSWORD_QUALITY_MODERATE)) { devicePolicyManager.setPasswordQuality(adminComponentName, DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC); diff --git a/app/src/main/java/com/hmdm/launcher/worker/PushNotificationWorker.java b/app/src/main/java/com/hmdm/launcher/worker/PushNotificationWorker.java index a17719f..13b1da3 100644 --- a/app/src/main/java/com/hmdm/launcher/worker/PushNotificationWorker.java +++ b/app/src/main/java/com/hmdm/launcher/worker/PushNotificationWorker.java @@ -31,6 +31,7 @@ import com.hmdm.launcher.BuildConfig; import com.hmdm.launcher.Const; import com.hmdm.launcher.helper.ConfigUpdater; +import com.hmdm.launcher.helper.CryptoHelper; import com.hmdm.launcher.helper.SettingsHelper; import com.hmdm.launcher.json.PushMessage; import com.hmdm.launcher.json.PushResponse; @@ -40,7 +41,9 @@ import com.hmdm.launcher.util.PushNotificationMqttWrapper; import com.hmdm.launcher.util.RemoteLogger; +import java.io.UnsupportedEncodingException; import java.net.URL; +import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -109,10 +112,23 @@ private Result doPollingWork() { ServerService secondaryServerService = ServerServiceKeeper.getSecondaryServerServiceInstance(context); Response response = null; + // Calculate request signature + String encodedDeviceId = settingsHelper.getDeviceId(); + try { + encodedDeviceId = URLEncoder.encode(encodedDeviceId, "utf8"); + } catch (UnsupportedEncodingException e) { + } + String path = settingsHelper.getServerProject() + "/rest/notifications/device/" + encodedDeviceId; + String signature = null; + try { + signature = CryptoHelper.getSHA1String(BuildConfig.REQUEST_SIGNATURE + path); + } catch (Exception e) { + } + RemoteLogger.log(context, Const.LOG_DEBUG, "Querying push notifications"); try { response = serverService. - queryPushNotifications(settingsHelper.getServerProject(), settingsHelper.getDeviceId()).execute(); + queryPushNotifications(settingsHelper.getServerProject(), settingsHelper.getDeviceId(), signature).execute(); } catch (Exception e) { RemoteLogger.log(context, Const.LOG_WARN, "Failed to query push notifications: " + e.getMessage()); e.printStackTrace(); @@ -121,7 +137,7 @@ private Result doPollingWork() { try { if (response == null) { response = secondaryServerService. - queryPushNotifications(settingsHelper.getServerProject(), settingsHelper.getDeviceId()).execute(); + queryPushNotifications(settingsHelper.getServerProject(), settingsHelper.getDeviceId(), signature).execute(); } if ( response.isSuccessful() ) { diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml index 37a8e3f..7d50fce 100644 --- a/app/src/main/res/xml/network_security_config.xml +++ b/app/src/main/res/xml/network_security_config.xml @@ -1,6 +1,6 @@ - +