Skip to content

Commit 03a7f93

Browse files
authored
Implemented BadBT automation (#91)
1 parent 97c6116 commit 03a7f93

27 files changed

+702
-95
lines changed

application.fam

+7-1
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@ App(
1010
"dialogs",
1111
"storage",
1212
"input",
13-
"notification"
13+
"notification",
14+
#ifdef TOTP_BADBT_TYPE_ENABLED
15+
"bt"
16+
#endif
1417
],
1518
stack_size=2 * 1024,
1619
order=20,
20+
fap_author="Alexander Kopachov (@akopachov)",
21+
fap_description="Software-based TOTP authenticator for Flipper Zero device",
22+
fap_weburl="https://github.com/akopachov/flipper-zero_authenticator",
1723
fap_category="Misc",
1824
fap_icon_assets="images",
1925
fap_icon="totp_10px.png",

cli/cli.c

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "commands/pin/pin.h"
1313
#include "commands/notification/notification.h"
1414
#include "commands/reset/reset.h"
15+
#include "commands/automation/automation.h"
1516

1617
static void totp_cli_print_unknown_command(const FuriString* unknown_command) {
1718
TOTP_CLI_PRINTF_ERROR(
@@ -57,6 +58,8 @@ static void totp_cli_handler(Cli* cli, FuriString* args, void* context) {
5758
totp_cli_command_pin_handle(plugin_state, args, cli);
5859
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_NOTIFICATION) == 0) {
5960
totp_cli_command_notification_handle(plugin_state, args, cli);
61+
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_AUTOMATION) == 0) {
62+
totp_cli_command_automation_handle(plugin_state, args, cli);
6063
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_RESET) == 0) {
6164
totp_cli_command_reset_handle(cli, cli_context->event_queue);
6265
} else {

cli/commands/add/add.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ void totp_cli_command_add_docopt_usage() {
6262
}
6363

6464
void totp_cli_command_add_docopt_arguments() {
65-
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_ADD_ARG_NAME " Token name\r\n");
65+
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_ADD_ARG_NAME " Token name\r\n");
6666
}
6767

6868
void totp_cli_command_add_docopt_options() {

cli/commands/automation/automation.c

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#include "automation.h"
2+
#include <lib/toolbox/args.h>
3+
#include "../../../services/config/config.h"
4+
#include "../../../ui/scene_director.h"
5+
#include "../../cli_helpers.h"
6+
7+
#define TOTP_CLI_COMMAND_AUTOMATION_ARG_METHOD "automation"
8+
#define TOTP_CLI_COMMAND_AUTOMATION_METHOD_NONE "none"
9+
#define TOTP_CLI_COMMAND_AUTOMATION_METHOD_USB "usb"
10+
#ifdef TOTP_BADBT_TYPE_ENABLED
11+
#define TOTP_CLI_COMMAND_AUTOMATION_METHOD_BT "bt"
12+
#endif
13+
14+
void totp_cli_command_automation_docopt_commands() {
15+
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_AUTOMATION " Get or set automation method\r\n");
16+
}
17+
18+
void totp_cli_command_automation_docopt_usage() {
19+
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_NAME " " TOTP_CLI_COMMAND_AUTOMATION " " DOCOPT_OPTIONAL(
20+
DOCOPT_MULTIPLE(DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_AUTOMATION_ARG_METHOD))) "\r\n");
21+
}
22+
23+
void totp_cli_command_automation_docopt_arguments() {
24+
TOTP_CLI_PRINTF(
25+
" " TOTP_CLI_COMMAND_AUTOMATION_ARG_METHOD
26+
" Automation method to be set. Must be one of [" TOTP_CLI_COMMAND_AUTOMATION_METHOD_NONE
27+
", " TOTP_CLI_COMMAND_AUTOMATION_METHOD_USB
28+
#ifdef TOTP_BADBT_TYPE_ENABLED
29+
", " TOTP_CLI_COMMAND_AUTOMATION_METHOD_BT
30+
#endif
31+
"]\r\n");
32+
}
33+
34+
static void totp_cli_command_automation_print_method(AutomationMethod method, char* color) {
35+
#ifdef TOTP_BADBT_TYPE_ENABLED
36+
bool has_previous_method = false;
37+
#endif
38+
if(method & AutomationMethodBadUsb) {
39+
TOTP_CLI_PRINTF_COLORFUL(color, "\"" TOTP_CLI_COMMAND_AUTOMATION_METHOD_USB "\"");
40+
#ifdef TOTP_BADBT_TYPE_ENABLED
41+
has_previous_method = true;
42+
#endif
43+
}
44+
45+
#ifdef TOTP_BADBT_TYPE_ENABLED
46+
if(method & AutomationMethodBadBt) {
47+
if(has_previous_method) {
48+
TOTP_CLI_PRINTF_COLORFUL(color, " and ");
49+
}
50+
51+
TOTP_CLI_PRINTF_COLORFUL(color, "\"" TOTP_CLI_COMMAND_AUTOMATION_METHOD_BT "\"");
52+
}
53+
#endif
54+
55+
if(method == AutomationMethodNone) {
56+
TOTP_CLI_PRINTF_COLORFUL(color, "\"" TOTP_CLI_COMMAND_AUTOMATION_METHOD_NONE "\"");
57+
}
58+
}
59+
60+
void totp_cli_command_automation_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
61+
if(!totp_cli_ensure_authenticated(plugin_state, cli)) {
62+
return;
63+
}
64+
65+
FuriString* temp_str = furi_string_alloc();
66+
bool new_method_provided = false;
67+
AutomationMethod new_method = AutomationMethodNone;
68+
bool args_valid = true;
69+
while(args_read_string_and_trim(args, temp_str)) {
70+
if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_AUTOMATION_METHOD_NONE) == 0) {
71+
new_method_provided = true;
72+
new_method = AutomationMethodNone;
73+
} else if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_AUTOMATION_METHOD_USB) == 0) {
74+
new_method_provided = true;
75+
new_method |= AutomationMethodBadUsb;
76+
}
77+
#ifdef TOTP_BADBT_TYPE_ENABLED
78+
else if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_AUTOMATION_METHOD_BT) == 0) {
79+
new_method_provided = true;
80+
new_method |= AutomationMethodBadBt;
81+
}
82+
#endif
83+
else {
84+
args_valid = false;
85+
break;
86+
}
87+
}
88+
89+
do {
90+
if(!args_valid) {
91+
TOTP_CLI_PRINT_INVALID_ARGUMENTS();
92+
break;
93+
}
94+
95+
if(new_method_provided) {
96+
Scene previous_scene = TotpSceneNone;
97+
if(plugin_state->current_scene == TotpSceneGenerateToken ||
98+
plugin_state->current_scene == TotpSceneAppSettings) {
99+
previous_scene = plugin_state->current_scene;
100+
totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL);
101+
}
102+
103+
plugin_state->automation_method = new_method;
104+
if(totp_config_file_update_automation_method(new_method) ==
105+
TotpConfigFileUpdateSuccess) {
106+
TOTP_CLI_PRINTF_SUCCESS("Automation method is set to ");
107+
totp_cli_command_automation_print_method(new_method, TOTP_CLI_COLOR_SUCCESS);
108+
cli_nl();
109+
} else {
110+
TOTP_CLI_PRINT_ERROR_UPDATING_CONFIG_FILE();
111+
}
112+
113+
#ifdef TOTP_BADBT_TYPE_ENABLED
114+
if(!(new_method & AutomationMethodBadBt) &&
115+
plugin_state->bt_type_code_worker_context != NULL) {
116+
totp_bt_type_code_worker_free(plugin_state->bt_type_code_worker_context);
117+
plugin_state->bt_type_code_worker_context = NULL;
118+
}
119+
#endif
120+
121+
if(previous_scene != TotpSceneNone) {
122+
totp_scene_director_activate_scene(plugin_state, previous_scene, NULL);
123+
}
124+
} else {
125+
TOTP_CLI_PRINTF_INFO("Current automation method is ");
126+
totp_cli_command_automation_print_method(
127+
plugin_state->automation_method, TOTP_CLI_COLOR_INFO);
128+
cli_nl();
129+
}
130+
} while(false);
131+
132+
furi_string_free(temp_str);
133+
}

cli/commands/automation/automation.h

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#pragma once
2+
3+
#include <cli/cli.h>
4+
#include "../../../types/plugin_state.h"
5+
6+
#define TOTP_CLI_COMMAND_AUTOMATION "automation"
7+
8+
void totp_cli_command_automation_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
9+
void totp_cli_command_automation_docopt_commands();
10+
void totp_cli_command_automation_docopt_usage();
11+
void totp_cli_command_automation_docopt_arguments();

cli/commands/delete/delete.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ void totp_cli_command_delete_docopt_usage() {
2424
}
2525

2626
void totp_cli_command_delete_docopt_arguments() {
27-
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_DELETE_ARG_INDEX " Token index in the list\r\n");
27+
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_DELETE_ARG_INDEX " Token index in the list\r\n");
2828
}
2929

3030
void totp_cli_command_delete_docopt_options() {

cli/commands/help/help.c

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "../pin/pin.h"
99
#include "../notification/notification.h"
1010
#include "../reset/reset.h"
11+
#include "../automation/automation.h"
1112

1213
void totp_cli_command_help_docopt_commands() {
1314
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_HELP ", " TOTP_CLI_COMMAND_HELP_ALT
@@ -31,6 +32,7 @@ void totp_cli_command_help_handle() {
3132
totp_cli_command_pin_docopt_usage();
3233
totp_cli_command_notification_docopt_usage();
3334
totp_cli_command_reset_docopt_usage();
35+
totp_cli_command_automation_docopt_usage();
3436
cli_nl();
3537
TOTP_CLI_PRINTF("Commands:\r\n");
3638
totp_cli_command_help_docopt_commands();
@@ -42,12 +44,14 @@ void totp_cli_command_help_handle() {
4244
totp_cli_command_pin_docopt_commands();
4345
totp_cli_command_notification_docopt_commands();
4446
totp_cli_command_reset_docopt_commands();
47+
totp_cli_command_automation_docopt_commands();
4548
cli_nl();
4649
TOTP_CLI_PRINTF("Arguments:\r\n");
4750
totp_cli_command_add_docopt_arguments();
4851
totp_cli_command_delete_docopt_arguments();
4952
totp_cli_command_timezone_docopt_arguments();
5053
totp_cli_command_notification_docopt_arguments();
54+
totp_cli_command_automation_docopt_arguments();
5155
cli_nl();
5256
TOTP_CLI_PRINTF("Options:\r\n");
5357
totp_cli_command_add_docopt_options();

cli/commands/notification/notification.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include "../../../ui/scene_director.h"
55
#include "../../cli_helpers.h"
66

7-
#define TOTP_CLI_COMMAND_NOTIFICATION_ARG_METHOD "method"
7+
#define TOTP_CLI_COMMAND_NOTIFICATION_ARG_METHOD "notification"
88
#define TOTP_CLI_COMMAND_NOTIFICATION_METHOD_NONE "none"
99
#define TOTP_CLI_COMMAND_NOTIFICATION_METHOD_SOUND "sound"
1010
#define TOTP_CLI_COMMAND_NOTIFICATION_METHOD_VIBRO "vibro"
@@ -23,7 +23,7 @@ void totp_cli_command_notification_docopt_usage() {
2323
void totp_cli_command_notification_docopt_arguments() {
2424
TOTP_CLI_PRINTF(
2525
" " TOTP_CLI_COMMAND_NOTIFICATION_ARG_METHOD
26-
" Notification method to be set. Must be one of [" TOTP_CLI_COMMAND_NOTIFICATION_METHOD_NONE
26+
" Notification method to be set. Must be one of [" TOTP_CLI_COMMAND_NOTIFICATION_METHOD_NONE
2727
", " TOTP_CLI_COMMAND_NOTIFICATION_METHOD_SOUND
2828
", " TOTP_CLI_COMMAND_NOTIFICATION_METHOD_VIBRO "]\r\n");
2929
}

cli/commands/timezone/timezone.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ void totp_cli_command_timezone_docopt_usage() {
2020

2121
void totp_cli_command_timezone_docopt_arguments() {
2222
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_TIMEZONE_ARG_TIMEZONE
23-
" Timezone offset in hours to be set\r\n");
23+
" Timezone offset in hours to be set\r\n");
2424
}
2525

2626
void totp_cli_command_timezone_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {

features_config.h

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#define TOTP_BADBT_TYPE_ENABLED
2+
#define TOTP_BADBT_TYPE_ICON_ENABLED

images/hid_ble_10x7.png

158 Bytes
Loading

services/config/config.c

+59
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "../list/list.h"
55
#include "../../types/common.h"
66
#include "../../types/token_info.h"
7+
#include "../../features_config.h"
78
#include "migrations/config_migration_v1_to_v2.h"
89
#include "migrations/config_migration_v2_to_v3.h"
910

@@ -136,6 +137,14 @@ static TotpConfigFileOpenResult totp_open_config_file(Storage* storage, FlipperF
136137
flipper_format_write_uint32(
137138
fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, &tmp_uint32, 1);
138139

140+
tmp_uint32 = AutomationMethodBadUsb;
141+
flipper_format_write_comment_cstr(fff_data_file, " ");
142+
flipper_format_write_comment_cstr(
143+
fff_data_file,
144+
"Automation method (0 - None, 1 - BadUSB, 2 - BadBT, 3 - BadUSB and BadBT)");
145+
flipper_format_write_uint32(
146+
fff_data_file, TOTP_CONFIG_KEY_AUTOMATION_METHOD, &tmp_uint32, 1);
147+
139148
FuriString* temp_str = furi_string_alloc();
140149

141150
flipper_format_write_comment_cstr(fff_data_file, " ");
@@ -329,6 +338,33 @@ TotpConfigFileUpdateResult
329338
return update_result;
330339
}
331340

341+
TotpConfigFileUpdateResult
342+
totp_config_file_update_automation_method(AutomationMethod new_automation_method) {
343+
Storage* cfg_storage = totp_open_storage();
344+
FlipperFormat* file;
345+
TotpConfigFileUpdateResult update_result;
346+
347+
if(totp_open_config_file(cfg_storage, &file) == TotpConfigFileOpenSuccess) {
348+
do {
349+
uint32_t tmp_uint32 = new_automation_method;
350+
if(!flipper_format_insert_or_update_uint32(
351+
file, TOTP_CONFIG_KEY_AUTOMATION_METHOD, &tmp_uint32, 1)) {
352+
update_result = TotpConfigFileUpdateError;
353+
break;
354+
}
355+
356+
update_result = TotpConfigFileUpdateSuccess;
357+
} while(false);
358+
359+
totp_close_config_file(file);
360+
} else {
361+
update_result = TotpConfigFileUpdateError;
362+
}
363+
364+
totp_close_storage();
365+
return update_result;
366+
}
367+
332368
TotpConfigFileUpdateResult totp_config_file_update_user_settings(const PluginState* plugin_state) {
333369
Storage* cfg_storage = totp_open_storage();
334370
FlipperFormat* file;
@@ -347,6 +383,13 @@ TotpConfigFileUpdateResult totp_config_file_update_user_settings(const PluginSta
347383
break;
348384
}
349385

386+
tmp_uint32 = plugin_state->automation_method;
387+
if(!flipper_format_insert_or_update_uint32(
388+
file, TOTP_CONFIG_KEY_AUTOMATION_METHOD, &tmp_uint32, 1)) {
389+
update_result = TotpConfigFileUpdateError;
390+
break;
391+
}
392+
350393
update_result = TotpConfigFileUpdateSuccess;
351394
} while(false);
352395

@@ -409,6 +452,13 @@ TotpConfigFileUpdateResult totp_full_save_config_file(const PluginState* const p
409452
break;
410453
}
411454

455+
tmp_uint32 = plugin_state->automation_method;
456+
if(!flipper_format_write_uint32(
457+
fff_data_file, TOTP_CONFIG_KEY_AUTOMATION_METHOD, &tmp_uint32, 1)) {
458+
result = TotpConfigFileUpdateError;
459+
break;
460+
}
461+
412462
bool tokens_written = true;
413463
TOTP_LIST_FOREACH(plugin_state->tokens_list, node, {
414464
const TokenInfo* token_info = node->data;
@@ -594,6 +644,15 @@ TotpConfigFileOpenResult totp_config_file_load_base(PluginState* const plugin_st
594644
}
595645

596646
plugin_state->notification_method = tmp_uint32;
647+
648+
flipper_format_rewind(fff_data_file);
649+
650+
if(!flipper_format_read_uint32(
651+
fff_data_file, TOTP_CONFIG_KEY_AUTOMATION_METHOD, &tmp_uint32, 1)) {
652+
tmp_uint32 = AutomationMethodBadUsb;
653+
}
654+
655+
plugin_state->automation_method = tmp_uint32;
597656
} while(false);
598657

599658
furi_string_free(temp_str);

services/config/config.h

+8
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ TotpConfigFileUpdateResult totp_config_file_update_timezone_offset(float new_tim
103103
TotpConfigFileUpdateResult
104104
totp_config_file_update_notification_method(NotificationMethod new_notification_method);
105105

106+
/**
107+
* @brief Updates automation method in an application config file
108+
* @param new_automation_method new automation method to be set
109+
* @return Config file update result
110+
*/
111+
TotpConfigFileUpdateResult
112+
totp_config_file_update_automation_method(AutomationMethod new_automation_method);
113+
106114
/**
107115
* @brief Updates application user settings
108116
* @param plugin_state application state

services/config/constants.h

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#define TOTP_CONFIG_KEY_BASE_IV "BaseIV"
1414
#define TOTP_CONFIG_KEY_PINSET "PinIsSet"
1515
#define TOTP_CONFIG_KEY_NOTIFICATION_METHOD "NotificationMethod"
16+
#define TOTP_CONFIG_KEY_AUTOMATION_METHOD "AutomationMethod"
1617

1718
#define TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME "sha1"
1819
#define TOTP_CONFIG_TOKEN_ALGO_SHA256_NAME "sha256"

0 commit comments

Comments
 (0)