diff --git a/CHANGELOG.md b/CHANGELOG.md index 0534ce4fb..cd2eb93c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,13 @@ ----- * Plugins: **New RFID 125KHz and iButton Fuzzers (remake from scratch + new features)** (by @gid9798 | PR #507) * Plugins: SubGHz Bruteforcer -> Time delay (between signals) setting (hold Up in main screen(says Up to Save)) + allow more repeats (by @gid9798 & @xMasterX) -* GUI: `Byte input` new feature: editor without keyboard (press Up until you get into new input, then use up/down to input values) (by @gid9798 | PR #509) -* Infrared: Update universal remote assets - add new ACs and TCL TV -* SubGHz: Remove broken modulation that was causing buffer overrun (fixes issue #506) -* SubGHz: Notifications fixes (by @wosk | PR #464) +* Plugins: Update TOTP (Authenticator) [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) * Plugins: Unitemp SCD30 support (PR in unitemp repo by @divinebird / fixed by @xMasterX) * Plugins: Fix ProtoView issue #503 -> (Broken saved files with custom modulation) +* SubGHz: Remove broken modulation that was causing buffer overrun (fixes issue #506) +* SubGHz: Notifications fixes (by @wosk | PR #464) +* GUI: `Byte input` new feature: editor without keyboard (press Up until you get into new input, then use up/down to input values) (by @gid9798 | PR #509) +* Infrared: Update universal remote assets - add new ACs and TCL TV * API: Add furi_hal_version_uid_default (+ Fix TOTP) (by @ClaraCrazy | PR #502) * OFW: Fix reading Mifare Classic cards with unusual access conditions and fix emulation of unknown keys * OFW: fbt: stable build dates diff --git a/applications/external/totp/features_config.h b/applications/external/totp/features_config.h index 15e81b28a..59a1e0ecc 100644 --- a/applications/external/totp/features_config.h +++ b/applications/external/totp/features_config.h @@ -1,3 +1,8 @@ +// Application automatic lock timeout if user IDLE. (ticks) +#ifndef TOTP_AUTO_LOCK_IDLE_TIMEOUT_SEC +#define TOTP_AUTO_LOCK_IDLE_TIMEOUT_SEC (60) +#endif + // Include Bluetooth token input automation #define TOTP_BADBT_TYPE_ENABLED diff --git a/applications/external/totp/services/crypto/crypto.c b/applications/external/totp/services/crypto/crypto.c index 448529100..8c20fe785 100644 --- a/applications/external/totp/services/crypto/crypto.c +++ b/applications/external/totp/services/crypto/crypto.c @@ -6,10 +6,11 @@ #include "memset_s.h" #define CRYPTO_KEY_SLOT (2) -#define CRYPTO_VERIFY_KEY "FFF_Crypto_pass" #define CRYPTO_VERIFY_KEY_LENGTH (16) #define CRYPTO_ALIGNMENT_FACTOR (16) +static const char* CRYPTO_VERIFY_KEY = "FFF_Crypto_pass"; + uint8_t* totp_crypto_encrypt( const uint8_t* plain_data, const size_t plain_data_length, @@ -107,7 +108,7 @@ CryptoSeedIVResult plugin_state->crypto_verify_data_length = CRYPTO_VERIFY_KEY_LENGTH; plugin_state->crypto_verify_data = totp_crypto_encrypt( - (uint8_t*)CRYPTO_VERIFY_KEY, + (const uint8_t*)CRYPTO_VERIFY_KEY, CRYPTO_VERIFY_KEY_LENGTH, &plugin_state->iv[0], &plugin_state->crypto_verify_data_length); @@ -122,7 +123,7 @@ CryptoSeedIVResult bool totp_crypto_verify_key(const PluginState* plugin_state) { size_t decrypted_key_length; - const uint8_t* decrypted_key = totp_crypto_decrypt( + uint8_t* decrypted_key = totp_crypto_decrypt( plugin_state->crypto_verify_data, plugin_state->crypto_verify_data_length, &plugin_state->iv[0], @@ -133,5 +134,7 @@ bool totp_crypto_verify_key(const PluginState* plugin_state) { if(decrypted_key[i] != CRYPTO_VERIFY_KEY[i]) key_valid = false; } + free(decrypted_key); + return key_valid; -} \ No newline at end of file +} diff --git a/applications/external/totp/services/idle_timeout/idle_timeout.c b/applications/external/totp/services/idle_timeout/idle_timeout.c new file mode 100644 index 000000000..9df1b5487 --- /dev/null +++ b/applications/external/totp/services/idle_timeout/idle_timeout.c @@ -0,0 +1,66 @@ +#include "idle_timeout.h" +#include +#include + +#define IDLE_TIMER_CHECK_PERIODICITY_SEC (1) +#define SEC_TO_TICKS(sec) ((sec)*1000) + +struct IdleTimeoutContext { + FuriTimer* timer; + bool activity_reported; + void* on_idle_callback_context; + IDLE_TIMEOUT_CALLBACK on_idle_callback; + uint16_t timeout_sec; + uint16_t idle_period_sec; + bool idle_handled; +}; + +static void idle_timer_callback(void* context) { + IdleTimeoutContext* instance = context; + if(instance->activity_reported) { + instance->idle_period_sec = 0; + instance->idle_handled = false; + instance->activity_reported = false; + } else if(!instance->idle_handled) { + if(instance->idle_period_sec >= instance->timeout_sec) { + instance->idle_handled = + instance->on_idle_callback(instance->on_idle_callback_context); + } else { + instance->idle_period_sec += IDLE_TIMER_CHECK_PERIODICITY_SEC; + } + } +} + +IdleTimeoutContext* idle_timeout_alloc( + uint16_t timeout_sec, + IDLE_TIMEOUT_CALLBACK on_idle_callback, + void* on_idle_callback_context) { + IdleTimeoutContext* instance = malloc(sizeof(IdleTimeoutContext)); + if(instance == NULL) return NULL; + + instance->timer = furi_timer_alloc(&idle_timer_callback, FuriTimerTypePeriodic, instance); + if(instance->timer == NULL) return NULL; + + instance->timeout_sec = timeout_sec; + instance->on_idle_callback = on_idle_callback; + instance->on_idle_callback_context = on_idle_callback_context; + return instance; +} + +void idle_timeout_start(IdleTimeoutContext* context) { + furi_timer_start(context->timer, SEC_TO_TICKS(IDLE_TIMER_CHECK_PERIODICITY_SEC)); +} + +void idle_timeout_stop(IdleTimeoutContext* context) { + furi_timer_stop(context->timer); +} + +void idle_timeout_report_activity(IdleTimeoutContext* context) { + context->activity_reported = true; +} + +void idle_timeout_free(IdleTimeoutContext* context) { + furi_timer_stop(context->timer); + furi_timer_free(context->timer); + free(context); +} diff --git a/applications/external/totp/services/idle_timeout/idle_timeout.h b/applications/external/totp/services/idle_timeout/idle_timeout.h new file mode 100644 index 000000000..12825e454 --- /dev/null +++ b/applications/external/totp/services/idle_timeout/idle_timeout.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include + +typedef struct IdleTimeoutContext IdleTimeoutContext; + +typedef bool (*IDLE_TIMEOUT_CALLBACK)(void* context); + +/** + * @brief Initializes a new instance of IDLE timeout + * @param timeout_sec IDLE timeout in seconds + * @param on_idle_callback callback function to trigger when IDLE timeout happened + * @param on_idle_callback_context callback function context + * @return IDLE timeout context + */ +IdleTimeoutContext* idle_timeout_alloc( + uint16_t timeout_sec, + IDLE_TIMEOUT_CALLBACK on_idle_callback, + void* on_idle_callback_context); + +/** + * @brief Starts IDLE timeout + * @param context IDLE timeout context + */ +void idle_timeout_start(IdleTimeoutContext* context); + +/** + * @brief Stops IDLE timeout + * @param context IDLE timeout context + */ +void idle_timeout_stop(IdleTimeoutContext* context); + +/** + * @brief Reports activity to IDLE timeout + * @param context IDLE timeout context + */ +void idle_timeout_report_activity(IdleTimeoutContext* context); + +/** + * @brief Disposes IDLE timeout and releases all the resources + * @param context IDLE timeout context + */ +void idle_timeout_free(IdleTimeoutContext* context); diff --git a/applications/external/totp/totp_app.c b/applications/external/totp/totp_app.c index 57e5ff04f..642e27c61 100644 --- a/applications/external/totp/totp_app.c +++ b/applications/external/totp/totp_app.c @@ -18,8 +18,6 @@ #include "services/crypto/crypto.h" #include "cli/cli.h" -#define IDLE_TIMEOUT (60000) - static void render_callback(Canvas* const canvas, void* ctx) { furi_assert(ctx); PluginState* plugin_state = ctx; @@ -106,6 +104,17 @@ static bool totp_activate_initial_scene(PluginState* const plugin_state) { return true; } +static bool on_user_idle(void* context) { + PluginState* plugin_state = context; + if(plugin_state->current_scene != TotpSceneAuthentication && + plugin_state->current_scene != TotpSceneStandby) { + totp_scene_director_activate_scene(plugin_state, TotpSceneAuthentication); + return true; + } + + return false; +} + static bool totp_plugin_state_init(PluginState* const plugin_state) { plugin_state->selected_font = 0; plugin_state->gui = furi_record_open(RECORD_GUI); @@ -128,10 +137,23 @@ static bool totp_plugin_state_init(PluginState* const plugin_state) { } #endif + if(plugin_state->pin_set) { + plugin_state->idle_timeout_context = + idle_timeout_alloc(TOTP_AUTO_LOCK_IDLE_TIMEOUT_SEC, &on_user_idle, plugin_state); + idle_timeout_start(plugin_state->idle_timeout_context); + } else { + plugin_state->idle_timeout_context = NULL; + } + return true; } static void totp_plugin_state_free(PluginState* plugin_state) { + if(plugin_state->idle_timeout_context != NULL) { + idle_timeout_stop(plugin_state->idle_timeout_context); + idle_timeout_free(plugin_state->idle_timeout_context); + } + furi_record_close(RECORD_GUI); furi_record_close(RECORD_NOTIFICATION); furi_record_close(RECORD_DIALOGS); @@ -185,14 +207,13 @@ int32_t totp_app() { PluginEvent event; bool processing = true; - uint32_t last_user_interaction_time = furi_get_tick(); while(processing) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + FuriStatus event_status = furi_message_queue_get(event_queue, &event, FuriWaitForever); if(furi_mutex_acquire(plugin_state->mutex, FuriWaitForever) == FuriStatusOk) { if(event_status == FuriStatusOk) { - if(event.type == EventTypeKey) { - last_user_interaction_time = furi_get_tick(); + if(event.type == EventTypeKey && plugin_state->idle_timeout_context != NULL) { + idle_timeout_report_activity(plugin_state->idle_timeout_context); } if(event.type == EventForceCloseApp) { @@ -200,11 +221,6 @@ int32_t totp_app() { } else { processing = totp_scene_director_handle_event(&event, plugin_state); } - } else if( - plugin_state->pin_set && plugin_state->current_scene != TotpSceneAuthentication && - plugin_state->current_scene != TotpSceneStandby && - furi_get_tick() - last_user_interaction_time > IDLE_TIMEOUT) { - totp_scene_director_activate_scene(plugin_state, TotpSceneAuthentication); } view_port_update(view_port); diff --git a/applications/external/totp/types/plugin_state.h b/applications/external/totp/types/plugin_state.h index 97d126330..234894d58 100644 --- a/applications/external/totp/types/plugin_state.h +++ b/applications/external/totp/types/plugin_state.h @@ -6,6 +6,7 @@ #include "../features_config.h" #include "../ui/totp_scenes_enum.h" #include "../services/config/config_file_context.h" +#include "../services/idle_timeout/idle_timeout.h" #include "notification_method.h" #include "automation_method.h" #ifdef TOTP_BADBT_TYPE_ENABLED @@ -48,6 +49,9 @@ typedef struct { */ float timezone_offset; + /** + * @brief Config file context + */ ConfigFileContext* config_file_context; /** @@ -101,4 +105,9 @@ typedef struct { */ TotpBtTypeCodeWorkerContext* bt_type_code_worker_context; #endif + + /** + * @brief IDLE timeout context + */ + IdleTimeoutContext* idle_timeout_context; } PluginState;