MX 2 лет назад
Родитель
Сommit
737f74be21

+ 1 - 1
ReadMe.md

@@ -97,7 +97,7 @@ The Flipper and its community wouldn't be as rich as it is without your contribu
 - [Wiegand Reader (By jamisonderek)](https://github.com/jamisonderek/flipper-zero-tutorials/tree/main/gpio)
 - [Wiegand Reader (By jamisonderek)](https://github.com/jamisonderek/flipper-zero-tutorials/tree/main/gpio)
 - [MH-Z19 - CO2 sensor (By meshchaninov)](https://github.com/meshchaninov/flipper-zero-mh-z19)
 - [MH-Z19 - CO2 sensor (By meshchaninov)](https://github.com/meshchaninov/flipper-zero-mh-z19)
 - [Plantower PMSx003 sensor reader (By 3cky)](https://github.com/3cky/flipperzero-airmon)
 - [Plantower PMSx003 sensor reader (By 3cky)](https://github.com/3cky/flipperzero-airmon)
-- [Evil captive portal (By bigbrodude6119)](https://github.com/bigbrodude6119/flipper-zero-evil-portal) - WIP
+- [Evil captive portal (By bigbrodude6119)](https://github.com/bigbrodude6119/flipper-zero-evil-portal) - WIP -> +2 new features [by leedave](https://github.com/leedave/flipper-zero-evil-portal/tree/leedave/ap_rename)
 - [ESP Flasher (By 0xchocolate)](https://github.com/0xchocolate/flipperzero-esp-flasher)
 - [ESP Flasher (By 0xchocolate)](https://github.com/0xchocolate/flipperzero-esp-flasher)
 - [ESP32-C6 Gravity terminal (By chris-bc)](https://github.com/chris-bc/Flipper-Gravity)
 - [ESP32-C6 Gravity terminal (By chris-bc)](https://github.com/chris-bc/Flipper-Gravity)
 - [u-blox GPS (By liamhays)](https://github.com/liamhays/ublox)
 - [u-blox GPS (By liamhays)](https://github.com/liamhays/ublox)

BIN
apps/GPIO/evil_portal.fap


+ 5 - 1
non_catalog_apps/flipper_evil_portal/application.fam

@@ -7,6 +7,10 @@ App(
     requires=["gui"],
     requires=["gui"],
     stack_size=1 * 1024,
     stack_size=1 * 1024,
     order=90,
     order=90,
+	fap_author="bigbrodude6119",
+	fap_description="Create an evil captive portal Wi-Fi access point",
+    fap_libs=["assets"],
+    fap_icon_assets="icons",
     fap_icon="icons/evil_portal_10px.png",
     fap_icon="icons/evil_portal_10px.png",
-    fap_category="GPIO",    
+    fap_category="GPIO",
 )
 )

+ 19 - 13
non_catalog_apps/flipper_evil_portal/evil_portal_app.c

@@ -32,9 +32,15 @@ Evil_PortalApp* evil_portal_app_alloc() {
     app->command_index = 0;
     app->command_index = 0;
     app->portal_logs = furi_string_alloc();
     app->portal_logs = furi_string_alloc();
 
 
+    app->dialogs = furi_record_open(RECORD_DIALOGS);
+    app->file_path = furi_string_alloc();
+
     app->gui = furi_record_open(RECORD_GUI);
     app->gui = furi_record_open(RECORD_GUI);
 
 
     app->view_dispatcher = view_dispatcher_alloc();
     app->view_dispatcher = view_dispatcher_alloc();
+
+    app->loading = loading_alloc();
+
     app->scene_manager = scene_manager_alloc(&evil_portal_scene_handlers, app);
     app->scene_manager = scene_manager_alloc(&evil_portal_scene_handlers, app);
     view_dispatcher_enable_queue(app->view_dispatcher);
     view_dispatcher_enable_queue(app->view_dispatcher);
     view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
     view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
@@ -48,12 +54,18 @@ Evil_PortalApp* evil_portal_app_alloc() {
 
 
     view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
     view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
 
 
+    app->view_stack = view_stack_alloc();
+
     app->var_item_list = variable_item_list_alloc();
     app->var_item_list = variable_item_list_alloc();
     view_dispatcher_add_view(
     view_dispatcher_add_view(
         app->view_dispatcher,
         app->view_dispatcher,
         Evil_PortalAppViewVarItemList,
         Evil_PortalAppViewVarItemList,
         variable_item_list_get_view(app->var_item_list));
         variable_item_list_get_view(app->var_item_list));
 
 
+    app->text_input = text_input_alloc();
+    view_dispatcher_add_view(
+        app->view_dispatcher, Evil_PortalAppViewTextInput, text_input_get_view(app->text_input));
+
     for(int i = 0; i < NUM_MENU_ITEMS; ++i) {
     for(int i = 0; i < NUM_MENU_ITEMS; ++i) {
         app->selected_option_index[i] = 0;
         app->selected_option_index[i] = 0;
     }
     }
@@ -88,6 +100,10 @@ void evil_portal_app_free(Evil_PortalApp* app) {
 
 
     text_box_free(app->text_box);
     text_box_free(app->text_box);
     furi_string_free(app->text_box_store);
     furi_string_free(app->text_box_store);
+    text_input_free(app->text_input);
+
+    view_stack_free(app->view_stack);
+    loading_free(app->loading);
 
 
     // View dispatcher
     // View dispatcher
     view_dispatcher_free(app->view_dispatcher);
     view_dispatcher_free(app->view_dispatcher);
@@ -98,20 +114,14 @@ void evil_portal_app_free(Evil_PortalApp* app) {
     // Close records
     // Close records
     furi_record_close(RECORD_GUI);
     furi_record_close(RECORD_GUI);
 
 
+    furi_record_close(RECORD_DIALOGS);
+    furi_string_free(app->file_path);
+
     free(app);
     free(app);
 }
 }
 
 
 int32_t evil_portal_app(void* p) {
 int32_t evil_portal_app(void* p) {
     UNUSED(p);
     UNUSED(p);
-
-    // Enable 5v on startup
-    uint8_t attempts = 0;
-    while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
-        furi_hal_power_enable_otg();
-        furi_delay_ms(10);
-    }
-    furi_delay_ms(200);
-
     Evil_PortalApp* evil_portal_app = evil_portal_app_alloc();
     Evil_PortalApp* evil_portal_app = evil_portal_app_alloc();
 
 
     evil_portal_app->uart = evil_portal_uart_init(evil_portal_app);
     evil_portal_app->uart = evil_portal_uart_init(evil_portal_app);
@@ -120,9 +130,5 @@ int32_t evil_portal_app(void* p) {
 
 
     evil_portal_app_free(evil_portal_app);
     evil_portal_app_free(evil_portal_app);
 
 
-    if(furi_hal_power_is_otg_enabled()) {
-        furi_hal_power_disable_otg();
-    }
-
     return 0;
     return 0;
 }
 }

+ 1 - 1
non_catalog_apps/flipper_evil_portal/evil_portal_app.h

@@ -8,4 +8,4 @@ typedef struct Evil_PortalApp Evil_PortalApp;
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
-#endif
+#endif

+ 16 - 1
non_catalog_apps/flipper_evil_portal/evil_portal_app_i.h

@@ -4,14 +4,19 @@
 #include "evil_portal_custom_event.h"
 #include "evil_portal_custom_event.h"
 #include "evil_portal_uart.h"
 #include "evil_portal_uart.h"
 #include "scenes/evil_portal_scene.h"
 #include "scenes/evil_portal_scene.h"
+#include "evil_portal_icons.h"
 
 
 #include <gui/gui.h>
 #include <gui/gui.h>
+#include <gui/modules/loading.h>
 #include <gui/modules/text_box.h>
 #include <gui/modules/text_box.h>
+#include <gui/modules/text_input.h>
 #include <gui/modules/variable_item_list.h>
 #include <gui/modules/variable_item_list.h>
 #include <gui/scene_manager.h>
 #include <gui/scene_manager.h>
 #include <gui/view_dispatcher.h>
 #include <gui/view_dispatcher.h>
+#include <gui/view_stack.h>
+#include <dialogs/dialogs.h>
 
 
-#define NUM_MENU_ITEMS (4)
+#define NUM_MENU_ITEMS (6)
 
 
 #define EVIL_PORTAL_TEXT_BOX_STORE_SIZE (4096)
 #define EVIL_PORTAL_TEXT_BOX_STORE_SIZE (4096)
 #define UART_CH (FuriHalUartIdUSART1)
 #define UART_CH (FuriHalUartIdUSART1)
@@ -20,6 +25,9 @@
 #define SET_AP_CMD "setap"
 #define SET_AP_CMD "setap"
 #define RESET_CMD "reset"
 #define RESET_CMD "reset"
 
 
+#define HTML_EXTENSION ".html"
+#define HTML_FOLDER ANY_PATH("apps_data/evil_portal/html")
+
 struct Evil_PortalApp {
 struct Evil_PortalApp {
     Gui* gui;
     Gui* gui;
     ViewDispatcher* view_dispatcher;
     ViewDispatcher* view_dispatcher;
@@ -36,6 +44,11 @@ struct Evil_PortalApp {
 
 
     VariableItemList* var_item_list;
     VariableItemList* var_item_list;
     Evil_PortalUart* uart;
     Evil_PortalUart* uart;
+    TextInput* text_input;
+    DialogsApp* dialogs;
+    FuriString* file_path;
+    Loading* loading;
+    ViewStack* view_stack;
 
 
     int selected_menu_index;
     int selected_menu_index;
     int selected_option_index[NUM_MENU_ITEMS];
     int selected_option_index[NUM_MENU_ITEMS];
@@ -48,6 +61,7 @@ struct Evil_PortalApp {
     bool sent_html;
     bool sent_html;
     bool sent_reset;
     bool sent_reset;
     int BAUDRATE;
     int BAUDRATE;
+    char text_store[2][128 + 1];
 
 
     uint8_t* index_html;
     uint8_t* index_html;
     uint8_t* ap_name;
     uint8_t* ap_name;
@@ -57,4 +71,5 @@ typedef enum {
     Evil_PortalAppViewVarItemList,
     Evil_PortalAppViewVarItemList,
     Evil_PortalAppViewConsoleOutput,
     Evil_PortalAppViewConsoleOutput,
     Evil_PortalAppViewStartPortal,
     Evil_PortalAppViewStartPortal,
+    Evil_PortalAppViewTextInput,
 } Evil_PortalAppView;
 } Evil_PortalAppView;

+ 1 - 0
non_catalog_apps/flipper_evil_portal/evil_portal_custom_event.h

@@ -5,4 +5,5 @@ typedef enum {
     Evil_PortalEventStartConsole,
     Evil_PortalEventStartConsole,
     Evil_PortalEventStartKeyboard,
     Evil_PortalEventStartKeyboard,
     Evil_PortalEventStartPortal,
     Evil_PortalEventStartPortal,
+    Evil_PortalEventTextInput,
 } Evil_PortalCustomEvent;
 } Evil_PortalCustomEvent;

+ 40 - 0
non_catalog_apps/flipper_evil_portal/helpers/evil_portal_storage.c

@@ -42,6 +42,33 @@ void evil_portal_read_index_html(void* context) {
     evil_portal_close_storage();
     evil_portal_close_storage();
 }
 }
 
 
+void evil_portal_replace_index_html(FuriString* path) {
+    Storage* storage = evil_portal_open_storage();
+    FS_Error error;
+    error = storage_common_remove(storage, EVIL_PORTAL_INDEX_SAVE_PATH);
+    if(error != FSE_OK) {
+        FURI_LOG_D("EVIL PORTAL", "Error removing file");
+    } else {
+        FURI_LOG_D("EVIL PORTAL", "Error removed file");
+    }
+    error = storage_common_copy(storage, furi_string_get_cstr(path), EVIL_PORTAL_INDEX_SAVE_PATH);
+    if(error != FSE_OK) {
+        FURI_LOG_D("EVIL PORTAL", "Error copying file");
+    }
+    evil_portal_close_storage();
+}
+
+void evil_portal_create_html_folder_if_not_exists() {
+    Storage* storage = evil_portal_open_storage();
+    if(storage_common_stat(storage, HTML_FOLDER, NULL) == FSE_NOT_EXIST) {
+        FURI_LOG_D("Evil Portal", "Directory %s doesn't exist. Will create new.", HTML_FOLDER);
+        if(!storage_simply_mkdir(storage, HTML_FOLDER)) {
+            FURI_LOG_E("Evil Portal", "Error creating directory %s", HTML_FOLDER);
+        }
+    }
+    evil_portal_close_storage();
+}
+
 void evil_portal_read_ap_name(void* context) {
 void evil_portal_read_ap_name(void* context) {
     Evil_PortalApp* app = context;
     Evil_PortalApp* app = context;
     Storage* storage = evil_portal_open_storage();
     Storage* storage = evil_portal_open_storage();
@@ -71,6 +98,19 @@ void evil_portal_read_ap_name(void* context) {
     evil_portal_close_storage();
     evil_portal_close_storage();
 }
 }
 
 
+void evil_portal_write_ap_name(void* context) {
+    Evil_PortalApp* app = context;
+    Storage* storage = evil_portal_open_storage();
+
+    File* ap_name = storage_file_alloc(storage);
+    if(storage_file_open(ap_name, EVIL_PORTAL_AP_SAVE_PATH, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
+        storage_file_write(ap_name, app->text_store[0], strlen(app->text_store[0]));
+    }
+    storage_file_close(ap_name);
+    storage_file_free(ap_name);
+    evil_portal_close_storage();
+}
+
 char* sequential_file_resolve_path(
 char* sequential_file_resolve_path(
     Storage* storage,
     Storage* storage,
     const char* dir,
     const char* dir,

+ 3 - 0
non_catalog_apps/flipper_evil_portal/helpers/evil_portal_storage.h

@@ -12,6 +12,9 @@
 
 
 void evil_portal_read_index_html(void* context);
 void evil_portal_read_index_html(void* context);
 void evil_portal_read_ap_name(void* context);
 void evil_portal_read_ap_name(void* context);
+void evil_portal_write_ap_name(void* context);
+void evil_portal_replace_index_html(FuriString* path);
+void evil_portal_create_html_folder_if_not_exists();
 void write_logs(FuriString* portal_logs);
 void write_logs(FuriString* portal_logs);
 char* sequential_file_resolve_path(
 char* sequential_file_resolve_path(
     Storage* storage,
     Storage* storage,

+ 2 - 0
non_catalog_apps/flipper_evil_portal/scenes/evil_portal_scene_config.h

@@ -1,2 +1,4 @@
 ADD_SCENE(evil_portal, start, Start)
 ADD_SCENE(evil_portal, start, Start)
 ADD_SCENE(evil_portal, console_output, ConsoleOutput)
 ADD_SCENE(evil_portal, console_output, ConsoleOutput)
+ADD_SCENE(evil_portal, rename, Rename)
+ADD_SCENE(evil_portal, select_html, SelectHtml)

+ 10 - 0
non_catalog_apps/flipper_evil_portal/scenes/evil_portal_scene_console_output.c

@@ -62,6 +62,16 @@ void evil_portal_scene_console_output_on_enter(void* context) {
             }
             }
         }
         }
 
 
+        if(0 == strncmp("setapname", app->selected_tx_string, strlen("setapname"))) {
+            scene_manager_next_scene(app->scene_manager, Evil_PortalSceneRename);
+            return;
+        }
+
+        if(0 == strncmp("selecthtml", app->selected_tx_string, strlen("selecthtml"))) {
+            scene_manager_next_scene(app->scene_manager, Evil_PortalSceneSelectHtml);
+            return;
+        }
+
         if(0 == strncmp(SET_HTML_CMD, app->selected_tx_string, strlen(SET_HTML_CMD))) {
         if(0 == strncmp(SET_HTML_CMD, app->selected_tx_string, strlen(SET_HTML_CMD))) {
             app->command_queue[0] = SET_AP_CMD;
             app->command_queue[0] = SET_AP_CMD;
             app->has_command_queue = true;
             app->has_command_queue = true;

+ 42 - 0
non_catalog_apps/flipper_evil_portal/scenes/evil_portal_scene_rename.c

@@ -0,0 +1,42 @@
+#include "../evil_portal_app_i.h"
+#include "../helpers/evil_portal_storage.h"
+
+void evil_portal_text_input_callback(void* context) {
+    furi_assert(context);
+    Evil_PortalApp* app = context;
+    view_dispatcher_send_custom_event(app->view_dispatcher, Evil_PortalEventTextInput);
+}
+
+void evil_portal_scene_rename_on_enter(void* context) {
+    Evil_PortalApp* app = context;
+    TextInput* text_input = app->text_input;
+    size_t enter_name_length = 25;
+    evil_portal_read_ap_name(app);
+    text_input_set_header_text(text_input, "AP Name/SSID");
+    strncpy(app->text_store[0], (char*)app->ap_name, enter_name_length);
+    text_input_set_result_callback(
+        text_input,
+        evil_portal_text_input_callback,
+        context,
+        app->text_store[0],
+        enter_name_length,
+        false);
+    view_dispatcher_switch_to_view(app->view_dispatcher, Evil_PortalAppViewTextInput);
+}
+
+bool evil_portal_scene_rename_on_event(void* context, SceneManagerEvent event) {
+    Evil_PortalApp* app = context;
+    SceneManager* scene_manager = app->scene_manager;
+    bool consumed = false;
+    if(event.type == SceneManagerEventTypeCustom) {
+        evil_portal_write_ap_name(app);
+        scene_manager_search_and_switch_to_previous_scene(scene_manager, Evil_PortalSceneStart);
+        consumed = true;
+    }
+    return consumed;
+}
+
+void evil_portal_scene_rename_on_exit(void* context) {
+    Evil_PortalApp* app = context;
+    variable_item_list_reset(app->var_item_list);
+}

+ 54 - 0
non_catalog_apps/flipper_evil_portal/scenes/evil_portal_scene_select_html.c

@@ -0,0 +1,54 @@
+#include "../evil_portal_app_i.h"
+#include "../helpers/evil_portal_storage.h"
+
+void evil_portal_show_loading_popup(Evil_PortalApp* app, bool show) {
+    TaskHandle_t timer_task = xTaskGetHandle(configTIMER_SERVICE_TASK_NAME);
+    ViewStack* view_stack = app->view_stack;
+    Loading* loading = app->loading;
+    if(show) {
+        // Raise timer priority so that animations can play
+        vTaskPrioritySet(timer_task, configMAX_PRIORITIES - 1);
+        view_stack_add_view(view_stack, loading_get_view(loading));
+    } else {
+        view_stack_remove_view(view_stack, loading_get_view(loading));
+        // Restore default timer priority
+        vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY);
+    }
+}
+
+void evil_portal_scene_select_html_on_enter(void* context) {
+    Evil_PortalApp* app = context;
+    DialogsFileBrowserOptions browser_options;
+    evil_portal_create_html_folder_if_not_exists();
+
+    dialog_file_browser_set_basic_options(&browser_options, HTML_EXTENSION, &I_evil_portal_10px);
+    browser_options.base_path = HTML_FOLDER;
+
+    FuriString* path;
+    path = furi_string_alloc();
+
+    furi_string_set(path, HTML_FOLDER);
+
+    bool success = dialog_file_browser_show(app->dialogs, app->file_path, path, &browser_options);
+    furi_string_free(path);
+
+    if(success) {
+        //Replace HTML File
+        evil_portal_show_loading_popup(app, true);
+        evil_portal_replace_index_html(app->file_path);
+        evil_portal_show_loading_popup(app, false);
+    }
+
+    scene_manager_search_and_switch_to_previous_scene(app->scene_manager, Evil_PortalSceneStart);
+}
+
+bool evil_portal_scene_select_html_on_event(void* context, SceneManagerEvent event) {
+    UNUSED(context);
+    UNUSED(event);
+    bool consumed = true;
+    return consumed;
+}
+
+void evil_portal_scene_select_html_on_exit(void* context) {
+    UNUSED(context);
+}

+ 6 - 0
non_catalog_apps/flipper_evil_portal/scenes/evil_portal_scene_start.c

@@ -33,6 +33,12 @@ const Evil_PortalItem items[NUM_MENU_ITEMS] = {
     // console
     // console
     {"Save logs", {""}, 1, {"savelogs"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
     {"Save logs", {""}, 1, {"savelogs"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
 
 
+    // set AP name
+    {"Set AP name", {""}, 1, {"setapname"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
+
+    // select HTML Portal File
+    {"Select HTML", {""}, 1, {"selecthtml"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
+
     // help
     // help
     {"Help", {""}, 1, {"help"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
     {"Help", {""}, 1, {"help"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
 };
 };