Skip to content

Commit fea22d7

Browse files
authored
Implemented PIN changing via CLI (#32)
1 parent 018aa7e commit fea22d7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+372
-175
lines changed

application.fam

+18-1
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,22 @@ App(
1616
order=20,
1717
fap_category="Misc",
1818
fap_icon_assets="images",
19-
fap_icon="totp_10px.png"
19+
fap_icon="totp_10px.png",
20+
fap_private_libs=[
21+
Lib(
22+
name="base32",
23+
),
24+
Lib(
25+
name="list",
26+
),
27+
Lib(
28+
name="timezone_utils",
29+
),
30+
Lib(
31+
name="polyfills",
32+
),
33+
Lib(
34+
name="roll_value",
35+
),
36+
],
2037
)

services/cli/cli.c cli/cli.c

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "commands/timezone/timezone.h"
1010
#include "commands/help/help.h"
1111
#include "commands/move/move.h"
12+
#include "commands/pin/pin.h"
1213

1314
static void totp_cli_print_unknown_command(const FuriString* unknown_command) {
1415
TOTP_CLI_PRINTF(
@@ -49,6 +50,9 @@ static void totp_cli_handler(Cli* cli, FuriString* args, void* context) {
4950
furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_MOVE) == 0 ||
5051
furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_MOVE_ALT) == 0) {
5152
totp_cli_command_move_handle(plugin_state, args, cli);
53+
} else if(
54+
furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_PIN) == 0) {
55+
totp_cli_command_pin_handle(plugin_state, args, cli);
5256
} else {
5357
totp_cli_print_unknown_command(cmd);
5458
}

services/cli/cli.h cli/cli.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22

33
#include <cli/cli.h>
4-
#include "../../types/plugin_state.h"
4+
#include "../types/plugin_state.h"
55

66
void totp_cli_register_command_handler(PluginState* plugin_state);
77
void totp_cli_unregister_command_handler();
File renamed without changes.

services/cli/cli_helpers.h cli/cli_helpers.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22

33
#include <cli/cli.h>
4-
#include "../../types/plugin_state.h"
4+
#include "../types/plugin_state.h"
55

66
#define TOTP_CLI_COMMAND_NAME "totp"
77

services/cli/commands/add/add.c cli/commands/add/add.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#include "add.h"
22
#include <stdlib.h>
33
#include <lib/toolbox/args.h>
4-
#include "../../../list/list.h"
5-
#include "../../../../types/token_info.h"
6-
#include "../../../config/config.h"
4+
#include "../../../lib/list/list.h"
5+
#include "../../../types/token_info.h"
6+
#include "../../../services/config/config.h"
77
#include "../../cli_helpers.h"
8-
#include "../../../../scenes/scene_director.h"
8+
#include "../../../ui/scene_director.h"
99

1010
#define TOTP_CLI_COMMAND_ADD_ARG_NAME "name"
1111
#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
9494
while(cli_read(cli, &c, 1) == 1) {
9595
if(c == CliSymbolAsciiEsc) {
9696
// Some keys generating escape-sequences
97-
// We need to ignore them as we case about alpha-numerics only
97+
// We need to ignore them as we care about alpha-numerics only
9898
uint8_t c2;
9999
cli_read_timeout(cli, &c2, 1, 0);
100100
cli_read_timeout(cli, &c2, 1, 0);

services/cli/commands/add/add.h cli/commands/add/add.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22

33
#include <cli/cli.h>
4-
#include "../../../../types/plugin_state.h"
4+
#include "../../../types/plugin_state.h"
55

66
#define TOTP_CLI_COMMAND_ADD "add"
77
#define TOTP_CLI_COMMAND_ADD_ALT "mk"

services/cli/commands/delete/delete.c cli/commands/delete/delete.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
#include <stdlib.h>
44
#include <ctype.h>
55
#include <lib/toolbox/args.h>
6-
#include "../../../list/list.h"
7-
#include "../../../config/config.h"
6+
#include "../../../lib/list/list.h"
7+
#include "../../../services/config/config.h"
88
#include "../../cli_helpers.h"
9-
#include "../../../../scenes/scene_director.h"
9+
#include "../../../ui/scene_director.h"
1010

1111
#define TOTP_CLI_COMMAND_DELETE_ARG_INDEX "index"
1212
#define TOTP_CLI_COMMAND_DELETE_ARG_FORCE_SUFFIX "-f"

services/cli/commands/delete/delete.h cli/commands/delete/delete.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22

33
#include <cli/cli.h>
4-
#include "../../../../types/plugin_state.h"
4+
#include "../../../types/plugin_state.h"
55

66
#define TOTP_CLI_COMMAND_DELETE "delete"
77
#define TOTP_CLI_COMMAND_DELETE_ALT "rm"

services/cli/commands/help/help.c cli/commands/help/help.c

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "../list/list.h"
66
#include "../timezone/timezone.h"
77
#include "../move/move.h"
8+
#include "../pin/pin.h"
89

910
void totp_cli_command_help_docopt_commands() {
1011
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_HELP ", " TOTP_CLI_COMMAND_HELP_ALT
@@ -25,6 +26,7 @@ void totp_cli_command_help_handle() {
2526
totp_cli_command_delete_docopt_usage();
2627
totp_cli_command_timezone_docopt_usage();
2728
totp_cli_command_move_docopt_usage();
29+
totp_cli_command_pin_docopt_usage();
2830
cli_nl();
2931
TOTP_CLI_PRINTF("Commands:\r\n");
3032
totp_cli_command_help_docopt_commands();
@@ -33,6 +35,7 @@ void totp_cli_command_help_handle() {
3335
totp_cli_command_delete_docopt_commands();
3436
totp_cli_command_timezone_docopt_commands();
3537
totp_cli_command_move_docopt_commands();
38+
totp_cli_command_pin_docopt_commands();
3639
cli_nl();
3740
TOTP_CLI_PRINTF("Arguments:\r\n");
3841
totp_cli_command_add_docopt_arguments();
File renamed without changes.

services/cli/commands/list/list.c cli/commands/list/list.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#include "list.h"
22
#include <stdlib.h>
3-
#include "../../../list/list.h"
4-
#include "../../../../types/token_info.h"
5-
#include "../../../config/constants.h"
3+
#include "../../../lib/list/list.h"
4+
#include "../../../types/token_info.h"
5+
#include "../../../services/config/constants.h"
66
#include "../../cli_helpers.h"
77

88
static char* get_algo_as_cstr(TokenHashAlgo algo) {

services/cli/commands/list/list.h cli/commands/list/list.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22

33
#include <cli/cli.h>
4-
#include "../../../../types/plugin_state.h"
4+
#include "../../../types/plugin_state.h"
55

66
#define TOTP_CLI_COMMAND_LIST "list"
77
#define TOTP_CLI_COMMAND_LIST_ALT "ls"

services/cli/commands/move/move.c cli/commands/move/move.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
#include <stdlib.h>
44
#include <lib/toolbox/args.h>
5-
#include "../../../list/list.h"
6-
#include "../../../../types/token_info.h"
7-
#include "../../../config/config.h"
5+
#include "../../../lib/list/list.h"
6+
#include "../../../types/token_info.h"
7+
#include "../../../services/config/config.h"
88
#include "../../cli_helpers.h"
9-
#include "../../../../scenes/scene_director.h"
9+
#include "../../../ui/scene_director.h"
1010

1111
#define TOTP_CLI_COMMAND_MOVE_ARG_INDEX "index"
1212

services/cli/commands/move/move.h cli/commands/move/move.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22

33
#include <cli/cli.h>
4-
#include "../../../../types/plugin_state.h"
4+
#include "../../../types/plugin_state.h"
55

66
#define TOTP_CLI_COMMAND_MOVE "move"
77
#define TOTP_CLI_COMMAND_MOVE_ALT "mv"

cli/commands/pin/pin.c

+166
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#include "pin.h"
2+
3+
#include <stdlib.h>
4+
#include <lib/toolbox/args.h>
5+
#include "../../../types/token_info.h"
6+
#include "../../../types/user_pin_codes.h"
7+
#include "../../../services/config/config.h"
8+
#include "../../cli_helpers.h"
9+
#include "../../../lib/polyfills/memset_s.h"
10+
#include "../../../services/crypto/crypto.h"
11+
#include "../../../ui/scene_director.h"
12+
13+
#define TOTP_CLI_COMMAND_PIN_COMMAND_SET "set"
14+
#define TOTP_CLI_COMMAND_PIN_COMMAND_REMOVE "remove"
15+
16+
void totp_cli_command_pin_docopt_commands() {
17+
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_PIN " Set\\change\\remove PIN\r\n");
18+
}
19+
20+
void totp_cli_command_pin_docopt_usage() {
21+
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");
22+
}
23+
24+
static bool totp_cli_read_pin(Cli* cli, uint8_t* pin, uint8_t* pin_length) {
25+
TOTP_CLI_PRINTF("Enter new PIN (use arrow keys on your keyboard): ");
26+
fflush(stdout);
27+
uint8_t c;
28+
*pin_length = 0;
29+
while(cli_read(cli, &c, 1) == 1) {
30+
if(c == CliSymbolAsciiEsc) {
31+
uint8_t c2;
32+
uint8_t c3;
33+
if (cli_read_timeout(cli, &c2, 1, 0) == 1 &&
34+
cli_read_timeout(cli, &c3, 1, 0) == 1 &&
35+
c2 == 0x5b) {
36+
uint8_t code = 0;
37+
switch (c3) {
38+
case 0x44: // left
39+
code = PinCodeArrowLeft;
40+
break;
41+
case 0x41: // up
42+
code = PinCodeArrowUp;
43+
break;
44+
case 0x43: // right
45+
code = PinCodeArrowRight;
46+
break;
47+
case 0x42: // down
48+
code = PinCodeArrowDown;
49+
break;
50+
default:
51+
break;
52+
}
53+
54+
if (code > 0) {
55+
pin[*pin_length] = code;
56+
*pin_length = *pin_length + 1;
57+
putc('*', stdout);
58+
fflush(stdout);
59+
}
60+
}
61+
} else if(c == CliSymbolAsciiETX) {
62+
TOTP_CLI_DELETE_CURRENT_LINE();
63+
TOTP_CLI_PRINTF("Cancelled by user\r\n");
64+
return false;
65+
} else if(c == CliSymbolAsciiBackspace || c == CliSymbolAsciiDel) {
66+
if (*pin_length > 0) {
67+
*pin_length = *pin_length - 1;
68+
pin[*pin_length] = 0;
69+
TOTP_CLI_DELETE_LAST_CHAR();
70+
}
71+
} else if(c == CliSymbolAsciiCR) {
72+
cli_nl();
73+
break;
74+
}
75+
}
76+
77+
TOTP_CLI_DELETE_LAST_LINE();
78+
return true;
79+
}
80+
81+
void totp_cli_command_pin_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
82+
UNUSED(plugin_state);
83+
FuriString* temp_str = furi_string_alloc();
84+
85+
bool do_change = false;
86+
bool do_remove = false;
87+
UNUSED(do_remove);
88+
do {
89+
if (!args_read_string_and_trim(args, temp_str)) {
90+
TOTP_CLI_PRINT_INVALID_ARGUMENTS();
91+
break;
92+
}
93+
94+
if (furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_PIN_COMMAND_SET) == 0) {
95+
do_change = true;
96+
} else if (furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_PIN_COMMAND_REMOVE) == 0) {
97+
do_remove = true;
98+
} else {
99+
TOTP_CLI_PRINT_INVALID_ARGUMENTS();
100+
break;
101+
}
102+
} while (false);
103+
104+
if ((do_change || do_remove) && totp_cli_ensure_authenticated(plugin_state, cli)) {
105+
bool load_generate_token_scene = false;
106+
do {
107+
uint8_t old_iv[TOTP_IV_SIZE];
108+
memcpy(&old_iv[0], &plugin_state->iv[0], TOTP_IV_SIZE);
109+
uint8_t new_pin[TOTP_IV_SIZE];
110+
uint8_t new_pin_length = 0;
111+
if (do_change) {
112+
if (!totp_cli_read_pin(cli, &new_pin[0], &new_pin_length) ||
113+
!totp_cli_ensure_authenticated(plugin_state, cli)) {
114+
memset_s(&new_pin[0], TOTP_IV_SIZE, 0, TOTP_IV_SIZE);
115+
break;
116+
}
117+
} else if (do_remove) {
118+
new_pin_length = 0;
119+
memset(&new_pin[0], 0, TOTP_IV_SIZE);
120+
}
121+
122+
if(plugin_state->current_scene == TotpSceneGenerateToken) {
123+
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
124+
load_generate_token_scene = true;
125+
}
126+
127+
TOTP_CLI_PRINTF("Encrypting, please wait...\r\n");
128+
129+
memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE);
130+
memset(&plugin_state->base_iv[0], 0, TOTP_IV_SIZE);
131+
if (plugin_state->crypto_verify_data != NULL) {
132+
free(plugin_state->crypto_verify_data);
133+
plugin_state->crypto_verify_data = NULL;
134+
}
135+
136+
totp_crypto_seed_iv(plugin_state, new_pin_length > 0 ? &new_pin[0] : NULL, new_pin_length);
137+
ListNode* node = plugin_state->tokens_list;
138+
while (node != NULL) {
139+
TokenInfo* token_info = node->data;
140+
size_t plain_token_length;
141+
uint8_t* plain_token = totp_crypto_decrypt(token_info->token, token_info->token_length, &old_iv[0], &plain_token_length);
142+
free(token_info->token);
143+
token_info->token = totp_crypto_encrypt(plain_token, plain_token_length, &plugin_state->iv[0], &token_info->token_length);
144+
memset_s(plain_token, plain_token_length, 0, plain_token_length);
145+
free(plain_token);
146+
node = node->next;
147+
}
148+
149+
totp_full_save_config_file(plugin_state);
150+
151+
TOTP_CLI_DELETE_LAST_LINE();
152+
153+
if (do_change) {
154+
TOTP_CLI_PRINTF("PIN has been successfully changed\r\n");
155+
} else if (do_remove) {
156+
TOTP_CLI_PRINTF("PIN has been successfully removed\r\n");
157+
}
158+
} while (false);
159+
160+
if(load_generate_token_scene) {
161+
totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL);
162+
}
163+
}
164+
165+
furi_string_free(temp_str);
166+
}

cli/commands/pin/pin.h

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#pragma once
2+
3+
#include <cli/cli.h>
4+
#include "../../../types/plugin_state.h"
5+
6+
#define TOTP_CLI_COMMAND_PIN "pin"
7+
8+
void totp_cli_command_pin_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
9+
void totp_cli_command_pin_docopt_commands();
10+
void totp_cli_command_pin_docopt_usage();

services/cli/commands/timezone/timezone.c cli/commands/timezone/timezone.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include "timezone.h"
22
#include <lib/toolbox/args.h>
3-
#include "../../../config/config.h"
4-
#include "../../../../scenes/scene_director.h"
3+
#include "../../../services/config/config.h"
4+
#include "../../../ui/scene_director.h"
55
#include "../../cli_helpers.h"
66

77
#define TOTP_CLI_COMMAND_TIMEZONE_ARG_TIMEZONE "timezone"

services/cli/commands/timezone/timezone.h cli/commands/timezone/timezone.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22

33
#include <cli/cli.h>
4-
#include "../../../../types/plugin_state.h"
4+
#include "../../../types/plugin_state.h"
55

66
#define TOTP_CLI_COMMAND_TIMEZONE "timezone"
77
#define TOTP_CLI_COMMAND_TIMEZONE_ALT "tz"
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

lib/polyfills/strnlen.c

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "strnlen.h"
2+
3+
size_t strnlen(const char* s, size_t maxlen) {
4+
size_t len;
5+
6+
for(len = 0; len < maxlen; len++, s++) {
7+
if(!*s) break;
8+
}
9+
10+
return len;
11+
}

0 commit comments

Comments
 (0)