Skip to content

Commit

Permalink
Implemented PIN changing via CLI (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
akopachov committed Nov 21, 2022
1 parent 018aa7e commit fea22d7
Show file tree
Hide file tree
Showing 58 changed files with 372 additions and 175 deletions.
19 changes: 18 additions & 1 deletion application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 4 additions & 0 deletions services/cli/cli.c → cli/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion services/cli/cli.h → cli/cli.h
Original file line number Diff line number Diff line change
@@ -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();
File renamed without changes.
2 changes: 1 addition & 1 deletion services/cli/cli_helpers.h → cli/cli_helpers.h
Original file line number Diff line number Diff line change
@@ -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"

Expand Down
10 changes: 5 additions & 5 deletions services/cli/commands/add/add.c → cli/commands/add/add.c
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion services/cli/commands/add/add.h → cli/commands/add/add.h
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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();
Expand All @@ -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();
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
166 changes: 166 additions & 0 deletions cli/commands/pin/pin.c
Original file line number Diff line number Diff line change
@@ -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 changes: 10 additions & 0 deletions cli/commands/pin/pin.h
Original file line number Diff line number Diff line change
@@ -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();
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
11 changes: 11 additions & 0 deletions lib/polyfills/strnlen.c
Original file line number Diff line number Diff line change
@@ -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;
}
Loading

0 comments on commit fea22d7

Please sign in to comment.