mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-11-24 11:14:26 +03:00
parent
7a211e0018
commit
adfac7affb
@ -14,6 +14,8 @@
|
|||||||
#define TOTP_CLI_COMMAND_ADD_ARG_DIGITS "digits"
|
#define TOTP_CLI_COMMAND_ADD_ARG_DIGITS "digits"
|
||||||
#define TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "-d"
|
#define TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "-d"
|
||||||
#define TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX "-u"
|
#define TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX "-u"
|
||||||
|
#define TOTP_CLI_COMMAND_ADD_ARG_DURATION "duration"
|
||||||
|
#define TOTP_CLI_COMMAND_ADD_ARG_DURATION_PREFIX "-l"
|
||||||
|
|
||||||
static bool token_info_set_algo_from_str(TokenInfo* token_info, const FuriString* str) {
|
static bool token_info_set_algo_from_str(TokenInfo* token_info, const FuriString* str) {
|
||||||
if(furi_string_cmpi_str(str, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME) == 0) {
|
if(furi_string_cmpi_str(str, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME) == 0) {
|
||||||
@ -34,6 +36,16 @@ static bool token_info_set_algo_from_str(TokenInfo* token_info, const FuriString
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool args_read_uint8_and_trim(FuriString* args, uint8_t* value) {
|
||||||
|
int int_value;
|
||||||
|
if(!args_read_int_and_trim(args, &int_value) || int_value < 0 || int_value > UINT8_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*value = (uint8_t)int_value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void totp_cli_command_add_docopt_commands() {
|
void totp_cli_command_add_docopt_commands() {
|
||||||
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_ADD ", " TOTP_CLI_COMMAND_ADD_ALT
|
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_ADD ", " TOTP_CLI_COMMAND_ADD_ALT
|
||||||
", " TOTP_CLI_COMMAND_ADD_ALT2 " Add new token\r\n");
|
", " TOTP_CLI_COMMAND_ADD_ALT2 " Add new token\r\n");
|
||||||
@ -42,11 +54,11 @@ void totp_cli_command_add_docopt_commands() {
|
|||||||
void totp_cli_command_add_docopt_usage() {
|
void totp_cli_command_add_docopt_usage() {
|
||||||
TOTP_CLI_PRINTF(
|
TOTP_CLI_PRINTF(
|
||||||
" " TOTP_CLI_COMMAND_NAME
|
" " TOTP_CLI_COMMAND_NAME
|
||||||
" " DOCOPT_REQUIRED(TOTP_CLI_COMMAND_ADD " | " TOTP_CLI_COMMAND_ADD_ALT " | " TOTP_CLI_COMMAND_ADD_ALT2) " " DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_NAME) " " DOCOPT_OPTIONAL(
|
" " DOCOPT_REQUIRED(TOTP_CLI_COMMAND_ADD " | " TOTP_CLI_COMMAND_ADD_ALT " | " TOTP_CLI_COMMAND_ADD_ALT2) " " DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_NAME) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_ALGO))) " " DOCOPT_OPTIONAL(
|
||||||
DOCOPT_OPTION(
|
DOCOPT_OPTION(
|
||||||
TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX,
|
TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX,
|
||||||
DOCOPT_ARGUMENT(
|
DOCOPT_ARGUMENT(
|
||||||
TOTP_CLI_COMMAND_ADD_ARG_ALGO))) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_DIGITS))) " " DOCOPT_OPTIONAL(DOCOPT_SWITCH(TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX)) "\r\n");
|
TOTP_CLI_COMMAND_ADD_ARG_DIGITS))) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ADD_ARG_DURATION_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_DURATION))) " " DOCOPT_OPTIONAL(DOCOPT_SWITCH(TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX)) "\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void totp_cli_command_add_docopt_arguments() {
|
void totp_cli_command_add_docopt_arguments() {
|
||||||
@ -64,6 +76,10 @@ void totp_cli_command_add_docopt_options() {
|
|||||||
TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX,
|
TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX,
|
||||||
DOCOPT_ARGUMENT(
|
DOCOPT_ARGUMENT(
|
||||||
TOTP_CLI_COMMAND_ADD_ARG_DIGITS)) " Number of digits to generate, one of: 6, 8 " DOCOPT_DEFAULT("6") "\r\n");
|
TOTP_CLI_COMMAND_ADD_ARG_DIGITS)) " Number of digits to generate, one of: 6, 8 " DOCOPT_DEFAULT("6") "\r\n");
|
||||||
|
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(
|
||||||
|
TOTP_CLI_COMMAND_ADD_ARG_DURATION_PREFIX,
|
||||||
|
DOCOPT_ARGUMENT(
|
||||||
|
TOTP_CLI_COMMAND_ADD_ARG_DURATION)) " Token lifetime duration in seconds, between: 15 and 255 " DOCOPT_DEFAULT("30") "\r\n");
|
||||||
TOTP_CLI_PRINTF(" " DOCOPT_SWITCH(
|
TOTP_CLI_PRINTF(" " DOCOPT_SWITCH(
|
||||||
TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX) " Show console user input as-is without masking\r\n");
|
TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX) " Show console user input as-is without masking\r\n");
|
||||||
}
|
}
|
||||||
@ -110,16 +126,32 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl
|
|||||||
parsed = true;
|
parsed = true;
|
||||||
}
|
}
|
||||||
} else if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX) == 0) {
|
} else if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX) == 0) {
|
||||||
if(!args_read_string_and_trim(args, temp_str)) {
|
uint8_t digit_value;
|
||||||
|
if(!args_read_uint8_and_trim(args, &digit_value)) {
|
||||||
TOTP_CLI_PRINTF(
|
TOTP_CLI_PRINTF(
|
||||||
"Missed value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX
|
"Missed or incorrect value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX
|
||||||
"\"\r\n");
|
"\"\r\n");
|
||||||
} else if(!token_info_set_digits_from_int(
|
} else if(!token_info_set_digits_from_int(token_info, digit_value)) {
|
||||||
token_info, CONVERT_CHAR_TO_DIGIT(furi_string_get_char(temp_str, 0)))) {
|
|
||||||
TOTP_CLI_PRINTF(
|
TOTP_CLI_PRINTF(
|
||||||
"\"%s\" is incorrect value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX
|
"\"%" PRIu8
|
||||||
|
"\" is incorrect value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX
|
||||||
"\"\r\n",
|
"\"\r\n",
|
||||||
furi_string_get_cstr(temp_str));
|
digit_value);
|
||||||
|
} else {
|
||||||
|
parsed = true;
|
||||||
|
}
|
||||||
|
} else if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_ADD_ARG_DURATION_PREFIX) == 0) {
|
||||||
|
uint8_t duration_value;
|
||||||
|
if(!args_read_uint8_and_trim(args, &duration_value)) {
|
||||||
|
TOTP_CLI_PRINTF(
|
||||||
|
"Missed or incorrect value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DURATION_PREFIX
|
||||||
|
"\"\r\n");
|
||||||
|
} else if(!token_info_set_duration_from_int(token_info, duration_value)) {
|
||||||
|
TOTP_CLI_PRINTF(
|
||||||
|
"\"%" PRIu8
|
||||||
|
"\" is incorrect value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DURATION_PREFIX
|
||||||
|
"\"\r\n",
|
||||||
|
duration_value);
|
||||||
} else {
|
} else {
|
||||||
parsed = true;
|
parsed = true;
|
||||||
}
|
}
|
||||||
|
@ -40,19 +40,21 @@ void totp_cli_command_list_handle(PluginState* plugin_state, Cli* cli) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TOTP_CLI_PRINTF("+-----+-----------------------------+--------+--------+\r\n");
|
TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n");
|
||||||
TOTP_CLI_PRINTF("| %-*s | %-*s | %-*s | %-s |\r\n", 3, "#", 27, "Name", 6, "Algo", "Digits");
|
TOTP_CLI_PRINTF(
|
||||||
TOTP_CLI_PRINTF("+-----+-----------------------------+--------+--------+\r\n");
|
"| %-*s | %-*s | %-*s | %-s | %-s |\r\n", 3, "#", 25, "Name", 6, "Algo", "Ln", "Dur");
|
||||||
|
TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n");
|
||||||
uint16_t index = 1;
|
uint16_t index = 1;
|
||||||
TOTP_LIST_FOREACH(plugin_state->tokens_list, node, {
|
TOTP_LIST_FOREACH(plugin_state->tokens_list, node, {
|
||||||
TokenInfo* token_info = (TokenInfo*)node->data;
|
TokenInfo* token_info = (TokenInfo*)node->data;
|
||||||
TOTP_CLI_PRINTF(
|
TOTP_CLI_PRINTF(
|
||||||
"| %-3" PRIu16 " | %-27.27s | %-6s | %-6" PRIu8 " |\r\n",
|
"| %-3" PRIu16 " | %-25.25s | %-6s | %-2" PRIu8 " | %-3" PRIu8 " |\r\n",
|
||||||
index,
|
index,
|
||||||
token_info->name,
|
token_info->name,
|
||||||
get_algo_as_cstr(token_info->algo),
|
get_algo_as_cstr(token_info->algo),
|
||||||
token_info->digits);
|
token_info->digits,
|
||||||
|
token_info->duration);
|
||||||
index++;
|
index++;
|
||||||
});
|
});
|
||||||
TOTP_CLI_PRINTF("+-----+-----------------------------+--------+--------+\r\n");
|
TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n");
|
||||||
}
|
}
|
@ -5,6 +5,7 @@
|
|||||||
#include "../../types/common.h"
|
#include "../../types/common.h"
|
||||||
#include "../../types/token_info.h"
|
#include "../../types/token_info.h"
|
||||||
#include "migrations/config_migration_v1_to_v2.h"
|
#include "migrations/config_migration_v1_to_v2.h"
|
||||||
|
#include "migrations/config_migration_v2_to_v3.h"
|
||||||
|
|
||||||
#define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("authenticator")
|
#define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("authenticator")
|
||||||
#define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/totp.conf"
|
#define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/totp.conf"
|
||||||
@ -173,6 +174,13 @@ static TotpConfigFileOpenResult totp_open_config_file(Storage* storage, FlipperF
|
|||||||
flipper_format_write_comment(fff_data_file, temp_str);
|
flipper_format_write_comment(fff_data_file, temp_str);
|
||||||
flipper_format_write_comment_cstr(fff_data_file, " ");
|
flipper_format_write_comment_cstr(fff_data_file, " ");
|
||||||
|
|
||||||
|
flipper_format_write_comment_cstr(
|
||||||
|
fff_data_file,
|
||||||
|
"# Token lifetime duration in seconds. Should be between 15 and 255. Majority websites requires 30, however some rare websites may require custom lifetime. If you are not sure which one to use - use 30");
|
||||||
|
furi_string_printf(temp_str, "%s: 30", TOTP_CONFIG_KEY_TOKEN_DURATION);
|
||||||
|
flipper_format_write_comment(fff_data_file, temp_str);
|
||||||
|
flipper_format_write_comment_cstr(fff_data_file, " ");
|
||||||
|
|
||||||
flipper_format_write_comment_cstr(fff_data_file, "=== TOKEN SAMPLE END ===");
|
flipper_format_write_comment_cstr(fff_data_file, "=== TOKEN SAMPLE END ===");
|
||||||
flipper_format_write_comment_cstr(fff_data_file, " ");
|
flipper_format_write_comment_cstr(fff_data_file, " ");
|
||||||
|
|
||||||
@ -232,6 +240,12 @@ TotpConfigFileUpdateResult
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmp_uint32 = token_info->duration;
|
||||||
|
if(!flipper_format_write_uint32(file, TOTP_CONFIG_KEY_TOKEN_DURATION, &tmp_uint32, 1)) {
|
||||||
|
update_result = TotpConfigFileUpdateError;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
update_result = TotpConfigFileUpdateSuccess;
|
update_result = TotpConfigFileUpdateSuccess;
|
||||||
} while(false);
|
} while(false);
|
||||||
|
|
||||||
@ -483,6 +497,7 @@ TotpConfigFileOpenResult totp_config_file_load_base(PluginState* const plugin_st
|
|||||||
if(file_version == 1) {
|
if(file_version == 1) {
|
||||||
if(totp_config_migrate_v1_to_v2(fff_data_file, fff_backup_data_file)) {
|
if(totp_config_migrate_v1_to_v2(fff_data_file, fff_backup_data_file)) {
|
||||||
FURI_LOG_I(LOGGING_TAG, "Applied migration from v1 to v2");
|
FURI_LOG_I(LOGGING_TAG, "Applied migration from v1 to v2");
|
||||||
|
file_version = 2;
|
||||||
} else {
|
} else {
|
||||||
FURI_LOG_W(
|
FURI_LOG_W(
|
||||||
LOGGING_TAG, "An error occurred during migration from v1 to v2");
|
LOGGING_TAG, "An error occurred during migration from v1 to v2");
|
||||||
@ -491,6 +506,18 @@ TotpConfigFileOpenResult totp_config_file_load_base(PluginState* const plugin_st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(file_version == 2) {
|
||||||
|
if(totp_config_migrate_v2_to_v3(fff_data_file, fff_backup_data_file)) {
|
||||||
|
FURI_LOG_I(LOGGING_TAG, "Applied migration from v2 to v3");
|
||||||
|
file_version = 3;
|
||||||
|
} else {
|
||||||
|
FURI_LOG_W(
|
||||||
|
LOGGING_TAG, "An error occurred during migration from v2 to v3");
|
||||||
|
result = TotpConfigFileOpenError;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
flipper_format_file_close(fff_backup_data_file);
|
flipper_format_file_close(fff_backup_data_file);
|
||||||
flipper_format_free(fff_backup_data_file);
|
flipper_format_free(fff_backup_data_file);
|
||||||
flipper_format_rewind(fff_data_file);
|
flipper_format_rewind(fff_data_file);
|
||||||
@ -669,6 +696,12 @@ TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state)
|
|||||||
tokenInfo->digits = TOTP_6_DIGITS;
|
tokenInfo->digits = TOTP_6_DIGITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!flipper_format_read_uint32(
|
||||||
|
fff_data_file, TOTP_CONFIG_KEY_TOKEN_DURATION, &temp_data32, 1) ||
|
||||||
|
!token_info_set_duration_from_int(tokenInfo, temp_data32)) {
|
||||||
|
tokenInfo->duration = TOTP_TOKEN_DURATION_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
FURI_LOG_D(LOGGING_TAG, "Found token \"%s\"", tokenInfo->name);
|
FURI_LOG_D(LOGGING_TAG, "Found token \"%s\"", tokenInfo->name);
|
||||||
|
|
||||||
TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, tokenInfo, furi_check);
|
TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, tokenInfo, furi_check);
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define CONFIG_FILE_HEADER "Flipper TOTP plugin config file"
|
#define CONFIG_FILE_HEADER "Flipper TOTP plugin config file"
|
||||||
#define CONFIG_FILE_ACTUAL_VERSION 2
|
#define CONFIG_FILE_ACTUAL_VERSION 3
|
||||||
|
|
||||||
#define TOTP_CONFIG_KEY_TIMEZONE "Timezone"
|
#define TOTP_CONFIG_KEY_TIMEZONE "Timezone"
|
||||||
#define TOTP_CONFIG_KEY_TOKEN_NAME "TokenName"
|
#define TOTP_CONFIG_KEY_TOKEN_NAME "TokenName"
|
||||||
#define TOTP_CONFIG_KEY_TOKEN_SECRET "TokenSecret"
|
#define TOTP_CONFIG_KEY_TOKEN_SECRET "TokenSecret"
|
||||||
#define TOTP_CONFIG_KEY_TOKEN_ALGO "TokenAlgo"
|
#define TOTP_CONFIG_KEY_TOKEN_ALGO "TokenAlgo"
|
||||||
#define TOTP_CONFIG_KEY_TOKEN_DIGITS "TokenDigits"
|
#define TOTP_CONFIG_KEY_TOKEN_DIGITS "TokenDigits"
|
||||||
|
#define TOTP_CONFIG_KEY_TOKEN_DURATION "TokenDuration"
|
||||||
#define TOTP_CONFIG_KEY_CRYPTO_VERIFY "Crypto"
|
#define TOTP_CONFIG_KEY_CRYPTO_VERIFY "Crypto"
|
||||||
#define TOTP_CONFIG_KEY_BASE_IV "BaseIV"
|
#define TOTP_CONFIG_KEY_BASE_IV "BaseIV"
|
||||||
#define TOTP_CONFIG_KEY_PINSET "PinIsSet"
|
#define TOTP_CONFIG_KEY_PINSET "PinIsSet"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "config_migration_v1_to_v2.h"
|
#include "config_migration_v1_to_v2.h"
|
||||||
#include <flipper_format/flipper_format.h>
|
#include <flipper_format/flipper_format.h>
|
||||||
#include "../constants.h"
|
#include "../constants.h"
|
||||||
|
#include "../../../types/token_info.h"
|
||||||
|
|
||||||
#define NEW_VERSION 2
|
#define NEW_VERSION 2
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ bool totp_config_migrate_v1_to_v2(
|
|||||||
|
|
||||||
flipper_format_write_string_cstr(
|
flipper_format_write_string_cstr(
|
||||||
fff_data_file, TOTP_CONFIG_KEY_TOKEN_ALGO, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME);
|
fff_data_file, TOTP_CONFIG_KEY_TOKEN_ALGO, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME);
|
||||||
uint32_t default_digits = 6;
|
const uint32_t default_digits = TOTP_6_DIGITS;
|
||||||
flipper_format_write_uint32(
|
flipper_format_write_uint32(
|
||||||
fff_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &default_digits, 1);
|
fff_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &default_digits, 1);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
#include "config_migration_v2_to_v3.h"
|
||||||
|
#include <flipper_format/flipper_format.h>
|
||||||
|
#include "../constants.h"
|
||||||
|
#include "../../../types/token_info.h"
|
||||||
|
|
||||||
|
#define NEW_VERSION 3
|
||||||
|
|
||||||
|
bool totp_config_migrate_v2_to_v3(
|
||||||
|
FlipperFormat* fff_data_file,
|
||||||
|
FlipperFormat* fff_backup_data_file) {
|
||||||
|
flipper_format_write_header_cstr(fff_data_file, CONFIG_FILE_HEADER, NEW_VERSION);
|
||||||
|
|
||||||
|
FuriString* temp_str = furi_string_alloc();
|
||||||
|
|
||||||
|
if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_BASE_IV, temp_str)) {
|
||||||
|
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_BASE_IV, temp_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
flipper_format_rewind(fff_backup_data_file);
|
||||||
|
|
||||||
|
if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, temp_str)) {
|
||||||
|
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, temp_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
flipper_format_rewind(fff_backup_data_file);
|
||||||
|
|
||||||
|
if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_TIMEZONE, temp_str)) {
|
||||||
|
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, temp_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
flipper_format_rewind(fff_backup_data_file);
|
||||||
|
|
||||||
|
if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_PINSET, temp_str)) {
|
||||||
|
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_PINSET, temp_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
flipper_format_rewind(fff_backup_data_file);
|
||||||
|
|
||||||
|
if(flipper_format_read_string(
|
||||||
|
fff_backup_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, temp_str)) {
|
||||||
|
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, temp_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
flipper_format_rewind(fff_backup_data_file);
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
if(!flipper_format_read_string(
|
||||||
|
fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_NAME, temp_str)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_NAME, temp_str);
|
||||||
|
|
||||||
|
flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_SECRET, temp_str);
|
||||||
|
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_SECRET, temp_str);
|
||||||
|
|
||||||
|
flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_ALGO, temp_str);
|
||||||
|
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_ALGO, temp_str);
|
||||||
|
|
||||||
|
flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, temp_str);
|
||||||
|
flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, temp_str);
|
||||||
|
|
||||||
|
const uint32_t default_duration = TOTP_TOKEN_DURATION_DEFAULT;
|
||||||
|
flipper_format_write_uint32(
|
||||||
|
fff_data_file, TOTP_CONFIG_KEY_TOKEN_DURATION, &default_duration, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
furi_string_free(temp_str);
|
||||||
|
return true;
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <flipper_format/flipper_format.h>
|
||||||
|
|
||||||
|
bool totp_config_migrate_v2_to_v3(
|
||||||
|
FlipperFormat* fff_data_file,
|
||||||
|
FlipperFormat* fff_backup_data_file);
|
@ -61,3 +61,12 @@ bool token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits) {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool token_info_set_duration_from_int(TokenInfo* token_info, uint8_t duration) {
|
||||||
|
if(duration >= 15) {
|
||||||
|
token_info->duration = duration;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#define TOTP_TOKEN_DURATION_DEFAULT 30
|
||||||
|
|
||||||
typedef uint8_t TokenHashAlgo;
|
typedef uint8_t TokenHashAlgo;
|
||||||
typedef uint8_t TokenDigitsCount;
|
typedef uint8_t TokenDigitsCount;
|
||||||
|
|
||||||
@ -70,6 +72,11 @@ typedef struct {
|
|||||||
* @brief Desired TOTP token length
|
* @brief Desired TOTP token length
|
||||||
*/
|
*/
|
||||||
TokenDigitsCount digits;
|
TokenDigitsCount digits;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Desired TOTP token duration in seconds
|
||||||
|
*/
|
||||||
|
uint8_t duration;
|
||||||
} TokenInfo;
|
} TokenInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,6 +109,14 @@ bool token_info_set_secret(
|
|||||||
* @brief Sets token digits count from \c uint8_t value
|
* @brief Sets token digits count from \c uint8_t value
|
||||||
* @param token_info instance whichs token digits count length should be updated
|
* @param token_info instance whichs token digits count length should be updated
|
||||||
* @param digits desired token digits count length
|
* @param digits desired token digits count length
|
||||||
* @return \c true if token digits count length has been updated; \c false p
|
* @return \c true if token digits count length has been updated; \c false otherwise
|
||||||
*/
|
*/
|
||||||
bool token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits);
|
bool token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets token duration from \c uint8_t value
|
||||||
|
* @param token_info instance whichs token digits count length should be updated
|
||||||
|
* @param duration desired token duration in seconds
|
||||||
|
* @return \c true if token duration has been updated; \c false otherwise
|
||||||
|
*/
|
||||||
|
bool token_info_set_duration_from_int(TokenInfo* token_info, uint8_t duration);
|
||||||
|
@ -21,6 +21,7 @@ typedef enum {
|
|||||||
TokenSecretTextBox,
|
TokenSecretTextBox,
|
||||||
TokenAlgoSelect,
|
TokenAlgoSelect,
|
||||||
TokenLengthSelect,
|
TokenLengthSelect,
|
||||||
|
TokenDurationSelect,
|
||||||
ConfirmButton,
|
ConfirmButton,
|
||||||
} Control;
|
} Control;
|
||||||
|
|
||||||
@ -39,6 +40,8 @@ typedef struct {
|
|||||||
int16_t screen_y_offset;
|
int16_t screen_y_offset;
|
||||||
TokenHashAlgo algo;
|
TokenHashAlgo algo;
|
||||||
uint8_t digits_count_index;
|
uint8_t digits_count_index;
|
||||||
|
uint8_t duration;
|
||||||
|
FuriString* duration_text;
|
||||||
} SceneState;
|
} SceneState;
|
||||||
|
|
||||||
void totp_scene_add_new_token_init(const PluginState* plugin_state) {
|
void totp_scene_add_new_token_init(const PluginState* plugin_state) {
|
||||||
@ -63,6 +66,10 @@ static void on_token_secret_user_comitted(InputTextSceneCallbackResult* result)
|
|||||||
free(result);
|
free(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void update_duration_text(SceneState* scene_state) {
|
||||||
|
furi_string_printf(scene_state->duration_text, "%d sec.", scene_state->duration);
|
||||||
|
}
|
||||||
|
|
||||||
void totp_scene_add_new_token_activate(
|
void totp_scene_add_new_token_activate(
|
||||||
PluginState* plugin_state,
|
PluginState* plugin_state,
|
||||||
const TokenAddEditSceneContext* context) {
|
const TokenAddEditSceneContext* context) {
|
||||||
@ -89,6 +96,9 @@ void totp_scene_add_new_token_activate(
|
|||||||
scene_state->screen_y_offset = 0;
|
scene_state->screen_y_offset = 0;
|
||||||
|
|
||||||
scene_state->input_state = NULL;
|
scene_state->input_state = NULL;
|
||||||
|
scene_state->duration = TOTP_TOKEN_DURATION_DEFAULT;
|
||||||
|
scene_state->duration_text = furi_string_alloc();
|
||||||
|
update_duration_text(scene_state);
|
||||||
|
|
||||||
if(context == NULL) {
|
if(context == NULL) {
|
||||||
TOTP_NULLABLE_NULL(scene_state->current_token_index);
|
TOTP_NULLABLE_NULL(scene_state->current_token_index);
|
||||||
@ -124,14 +134,23 @@ void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_s
|
|||||||
ui_control_select_render(
|
ui_control_select_render(
|
||||||
canvas,
|
canvas,
|
||||||
0,
|
0,
|
||||||
63 - scene_state->screen_y_offset,
|
61 - scene_state->screen_y_offset,
|
||||||
SCREEN_WIDTH,
|
SCREEN_WIDTH,
|
||||||
TOKEN_DIGITS_TEXT_LIST[scene_state->digits_count_index],
|
TOKEN_DIGITS_TEXT_LIST[scene_state->digits_count_index],
|
||||||
scene_state->selected_control == TokenLengthSelect);
|
scene_state->selected_control == TokenLengthSelect);
|
||||||
|
|
||||||
|
ui_control_select_render(
|
||||||
|
canvas,
|
||||||
|
0,
|
||||||
|
78 - scene_state->screen_y_offset,
|
||||||
|
SCREEN_WIDTH,
|
||||||
|
furi_string_get_cstr(scene_state->duration_text),
|
||||||
|
scene_state->selected_control == TokenDurationSelect);
|
||||||
|
|
||||||
ui_control_button_render(
|
ui_control_button_render(
|
||||||
canvas,
|
canvas,
|
||||||
SCREEN_WIDTH_CENTER - 24,
|
SCREEN_WIDTH_CENTER - 24,
|
||||||
85 - scene_state->screen_y_offset,
|
101 - scene_state->screen_y_offset,
|
||||||
48,
|
48,
|
||||||
13,
|
13,
|
||||||
"Confirm",
|
"Confirm",
|
||||||
@ -146,8 +165,12 @@ void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_s
|
|||||||
}
|
}
|
||||||
|
|
||||||
void update_screen_y_offset(SceneState* scene_state) {
|
void update_screen_y_offset(SceneState* scene_state) {
|
||||||
if(scene_state->selected_control > TokenAlgoSelect) {
|
if(scene_state->selected_control > TokenLengthSelect) {
|
||||||
scene_state->screen_y_offset = 35;
|
scene_state->screen_y_offset = 51;
|
||||||
|
} else if(scene_state->selected_control > TokenAlgoSelect) {
|
||||||
|
scene_state->screen_y_offset = 34;
|
||||||
|
} else if(scene_state->selected_control > TokenSecretTextBox) {
|
||||||
|
scene_state->screen_y_offset = 17;
|
||||||
} else {
|
} else {
|
||||||
scene_state->screen_y_offset = 0;
|
scene_state->screen_y_offset = 0;
|
||||||
}
|
}
|
||||||
@ -197,6 +220,9 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
|||||||
} else if(scene_state->selected_control == TokenLengthSelect) {
|
} else if(scene_state->selected_control == TokenLengthSelect) {
|
||||||
totp_roll_value_uint8_t(
|
totp_roll_value_uint8_t(
|
||||||
&scene_state->digits_count_index, 1, 0, 1, RollOverflowBehaviorRoll);
|
&scene_state->digits_count_index, 1, 0, 1, RollOverflowBehaviorRoll);
|
||||||
|
} else if(scene_state->selected_control == TokenDurationSelect) {
|
||||||
|
totp_roll_value_uint8_t(&scene_state->duration, 15, 15, 255, RollOverflowBehaviorStop);
|
||||||
|
update_duration_text(scene_state);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case InputKeyLeft:
|
case InputKeyLeft:
|
||||||
@ -206,6 +232,10 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
|||||||
} else if(scene_state->selected_control == TokenLengthSelect) {
|
} else if(scene_state->selected_control == TokenLengthSelect) {
|
||||||
totp_roll_value_uint8_t(
|
totp_roll_value_uint8_t(
|
||||||
&scene_state->digits_count_index, -1, 0, 1, RollOverflowBehaviorRoll);
|
&scene_state->digits_count_index, -1, 0, 1, RollOverflowBehaviorRoll);
|
||||||
|
} else if(scene_state->selected_control == TokenDurationSelect) {
|
||||||
|
totp_roll_value_uint8_t(
|
||||||
|
&scene_state->duration, -15, 15, 255, RollOverflowBehaviorStop);
|
||||||
|
update_duration_text(scene_state);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case InputKeyOk:
|
case InputKeyOk:
|
||||||
@ -230,6 +260,8 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
|||||||
break;
|
break;
|
||||||
case TokenLengthSelect:
|
case TokenLengthSelect:
|
||||||
break;
|
break;
|
||||||
|
case TokenDurationSelect:
|
||||||
|
break;
|
||||||
case ConfirmButton: {
|
case ConfirmButton: {
|
||||||
TokenInfo* tokenInfo = token_info_alloc();
|
TokenInfo* tokenInfo = token_info_alloc();
|
||||||
bool token_secret_set = token_info_set_secret(
|
bool token_secret_set = token_info_set_secret(
|
||||||
@ -245,6 +277,7 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
|
|||||||
tokenInfo->name, scene_state->token_name, scene_state->token_name_length + 1);
|
tokenInfo->name, scene_state->token_name, scene_state->token_name_length + 1);
|
||||||
tokenInfo->algo = scene_state->algo;
|
tokenInfo->algo = scene_state->algo;
|
||||||
tokenInfo->digits = TOKEN_DIGITS_VALUE_LIST[scene_state->digits_count_index];
|
tokenInfo->digits = TOKEN_DIGITS_VALUE_LIST[scene_state->digits_count_index];
|
||||||
|
tokenInfo->duration = scene_state->duration;
|
||||||
|
|
||||||
TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, tokenInfo, furi_check);
|
TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, tokenInfo, furi_check);
|
||||||
plugin_state->tokens_count++;
|
plugin_state->tokens_count++;
|
||||||
@ -310,6 +343,8 @@ void totp_scene_add_new_token_deactivate(PluginState* plugin_state) {
|
|||||||
free(scene_state->token_secret_input_context->header_text);
|
free(scene_state->token_secret_input_context->header_text);
|
||||||
free(scene_state->token_secret_input_context);
|
free(scene_state->token_secret_input_context);
|
||||||
|
|
||||||
|
furi_string_free(scene_state->duration_text);
|
||||||
|
|
||||||
if(scene_state->input_state != NULL) {
|
if(scene_state->input_state != NULL) {
|
||||||
totp_input_text_free(scene_state->input_state);
|
totp_input_text_free(scene_state->input_state);
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,11 @@
|
|||||||
#include "../token_menu/totp_scene_token_menu.h"
|
#include "../token_menu/totp_scene_token_menu.h"
|
||||||
#include "../../../workers/type_code/type_code.h"
|
#include "../../../workers/type_code/type_code.h"
|
||||||
|
|
||||||
#define TOKEN_LIFETIME 30
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t current_token_index;
|
uint16_t current_token_index;
|
||||||
char last_code[TOTP_TOKEN_DIGITS_MAX_COUNT + 1];
|
char last_code[TOTP_TOKEN_DIGITS_MAX_COUNT + 1];
|
||||||
char* last_code_name;
|
|
||||||
bool need_token_update;
|
bool need_token_update;
|
||||||
|
TokenInfo* current_token;
|
||||||
uint32_t last_token_gen_time;
|
uint32_t last_token_gen_time;
|
||||||
TotpTypeCodeWorkerContext* type_code_worker_context;
|
TotpTypeCodeWorkerContext* type_code_worker_context;
|
||||||
NotificationMessage const** notification_sequence_new_token;
|
NotificationMessage const** notification_sequence_new_token;
|
||||||
@ -151,7 +149,7 @@ static void update_totp_params(PluginState* const plugin_state) {
|
|||||||
list_element_at(plugin_state->tokens_list, scene_state->current_token_index)->data;
|
list_element_at(plugin_state->tokens_list, scene_state->current_token_index)->data;
|
||||||
|
|
||||||
scene_state->need_token_update = true;
|
scene_state->need_token_update = true;
|
||||||
scene_state->last_code_name = tokenInfo->name;
|
scene_state->current_token = tokenInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +227,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
|||||||
furi_hal_rtc_get_datetime(&curr_dt);
|
furi_hal_rtc_get_datetime(&curr_dt);
|
||||||
uint32_t curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt);
|
uint32_t curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt);
|
||||||
|
|
||||||
bool is_new_token_time = curr_ts % TOKEN_LIFETIME == 0;
|
bool is_new_token_time = curr_ts % scene_state->current_token->duration == 0;
|
||||||
if(is_new_token_time && scene_state->last_token_gen_time != curr_ts) {
|
if(is_new_token_time && scene_state->last_token_gen_time != curr_ts) {
|
||||||
scene_state->need_token_update = true;
|
scene_state->need_token_update = true;
|
||||||
}
|
}
|
||||||
@ -238,10 +236,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
|||||||
scene_state->need_token_update = false;
|
scene_state->need_token_update = false;
|
||||||
scene_state->last_token_gen_time = curr_ts;
|
scene_state->last_token_gen_time = curr_ts;
|
||||||
|
|
||||||
const TokenInfo* tokenInfo =
|
const TokenInfo* tokenInfo = scene_state->current_token;
|
||||||
(TokenInfo*)(list_element_at(
|
|
||||||
plugin_state->tokens_list, scene_state->current_token_index)
|
|
||||||
->data);
|
|
||||||
|
|
||||||
if(tokenInfo->token != NULL && tokenInfo->token_length > 0) {
|
if(tokenInfo->token != NULL && tokenInfo->token_length > 0) {
|
||||||
furi_mutex_acquire(
|
furi_mutex_acquire(
|
||||||
@ -258,7 +253,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
|||||||
key_length,
|
key_length,
|
||||||
curr_ts,
|
curr_ts,
|
||||||
plugin_state->timezone_offset,
|
plugin_state->timezone_offset,
|
||||||
TOKEN_LIFETIME),
|
tokenInfo->duration),
|
||||||
scene_state->last_code,
|
scene_state->last_code,
|
||||||
tokenInfo->digits);
|
tokenInfo->digits);
|
||||||
memset_s(key, key_length, 0, key_length);
|
memset_s(key, key_length, 0, key_length);
|
||||||
@ -279,7 +274,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
|||||||
}
|
}
|
||||||
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
canvas_set_font(canvas, FontPrimary);
|
||||||
uint16_t token_name_width = canvas_string_width(canvas, scene_state->last_code_name);
|
uint16_t token_name_width = canvas_string_width(canvas, scene_state->current_token->name);
|
||||||
if(SCREEN_WIDTH - token_name_width > 18) {
|
if(SCREEN_WIDTH - token_name_width > 18) {
|
||||||
canvas_draw_str_aligned(
|
canvas_draw_str_aligned(
|
||||||
canvas,
|
canvas,
|
||||||
@ -287,7 +282,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
|||||||
SCREEN_HEIGHT_CENTER - 20,
|
SCREEN_HEIGHT_CENTER - 20,
|
||||||
AlignCenter,
|
AlignCenter,
|
||||||
AlignCenter,
|
AlignCenter,
|
||||||
scene_state->last_code_name);
|
scene_state->current_token->name);
|
||||||
} else {
|
} else {
|
||||||
canvas_draw_str_aligned(
|
canvas_draw_str_aligned(
|
||||||
canvas,
|
canvas,
|
||||||
@ -295,7 +290,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
|||||||
SCREEN_HEIGHT_CENTER - 20,
|
SCREEN_HEIGHT_CENTER - 20,
|
||||||
AlignLeft,
|
AlignLeft,
|
||||||
AlignCenter,
|
AlignCenter,
|
||||||
scene_state->last_code_name);
|
scene_state->current_token->name);
|
||||||
canvas_set_color(canvas, ColorWhite);
|
canvas_set_color(canvas, ColorWhite);
|
||||||
canvas_draw_box(canvas, 0, SCREEN_HEIGHT_CENTER - 24, 9, 9);
|
canvas_draw_box(canvas, 0, SCREEN_HEIGHT_CENTER - 24, 9, 9);
|
||||||
canvas_draw_box(canvas, SCREEN_WIDTH - 10, SCREEN_HEIGHT_CENTER - 24, 9, 9);
|
canvas_draw_box(canvas, SCREEN_WIDTH - 10, SCREEN_HEIGHT_CENTER - 24, 9, 9);
|
||||||
@ -313,6 +308,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_
|
|||||||
|
|
||||||
const uint8_t BAR_MARGIN = 3;
|
const uint8_t BAR_MARGIN = 3;
|
||||||
const uint8_t BAR_HEIGHT = 4;
|
const uint8_t BAR_HEIGHT = 4;
|
||||||
|
const uint8_t TOKEN_LIFETIME = scene_state->current_token->duration;
|
||||||
float percentDone = (float)(TOKEN_LIFETIME - curr_ts % TOKEN_LIFETIME) / (float)TOKEN_LIFETIME;
|
float percentDone = (float)(TOKEN_LIFETIME - curr_ts % TOKEN_LIFETIME) / (float)TOKEN_LIFETIME;
|
||||||
uint8_t barWidth = (uint8_t)((float)(SCREEN_WIDTH - (BAR_MARGIN << 1)) * percentDone);
|
uint8_t barWidth = (uint8_t)((float)(SCREEN_WIDTH - (BAR_MARGIN << 1)) * percentDone);
|
||||||
uint8_t barX = ((SCREEN_WIDTH - (BAR_MARGIN << 1) - barWidth) >> 1) + BAR_MARGIN;
|
uint8_t barX = ((SCREEN_WIDTH - (BAR_MARGIN << 1) - barWidth) >> 1) + BAR_MARGIN;
|
||||||
|
Loading…
Reference in New Issue
Block a user