Skip to content

Commit

Permalink
* Updated firmware submodules
Browse files Browse the repository at this point in the history
* Initial implementation of #11
  • Loading branch information
akopachov committed Oct 24, 2022
1 parent 75b3849 commit bc9836e
Show file tree
Hide file tree
Showing 18 changed files with 394 additions and 20 deletions.
1 change: 1 addition & 0 deletions scenes/authenticate/totp_scene_authenticate.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ void totp_scene_authenticate_activate(PluginState* plugin_state) {
scene_state->code_length = 0;
memset(&scene_state->code_input[0], 0, MAX_CODE_LENGTH);
plugin_state->current_scene_state = scene_state;
memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE);
}

void totp_scene_authenticate_render(Canvas* const canvas, PluginState* plugin_state) {
Expand Down
2 changes: 1 addition & 1 deletion scenes/generate_token/totp_scene_generate_token.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ void totp_scene_generate_token_activate(
}
}
SceneState* scene_state = malloc(sizeof(SceneState));
if(context == NULL) {
if(context == NULL || context->current_token_index > plugin_state->tokens_count) {
scene_state->current_token_index = 0;
} else {
scene_state->current_token_index = context->current_token_index;
Expand Down
8 changes: 8 additions & 0 deletions scenes/scene_director.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ void totp_scene_director_activate_scene(
case TotpSceneAppSettings:
totp_scene_app_settings_activate(plugin_state, context);
break;
case TotpSceneNone:
break;
}

plugin_state->current_scene = scene;
Expand All @@ -51,6 +53,8 @@ void totp_scene_director_deactivate_active_scene(PluginState* const plugin_state
case TotpSceneAppSettings:
totp_scene_app_settings_deactivate(plugin_state);
break;
case TotpSceneNone:
break;
}
}

Expand Down Expand Up @@ -79,6 +83,8 @@ void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_
case TotpSceneAppSettings:
totp_scene_app_settings_render(canvas, plugin_state);
break;
case TotpSceneNone:
break;
}
}

Expand Down Expand Up @@ -108,6 +114,8 @@ bool totp_scene_director_handle_event(PluginEvent* const event, PluginState* con
case TotpSceneAppSettings:
processing = totp_scene_app_settings_handle_event(event, plugin_state);
break;
case TotpSceneNone:
break;
}

return processing;
Expand Down
8 changes: 1 addition & 7 deletions scenes/token_menu/totp_scene_token_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,7 @@ bool totp_scene_token_menu_handle_event(PluginEvent* const event, PluginState* p
dialog_message_show(plugin_state->dialogs, message);
dialog_message_free(message);
if(dialog_result == DialogMessageButtonRight) {
uint8_t i = 0;

ListNode* list_node = plugin_state->tokens_list;
while(i < scene_state->current_token_index && list_node->next != NULL) {
list_node = list_node->next;
i++;
}
ListNode* list_node = list_element_at(plugin_state->tokens_list, scene_state->current_token_index);

TokenInfo* tokenInfo = list_node->data;
token_info_free(tokenInfo);
Expand Down
1 change: 1 addition & 0 deletions scenes/totp_scenes_enum.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

typedef enum {
TotpSceneNone,
TotpSceneAuthentication,
TotpSceneGenerateToken,
TotpSceneAddNewToken,
Expand Down
79 changes: 79 additions & 0 deletions services/cli/cli.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Original idea: https://github.com/br0ziliy

#include "cli.h"
#include <lib/toolbox/args.h>
#include "commands/list/list.h"
#include "commands/add/add.h"
#include "commands/delete/delete.h"

#define TOTP_CLI_COMMAND_NAME "totp"

static void totp_cli_print_unknown_command(FuriString* unknown_command) {
printf("Command \"%s\" is unknown. Use \"help\" command to get list of available commands.", furi_string_get_cstr(unknown_command));
}

static void totp_cli_print_help() {
printf("Usage:\r\n");
printf("totp <command> <arguments>\r\n");
printf("Command list:\r\n");
printf("\thelp - print command usage help\r\n");
printf("\tlist - list all tokens\r\n");
printf("\tdelete <INDEX> [-f] - delete token\r\n");
printf("\t\t<INDEX> - token index in the list\r\n");
printf("\t\t-f - [OPTIONAL] force command to do not ask user for interactive confirmation\r\n");
printf("\tadd <NAME> <SECRET> [-a <ALGO>] [-d <DIGITS>] - add new token\r\n");
printf("\t\t<NAME> - token name\r\n");
printf("\t\t<SECRET> - Base32 token secret\r\n");
printf("\t\t<ALGO> - [OPTIONAL] token hashing algorithm, could be one of: sha1, sha256, sha512; default: sha1\r\n");
printf("\t\t<DIGITS> - [OPTIONAL] number of digits to generate, one of: 6, 8; default: 6\r\n\r\n");
}

static void totp_cli_print_unauthenticated() {
printf("Pleases enter PIN on your flipper device\r\n");
}

static void totp_cli_handler(Cli* cli, FuriString* args, void* context) {
PluginState* plugin_state = (PluginState* )context;

if (plugin_state->current_scene == TotpSceneAuthentication) {
totp_cli_print_unauthenticated();

while (plugin_state->current_scene == TotpSceneAuthentication && !cli_cmd_interrupt_received(cli)) {
furi_delay_tick(0);
}

if (plugin_state->current_scene == TotpSceneAuthentication) {
return;
}
}

FuriString* cmd = furi_string_alloc();

args_read_string_and_trim(args, cmd);

if(furi_string_cmp_str(cmd, "help") == 0 || furi_string_empty(cmd)) {
totp_cli_print_help();
} else if(furi_string_cmp_str(cmd, "add") == 0) {
totp_cli_handle_add_command(plugin_state, args);
} else if(furi_string_cmp_str(cmd, "list") == 0) {
totp_cli_handle_list_command(plugin_state);
} else if(furi_string_cmp_str(cmd, "delete") == 0) {
totp_cli_handle_delete_command(plugin_state, args, cli);
} else {
totp_cli_print_unknown_command(cmd);
}

furi_string_free(cmd);
}

void totp_cli_register_command_handler(PluginState* plugin_state) {
Cli* cli = furi_record_open(RECORD_CLI);
cli_add_command(cli, TOTP_CLI_COMMAND_NAME, CliCommandFlagParallelSafe, totp_cli_handler, plugin_state);
furi_record_close(RECORD_CLI);
}

void totp_cli_unregister_command_handler() {
Cli* cli = furi_record_open(RECORD_CLI);
cli_delete_command(cli, TOTP_CLI_COMMAND_NAME);
furi_record_close(RECORD_CLI);
}
7 changes: 7 additions & 0 deletions services/cli/cli.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

#include <cli/cli.h>
#include "../../types/plugin_state.h"

void totp_cli_register_command_handler(PluginState* plugin_state);
void totp_cli_unregister_command_handler();
6 changes: 6 additions & 0 deletions services/cli/cli_common_helpers.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "cli_common_helpers.h"
#include <cli/cli.h>

void totp_cli_print_invalid_arguments() {
printf("Invalid command arguments. use \"help\" command to get list of available commands");
}
3 changes: 3 additions & 0 deletions services/cli/cli_common_helpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

void totp_cli_print_invalid_arguments();
125 changes: 125 additions & 0 deletions services/cli/commands/add/add.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#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 "../../cli_common_helpers.h"
#include "../../../../scenes/scene_director.h"

static bool token_info_set_digits_from_str(TokenInfo* token_info, FuriString* str) {
switch(furi_string_get_char(str, 0)) {
case '6':
token_info->digits = TOTP_6_DIGITS;
return true;
case '8':
token_info->digits = TOTP_8_DIGITS;
return true;
}

return false;
}

static bool token_info_set_algo_from_str(TokenInfo* token_info, FuriString* str) {
if(furi_string_cmpi_str(str, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME) == 0) {
token_info->algo = SHA1;
return true;
}

if(furi_string_cmpi_str(str, TOTP_CONFIG_TOKEN_ALGO_SHA256_NAME) == 0) {
token_info->algo = SHA256;
return true;
}

if(furi_string_cmpi_str(str, TOTP_CONFIG_TOKEN_ALGO_SHA512_NAME) == 0) {
token_info->algo = SHA512;
return true;
}

return false;
}

void totp_cli_handle_add_command(PluginState* plugin_state, FuriString* args) {
FuriString* temp_str = furi_string_alloc();
const char* temp_cstr;

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);
return;
}

temp_cstr = furi_string_get_cstr(temp_str);
token_info->name = malloc(strlen(temp_cstr) + 1);
strcpy(token_info->name, temp_cstr);

// Reading token secret
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);
return;
}

temp_cstr = furi_string_get_cstr(temp_str);
if (!token_info_set_secret(token_info, temp_cstr, strlen(temp_cstr), plugin_state->iv)) {
printf("Token secret seems to be invalid and can not be parsed\r\n");
furi_string_free(temp_str);
token_info_free(token_info);
return;
}

// Read optional arguments
while (args_read_string_and_trim(args, temp_str)) {
bool parsed = false;
if (furi_string_cmpi_str(temp_str, "-a") == 0) {
if (!args_read_string_and_trim(args, temp_str)) {
printf("Missed value for argument \"-a\"\r\n");
} else if (!token_info_set_algo_from_str(token_info, temp_str)) {
printf("\"%s\" is incorrect value for argument \"-a\"\r\n", furi_string_get_cstr(temp_str));
} else {
parsed = true;
}
} else if (furi_string_cmpi_str(temp_str, "-d") == 0) {
if (!args_read_string_and_trim(args, temp_str)) {
printf("Missed value for argument \"-d\"\r\n");
} else if (!token_info_set_digits_from_str(token_info, temp_str)) {
printf("\"%s\" is incorrect value for argument \"-d\"\r\n", furi_string_get_cstr(temp_str));
} else {
parsed = true;
}
}
if (!parsed) {
totp_cli_print_invalid_arguments();
furi_string_free(temp_str);
token_info_free(token_info);
return;
}
}

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;
}

if(plugin_state->tokens_list == NULL) {
plugin_state->tokens_list = list_init_head(token_info);
} else {
list_add(plugin_state->tokens_list, token_info);
}
plugin_state->tokens_count++;
totp_config_file_save_new_token(token_info);

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

furi_string_free(temp_str);

printf("Token \"%s\" has been successfully added\r\n", token_info->name);
}
6 changes: 6 additions & 0 deletions services/cli/commands/add/add.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

#include <cli/cli.h>
#include "../../../../types/plugin_state.h"

void totp_cli_handle_add_command(PluginState* plugin_state, FuriString* args);
71 changes: 71 additions & 0 deletions services/cli/commands/delete/delete.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include "delete.h"

#include <stdlib.h>
#include <ctype.h>
#include <lib/toolbox/args.h>
#include "../../../list/list.h"
#include "../../../config/config.h"
#include "../../cli_common_helpers.h"
#include "../../../../scenes/scene_director.h"

void totp_cli_handle_delete_command(PluginState* plugin_state, FuriString* args, Cli* cli) {
int token_number;
if (!args_read_int_and_trim(args, &token_number) || token_number <= 0 || token_number > plugin_state->tokens_count) {
totp_cli_print_invalid_arguments();
return;
}

FuriString* temp_str = furi_string_alloc();
bool confirm_needed = true;
if (args_read_string_and_trim(args, temp_str)) {
if (furi_string_cmpi_str(temp_str, "-f") == 0) {
confirm_needed = false;
} else {
printf("Unknown argument \"%s\"\r\n", furi_string_get_cstr(temp_str));
totp_cli_print_invalid_arguments();
furi_string_free(temp_str);
return;
}
}
furi_string_free(temp_str);

ListNode* list_node = list_element_at(plugin_state->tokens_list, token_number - 1);

TokenInfo* token_info = list_node->data;

bool confirmed = !confirm_needed;
if (confirm_needed) {
printf("WARNING!\r\n");
printf("Token \"%s\" will be permanently deleted without ability to recover it.\r\n", token_info->name);
printf("Confirm? [y/n]\r\n");
fflush(stdout);
char user_pick;
do {
user_pick = tolower(cli_getc(cli));
} while (user_pick != 'y' && user_pick != 'n' && user_pick != 0x0d);

confirmed = user_pick == 'y' || user_pick == 0x0d;
}

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

plugin_state->tokens_list = list_remove(plugin_state->tokens_list, list_node);
plugin_state->tokens_count--;

totp_full_save_config_file(plugin_state);

if (activate_generate_token_scene) {
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
}

printf("Token \"%s\" has been successfully deleted\r\n", token_info->name);
token_info_free(token_info);
} else {
printf("User not confirmed\r\n");
}
}
6 changes: 6 additions & 0 deletions services/cli/commands/delete/delete.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

#include <cli/cli.h>
#include "../../../../types/plugin_state.h"

void totp_cli_handle_delete_command(PluginState* plugin_state, FuriString* args, Cli* cli);
Loading

0 comments on commit bc9836e

Please sign in to comment.