Kaynağa Gözat

Merge totp from https://github.com/akopachov/flipper-zero_authenticator

Willy-JL 1 yıl önce
ebeveyn
işleme
d63a35546f

+ 1 - 1
totp/application.fam

@@ -7,7 +7,7 @@ App(
     requires=["gui", "cli", "dialogs", "storage", "input", "notification", "bt"],
     stack_size=2 * 1024,
     order=20,
-    fap_version="5.141",
+    fap_version="5.150",
     fap_author="Alexander Kopachov (@akopachov)",
     fap_description="Software-based TOTP/HOTP authenticator for Flipper Zero device",
     fap_weburl="https://github.com/akopachov/flipper-zero_authenticator",

+ 35 - 0
totp/services/config/config.c

@@ -178,6 +178,12 @@ static bool totp_open_config_file(Storage* storage, FlipperFormat** file) {
         flipper_format_write_uint32(
             fff_data_file, TOTP_CONFIG_KEY_AUTOMATION_KB_LAYOUT, &tmp_uint32, 1);
 
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+        tmp_uint32 = 0; //-V1048
+        flipper_format_write_uint32(
+            fff_data_file, TOTP_CONFIG_KEY_AUTOMATION_BADBT_PROFILE, &tmp_uint32, 1);
+#endif
+
         tmp_uint32 = 500;
         flipper_format_write_uint32(
             fff_data_file, TOTP_CONFIG_KEY_AUTOMATION_INITIAL_DELAY, &tmp_uint32, 1);
@@ -267,6 +273,14 @@ bool totp_config_file_update_automation_method(const PluginState* plugin_state)
             break;
         }
 
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+        tmp_uint32 = plugin_state->bt_type_code_worker_profile_index;
+        if(!flipper_format_insert_or_update_uint32(
+               file, TOTP_CONFIG_KEY_AUTOMATION_BADBT_PROFILE, &tmp_uint32, 1)) {
+            break;
+        }
+#endif
+
         tmp_uint32 = plugin_state->automation_initial_delay;
         if(!flipper_format_insert_or_update_uint32(
                file, TOTP_CONFIG_KEY_AUTOMATION_INITIAL_DELAY, &tmp_uint32, 1)) {
@@ -311,6 +325,14 @@ bool totp_config_file_update_user_settings(const PluginState* plugin_state) {
             break;
         }
 
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+        tmp_uint32 = plugin_state->bt_type_code_worker_profile_index;
+        if(!flipper_format_insert_or_update_uint32(
+               file, TOTP_CONFIG_KEY_AUTOMATION_BADBT_PROFILE, &tmp_uint32, 1)) {
+            break;
+        }
+#endif
+
         tmp_uint32 = plugin_state->automation_initial_delay;
         if(!flipper_format_insert_or_update_uint32(
                file, TOTP_CONFIG_KEY_AUTOMATION_INITIAL_DELAY, &tmp_uint32, 1)) {
@@ -517,6 +539,19 @@ bool totp_config_file_load(PluginState* const plugin_state) {
             break;
         }
 
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+        if(!flipper_format_read_uint32(
+               fff_data_file, TOTP_CONFIG_KEY_AUTOMATION_BADBT_PROFILE, &tmp_uint32, 1)) {
+            tmp_uint32 = 0;
+        }
+
+        plugin_state->bt_type_code_worker_profile_index = tmp_uint32;
+
+        if(!flipper_format_rewind(fff_data_file)) {
+            break;
+        }
+#endif
+
         if(!flipper_format_read_uint32(
                fff_data_file, TOTP_CONFIG_KEY_AUTOMATION_INITIAL_DELAY, &tmp_uint32, 1)) {
             tmp_uint32 = 500;

+ 5 - 1
totp/services/config/constants.h

@@ -1,10 +1,11 @@
 #pragma once
 
 #include <storage/storage.h>
+#include "../../config/app/config.h"
 
 #define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("apps_data/totp")
 #define CONFIG_FILE_HEADER "Flipper TOTP plugin config file"
-#define CONFIG_FILE_ACTUAL_VERSION (12)
+#define CONFIG_FILE_ACTUAL_VERSION (13)
 
 #define TOTP_CONFIG_KEY_TIMEZONE "Timezone"
 #define TOTP_CONFIG_KEY_TOKEN_NAME "TokenName"
@@ -20,6 +21,9 @@
 #define TOTP_CONFIG_KEY_PINSET "PinIsSet"
 #define TOTP_CONFIG_KEY_NOTIFICATION_METHOD "NotificationMethod"
 #define TOTP_CONFIG_KEY_AUTOMATION_METHOD "AutomationMethod"
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+#define TOTP_CONFIG_KEY_AUTOMATION_BADBT_PROFILE "BadBTProfile"
+#endif
 #define TOTP_CONFIG_KEY_AUTOMATION_KB_LAYOUT "AutomationKbLayout"
 #define TOTP_CONFIG_KEY_AUTOMATION_INITIAL_DELAY "AutomationInitialDelay"
 #define TOTP_CONFIG_KEY_FONT "Font"

+ 16 - 0
totp/services/config/migrations/common_migration.c

@@ -109,6 +109,22 @@ bool totp_config_migrate_to_latest(
 
         flipper_format_rewind(fff_backup_data_file);
 
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+        uint32_t bt_profile_index;
+        if(!flipper_format_read_uint32(
+               fff_backup_data_file,
+               TOTP_CONFIG_KEY_AUTOMATION_BADBT_PROFILE,
+               &bt_profile_index,
+               1)) {
+            bt_profile_index = 0;
+        }
+
+        flipper_format_write_uint32(
+            fff_data_file, TOTP_CONFIG_KEY_AUTOMATION_BADBT_PROFILE, &bt_profile_index, 1);
+
+        flipper_format_rewind(fff_backup_data_file);
+#endif
+
         if(flipper_format_read_string(
                fff_backup_data_file, TOTP_CONFIG_KEY_AUTOMATION_INITIAL_DELAY, temp_str)) {
             flipper_format_write_string(

+ 2 - 1
totp/totp_app.c

@@ -167,7 +167,8 @@ static bool totp_plugin_state_init(PluginState* const plugin_state) {
 #ifdef TOTP_BADBT_AUTOMATION_ENABLED
     if(plugin_state->automation_method & AutomationMethodBadBt) {
         plugin_state->bt_type_code_worker_context = totp_bt_type_code_worker_init(
-            *((uint16_t*)plugin_state->crypto_settings.crypto_verify_data));
+            *((uint16_t*)plugin_state->crypto_settings.crypto_verify_data),
+            plugin_state->bt_type_code_worker_profile_index);
     } else {
         plugin_state->bt_type_code_worker_context = NULL;
     }

+ 5 - 0
totp/types/plugin_state.h

@@ -74,6 +74,11 @@ typedef struct {
      * @brief Bad-Bluetooth worker context
      */
     TotpBtTypeCodeWorkerContext* bt_type_code_worker_context;
+
+    /**
+     * @brief Bad-Bluetooth profile index.
+     */
+    uint8_t bt_type_code_worker_profile_index;
 #endif
 
     /**

+ 92 - 17
totp/ui/scenes/app_settings/totp_app_settings.c

@@ -41,6 +41,7 @@ typedef enum {
     AutomationSwitch,
     BadKeyboardLayoutSelect,
     AutomationDelaySelect,
+    BadBtProfileSelect,
     ConfirmButton
 } Control;
 
@@ -59,6 +60,9 @@ typedef struct {
     FontInfo* active_font;
     uint8_t total_fonts_count;
     uint16_t automation_initial_delay;
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+    uint8_t badbt_profile_index;
+#endif
     char automation_initial_delay_formatted[10];
 } SceneState;
 
@@ -109,6 +113,9 @@ void totp_scene_app_settings_activate(PluginState* plugin_state) {
         MIN(plugin_state->automation_kb_layout, scene_state->automation_kb_layout_count - 1);
 
     scene_state->automation_initial_delay = plugin_state->automation_initial_delay;
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+    scene_state->badbt_profile_index = plugin_state->bt_type_code_worker_profile_index;
+#endif
     scene_state->total_fonts_count = totp_font_provider_get_fonts_count();
     scene_state->active_font_index = plugin_state->active_font_index;
     scene_state->active_font = totp_font_info_alloc();
@@ -207,7 +214,7 @@ void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plu
 
         int group_offset = 0;
 
-        if(scene_state->selected_control <= AutomationSwitch) {
+        if(scene_state->selected_control <= BadKeyboardLayoutSelect) {
             canvas_draw_str_aligned(
                 canvas,
                 0,
@@ -226,16 +233,30 @@ void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plu
             group_offset += 18;
         }
 
-        canvas_draw_str_aligned(
-            canvas, 0, 227 - scene_state->y_offset - group_offset, AlignLeft, AlignTop, "Layout:");
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+        if(scene_state->selected_control <= AutomationDelaySelect ||
+           (scene_state->automation_method & AutomationMethodBadBt) == 0) {
+#endif
+            canvas_draw_str_aligned(
+                canvas,
+                0,
+                227 - scene_state->y_offset - group_offset,
+                AlignLeft,
+                AlignTop,
+                "Layout:");
 
-        ui_control_select_render(
-            canvas,
-            36,
-            220 - scene_state->y_offset - group_offset,
-            SCREEN_WIDTH - 36 - UI_CONTROL_VSCROLL_WIDTH,
-            scene_state->automation_kb_layout_name,
-            scene_state->selected_control == BadKeyboardLayoutSelect);
+            ui_control_select_render(
+                canvas,
+                36,
+                220 - scene_state->y_offset - group_offset,
+                SCREEN_WIDTH - 36 - UI_CONTROL_VSCROLL_WIDTH,
+                scene_state->automation_kb_layout_name,
+                scene_state->selected_control == BadKeyboardLayoutSelect);
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+        } else if((scene_state->automation_method & AutomationMethodBadBt) != 0) {
+            group_offset += 18;
+        }
+#endif
 
         canvas_draw_str_aligned(
             canvas, 0, 245 - scene_state->y_offset - group_offset, AlignLeft, AlignTop, "Delay:");
@@ -248,10 +269,38 @@ void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plu
             &scene_state->automation_initial_delay_formatted[0],
             scene_state->selected_control == AutomationDelaySelect);
 
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+        if((scene_state->automation_method & AutomationMethodBadBt) != 0) {
+            canvas_draw_str_aligned(
+                canvas,
+                0,
+                263 - scene_state->y_offset - group_offset,
+                AlignLeft,
+                AlignTop,
+                "BT Profile:");
+
+            char profile_index_formatted[4];
+            snprintf(profile_index_formatted, 4, "%d", scene_state->badbt_profile_index);
+
+            ui_control_select_render(
+                canvas,
+                42,
+                256 - scene_state->y_offset - group_offset,
+                SCREEN_WIDTH - 42 - UI_CONTROL_VSCROLL_WIDTH,
+                &profile_index_formatted[0],
+                scene_state->selected_control == BadBtProfileSelect);
+        }
+#endif
+
         ui_control_button_render(
             canvas,
             SCREEN_WIDTH_CENTER - 24,
-            260 - scene_state->y_offset - group_offset,
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+            ((scene_state->automation_method & AutomationMethodBadBt) == 0 ? 260 : 278)
+#else
+            260
+#endif
+                - scene_state->y_offset - group_offset,
             48,
             13,
             "Confirm",
@@ -279,6 +328,12 @@ bool totp_scene_app_settings_handle_event(
                 HoursInput,
                 ConfirmButton,
                 RollOverflowBehaviorStop);
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+            if((scene_state->automation_method & AutomationMethodBadBt) == 0 &&
+               scene_state->selected_control == BadBtProfileSelect) {
+                scene_state->selected_control--;
+            }
+#endif
             if(scene_state->selected_control > VibroSwitch) {
                 scene_state->y_offset = SCREEN_HEIGHT * 3;
             } else if(scene_state->selected_control > FontSelect) {
@@ -296,6 +351,12 @@ bool totp_scene_app_settings_handle_event(
                 HoursInput,
                 ConfirmButton,
                 RollOverflowBehaviorStop);
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+            if((scene_state->automation_method & AutomationMethodBadBt) == 0 &&
+               scene_state->selected_control == BadBtProfileSelect) {
+                scene_state->selected_control++;
+            }
+#endif
             if(scene_state->selected_control > VibroSwitch) {
                 scene_state->y_offset = SCREEN_HEIGHT * 3;
             } else if(scene_state->selected_control > FontSelect) {
@@ -350,6 +411,12 @@ bool totp_scene_app_settings_handle_event(
                     RollOverflowBehaviorStop);
                 update_formatted_automation_initial_delay(scene_state);
             }
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+            else if(scene_state->selected_control == BadBtProfileSelect) {
+                totp_roll_value_uint8_t(
+                    &scene_state->badbt_profile_index, 1, 0, UINT8_MAX, RollOverflowBehaviorRoll);
+            }
+#endif
             break;
         case InputKeyLeft:
             if(scene_state->selected_control == HoursInput) {
@@ -395,6 +462,12 @@ bool totp_scene_app_settings_handle_event(
                     RollOverflowBehaviorStop);
                 update_formatted_automation_initial_delay(scene_state);
             }
+#ifdef TOTP_BADBT_AUTOMATION_ENABLED
+            else if(scene_state->selected_control == BadBtProfileSelect) {
+                totp_roll_value_uint8_t(
+                    &scene_state->badbt_profile_index, -1, 0, UINT8_MAX, RollOverflowBehaviorRoll);
+            }
+#endif
             break;
         case InputKeyOk:
             if(scene_state->selected_control == ConfirmButton) {
@@ -412,18 +485,20 @@ bool totp_scene_app_settings_handle_event(
                 plugin_state->automation_kb_layout = scene_state->automation_kb_layout;
                 plugin_state->automation_initial_delay = scene_state->automation_initial_delay;
 
-                if(!totp_config_file_update_user_settings(plugin_state)) {
-                    totp_dialogs_config_updating_error(plugin_state);
-                    return false;
-                }
-
 #ifdef TOTP_BADBT_AUTOMATION_ENABLED
-                if((scene_state->automation_method & AutomationMethodBadBt) == 0 &&
+                if(((scene_state->automation_method & AutomationMethodBadBt) == 0 ||
+                    plugin_state->bt_type_code_worker_profile_index !=
+                        scene_state->badbt_profile_index) &&
                    plugin_state->bt_type_code_worker_context != NULL) {
                     totp_bt_type_code_worker_free(plugin_state->bt_type_code_worker_context);
                     plugin_state->bt_type_code_worker_context = NULL;
                 }
+                plugin_state->bt_type_code_worker_profile_index = scene_state->badbt_profile_index;
 #endif
+                if(!totp_config_file_update_user_settings(plugin_state)) {
+                    totp_dialogs_config_updating_error(plugin_state);
+                    return false;
+                }
 
                 totp_scene_director_activate_scene(plugin_state, TotpSceneTokenMenu);
             }

+ 2 - 1
totp/ui/scenes/generate_token/totp_scene_generate_token.c

@@ -204,7 +204,8 @@ void totp_scene_generate_token_activate(PluginState* plugin_state) {
     if(plugin_state->automation_method & AutomationMethodBadBt) {
         if(plugin_state->bt_type_code_worker_context == NULL) {
             plugin_state->bt_type_code_worker_context = totp_bt_type_code_worker_init(
-                *((uint16_t*)plugin_state->crypto_settings.crypto_verify_data));
+                *((uint16_t*)plugin_state->crypto_settings.crypto_verify_data),
+                plugin_state->bt_type_code_worker_profile_index);
         }
         totp_bt_type_code_worker_start(
             plugin_state->bt_type_code_worker_context,

+ 2 - 2
totp/version.h

@@ -1,5 +1,5 @@
 #pragma once
 
 #define TOTP_APP_VERSION_MAJOR (5)
-#define TOTP_APP_VERSION_MINOR (14)
-#define TOTP_APP_VERSION_PATCH (1)
+#define TOTP_APP_VERSION_MINOR (15)
+#define TOTP_APP_VERSION_PATCH (0)

+ 17 - 4
totp/workers/bt_type_code/bt_type_code.c

@@ -14,7 +14,7 @@
 #include "../../config/app/config.h"
 #include "../../services/config/constants.h"
 
-#define HID_BT_KEYS_STORAGE_PATH CONFIG_FILE_DIRECTORY_PATH "/.bt_hid.keys"
+#define HID_BT_KEYS_STORAGE_PATH_FORMAT CONFIG_FILE_DIRECTORY_PATH "/.bt_hid_%2X.keys"
 
 struct TotpBtTypeCodeWorkerContext {
     char* code_buffer;
@@ -141,7 +141,8 @@ void totp_bt_type_code_worker_notify(
     furi_thread_flags_set(furi_thread_get_id(context->thread), event);
 }
 
-TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init(uint16_t mac_xor) {
+TotpBtTypeCodeWorkerContext*
+    totp_bt_type_code_worker_init(uint16_t mac_xor, uint8_t profile_index) {
     TotpBtTypeCodeWorkerContext* context = malloc(sizeof(TotpBtTypeCodeWorkerContext));
     furi_check(context != NULL);
 
@@ -150,9 +151,21 @@ TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init(uint16_t mac_xor) {
     context->is_connected = false;
     bt_disconnect(context->bt);
     furi_delay_ms(200);
-    bt_keys_storage_set_storage_path(context->bt, HID_BT_KEYS_STORAGE_PATH);
 
-    BleProfileHidParams ble_params = {.device_name_prefix = "TOTP", .mac_xor = mac_xor};
+    char keys_storage_path[sizeof(HID_BT_KEYS_STORAGE_PATH_FORMAT)];
+    snprintf(
+        keys_storage_path,
+        sizeof(keys_storage_path),
+        HID_BT_KEYS_STORAGE_PATH_FORMAT,
+        profile_index);
+    bt_keys_storage_set_storage_path(context->bt, &keys_storage_path[0]);
+
+    uint16_t final_mac_xor = (mac_xor & 0xFF80) + profile_index;
+    char* device_prefix = "TOTP-00";
+    snprintf(&device_prefix[5], 3, "%02X", profile_index);
+
+    BleProfileHidParams ble_params = {
+        .device_name_prefix = device_prefix, .mac_xor = final_mac_xor};
     context->ble_hid_profile = bt_profile_start(context->bt, ble_profile_hid, &ble_params);
     furi_check(context->ble_hid_profile);
 

+ 3 - 1
totp/workers/bt_type_code/bt_type_code.h

@@ -37,9 +37,11 @@ enum TotpBtTypeCodeWorkerEvents {
 /**
  * @brief Initializes bluetooth token input automation worker
  * @param mac_xor value to be used to XOR BT MAC address to make it unique
+ * @param profile_index profile index to be used
  * @return worker context
  */
-TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init(uint16_t mac_xor);
+TotpBtTypeCodeWorkerContext*
+    totp_bt_type_code_worker_init(uint16_t mac_xor, uint8_t profile_index);
 
 /**
  * @brief Disposes bluetooth token input automation worker and releases all the allocated resources