From ba0ca1de75b4f7758055dcb7d3213bd2c2bb4dee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sat, 2 Dec 2023 10:59:34 +0000 Subject: [PATCH] Delegate auth key validation to coordinator --- .../activities/discovery/DiscoveryActivityV2.java | 2 +- .../devices/AbstractDeviceCoordinator.java | 11 +++++++++++ .../gadgetbridge/devices/DeviceCoordinator.java | 2 ++ .../devices/huami/Huami2021Coordinator.java | 6 ++++++ .../devices/xiaomi/XiaomiEncryptedCoordinator.java | 6 ++++++ .../devices/xiaomi/XiaomiPlaintextCoordinator.java | 9 +++++++++ .../devices/huami/operations/InitOperation.java | 2 +- .../service/devices/xiaomi/XiaomiAuthService.java | 2 +- 8 files changed, 37 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/discovery/DiscoveryActivityV2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/discovery/DiscoveryActivityV2.java index 0a810e30e..0d6352d74 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/discovery/DiscoveryActivityV2.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/discovery/DiscoveryActivityV2.java @@ -607,7 +607,7 @@ public class DiscoveryActivityV2 extends AbstractGBActivity implements AdapterVi if (authKey == null || authKey.isEmpty()) { toast(DiscoveryActivityV2.this, getString(R.string.discovery_need_to_enter_authkey), Toast.LENGTH_LONG, GB.WARN); return; - } else if (authKey.getBytes().length < 34 || !authKey.startsWith("0x")) { + } else if (!coordinator.validateAuthKey(authKey)) { toast(DiscoveryActivityV2.this, getString(R.string.discovery_entered_invalid_authkey), Toast.LENGTH_LONG, GB.WARN); return; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java index 934eb6780..080df31ad 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java @@ -607,27 +607,38 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator { return R.drawable.ic_device_default_disabled; } + @Override public boolean supportsNotificationVibrationPatterns() { return false; } + @Override public boolean supportsNotificationVibrationRepetitionPatterns() { return false; } + @Override public boolean supportsNotificationLedPatterns() { return false; } + @Override public AbstractNotificationPattern[] getNotificationVibrationPatterns() { return new AbstractNotificationPattern[0]; } + @Override public AbstractNotificationPattern[] getNotificationVibrationRepetitionPatterns() { return new AbstractNotificationPattern[0]; } + @Override public AbstractNotificationPattern[] getNotificationLedPatterns() { return new AbstractNotificationPattern[0]; } + + @Override + public boolean validateAuthKey(final String authKey) { + return !(authKey.getBytes().length < 34 || !authKey.startsWith("0x")); + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java index 8ce2641c6..913780c60 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java @@ -590,4 +590,6 @@ public interface DeviceCoordinator { * What LED patterns for notifications are supported by the device. */ AbstractNotificationPattern[] getNotificationLedPatterns(); + + boolean validateAuthKey(String authKey); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/Huami2021Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/Huami2021Coordinator.java index 4550da2dc..9c7d7e923 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/Huami2021Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/Huami2021Coordinator.java @@ -581,4 +581,10 @@ public abstract class Huami2021Coordinator extends HuamiCoordinator { public static boolean experimentalFeatures(final GBDevice device) { return getPrefs(device).getBoolean("zepp_os_experimental_features", false); } + + @Override + public boolean validateAuthKey(final String authKey) { + final byte[] authKeyBytes = authKey.trim().getBytes(); + return authKeyBytes.length == 32 || (authKey.trim().startsWith("0x") && authKeyBytes.length == 34); + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiEncryptedCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiEncryptedCoordinator.java index f8a705c88..07e29257e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiEncryptedCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiEncryptedCoordinator.java @@ -41,4 +41,10 @@ public abstract class XiaomiEncryptedCoordinator extends XiaomiCoordinator { public Class getDeviceSupportClass() { return XiaomiEncryptedSupport.class; } + + @Override + public boolean validateAuthKey(final String authKey) { + final byte[] authKeyBytes = authKey.trim().getBytes(); + return authKeyBytes.length == 32 || (authKey.startsWith("0x") && authKeyBytes.length == 34); + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiPlaintextCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiPlaintextCoordinator.java index 3a249da92..d46242572 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiPlaintextCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/xiaomi/XiaomiPlaintextCoordinator.java @@ -23,11 +23,15 @@ import androidx.annotation.NonNull; import java.util.Collection; import java.util.Collections; +import java.util.regex.Pattern; import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiPlaintextSupport; public abstract class XiaomiPlaintextCoordinator extends XiaomiCoordinator { + // user id is used as auth key - numeric + private static final Pattern AUTH_KEY_PATTERN = Pattern.compile("^[0-9]+$"); + @NonNull @Override public Collection createBLEScanFilters() { @@ -41,4 +45,9 @@ public abstract class XiaomiPlaintextCoordinator extends XiaomiCoordinator { public Class getDeviceSupportClass() { return XiaomiPlaintextSupport.class; } + + @Override + public boolean validateAuthKey(final String authKey) { + return AUTH_KEY_PATTERN.matcher(authKey.trim()).matches(); + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation.java index aef537941..c3136ec7b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/InitOperation.java @@ -95,7 +95,7 @@ public class InitOperation extends AbstractBTLEOperation { String authKey = sharedPrefs.getString("authkey", null); if (authKey != null && !authKey.isEmpty()) { byte[] srcBytes = authKey.trim().getBytes(); - if (authKey.length() == 34 && authKey.substring(0, 2).equals("0x")) { + if (authKey.length() == 34 && authKey.startsWith("0x")) { srcBytes = GB.hexStringToByteArray(authKey.substring(2)); } System.arraycopy(srcBytes, 0, authKeyBytes, 0, Math.min(srcBytes.length, 16)); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiAuthService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiAuthService.java index 707964857..bc3f79f76 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiAuthService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/XiaomiAuthService.java @@ -286,7 +286,7 @@ public class XiaomiAuthService extends AbstractXiaomiService { final SharedPreferences sharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()); - final String authKey = sharedPrefs.getString("authkey", null); + final String authKey = sharedPrefs.getString("authkey", "").trim(); if (StringUtils.isNotBlank(authKey)) { final byte[] srcBytes; // Allow both with and without 0x, to avoid user mistakes