Просмотр исходного кода

Implemented PIN changing via CLI (#32)

Alexander Kopachov 3 лет назад
Родитель
Сommit
fea22d719a
58 измененных файлов с 372 добавлено и 175 удалено
  1. 18 1
      application.fam
  2. 4 0
      cli/cli.c
  3. 1 1
      cli/cli.h
  4. 0 0
      cli/cli_helpers.c
  5. 1 1
      cli/cli_helpers.h
  6. 5 5
      cli/commands/add/add.c
  7. 1 1
      cli/commands/add/add.h
  8. 3 3
      cli/commands/delete/delete.c
  9. 1 1
      cli/commands/delete/delete.h
  10. 3 0
      cli/commands/help/help.c
  11. 0 0
      cli/commands/help/help.h
  12. 3 3
      cli/commands/list/list.c
  13. 1 1
      cli/commands/list/list.h
  14. 4 4
      cli/commands/move/move.c
  15. 1 1
      cli/commands/move/move.h
  16. 166 0
      cli/commands/pin/pin.c
  17. 10 0
      cli/commands/pin/pin.h
  18. 2 2
      cli/commands/timezone/timezone.c
  19. 1 1
      cli/commands/timezone/timezone.h
  20. 0 0
      lib/base32/base32.c
  21. 0 0
      lib/base32/base32.h
  22. 0 0
      lib/list/list.c
  23. 0 0
      lib/list/list.h
  24. 0 0
      lib/polyfills/memset_s.c
  25. 0 0
      lib/polyfills/memset_s.h
  26. 11 0
      lib/polyfills/strnlen.c
  27. 3 0
      lib/polyfills/strnlen.h
  28. 0 0
      lib/roll_value/roll_value.c
  29. 0 0
      lib/roll_value/roll_value.h
  30. 0 0
      lib/timezone_utils/timezone_utils.c
  31. 0 0
      lib/timezone_utils/timezone_utils.h
  32. 0 23
      services/hid_worker/hid_worker.h
  33. 1 1
      services/totp/totp.c
  34. 3 5
      totp_app.c
  35. 0 0
      types/nullable.h
  36. 2 2
      types/plugin_state.h
  37. 2 2
      types/token_info.c
  38. 8 0
      types/user_pin_codes.h
  39. 0 0
      ui/constants.h
  40. 5 5
      ui/scene_director.c
  41. 0 0
      ui/scene_director.h
  42. 1 11
      ui/scenes/add_new_token/totp_input_text.c
  43. 2 4
      ui/scenes/add_new_token/totp_input_text.h
  44. 9 10
      ui/scenes/add_new_token/totp_scene_add_new_token.c
  45. 2 2
      ui/scenes/add_new_token/totp_scene_add_new_token.h
  46. 7 6
      ui/scenes/app_settings/totp_app_settings.c
  47. 2 4
      ui/scenes/app_settings/totp_app_settings.h
  48. 12 15
      ui/scenes/authenticate/totp_scene_authenticate.c
  49. 2 4
      ui/scenes/authenticate/totp_scene_authenticate.h
  50. 19 19
      ui/scenes/generate_token/totp_scene_generate_token.c
  51. 2 4
      ui/scenes/generate_token/totp_scene_generate_token.h
  52. 8 8
      ui/scenes/token_menu/totp_scene_token_menu.c
  53. 2 4
      ui/scenes/token_menu/totp_scene_token_menu.h
  54. 0 0
      ui/totp_scenes_enum.h
  55. 0 0
      ui/ui_controls.c
  56. 0 0
      ui/ui_controls.h
  57. 21 21
      workers/type_code/type_code.c
  58. 23 0
      workers/type_code/type_code.h

+ 18 - 1
application.fam

@@ -16,5 +16,22 @@ App(
     order=20,
     fap_category="Misc",
     fap_icon_assets="images",
-    fap_icon="totp_10px.png"
+    fap_icon="totp_10px.png",
+    fap_private_libs=[
+        Lib(
+            name="base32",
+        ),
+        Lib(
+            name="list",
+        ),
+        Lib(
+            name="timezone_utils",
+        ),
+        Lib(
+            name="polyfills",
+        ),
+        Lib(
+            name="roll_value",
+        ),
+    ],
 )

+ 4 - 0
services/cli/cli.c → cli/cli.c

@@ -9,6 +9,7 @@
 #include "commands/timezone/timezone.h"
 #include "commands/help/help.h"
 #include "commands/move/move.h"
+#include "commands/pin/pin.h"
 
 static void totp_cli_print_unknown_command(const FuriString* unknown_command) {
     TOTP_CLI_PRINTF(
@@ -49,6 +50,9 @@ static void totp_cli_handler(Cli* cli, FuriString* args, void* context) {
         furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_MOVE) == 0 ||
         furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_MOVE_ALT) == 0) {
         totp_cli_command_move_handle(plugin_state, args, cli);
+    } else if(
+        furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_PIN) == 0) {
+        totp_cli_command_pin_handle(plugin_state, args, cli);
     } else {
         totp_cli_print_unknown_command(cmd);
     }

+ 1 - 1
services/cli/cli.h → cli/cli.h

@@ -1,7 +1,7 @@
 #pragma once
 
 #include <cli/cli.h>
-#include "../../types/plugin_state.h"
+#include "../types/plugin_state.h"
 
 void totp_cli_register_command_handler(PluginState* plugin_state);
 void totp_cli_unregister_command_handler();

+ 0 - 0
services/cli/cli_helpers.c → cli/cli_helpers.c


+ 1 - 1
services/cli/cli_helpers.h → cli/cli_helpers.h

@@ -1,7 +1,7 @@
 #pragma once
 
 #include <cli/cli.h>
-#include "../../types/plugin_state.h"
+#include "../types/plugin_state.h"
 
 #define TOTP_CLI_COMMAND_NAME "totp"
 

+ 5 - 5
services/cli/commands/add/add.c → cli/commands/add/add.c

@@ -1,11 +1,11 @@
 #include "add.h"
 #include <stdlib.h>
 #include <lib/toolbox/args.h>
-#include "../../../list/list.h"
-#include "../../../../types/token_info.h"
-#include "../../../config/config.h"
+#include "../../../lib/list/list.h"
+#include "../../../types/token_info.h"
+#include "../../../services/config/config.h"
 #include "../../cli_helpers.h"
-#include "../../../../scenes/scene_director.h"
+#include "../../../ui/scene_director.h"
 
 #define TOTP_CLI_COMMAND_ADD_ARG_NAME "name"
 #define TOTP_CLI_COMMAND_ADD_ARG_ALGO "algo"
@@ -94,7 +94,7 @@ static bool totp_cli_read_secret(Cli* cli, FuriString* out_str, bool mask_user_i
     while(cli_read(cli, &c, 1) == 1) {
         if(c == CliSymbolAsciiEsc) {
             // Some keys generating escape-sequences
-            // We need to ignore them as we case about alpha-numerics only
+            // We need to ignore them as we care about alpha-numerics only
             uint8_t c2;
             cli_read_timeout(cli, &c2, 1, 0);
             cli_read_timeout(cli, &c2, 1, 0);

+ 1 - 1
services/cli/commands/add/add.h → cli/commands/add/add.h

@@ -1,7 +1,7 @@
 #pragma once
 
 #include <cli/cli.h>
-#include "../../../../types/plugin_state.h"
+#include "../../../types/plugin_state.h"
 
 #define TOTP_CLI_COMMAND_ADD "add"
 #define TOTP_CLI_COMMAND_ADD_ALT "mk"

+ 3 - 3
services/cli/commands/delete/delete.c → cli/commands/delete/delete.c

@@ -3,10 +3,10 @@
 #include <stdlib.h>
 #include <ctype.h>
 #include <lib/toolbox/args.h>
-#include "../../../list/list.h"
-#include "../../../config/config.h"
+#include "../../../lib/list/list.h"
+#include "../../../services/config/config.h"
 #include "../../cli_helpers.h"
-#include "../../../../scenes/scene_director.h"
+#include "../../../ui/scene_director.h"
 
 #define TOTP_CLI_COMMAND_DELETE_ARG_INDEX "index"
 #define TOTP_CLI_COMMAND_DELETE_ARG_FORCE_SUFFIX "-f"

+ 1 - 1
services/cli/commands/delete/delete.h → cli/commands/delete/delete.h

@@ -1,7 +1,7 @@
 #pragma once
 
 #include <cli/cli.h>
-#include "../../../../types/plugin_state.h"
+#include "../../../types/plugin_state.h"
 
 #define TOTP_CLI_COMMAND_DELETE "delete"
 #define TOTP_CLI_COMMAND_DELETE_ALT "rm"

+ 3 - 0
services/cli/commands/help/help.c → cli/commands/help/help.c

@@ -5,6 +5,7 @@
 #include "../list/list.h"
 #include "../timezone/timezone.h"
 #include "../move/move.h"
+#include "../pin/pin.h"
 
 void totp_cli_command_help_docopt_commands() {
     TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_HELP ", " TOTP_CLI_COMMAND_HELP_ALT
@@ -25,6 +26,7 @@ void totp_cli_command_help_handle() {
     totp_cli_command_delete_docopt_usage();
     totp_cli_command_timezone_docopt_usage();
     totp_cli_command_move_docopt_usage();
+    totp_cli_command_pin_docopt_usage();
     cli_nl();
     TOTP_CLI_PRINTF("Commands:\r\n");
     totp_cli_command_help_docopt_commands();
@@ -33,6 +35,7 @@ void totp_cli_command_help_handle() {
     totp_cli_command_delete_docopt_commands();
     totp_cli_command_timezone_docopt_commands();
     totp_cli_command_move_docopt_commands();
+    totp_cli_command_pin_docopt_commands();
     cli_nl();
     TOTP_CLI_PRINTF("Arguments:\r\n");
     totp_cli_command_add_docopt_arguments();

+ 0 - 0
services/cli/commands/help/help.h → cli/commands/help/help.h


+ 3 - 3
services/cli/commands/list/list.c → cli/commands/list/list.c

@@ -1,8 +1,8 @@
 #include "list.h"
 #include <stdlib.h>
-#include "../../../list/list.h"
-#include "../../../../types/token_info.h"
-#include "../../../config/constants.h"
+#include "../../../lib/list/list.h"
+#include "../../../types/token_info.h"
+#include "../../../services/config/constants.h"
 #include "../../cli_helpers.h"
 
 static char* get_algo_as_cstr(TokenHashAlgo algo) {

+ 1 - 1
services/cli/commands/list/list.h → cli/commands/list/list.h

@@ -1,7 +1,7 @@
 #pragma once
 
 #include <cli/cli.h>
-#include "../../../../types/plugin_state.h"
+#include "../../../types/plugin_state.h"
 
 #define TOTP_CLI_COMMAND_LIST "list"
 #define TOTP_CLI_COMMAND_LIST_ALT "ls"

+ 4 - 4
services/cli/commands/move/move.c → cli/commands/move/move.c

@@ -2,11 +2,11 @@
 
 #include <stdlib.h>
 #include <lib/toolbox/args.h>
-#include "../../../list/list.h"
-#include "../../../../types/token_info.h"
-#include "../../../config/config.h"
+#include "../../../lib/list/list.h"
+#include "../../../types/token_info.h"
+#include "../../../services/config/config.h"
 #include "../../cli_helpers.h"
-#include "../../../../scenes/scene_director.h"
+#include "../../../ui/scene_director.h"
 
 #define TOTP_CLI_COMMAND_MOVE_ARG_INDEX "index"
 

+ 1 - 1
services/cli/commands/move/move.h → cli/commands/move/move.h

@@ -1,7 +1,7 @@
 #pragma once
 
 #include <cli/cli.h>
-#include "../../../../types/plugin_state.h"
+#include "../../../types/plugin_state.h"
 
 #define TOTP_CLI_COMMAND_MOVE "move"
 #define TOTP_CLI_COMMAND_MOVE_ALT "mv"

+ 166 - 0
cli/commands/pin/pin.c

@@ -0,0 +1,166 @@
+#include "pin.h"
+
+#include <stdlib.h>
+#include <lib/toolbox/args.h>
+#include "../../../types/token_info.h"
+#include "../../../types/user_pin_codes.h"
+#include "../../../services/config/config.h"
+#include "../../cli_helpers.h"
+#include "../../../lib/polyfills/memset_s.h"
+#include "../../../services/crypto/crypto.h"
+#include "../../../ui/scene_director.h"
+
+#define TOTP_CLI_COMMAND_PIN_COMMAND_SET "set"
+#define TOTP_CLI_COMMAND_PIN_COMMAND_REMOVE "remove"
+
+void totp_cli_command_pin_docopt_commands() {
+    TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_PIN "              Set\\change\\remove PIN\r\n");
+}
+
+void totp_cli_command_pin_docopt_usage() {
+    TOTP_CLI_PRINTF("  " TOTP_CLI_COMMAND_NAME " " TOTP_CLI_COMMAND_PIN " " DOCOPT_REQUIRED(TOTP_CLI_COMMAND_PIN_COMMAND_SET " | " TOTP_CLI_COMMAND_PIN_COMMAND_REMOVE) "\r\n");
+}
+
+static bool totp_cli_read_pin(Cli* cli, uint8_t* pin, uint8_t* pin_length) {
+    TOTP_CLI_PRINTF("Enter new PIN (use arrow keys on your keyboard): ");
+    fflush(stdout);
+    uint8_t c;
+    *pin_length = 0;
+    while(cli_read(cli, &c, 1) == 1) {
+        if(c == CliSymbolAsciiEsc) {
+            uint8_t c2;
+            uint8_t c3;
+            if (cli_read_timeout(cli, &c2, 1, 0) == 1 &&
+                cli_read_timeout(cli, &c3, 1, 0) == 1 &&
+                c2 == 0x5b) {
+                uint8_t code = 0;
+                switch (c3) {
+                    case 0x44: // left
+                        code = PinCodeArrowLeft;
+                        break;
+                    case 0x41: // up
+                        code = PinCodeArrowUp;
+                        break;
+                    case 0x43: // right
+                        code = PinCodeArrowRight;
+                        break;
+                    case 0x42: // down
+                        code = PinCodeArrowDown;
+                        break;
+                    default:
+                    break;
+                }
+
+                if (code > 0) {
+                    pin[*pin_length] = code;
+                    *pin_length = *pin_length + 1;
+                    putc('*', stdout);
+                    fflush(stdout);
+                }
+            }
+        } else if(c == CliSymbolAsciiETX) {
+            TOTP_CLI_DELETE_CURRENT_LINE();
+            TOTP_CLI_PRINTF("Cancelled by user\r\n");
+            return false;
+        } else if(c == CliSymbolAsciiBackspace || c == CliSymbolAsciiDel) {
+            if (*pin_length > 0) {
+                *pin_length = *pin_length - 1;
+                pin[*pin_length] = 0;
+                TOTP_CLI_DELETE_LAST_CHAR();
+            }
+        } else if(c == CliSymbolAsciiCR) {
+            cli_nl();
+            break;
+        }
+    }
+
+    TOTP_CLI_DELETE_LAST_LINE();
+    return true;
+}
+
+void totp_cli_command_pin_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
+    UNUSED(plugin_state);
+    FuriString* temp_str = furi_string_alloc();
+
+    bool do_change = false;
+    bool do_remove = false;
+    UNUSED(do_remove);
+    do {
+        if (!args_read_string_and_trim(args, temp_str)) {
+            TOTP_CLI_PRINT_INVALID_ARGUMENTS();
+            break;
+        }
+
+        if (furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_PIN_COMMAND_SET) == 0) {
+            do_change = true;
+        } else if (furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_PIN_COMMAND_REMOVE) == 0) {
+            do_remove = true;
+        } else {
+            TOTP_CLI_PRINT_INVALID_ARGUMENTS();
+            break;
+        }
+    } while (false);
+
+    if ((do_change || do_remove) && totp_cli_ensure_authenticated(plugin_state, cli)) {
+        bool load_generate_token_scene = false;
+        do {
+            uint8_t old_iv[TOTP_IV_SIZE];
+            memcpy(&old_iv[0], &plugin_state->iv[0], TOTP_IV_SIZE);
+            uint8_t new_pin[TOTP_IV_SIZE];
+            uint8_t new_pin_length = 0;
+            if (do_change) {
+                if (!totp_cli_read_pin(cli, &new_pin[0], &new_pin_length) ||
+                    !totp_cli_ensure_authenticated(plugin_state, cli)) {
+                    memset_s(&new_pin[0], TOTP_IV_SIZE, 0, TOTP_IV_SIZE);
+                    break;
+                }
+            } else if (do_remove) {
+                new_pin_length = 0;
+                memset(&new_pin[0], 0, TOTP_IV_SIZE);
+            }
+
+            if(plugin_state->current_scene == TotpSceneGenerateToken) {
+                totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
+                load_generate_token_scene = true;
+            }
+
+            TOTP_CLI_PRINTF("Encrypting, please wait...\r\n");
+
+            memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE);
+            memset(&plugin_state->base_iv[0], 0, TOTP_IV_SIZE);
+            if (plugin_state->crypto_verify_data != NULL) {
+                free(plugin_state->crypto_verify_data);
+                plugin_state->crypto_verify_data = NULL;
+            }
+
+            totp_crypto_seed_iv(plugin_state, new_pin_length > 0 ? &new_pin[0] : NULL, new_pin_length);
+            ListNode* node = plugin_state->tokens_list;
+            while (node != NULL) {
+                TokenInfo* token_info = node->data;
+                size_t plain_token_length; 
+                uint8_t* plain_token = totp_crypto_decrypt(token_info->token, token_info->token_length, &old_iv[0], &plain_token_length);
+                free(token_info->token);
+                token_info->token = totp_crypto_encrypt(plain_token, plain_token_length, &plugin_state->iv[0], &token_info->token_length);
+                memset_s(plain_token, plain_token_length, 0, plain_token_length);
+                free(plain_token);
+                node = node->next;
+            }
+
+            totp_full_save_config_file(plugin_state);
+
+            TOTP_CLI_DELETE_LAST_LINE();
+
+            if (do_change) {
+                TOTP_CLI_PRINTF("PIN has been successfully changed\r\n");
+            } else if (do_remove) {
+                TOTP_CLI_PRINTF("PIN has been successfully removed\r\n");
+            }
+        } while (false);
+
+        if(load_generate_token_scene) {
+            totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
+        }
+    }
+
+    furi_string_free(temp_str);
+}

+ 10 - 0
cli/commands/pin/pin.h

@@ -0,0 +1,10 @@
+#pragma once
+
+#include <cli/cli.h>
+#include "../../../types/plugin_state.h"
+
+#define TOTP_CLI_COMMAND_PIN "pin"
+
+void totp_cli_command_pin_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
+void totp_cli_command_pin_docopt_commands();
+void totp_cli_command_pin_docopt_usage();

+ 2 - 2
services/cli/commands/timezone/timezone.c → cli/commands/timezone/timezone.c

@@ -1,7 +1,7 @@
 #include "timezone.h"
 #include <lib/toolbox/args.h>
-#include "../../../config/config.h"
-#include "../../../../scenes/scene_director.h"
+#include "../../../services/config/config.h"
+#include "../../../ui/scene_director.h"
 #include "../../cli_helpers.h"
 
 #define TOTP_CLI_COMMAND_TIMEZONE_ARG_TIMEZONE "timezone"

+ 1 - 1
services/cli/commands/timezone/timezone.h → cli/commands/timezone/timezone.h

@@ -1,7 +1,7 @@
 #pragma once
 
 #include <cli/cli.h>
-#include "../../../../types/plugin_state.h"
+#include "../../../types/plugin_state.h"
 
 #define TOTP_CLI_COMMAND_TIMEZONE "timezone"
 #define TOTP_CLI_COMMAND_TIMEZONE_ALT "tz"

+ 0 - 0
services/base32/base32.c → lib/base32/base32.c


+ 0 - 0
services/base32/base32.h → lib/base32/base32.h


+ 0 - 0
services/list/list.c → lib/list/list.c


+ 0 - 0
services/list/list.h → lib/list/list.h


+ 0 - 0
services/crypto/memset_s.c → lib/polyfills/memset_s.c


+ 0 - 0
services/crypto/memset_s.h → lib/polyfills/memset_s.h


+ 11 - 0
lib/polyfills/strnlen.c

@@ -0,0 +1,11 @@
+#include "strnlen.h"
+
+size_t strnlen(const char* s, size_t maxlen) {
+    size_t len;
+
+    for(len = 0; len < maxlen; len++, s++) {
+        if(!*s) break;
+    }
+
+    return len;
+}

+ 3 - 0
lib/polyfills/strnlen.h

@@ -0,0 +1,3 @@
+#include <stddef.h>
+
+size_t strnlen(const char* s, size_t maxlen);

+ 0 - 0
services/roll_value/roll_value.c → lib/roll_value/roll_value.c


+ 0 - 0
services/roll_value/roll_value.h → lib/roll_value/roll_value.h


+ 0 - 0
services/timezone_utils/timezone_utils.c → lib/timezone_utils/timezone_utils.c


+ 0 - 0
services/timezone_utils/timezone_utils.h → lib/timezone_utils/timezone_utils.h


+ 0 - 23
services/hid_worker/hid_worker.h

@@ -1,23 +0,0 @@
-#pragma once
-
-#include <stdlib.h>
-#include <furi/furi.h>
-#include <furi_hal.h>
-
-typedef struct {
-    char* string;
-    uint8_t string_length;
-    FuriThread* thread;
-    FuriMutex* string_sync;
-    FuriHalUsbInterface* usb_mode_prev;
-} TotpHidWorkerTypeContext;
-
-typedef enum {
-    TotpHidWorkerEvtReserved = (1 << 0),
-    TotpHidWorkerEvtStop = (1 << 1),
-    TotpHidWorkerEvtType = (1 << 2)
-} TotpHidWorkerEvtFlags;
-
-TotpHidWorkerTypeContext* totp_hid_worker_start();
-void totp_hid_worker_stop(TotpHidWorkerTypeContext* context);
-void totp_hid_worker_notify(TotpHidWorkerTypeContext* context, TotpHidWorkerEvtFlags event);

+ 1 - 1
services/totp/totp.c

@@ -9,7 +9,7 @@
 #include "../hmac/hmac_sha256.h"
 #include "../hmac/hmac_sha512.h"
 #include "../hmac/byteswap.h"
-#include "../timezone_utils/timezone_utils.h"
+#include "../../lib/timezone_utils/timezone_utils.h"
 
 #define HMAC_MAX_SIZE 64
 

+ 3 - 5
totp_app.c

@@ -7,18 +7,16 @@
 #include <flipper_format/flipper_format.h>
 #include <notification/notification.h>
 #include <notification/notification_messages.h>
-#include "services/base32/base32.h"
-#include "services/list/list.h"
 #include "services/config/config.h"
 #include "types/plugin_state.h"
 #include "types/token_info.h"
 #include "types/plugin_event.h"
 #include "types/event_type.h"
 #include "types/common.h"
-#include "scenes/scene_director.h"
-#include "services/ui/constants.h"
+#include "ui/scene_director.h"
+#include "ui/constants.h"
 #include "services/crypto/crypto.h"
-#include "services/cli/cli.h"
+#include "cli/cli.h"
 
 #define IDLE_TIMEOUT 60000
 

+ 0 - 0
services/nullable/nullable.h → types/nullable.h


+ 2 - 2
types/plugin_state.h

@@ -3,8 +3,8 @@
 #include <notification/notification.h>
 #include <gui/gui.h>
 #include <dialogs/dialogs.h>
-#include "../services/list/list.h"
-#include "../scenes/totp_scenes_enum.h"
+#include "../lib/list/list.h"
+#include "../ui/totp_scenes_enum.h"
 
 #define TOTP_IV_SIZE 16
 

+ 2 - 2
types/token_info.c

@@ -3,9 +3,9 @@
 #include "token_info.h"
 #include "stdlib.h"
 #include "common.h"
-#include "../services/base32/base32.h"
+#include "../lib/base32/base32.h"
 #include "../services/crypto/crypto.h"
-#include "../services/crypto/memset_s.h"
+#include "../lib/polyfills/memset_s.h"
 
 TokenInfo* token_info_alloc() {
     TokenInfo* tokenInfo = malloc(sizeof(TokenInfo));

+ 8 - 0
types/user_pin_codes.h

@@ -0,0 +1,8 @@
+#pragma once
+
+typedef enum uint8_t {
+    PinCodeArrowUp = 2,
+    PinCodeArrowRight = 8,
+    PinCodeArrowDown = 11,
+    PinCodeArrowLeft = 5
+} TotpUserPinCode;

+ 0 - 0
services/ui/constants.h → ui/constants.h


+ 5 - 5
scenes/scene_director.c → ui/scene_director.c

@@ -1,10 +1,10 @@
 #include "../types/common.h"
 #include "scene_director.h"
-#include "authenticate/totp_scene_authenticate.h"
-#include "generate_token/totp_scene_generate_token.h"
-#include "add_new_token/totp_scene_add_new_token.h"
-#include "token_menu/totp_scene_token_menu.h"
-#include "app_settings/totp_app_settings.h"
+#include "scenes/authenticate/totp_scene_authenticate.h"
+#include "scenes/generate_token/totp_scene_generate_token.h"
+#include "scenes/add_new_token/totp_scene_add_new_token.h"
+#include "scenes/token_menu/totp_scene_token_menu.h"
+#include "scenes/app_settings/totp_app_settings.h"
 
 void totp_scene_director_activate_scene(
     PluginState* const plugin_state,

+ 0 - 0
scenes/scene_director.h → ui/scene_director.h


+ 1 - 11
scenes/add_new_token/totp_input_text.c → ui/scenes/add_new_token/totp_input_text.c

@@ -1,16 +1,6 @@
 #include "totp_input_text.h"
 #include <gui/view_i.h>
-#include "../../types/common.h"
-
-size_t strnlen(const char* s, size_t maxlen) {
-    size_t len;
-
-    for(len = 0; len < maxlen; len++, s++) {
-        if(!*s) break;
-    }
-
-    return len;
-}
+#include "../../../lib/polyfills/strnlen.h"
 
 void view_draw(View* view, Canvas* canvas) {
     furi_assert(view);

+ 2 - 4
scenes/add_new_token/totp_input_text.h → ui/scenes/add_new_token/totp_input_text.h

@@ -3,10 +3,8 @@
 #include <gui/gui.h>
 #include <gui/view.h>
 #include <gui/modules/text_input.h>
-#include <furi.h>
-#include <furi_hal.h>
-#include "../../types/plugin_state.h"
-#include "../../types/plugin_event.h"
+#include "../../../types/plugin_state.h"
+#include "../../../types/plugin_event.h"
 
 typedef struct {
     char* user_input;

+ 9 - 10
scenes/add_new_token/totp_scene_add_new_token.c → ui/scenes/add_new_token/totp_scene_add_new_token.c

@@ -1,15 +1,14 @@
 #include "totp_scene_add_new_token.h"
-#include "../../types/common.h"
-#include "../../services/ui/constants.h"
-#include "../scene_director.h"
+#include "../../../types/common.h"
+#include "../../constants.h"
+#include "../../scene_director.h"
 #include "totp_input_text.h"
-#include "../../types/token_info.h"
-#include "../../services/list/list.h"
-#include "../../services/base32/base32.h"
-#include "../../services/config/config.h"
-#include "../../services/ui/ui_controls.h"
-#include "../../services/roll_value/roll_value.h"
-#include "../../services/nullable/nullable.h"
+#include "../../../types/token_info.h"
+#include "../../../lib/list/list.h"
+#include "../../../services/config/config.h"
+#include "../../ui_controls.h"
+#include "../../../lib/roll_value/roll_value.h"
+#include "../../../types/nullable.h"
 #include "../generate_token/totp_scene_generate_token.h"
 
 #define TOKEN_ALGO_LIST_LENGTH 3

+ 2 - 2
scenes/add_new_token/totp_scene_add_new_token.h → ui/scenes/add_new_token/totp_scene_add_new_token.h

@@ -3,8 +3,8 @@
 #include <gui/gui.h>
 #include <furi.h>
 #include <furi_hal.h>
-#include "../../types/plugin_state.h"
-#include "../../types/plugin_event.h"
+#include "../../../types/plugin_state.h"
+#include "../../../types/plugin_event.h"
 
 typedef struct {
     uint16_t current_token_index;

+ 7 - 6
scenes/app_settings/totp_app_settings.c → ui/scenes/app_settings/totp_app_settings.c

@@ -1,11 +1,12 @@
 #include "totp_app_settings.h"
-#include "../../services/ui/ui_controls.h"
-#include "../scene_director.h"
+#include <math.h>
+#include "../../ui_controls.h"
+#include "../../scene_director.h"
 #include "../token_menu/totp_scene_token_menu.h"
-#include "../../services/ui/constants.h"
-#include "../../services/config/config.h"
-#include "../../services/roll_value/roll_value.h"
-#include "../../services/nullable/nullable.h"
+#include "../../constants.h"
+#include "../../../services/config/config.h"
+#include "../../../lib/roll_value/roll_value.h"
+#include "../../../types/nullable.h"
 
 #define DIGIT_TO_CHAR(digit) ((digit) + '0')
 

+ 2 - 4
scenes/app_settings/totp_app_settings.h → ui/scenes/app_settings/totp_app_settings.h

@@ -1,10 +1,8 @@
 #pragma once
 
 #include <gui/gui.h>
-#include <furi.h>
-#include <furi_hal.h>
-#include "../../types/plugin_state.h"
-#include "../../types/plugin_event.h"
+#include "../../../types/plugin_state.h"
+#include "../../../types/plugin_event.h"
 
 typedef struct {
     uint16_t current_token_index;

+ 12 - 15
scenes/authenticate/totp_scene_authenticate.c → ui/scenes/authenticate/totp_scene_authenticate.c

@@ -1,21 +1,18 @@
 #include "totp_scene_authenticate.h"
 #include <dialogs/dialogs.h>
 #include <totp_icons.h>
-#include "../../types/common.h"
-#include "../../services/ui/constants.h"
-#include "../../services/config/config.h"
-#include "../scene_director.h"
-#include "../totp_scenes_enum.h"
-#include "../../services/crypto/crypto.h"
+#include "../../../types/common.h"
+#include "../../constants.h"
+#include "../../../services/config/config.h"
+#include "../../scene_director.h"
+#include "../../totp_scenes_enum.h"
+#include "../../../services/crypto/crypto.h"
+#include "../../../types/user_pin_codes.h"
 
 #define MAX_CODE_LENGTH TOTP_IV_SIZE
-#define ARROW_UP_CODE 2
-#define ARROW_RIGHT_CODE 8
-#define ARROW_DOWN_CODE 11
-#define ARROW_LEFT_CODE 5
 
 typedef struct {
-    uint8_t code_input[MAX_CODE_LENGTH];
+    TotpUserPinCode code_input[MAX_CODE_LENGTH];
     uint8_t code_length;
 } SceneState;
 
@@ -98,25 +95,25 @@ bool totp_scene_authenticate_handle_event(
     switch(event->input.key) {
     case InputKeyUp:
         if(scene_state->code_length < MAX_CODE_LENGTH) {
-            scene_state->code_input[scene_state->code_length] = ARROW_UP_CODE;
+            scene_state->code_input[scene_state->code_length] = PinCodeArrowUp;
             scene_state->code_length++;
         }
         break;
     case InputKeyDown:
         if(scene_state->code_length < MAX_CODE_LENGTH) {
-            scene_state->code_input[scene_state->code_length] = ARROW_DOWN_CODE;
+            scene_state->code_input[scene_state->code_length] = PinCodeArrowDown;
             scene_state->code_length++;
         }
         break;
     case InputKeyRight:
         if(scene_state->code_length < MAX_CODE_LENGTH) {
-            scene_state->code_input[scene_state->code_length] = ARROW_RIGHT_CODE;
+            scene_state->code_input[scene_state->code_length] = PinCodeArrowRight;
             scene_state->code_length++;
         }
         break;
     case InputKeyLeft:
         if(scene_state->code_length < MAX_CODE_LENGTH) {
-            scene_state->code_input[scene_state->code_length] = ARROW_LEFT_CODE;
+            scene_state->code_input[scene_state->code_length] = PinCodeArrowLeft;
             scene_state->code_length++;
         }
         break;

+ 2 - 4
scenes/authenticate/totp_scene_authenticate.h → ui/scenes/authenticate/totp_scene_authenticate.h

@@ -1,10 +1,8 @@
 #pragma once
 
 #include <gui/gui.h>
-#include <furi.h>
-#include <furi_hal.h>
-#include "../../types/plugin_state.h"
-#include "../../types/plugin_event.h"
+#include "../../../types/plugin_state.h"
+#include "../../../types/plugin_event.h"
 
 void totp_scene_authenticate_init(PluginState* plugin_state);
 void totp_scene_authenticate_activate(PluginState* plugin_state);

+ 19 - 19
scenes/generate_token/totp_scene_generate_token.c → ui/scenes/generate_token/totp_scene_generate_token.c

@@ -3,17 +3,17 @@
 #include <notification/notification_messages.h>
 #include <totp_icons.h>
 #include "totp_scene_generate_token.h"
-#include "../../types/token_info.h"
-#include "../../types/common.h"
-#include "../../services/ui/constants.h"
-#include "../../services/totp/totp.h"
-#include "../../services/config/config.h"
-#include "../../services/crypto/crypto.h"
-#include "../../services/crypto/memset_s.h"
-#include "../../services/roll_value/roll_value.h"
-#include "../scene_director.h"
+#include "../../../types/token_info.h"
+#include "../../../types/common.h"
+#include "../../constants.h"
+#include "../../../services/totp/totp.h"
+#include "../../../services/config/config.h"
+#include "../../../services/crypto/crypto.h"
+#include "../../../lib/polyfills/memset_s.h"
+#include "../../../lib/roll_value/roll_value.h"
+#include "../../scene_director.h"
 #include "../token_menu/totp_scene_token_menu.h"
-#include "../../services/hid_worker/hid_worker.h"
+#include "../../../workers/type_code/type_code.h"
 
 #define TOKEN_LIFETIME 30
 #define DIGIT_TO_CHAR(digit) ((digit) + '0')
@@ -24,7 +24,7 @@ typedef struct {
     char* last_code_name;
     bool need_token_update;
     uint32_t last_token_gen_time;
-    TotpHidWorkerTypeContext* hid_worker_context;
+    TotpTypeCodeWorkerContext* type_code_worker_context;
 } SceneState;
 
 static const NotificationSequence notification_sequence_new_token = {
@@ -152,9 +152,9 @@ void totp_scene_generate_token_activate(
     plugin_state->current_scene_state = scene_state;
     FURI_LOG_D(LOGGING_TAG, "Timezone set to: %f", (double)plugin_state->timezone_offset);
     update_totp_params(plugin_state);
-    scene_state->hid_worker_context = totp_hid_worker_start();
-    scene_state->hid_worker_context->string = &scene_state->last_code[0];
-    scene_state->hid_worker_context->string_length = TOTP_TOKEN_DIGITS_MAX_COUNT + 1;
+    scene_state->type_code_worker_context = totp_type_code_worker_start();
+    scene_state->type_code_worker_context->string = &scene_state->last_code[0];
+    scene_state->type_code_worker_context->string_length = TOTP_TOKEN_DIGITS_MAX_COUNT + 1;
 }
 
 void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_state) {
@@ -196,7 +196,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
                              ->data);
 
         if(tokenInfo->token != NULL && tokenInfo->token_length > 0) {
-            furi_mutex_acquire(scene_state->hid_worker_context->string_sync, FuriWaitForever);
+            furi_mutex_acquire(scene_state->type_code_worker_context->string_sync, FuriWaitForever);
             size_t key_length;
             uint8_t* key = totp_crypto_decrypt(
                 tokenInfo->token, tokenInfo->token_length, &plugin_state->iv[0], &key_length);
@@ -215,11 +215,11 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
             memset_s(key, key_length, 0, key_length);
             free(key);
         } else {
-            furi_mutex_acquire(scene_state->hid_worker_context->string_sync, FuriWaitForever);
+            furi_mutex_acquire(scene_state->type_code_worker_context->string_sync, FuriWaitForever);
             i_token_to_str(0, scene_state->last_code, tokenInfo->digits);
         }
 
-        furi_mutex_release(scene_state->hid_worker_context->string_sync);
+        furi_mutex_release(scene_state->type_code_worker_context->string_sync);
 
         if(is_new_token_time) {
             notification_message(plugin_state->notification, &notification_sequence_new_token);
@@ -288,7 +288,7 @@ bool totp_scene_generate_token_handle_event(
     SceneState* scene_state;
     if(event->input.type == InputTypeLong && event->input.key == InputKeyDown) {
         scene_state = (SceneState*)plugin_state->current_scene_state;
-        totp_hid_worker_notify(scene_state->hid_worker_context, TotpHidWorkerEvtType);
+        totp_type_code_worker_notify(scene_state->type_code_worker_context, TotpTypeCodeWorkerEvtType);
         notification_message(plugin_state->notification, &notification_sequence_badusb);
         return true;
     }
@@ -342,7 +342,7 @@ void totp_scene_generate_token_deactivate(PluginState* plugin_state) {
     if(plugin_state->current_scene_state == NULL) return;
     SceneState* scene_state = (SceneState*)plugin_state->current_scene_state;
 
-    totp_hid_worker_stop(scene_state->hid_worker_context);
+    totp_type_code_worker_stop(scene_state->type_code_worker_context);
 
     free(scene_state);
     plugin_state->current_scene_state = NULL;

+ 2 - 4
scenes/generate_token/totp_scene_generate_token.h → ui/scenes/generate_token/totp_scene_generate_token.h

@@ -1,10 +1,8 @@
 #pragma once
 
 #include <gui/gui.h>
-#include <furi.h>
-#include <furi_hal.h>
-#include "../../types/plugin_state.h"
-#include "../../types/plugin_event.h"
+#include "../../../types/plugin_state.h"
+#include "../../../types/plugin_event.h"
 
 typedef struct {
     uint16_t current_token_index;

+ 8 - 8
scenes/token_menu/totp_scene_token_menu.c → ui/scenes/token_menu/totp_scene_token_menu.c

@@ -1,17 +1,17 @@
 #include "totp_scene_token_menu.h"
 #include <gui/gui.h>
 #include <dialogs/dialogs.h>
-#include "../../services/ui/ui_controls.h"
-#include "../../services/ui/constants.h"
-#include "../scene_director.h"
-#include "../../services/config/config.h"
-#include "../../services/list/list.h"
-#include "../../types/token_info.h"
+#include "../../ui_controls.h"
+#include "../../constants.h"
+#include "../../scene_director.h"
+#include "../../../services/config/config.h"
+#include "../../../lib/list/list.h"
+#include "../../../types/token_info.h"
 #include "../generate_token/totp_scene_generate_token.h"
 #include "../add_new_token/totp_scene_add_new_token.h"
 #include "../app_settings/totp_app_settings.h"
-#include "../../services/nullable/nullable.h"
-#include "../../services/roll_value/roll_value.h"
+#include "../../../types/nullable.h"
+#include "../../../lib/roll_value/roll_value.h"
 
 #define SCREEN_HEIGHT_THIRD (SCREEN_HEIGHT / 3)
 #define SCREEN_HEIGHT_THIRD_CENTER (SCREEN_HEIGHT_THIRD >> 1)

+ 2 - 4
scenes/token_menu/totp_scene_token_menu.h → ui/scenes/token_menu/totp_scene_token_menu.h

@@ -1,10 +1,8 @@
 #pragma once
 
 #include <gui/gui.h>
-#include <furi.h>
-#include <furi_hal.h>
-#include "../../types/plugin_state.h"
-#include "../../types/plugin_event.h"
+#include "../../../types/plugin_state.h"
+#include "../../../types/plugin_event.h"
 
 typedef struct {
     uint16_t current_token_index;

+ 0 - 0
scenes/totp_scenes_enum.h → ui/totp_scenes_enum.h


+ 0 - 0
services/ui/ui_controls.c → ui/ui_controls.c


+ 0 - 0
services/ui/ui_controls.h → ui/ui_controls.h


+ 21 - 21
services/hid_worker/hid_worker.c → workers/type_code/type_code.c

@@ -1,4 +1,4 @@
-#include "hid_worker.h"
+#include "type_code.h"
 
 static const uint8_t hid_number_keys[10] = {
     HID_KEYBOARD_0,
@@ -12,18 +12,18 @@ static const uint8_t hid_number_keys[10] = {
     HID_KEYBOARD_8,
     HID_KEYBOARD_9};
 
-static void totp_hid_worker_restore_usb_mode(TotpHidWorkerTypeContext* context) {
+static void totp_type_code_worker_restore_usb_mode(TotpTypeCodeWorkerContext* context) {
     if(context->usb_mode_prev != NULL) {
         furi_hal_usb_set_config(context->usb_mode_prev, NULL);
         context->usb_mode_prev = NULL;
     }
 }
 
-static inline bool totp_hid_worker_stop_requested() {
-    return furi_thread_flags_get() & TotpHidWorkerEvtStop;
+static inline bool totp_type_code_worker_stop_requested() {
+    return furi_thread_flags_get() & TotpTypeCodeWorkerEvtStop;
 }
 
-static void totp_hid_worker_type_code(TotpHidWorkerTypeContext* context) {
+static void totp_type_code_worker_type_code(TotpTypeCodeWorkerContext* context) {
     context->usb_mode_prev = furi_hal_usb_get_config();
     furi_hal_usb_unlock();
     furi_check(furi_hal_usb_set_config(&usb_hid, NULL) == true);
@@ -31,7 +31,7 @@ static void totp_hid_worker_type_code(TotpHidWorkerTypeContext* context) {
     do {
         furi_delay_ms(500);
         i++;
-    } while(!furi_hal_hid_is_connected() && i < 100 && !totp_hid_worker_stop_requested());
+    } while(!furi_hal_hid_is_connected() && i < 100 && !totp_type_code_worker_stop_requested());
 
     if(furi_hal_hid_is_connected() &&
        furi_mutex_acquire(context->string_sync, 500) == FuriStatusOk) {
@@ -52,24 +52,24 @@ static void totp_hid_worker_type_code(TotpHidWorkerTypeContext* context) {
         furi_delay_ms(100);
     }
 
-    totp_hid_worker_restore_usb_mode(context);
+    totp_type_code_worker_restore_usb_mode(context);
 }
 
-static int32_t totp_hid_worker_callback(void* context) {
+static int32_t totp_type_code_worker_callback(void* context) {
     ValueMutex context_mutex;
-    if(!init_mutex(&context_mutex, context, sizeof(TotpHidWorkerTypeContext))) {
+    if(!init_mutex(&context_mutex, context, sizeof(TotpTypeCodeWorkerContext))) {
         return 251;
     }
 
     while(true) {
         uint32_t flags = furi_thread_flags_wait(
-            TotpHidWorkerEvtStop | TotpHidWorkerEvtType, FuriFlagWaitAny, FuriWaitForever);
+            TotpTypeCodeWorkerEvtStop | TotpTypeCodeWorkerEvtType, FuriFlagWaitAny, FuriWaitForever);
         furi_check((flags & FuriFlagError) == 0); //-V562
-        if(flags & TotpHidWorkerEvtStop) break;
+        if(flags & TotpTypeCodeWorkerEvtStop) break;
 
-        TotpHidWorkerTypeContext* h_context = acquire_mutex_block(&context_mutex);
-        if(flags & TotpHidWorkerEvtType) {
-            totp_hid_worker_type_code(h_context);
+        TotpTypeCodeWorkerContext* h_context = acquire_mutex_block(&context_mutex);
+        if(flags & TotpTypeCodeWorkerEvtType) {
+            totp_type_code_worker_type_code(h_context);
         }
 
         release_mutex(&context_mutex, h_context);
@@ -80,8 +80,8 @@ static int32_t totp_hid_worker_callback(void* context) {
     return 0;
 }
 
-TotpHidWorkerTypeContext* totp_hid_worker_start() {
-    TotpHidWorkerTypeContext* context = malloc(sizeof(TotpHidWorkerTypeContext));
+TotpTypeCodeWorkerContext* totp_type_code_worker_start() {
+    TotpTypeCodeWorkerContext* context = malloc(sizeof(TotpTypeCodeWorkerContext));
     furi_check(context != NULL);
     context->string_sync = furi_mutex_alloc(FuriMutexTypeNormal);
     context->thread = furi_thread_alloc();
@@ -89,22 +89,22 @@ TotpHidWorkerTypeContext* totp_hid_worker_start() {
     furi_thread_set_name(context->thread, "TOTPHidWorker");
     furi_thread_set_stack_size(context->thread, 1024);
     furi_thread_set_context(context->thread, context);
-    furi_thread_set_callback(context->thread, totp_hid_worker_callback);
+    furi_thread_set_callback(context->thread, totp_type_code_worker_callback);
     furi_thread_start(context->thread);
     return context;
 }
 
-void totp_hid_worker_stop(TotpHidWorkerTypeContext* context) {
+void totp_type_code_worker_stop(TotpTypeCodeWorkerContext* context) {
     furi_assert(context != NULL);
-    furi_thread_flags_set(furi_thread_get_id(context->thread), TotpHidWorkerEvtStop);
+    furi_thread_flags_set(furi_thread_get_id(context->thread), TotpTypeCodeWorkerEvtStop);
     furi_thread_join(context->thread);
     furi_thread_free(context->thread);
     furi_mutex_free(context->string_sync);
-    totp_hid_worker_restore_usb_mode(context);
+    totp_type_code_worker_restore_usb_mode(context);
     free(context);
 }
 
-void totp_hid_worker_notify(TotpHidWorkerTypeContext* context, TotpHidWorkerEvtFlags event) {
+void totp_type_code_worker_notify(TotpTypeCodeWorkerContext* context, TotpTypeCodeWorkerEvtFlags event) {
     furi_assert(context != NULL);
     furi_thread_flags_set(furi_thread_get_id(context->thread), event);
 }

+ 23 - 0
workers/type_code/type_code.h

@@ -0,0 +1,23 @@
+#pragma once
+
+#include <stdlib.h>
+#include <furi/furi.h>
+#include <furi_hal.h>
+
+typedef struct {
+    char* string;
+    uint8_t string_length;
+    FuriThread* thread;
+    FuriMutex* string_sync;
+    FuriHalUsbInterface* usb_mode_prev;
+} TotpTypeCodeWorkerContext;
+
+typedef enum {
+    TotpTypeCodeWorkerEvtReserved = (1 << 0),
+    TotpTypeCodeWorkerEvtStop = (1 << 1),
+    TotpTypeCodeWorkerEvtType = (1 << 2)
+} TotpTypeCodeWorkerEvtFlags;
+
+TotpTypeCodeWorkerContext* totp_type_code_worker_start();
+void totp_type_code_worker_stop(TotpTypeCodeWorkerContext* context);
+void totp_type_code_worker_notify(TotpTypeCodeWorkerContext* context, TotpTypeCodeWorkerEvtFlags event);