Skip to content

Commit

Permalink
Implemented #137 (#141)
Browse files Browse the repository at this point in the history
* Implemented #137
*Refactoring
  • Loading branch information
akopachov authored Apr 25, 2023
1 parent 06df424 commit ebcc079
Show file tree
Hide file tree
Showing 59 changed files with 1,636 additions and 1,594 deletions.
2 changes: 1 addition & 1 deletion flipperzero-firmware_official_dev
Submodule flipperzero-firmware_official_dev updated 42 files
+39 −5 .github/workflows/build.yml
+29 −5 .github/workflows/lint_and_submodule_check.yml
+2 −2 applications/debug/unit_tests/rpc/rpc_test.c
+4 −1 applications/external/picopass/picopass_worker.c
+4 −2 applications/external/picopass/scenes/picopass_scene_elite_dict_attack.c
+1 −1 applications/services/bt/bt_service/bt.c
+29 −0 applications/services/desktop/desktop.c
+2 −0 applications/services/desktop/desktop_i.h
+12 −0 applications/services/desktop/scenes/desktop_scene_lock_menu.c
+2 −0 applications/services/desktop/views/desktop_events.h
+29 −9 applications/services/desktop/views/desktop_view_lock_menu.c
+2 −0 applications/services/desktop/views/desktop_view_lock_menu.h
+18 −9 applications/services/notification/notification_app.c
+8 −1 applications/services/rpc/rpc.c
+17 −1 applications/services/rpc/rpc.h
+1 −1 applications/services/rpc/rpc_cli.c
+25 −1 applications/services/rpc/rpc_gui.c
+27 −12 applications/settings/notification_settings/notification_settings_app.c
+ assets/icons/StatusBar/Muted_8x8.png
+ assets/icons/StatusBar/Rpc_active_7x8.png
+23 −0 documentation/LFRFIDRaw.md
+1 −1 fbt_options.py
+21 −20 firmware/targets/f18/api_symbols.csv
+20 −19 firmware/targets/f7/api_symbols.csv
+1 −0 firmware/targets/f7/ble_glue/app_common.h
+2 −0 firmware/targets/f7/ble_glue/app_conf.h
+3 −2 firmware/targets/f7/ble_glue/app_debug.c
+22 −21 firmware/targets/f7/ble_glue/ble_app.c
+4 −0 firmware/targets/f7/ble_glue/ble_const.h
+2 −0 firmware/targets/f7/ble_glue/ble_glue.c
+9 −1 firmware/targets/f7/ble_glue/compiler.h
+25 −28 firmware/targets/f7/ble_glue/gap.c
+22 −11 firmware/targets/f7/furi_hal/furi_hal_flash.c
+25 −4 firmware/targets/f7/furi_hal/furi_hal_power.c
+3 −0 firmware/targets/f7/src/main.c
+1 −0 firmware/targets/furi_hal_include/furi_hal_rtc.h
+1 −1 lib/STM32CubeWB
+3 −1 scripts/fbt_tools/fbt_dist.py
+2 −2 scripts/flipper/assets/copro.py
+3 −1 scripts/flipper/storage.py
+2 −2 scripts/ob.data
+14 −0 scripts/ufbt/SConstruct
3 changes: 0 additions & 3 deletions totp/application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ App(
Lib(
name="base64",
),
Lib(
name="linked_list"
),
Lib(
name="timezone_utils",
),
Expand Down
2 changes: 1 addition & 1 deletion totp/cli/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ static void totp_cli_handler(Cli* cli, FuriString* args, void* context) {
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_AUTOMATION) == 0) {
totp_cli_command_automation_handle(plugin_state, args, cli);
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_RESET) == 0) {
totp_cli_command_reset_handle(cli, cli_context->event_queue);
totp_cli_command_reset_handle(plugin_state, cli, cli_context->event_queue);
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_UPDATE) == 0) {
totp_cli_command_update_handle(plugin_state, args, cli);
} else if(
Expand Down
42 changes: 40 additions & 2 deletions totp/cli/cli_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
#include <lib/toolbox/args.h>
#include "../types/plugin_event.h"

const char* TOTP_CLI_COLOR_ERROR = "91m";
const char* TOTP_CLI_COLOR_WARNING = "93m";
const char* TOTP_CLI_COLOR_SUCCESS = "92m";
const char* TOTP_CLI_COLOR_INFO = "96m";

bool totp_cli_ensure_authenticated(const PluginState* plugin_state, Cli* cli) {
if(plugin_state->current_scene == TotpSceneAuthentication) {
TOTP_CLI_PRINTF("Pleases enter PIN on your flipper device\r\n");
Expand All @@ -13,10 +18,11 @@ bool totp_cli_ensure_authenticated(const PluginState* plugin_state, Cli* cli) {
furi_delay_ms(100);
}

TOTP_CLI_DELETE_LAST_LINE();
totp_cli_delete_last_line();

if(plugin_state->current_scene == TotpSceneAuthentication || //-V560
plugin_state->current_scene == TotpSceneNone) { //-V560
TOTP_CLI_PRINTF_INFO("Cancelled by user\r\n");
return false;
}
}
Expand Down Expand Up @@ -54,7 +60,7 @@ bool totp_cli_read_line(Cli* cli, FuriString* out_str, bool mask_user_input) {
} else if(c == CliSymbolAsciiBackspace || c == CliSymbolAsciiDel) {
size_t out_str_size = furi_string_size(out_str);
if(out_str_size > 0) {
TOTP_CLI_DELETE_LAST_CHAR();
totp_cli_delete_last_char();
furi_string_left(out_str, out_str_size - 1);
}
} else if(c == CliSymbolAsciiCR) {
Expand Down Expand Up @@ -83,3 +89,35 @@ void furi_string_secure_free(FuriString* str) {

furi_string_free(str);
}

void totp_cli_print_invalid_arguments() {
TOTP_CLI_PRINTF_ERROR(
"Invalid command arguments. use \"help\" command to get list of available commands");
}

void totp_cli_print_error_updating_config_file() {
TOTP_CLI_PRINTF_ERROR("An error has occurred during updating config file\r\n");
}

void totp_cli_print_error_loading_token_info() {
TOTP_CLI_PRINTF_ERROR("An error has occurred during loading token information\r\n");
}

void totp_cli_print_processing() {
TOTP_CLI_PRINTF("Processing, please wait...\r\n");
}

void totp_cli_delete_last_char() {
TOTP_CLI_PRINTF("\b \b");
fflush(stdout);
}

void totp_cli_delete_current_line() {
TOTP_CLI_PRINTF("\33[2K\r");
fflush(stdout);
}

void totp_cli_delete_last_line() {
TOTP_CLI_PRINTF("\033[A\33[2K\r");
fflush(stdout);
}
67 changes: 45 additions & 22 deletions totp/cli/cli_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
#define DOCOPT_OPTIONS "[options]"
#define DOCOPT_DEFAULT(val) "[default: " val "]"

extern const char* TOTP_CLI_COLOR_ERROR;
extern const char* TOTP_CLI_COLOR_WARNING;
extern const char* TOTP_CLI_COLOR_SUCCESS;
extern const char* TOTP_CLI_COLOR_INFO;

#define TOTP_CLI_PRINTF(format, ...) printf(format, ##__VA_ARGS__)

#define TOTP_CLI_PRINTF_COLORFUL(color, format, ...) \
Expand All @@ -22,11 +27,6 @@
printf("\e[0m"); \
fflush(stdout)

#define TOTP_CLI_COLOR_ERROR "91m"
#define TOTP_CLI_COLOR_WARNING "93m"
#define TOTP_CLI_COLOR_SUCCESS "92m"
#define TOTP_CLI_COLOR_INFO "96m"

#define TOTP_CLI_PRINTF_ERROR(format, ...) \
TOTP_CLI_PRINTF_COLORFUL(TOTP_CLI_COLOR_ERROR, format, ##__VA_ARGS__)
#define TOTP_CLI_PRINTF_WARNING(format, ...) \
Expand All @@ -36,24 +36,12 @@
#define TOTP_CLI_PRINTF_INFO(format, ...) \
TOTP_CLI_PRINTF_COLORFUL(TOTP_CLI_COLOR_INFO, format, ##__VA_ARGS__)

#define TOTP_CLI_DELETE_LAST_LINE() \
TOTP_CLI_PRINTF("\033[A\33[2K\r"); \
fflush(stdout)

#define TOTP_CLI_DELETE_CURRENT_LINE() \
TOTP_CLI_PRINTF("\33[2K\r"); \
fflush(stdout)

#define TOTP_CLI_DELETE_LAST_CHAR() \
TOTP_CLI_PRINTF("\b \b"); \
fflush(stdout)

#define TOTP_CLI_PRINT_INVALID_ARGUMENTS() \
TOTP_CLI_PRINTF_ERROR( \
"Invalid command arguments. use \"help\" command to get list of available commands")
#define TOTP_CLI_LOCK_UI(plugin_state) \
Scene __previous_scene = plugin_state->current_scene; \
totp_scene_director_activate_scene(plugin_state, TotpSceneStandby)

#define TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE() \
TOTP_CLI_PRINTF_ERROR("An error has occurred during updating config file\r\n")
#define TOTP_CLI_UNLOCK_UI(plugin_state) \
totp_scene_director_activate_scene(plugin_state, __previous_scene)

/**
* @brief Checks whether user is authenticated and entered correct PIN.
Expand Down Expand Up @@ -92,3 +80,38 @@ bool args_read_uint8_and_trim(FuriString* args, uint8_t* value);
* @param str instance to free
*/
void furi_string_secure_free(FuriString* str);

/**
* @brief Deletes last printed line in console
*/
void totp_cli_delete_last_line();

/**
* @brief Deletes current printed line in console
*/
void totp_cli_delete_current_line();

/**
* @brief Deletes last printed char in console
*/
void totp_cli_delete_last_char();

/**
* @brief Prints error message about invalid command arguments
*/
void totp_cli_print_invalid_arguments();

/**
* @brief Prints error message about config file update error
*/
void totp_cli_print_error_updating_config_file();

/**
* @brief Prints error message about config file loading error
*/
void totp_cli_print_error_loading_token_info();

/**
* @brief Prints message to let user knwo that command is processing now
*/
void totp_cli_print_processing();
163 changes: 86 additions & 77 deletions totp/cli/commands/add/add.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,83 @@
#include "add.h"
#include <stdlib.h>
#include <lib/toolbox/args.h>
#include <linked_list.h>
#include "../../../types/token_info.h"
#include "../../../services/config/config.h"
#include "../../../services/convert/convert.h"
#include "../../cli_helpers.h"
#include "../../../ui/scene_director.h"
#include "../../common_command_arguments.h"

struct TotpAddContext {
FuriString* args;
Cli* cli;
uint8_t* iv;
};

enum TotpIteratorUpdateTokenResultsEx {
TotpIteratorUpdateTokenResultInvalidSecret = 1,
TotpIteratorUpdateTokenResultCancelled = 2,
TotpIteratorUpdateTokenResultInvalidArguments = 3
};

static TotpIteratorUpdateTokenResult add_token_handler(TokenInfo* token_info, const void* context) {
const struct TotpAddContext* context_t = context;

// Reading token name
if(!args_read_probably_quoted_string_and_trim(context_t->args, token_info->name)) {
return TotpIteratorUpdateTokenResultInvalidArguments;
}

FuriString* temp_str = furi_string_alloc();

// Read optional arguments
bool mask_user_input = true;
PlainTokenSecretEncoding token_secret_encoding = PLAIN_TOKEN_ENCODING_BASE32;
while(args_read_string_and_trim(context_t->args, temp_str)) {
bool parsed = false;
if(!totp_cli_try_read_algo(token_info, temp_str, context_t->args, &parsed) &&
!totp_cli_try_read_digits(token_info, temp_str, context_t->args, &parsed) &&
!totp_cli_try_read_duration(token_info, temp_str, context_t->args, &parsed) &&
!totp_cli_try_read_unsecure_flag(temp_str, &parsed, &mask_user_input) &&
!totp_cli_try_read_automation_features(token_info, temp_str, context_t->args, &parsed) &&
!totp_cli_try_read_plain_token_secret_encoding(
temp_str, context_t->args, &parsed, &token_secret_encoding)) {
totp_cli_printf_unknown_argument(temp_str);
}

if(!parsed) {
furi_string_free(temp_str);
return TotpIteratorUpdateTokenResultInvalidArguments;
}
}

// Reading token secret
furi_string_reset(temp_str);
TOTP_CLI_PRINTF("Enter token secret and confirm with [ENTER]\r\n");
if(!totp_cli_read_line(context_t->cli, temp_str, mask_user_input)) {
totp_cli_delete_last_line();
furi_string_secure_free(temp_str);
return TotpIteratorUpdateTokenResultCancelled;
}

totp_cli_delete_last_line();

bool secret_set = token_info_set_secret(
token_info,
furi_string_get_cstr(temp_str),
furi_string_size(temp_str),
token_secret_encoding,
context_t->iv);

furi_string_secure_free(temp_str);

if (!secret_set) {
return TotpIteratorUpdateTokenResultInvalidSecret;
}

return TotpIteratorUpdateTokenResultSuccess;
}

void totp_cli_command_add_docopt_commands() {
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_ADD ", " TOTP_CLI_COMMAND_ADD_ALT
", " TOTP_CLI_COMMAND_ADD_ALT2 " Add new token\r\n");
Expand Down Expand Up @@ -75,90 +144,30 @@ void totp_cli_command_add_docopt_options() {
}

void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
FuriString* temp_str = furi_string_alloc();
TokenInfo* token_info = token_info_alloc();

// Reading token name
if(!args_read_probably_quoted_string_and_trim(args, temp_str)) {
TOTP_CLI_PRINT_INVALID_ARGUMENTS();
furi_string_free(temp_str);
token_info_free(token_info);
if(!totp_cli_ensure_authenticated(plugin_state, cli)) {
return;
}

size_t temp_cstr_len = furi_string_size(temp_str);
token_info->name = malloc(temp_cstr_len + 1);
furi_check(token_info->name != NULL);
strlcpy(token_info->name, furi_string_get_cstr(temp_str), temp_cstr_len + 1);
TokenInfoIteratorContext* iterator_context = totp_config_get_token_iterator_context(plugin_state);

// Read optional arguments
bool mask_user_input = true;
PlainTokenSecretEncoding token_secret_encoding = PLAIN_TOKEN_ENCODING_BASE32;
while(args_read_string_and_trim(args, temp_str)) {
bool parsed = false;
if(!totp_cli_try_read_algo(token_info, temp_str, args, &parsed) &&
!totp_cli_try_read_digits(token_info, temp_str, args, &parsed) &&
!totp_cli_try_read_duration(token_info, temp_str, args, &parsed) &&
!totp_cli_try_read_unsecure_flag(temp_str, &parsed, &mask_user_input) &&
!totp_cli_try_read_automation_features(token_info, temp_str, args, &parsed) &&
!totp_cli_try_read_plain_token_secret_encoding(
temp_str, args, &parsed, &token_secret_encoding)) {
totp_cli_printf_unknown_argument(temp_str);
}
TOTP_CLI_LOCK_UI(plugin_state);

if(!parsed) {
TOTP_CLI_PRINT_INVALID_ARGUMENTS();
furi_string_free(temp_str);
token_info_free(token_info);
return;
}
}
struct TotpAddContext add_context = { .args = args, .cli = cli, .iv = &plugin_state->iv[0] };
TotpIteratorUpdateTokenResult add_result = totp_token_info_iterator_add_new_token(iterator_context, &add_token_handler, &add_context);

// Reading token secret
furi_string_reset(temp_str);
TOTP_CLI_PRINTF("Enter token secret and confirm with [ENTER]\r\n");
if(!totp_cli_read_line(cli, temp_str, mask_user_input) ||
!totp_cli_ensure_authenticated(plugin_state, cli)) {
TOTP_CLI_DELETE_LAST_LINE();
if(add_result == TotpIteratorUpdateTokenResultSuccess) {
TOTP_CLI_PRINTF_SUCCESS(
"Token \"%s\" has been successfully added\r\n",
furi_string_get_cstr(totp_token_info_iterator_get_current_token(iterator_context)->name));
} else if (add_result == TotpIteratorUpdateTokenResultCancelled) {
TOTP_CLI_PRINTF_INFO("Cancelled by user\r\n");
furi_string_secure_free(temp_str);
token_info_free(token_info);
return;
}

TOTP_CLI_DELETE_LAST_LINE();

bool load_generate_token_scene = false;
if(plugin_state->current_scene == TotpSceneGenerateToken) {
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
load_generate_token_scene = true;
}

bool secret_set = token_info_set_secret(
token_info,
furi_string_get_cstr(temp_str),
furi_string_size(temp_str),
token_secret_encoding,
plugin_state->iv);

furi_string_secure_free(temp_str);

if(secret_set) {
TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, token_info, furi_check);
plugin_state->tokens_count++;

if(totp_config_file_save_new_token(token_info) == TotpConfigFileUpdateSuccess) {
TOTP_CLI_PRINTF_SUCCESS(
"Token \"%s\" has been successfully added\r\n", token_info->name);
} else {
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
}
} else {
token_info_free(token_info);
} else if (add_result == TotpIteratorUpdateTokenResultInvalidArguments) {
totp_cli_print_invalid_arguments();
} else if (add_result == TotpIteratorUpdateTokenResultInvalidSecret) {
TOTP_CLI_PRINTF_ERROR("Token secret seems to be invalid and can not be parsed\r\n");
} else if (add_result == TotpIteratorUpdateTokenResultFileUpdateFailed) {
totp_cli_print_error_updating_config_file();
}

if(load_generate_token_scene) {
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
}
TOTP_CLI_UNLOCK_UI(plugin_state);
}
Loading

0 comments on commit ebcc079

Please sign in to comment.