diff --git a/Changelog.md b/Changelog.md index 569048ffc..647fa7106 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,22 @@ +## [16.0.0-RC6] - 2024-xx-xx + +For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.7.0...v16.0.0) + +#### Known issues +Please check the [issues](https://github.com/jomjol/AI-on-the-edge-device/issues) and +[discussions](https://github.com/jomjol/AI-on-the-edge-device/discussions) before reporting a new issue. + +#### Core Changes +Only changes since RC5 are listed: +- Added basic authentification of the Web Interface and the REST API, see https://jomjol.github.io/AI-on-the-edge-device-docs/Password-Protection/ +- xxx + + **:warning: Please check your Homeassistant instance to make sure it is handled correctly!** + +#### Bug Fixes +Only changes since RC5 are listed: + - xxx + ## [16.0.0-RC5] - 2024-12-05 For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.7.0...v16.0.0) @@ -22,11 +41,11 @@ Only changes since RC4 are listed: **:warning: Please check your Homeassistant instance to make sure it is handled correctly!** #### Bug Fixes -Only changes since RC3 are listed: +Only changes since RC4 are listed: - Added fix for ledintensity (#3418) - Added fix for OV2640 brightness contrast saturation (#3417) - Added fix for 'AnalogToDigitTransitionStart' always using 9.2 regardless of the configured value (#3393) - - Addef fix for HA menu entry (#3342) + - Added fix for HA menu entry (#3342) ## [16.0.0-RC4] - 2024-10-06 diff --git a/code/components/jomjol_controlGPIO/server_GPIO.cpp b/code/components/jomjol_controlGPIO/server_GPIO.cpp index 3d6f86595..f86efe933 100644 --- a/code/components/jomjol_controlGPIO/server_GPIO.cpp +++ b/code/components/jomjol_controlGPIO/server_GPIO.cpp @@ -25,6 +25,7 @@ #include "server_mqtt.h" #endif //ENABLE_MQTT +#include "basic_auth.h" static const char *TAG = "GPIO"; QueueHandle_t gpio_queue_handle = NULL; @@ -458,7 +459,7 @@ void GpioHandler::registerGpioUri() httpd_uri_t camuri = { }; camuri.method = HTTP_GET; camuri.uri = "/GPIO"; - camuri.handler = callHandleHttpRequest; + camuri.handler = APPLY_BASIC_AUTH_FILTER(callHandleHttpRequest); camuri.user_ctx = (void*)this; httpd_register_uri_handler(_httpServer, &camuri); } diff --git a/code/components/jomjol_controlcamera/server_camera.cpp b/code/components/jomjol_controlcamera/server_camera.cpp index 71eeba471..d79fbcdb7 100644 --- a/code/components/jomjol_controlcamera/server_camera.cpp +++ b/code/components/jomjol_controlcamera/server_camera.cpp @@ -10,6 +10,8 @@ #include "ClassLogFile.h" #include "esp_log.h" +#include "basic_auth.h" + #include "../../include/defines.h" static const char *TAG = "server_cam"; @@ -280,27 +282,27 @@ void register_server_camera_uri(httpd_handle_t server) camuri.method = HTTP_GET; camuri.uri = "/lighton"; - camuri.handler = handler_lightOn; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_lightOn); camuri.user_ctx = (void *)"Light On"; httpd_register_uri_handler(server, &camuri); camuri.uri = "/lightoff"; - camuri.handler = handler_lightOff; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_lightOff); camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); camuri.uri = "/capture"; - camuri.handler = handler_capture; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_capture); camuri.user_ctx = NULL; httpd_register_uri_handler(server, &camuri); camuri.uri = "/capture_with_flashlight"; - camuri.handler = handler_capture_with_light; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_capture_with_light); camuri.user_ctx = NULL; httpd_register_uri_handler(server, &camuri); camuri.uri = "/save"; - camuri.handler = handler_capture_save_to_file; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_capture_save_to_file); camuri.user_ctx = NULL; httpd_register_uri_handler(server, &camuri); } diff --git a/code/components/jomjol_fileserver_ota/server_file.cpp b/code/components/jomjol_fileserver_ota/server_file.cpp index 50e2c8f2d..eb69913aa 100644 --- a/code/components/jomjol_fileserver_ota/server_file.cpp +++ b/code/components/jomjol_fileserver_ota/server_file.cpp @@ -46,6 +46,7 @@ extern "C" { #include "Helper.h" #include "miniz.h" +#include "basic_auth.h" static const char *TAG = "OTA FILE"; @@ -1174,7 +1175,7 @@ void register_server_file_uri(httpd_handle_t server, const char *base_path) httpd_uri_t file_download = { .uri = "/fileserver*", // Match all URIs of type /path/to/file .method = HTTP_GET, - .handler = download_get_handler, + .handler = APPLY_BASIC_AUTH_FILTER(download_get_handler), .user_ctx = server_data // Pass server data as context }; httpd_register_uri_handler(server, &file_download); @@ -1183,7 +1184,7 @@ void register_server_file_uri(httpd_handle_t server, const char *base_path) httpd_uri_t file_datafileact = { .uri = "/datafileact", // Match all URIs of type /path/to/file .method = HTTP_GET, - .handler = datafileact_get_full_handler, + .handler = APPLY_BASIC_AUTH_FILTER(datafileact_get_full_handler), .user_ctx = server_data // Pass server data as context }; httpd_register_uri_handler(server, &file_datafileact); @@ -1192,7 +1193,7 @@ void register_server_file_uri(httpd_handle_t server, const char *base_path) httpd_uri_t file_datafile_last_part_handle = { .uri = "/data", // Match all URIs of type /path/to/file .method = HTTP_GET, - .handler = datafileact_get_last_part_handler, + .handler = APPLY_BASIC_AUTH_FILTER(datafileact_get_last_part_handler), .user_ctx = server_data // Pass server data as context }; httpd_register_uri_handler(server, &file_datafile_last_part_handle); @@ -1200,7 +1201,7 @@ void register_server_file_uri(httpd_handle_t server, const char *base_path) httpd_uri_t file_logfileact = { .uri = "/logfileact", // Match all URIs of type /path/to/file .method = HTTP_GET, - .handler = logfileact_get_full_handler, + .handler = APPLY_BASIC_AUTH_FILTER(logfileact_get_full_handler), .user_ctx = server_data // Pass server data as context }; httpd_register_uri_handler(server, &file_logfileact); @@ -1209,7 +1210,7 @@ void register_server_file_uri(httpd_handle_t server, const char *base_path) httpd_uri_t file_logfile_last_part_handle = { .uri = "/log", // Match all URIs of type /path/to/file .method = HTTP_GET, - .handler = logfileact_get_last_part_handler, + .handler = APPLY_BASIC_AUTH_FILTER(logfileact_get_last_part_handler), .user_ctx = server_data // Pass server data as context }; httpd_register_uri_handler(server, &file_logfile_last_part_handle); @@ -1219,7 +1220,7 @@ void register_server_file_uri(httpd_handle_t server, const char *base_path) httpd_uri_t file_upload = { .uri = "/upload/*", // Match all URIs of type /upload/path/to/file .method = HTTP_POST, - .handler = upload_post_handler, + .handler = APPLY_BASIC_AUTH_FILTER(upload_post_handler), .user_ctx = server_data // Pass server data as context }; httpd_register_uri_handler(server, &file_upload); @@ -1228,7 +1229,7 @@ void register_server_file_uri(httpd_handle_t server, const char *base_path) httpd_uri_t file_delete = { .uri = "/delete/*", // Match all URIs of type /delete/path/to/file .method = HTTP_POST, - .handler = delete_post_handler, + .handler = APPLY_BASIC_AUTH_FILTER(delete_post_handler), .user_ctx = server_data // Pass server data as context }; httpd_register_uri_handler(server, &file_delete); diff --git a/code/components/jomjol_fileserver_ota/server_ota.cpp b/code/components/jomjol_fileserver_ota/server_ota.cpp index ad7b1b598..523939784 100644 --- a/code/components/jomjol_fileserver_ota/server_ota.cpp +++ b/code/components/jomjol_fileserver_ota/server_ota.cpp @@ -42,6 +42,7 @@ #include "Helper.h" #include "statusled.h" +#include "basic_auth.h" #include "../../include/defines.h" /*an ota data write buffer ready to write to the flash*/ @@ -690,13 +691,13 @@ void register_server_ota_sdcard_uri(httpd_handle_t server) httpd_uri_t camuri = { }; camuri.method = HTTP_GET; camuri.uri = "/ota"; - camuri.handler = handler_ota_update; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_ota_update); camuri.user_ctx = (void*) "Do OTA"; httpd_register_uri_handler(server, &camuri); camuri.method = HTTP_GET; camuri.uri = "/reboot"; - camuri.handler = handler_reboot; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_reboot); camuri.user_ctx = (void*) "Reboot"; httpd_register_uri_handler(server, &camuri); diff --git a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp index b14cfa8ae..d0b4f737e 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp @@ -26,6 +26,7 @@ extern "C" { #include "server_help.h" #include "MainFlowControl.h" +#include "basic_auth.h" #include "../../include/defines.h" static const char* TAG = "FLOWCTRL"; diff --git a/code/components/jomjol_flowcontroll/MainFlowControl.cpp b/code/components/jomjol_flowcontroll/MainFlowControl.cpp index 8a98010c7..9f189af56 100644 --- a/code/components/jomjol_flowcontroll/MainFlowControl.cpp +++ b/code/components/jomjol_flowcontroll/MainFlowControl.cpp @@ -27,6 +27,7 @@ #include "read_wlanini.h" #include "connect_wlan.h" #include "psram.h" +#include "basic_auth.h" // support IDF 5.x #ifndef portTICK_RATE_MS @@ -1782,108 +1783,108 @@ void register_server_main_flow_task_uri(httpd_handle_t server) camuri.method = HTTP_GET; camuri.uri = "/doinit"; - camuri.handler = handler_init; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_init); camuri.user_ctx = (void *)"Light On"; httpd_register_uri_handler(server, &camuri); // Legacy API => New: "/setPreValue" camuri.uri = "/setPreValue.html"; - camuri.handler = handler_prevalue; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_prevalue); camuri.user_ctx = (void *)"Prevalue"; httpd_register_uri_handler(server, &camuri); camuri.uri = "/setPreValue"; - camuri.handler = handler_prevalue; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_prevalue); camuri.user_ctx = (void *)"Prevalue"; httpd_register_uri_handler(server, &camuri); camuri.uri = "/flow_start"; - camuri.handler = handler_flow_start; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_flow_start); camuri.user_ctx = (void *)"Flow Start"; httpd_register_uri_handler(server, &camuri); camuri.uri = "/statusflow.html"; - camuri.handler = handler_statusflow; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_statusflow); camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); camuri.uri = "/statusflow"; - camuri.handler = handler_statusflow; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_statusflow); camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); // Legacy API => New: "/cpu_temperature" camuri.uri = "/cputemp.html"; - camuri.handler = handler_cputemp; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_cputemp); camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); camuri.uri = "/cpu_temperature"; - camuri.handler = handler_cputemp; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_cputemp); camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); // Legacy API => New: "/rssi" camuri.uri = "/rssi.html"; - camuri.handler = handler_rssi; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_rssi); camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); camuri.uri = "/rssi"; - camuri.handler = handler_rssi; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_rssi); camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); camuri.uri = "/date"; - camuri.handler = handler_current_date; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_current_date); camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); camuri.uri = "/uptime"; - camuri.handler = handler_uptime; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_uptime); camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); camuri.uri = "/editflow"; - camuri.handler = handler_editflow; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_editflow); camuri.user_ctx = (void *)"EditFlow"; httpd_register_uri_handler(server, &camuri); // Legacy API => New: "/value" camuri.uri = "/value.html"; - camuri.handler = handler_wasserzaehler; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_wasserzaehler); camuri.user_ctx = (void *)"Value"; httpd_register_uri_handler(server, &camuri); camuri.uri = "/value"; - camuri.handler = handler_wasserzaehler; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_wasserzaehler); camuri.user_ctx = (void *)"Value"; httpd_register_uri_handler(server, &camuri); // Legacy API => New: "/value" camuri.uri = "/wasserzaehler.html"; - camuri.handler = handler_wasserzaehler; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_wasserzaehler); camuri.user_ctx = (void *)"Wasserzaehler"; httpd_register_uri_handler(server, &camuri); camuri.uri = "/json"; - camuri.handler = handler_json; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_json); camuri.user_ctx = (void *)"JSON"; httpd_register_uri_handler(server, &camuri); camuri.uri = "/heap"; - camuri.handler = handler_get_heap; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_get_heap); camuri.user_ctx = (void *)"Heap"; httpd_register_uri_handler(server, &camuri); camuri.uri = "/stream"; - camuri.handler = handler_stream; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_stream); camuri.user_ctx = (void *)"stream"; httpd_register_uri_handler(server, &camuri); /** will handle metrics requests */ camuri.uri = "/metrics"; - camuri.handler = handler_openmetrics; + camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_openmetrics); camuri.user_ctx = (void *)"metrics"; httpd_register_uri_handler(server, &camuri); diff --git a/code/components/jomjol_mqtt/server_mqtt.cpp b/code/components/jomjol_mqtt/server_mqtt.cpp index d20c102c9..9869bb448 100644 --- a/code/components/jomjol_mqtt/server_mqtt.cpp +++ b/code/components/jomjol_mqtt/server_mqtt.cpp @@ -12,6 +12,7 @@ #include "interface_mqtt.h" #include "time_sntp.h" #include "../../include/defines.h" +#include "basic_auth.h" @@ -347,7 +348,7 @@ void register_server_mqtt_uri(httpd_handle_t server) { uri.method = HTTP_GET; uri.uri = "/mqtt_publish_discovery"; - uri.handler = scheduleSendingDiscovery_and_static_Topics; + uri.handler = APPLY_BASIC_AUTH_FILTER(scheduleSendingDiscovery_and_static_Topics); uri.user_ctx = (void*) ""; httpd_register_uri_handler(server, &uri); } diff --git a/code/components/jomjol_wlan/basic_auth.cpp b/code/components/jomjol_wlan/basic_auth.cpp new file mode 100644 index 000000000..09d46b547 --- /dev/null +++ b/code/components/jomjol_wlan/basic_auth.cpp @@ -0,0 +1,107 @@ +#include "basic_auth.h" +#include "read_wlanini.h" +#include +#include + + +#define HTTPD_401 "401 UNAUTHORIZED" + +static const char *TAG = "HTTPAUTH"; + +typedef struct { + const char *username; + const char *password; +} basic_auth_info_t; + +basic_auth_info_t basic_auth_info = { NULL, NULL }; + +void init_basic_auth() { + if (!wlan_config.http_username.empty() && !wlan_config.http_password.empty()) { + basic_auth_info.username = wlan_config.http_username.c_str(); + basic_auth_info.password = wlan_config.http_password.c_str(); + } +} + +static char *http_auth_basic(const char *username, const char *password) +{ + int out; + char *user_info = NULL; + char *digest = NULL; + size_t n = 0; + asprintf(&user_info, "%s:%s", username, password); + if (!user_info) { + ESP_LOGE(TAG, "No enough memory for user information"); + return NULL; + } + esp_crypto_base64_encode(NULL, 0, &n, (const unsigned char *)user_info, strlen(user_info)); + + /* 6: The length of the "Basic " string + * n: Number of bytes for a base64 encode format + * 1: Number of bytes for a reserved which be used to fill zero + */ + digest = static_cast(calloc(1, 6 + n + 1)); + if (digest) { + strcpy(digest, "Basic "); + esp_crypto_base64_encode((unsigned char *)digest + 6, n, (size_t *)&out, (const unsigned char *)user_info, strlen(user_info)); + } + free(user_info); + return digest; +} + +esp_err_t basic_auth_request_filter(httpd_req_t *req, esp_err_t original_handler(httpd_req_t *)) +{ + char *buf = NULL; + size_t buf_len = 0; + esp_err_t ret = ESP_OK; + + char unauthorized[] = "You are not authorized to use this website!"; + + if (basic_auth_info.username == NULL || basic_auth_info.password == NULL) { + ret = original_handler(req); + } else { + buf_len = httpd_req_get_hdr_value_len(req, "Authorization") + 1; + if (buf_len > 1) { + buf = static_cast(calloc(1, buf_len)); + if (!buf) { + ESP_LOGE(TAG, "No enough memory for basic authorization"); + return ESP_ERR_NO_MEM; + } + + if (httpd_req_get_hdr_value_str(req, "Authorization", buf, buf_len) == ESP_OK) { + ESP_LOGI(TAG, "Found header => Authorization: %s", buf); + } else { + ESP_LOGE(TAG, "No auth value received"); + } + + char *auth_credentials = http_auth_basic(basic_auth_info.username, basic_auth_info.password); + if (!auth_credentials) { + ESP_LOGE(TAG, "No enough memory for basic authorization credentials"); + free(buf); + return ESP_ERR_NO_MEM; + } + + if (strncmp(auth_credentials, buf, buf_len)) { + ESP_LOGE(TAG, "Not authenticated"); + httpd_resp_set_status(req, HTTPD_401); + httpd_resp_set_type(req, HTTPD_TYPE_TEXT); + httpd_resp_set_hdr(req, "Connection", "keep-alive"); + httpd_resp_set_hdr(req, "WWW-Authenticate", "Basic realm=\"AIOTED\""); + httpd_resp_send(req, unauthorized, strlen(unauthorized)); + } else { + ESP_LOGI(TAG, "Authenticated calling http handler now!"); + ret=original_handler(req); + } + free(auth_credentials); + free(buf); + } else { + ESP_LOGE(TAG, "No auth header received"); + httpd_resp_set_status(req, HTTPD_401); + httpd_resp_set_type(req, HTTPD_TYPE_TEXT); + httpd_resp_set_hdr(req, "Connection", "keep-alive"); + httpd_resp_set_hdr(req, "WWW-Authenticate", "Basic realm=\"AIOTED\""); + httpd_resp_send(req, unauthorized, strlen(unauthorized)); + } + } + + return ret; +} diff --git a/code/components/jomjol_wlan/basic_auth.h b/code/components/jomjol_wlan/basic_auth.h new file mode 100644 index 000000000..51e021eb4 --- /dev/null +++ b/code/components/jomjol_wlan/basic_auth.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +void init_basic_auth(); +esp_err_t basic_auth_request_filter(httpd_req_t *req, esp_err_t original_handler(httpd_req_t *)); + +#define APPLY_BASIC_AUTH_FILTER(method) [](httpd_req_t *req){ return basic_auth_request_filter(req, method); } diff --git a/code/components/jomjol_wlan/read_wlanini.cpp b/code/components/jomjol_wlan/read_wlanini.cpp index 7ebca23da..8473a8886 100644 --- a/code/components/jomjol_wlan/read_wlanini.cpp +++ b/code/components/jomjol_wlan/read_wlanini.cpp @@ -145,6 +145,29 @@ int LoadWlanFromFile(std::string fn) wlan_config.dns = tmp; LogFile.WriteToFile(ESP_LOG_INFO, TAG, "DNS: " + wlan_config.dns); } + + else if ((splitted.size() > 1) && (toUpper(splitted[0]) == "HTTP_USERNAME")){ + tmp = splitted[1]; + if ((tmp[0] == '"') && (tmp[tmp.length()-1] == '"')){ + tmp = tmp.substr(1, tmp.length()-2); + } + wlan_config.http_username = tmp; + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "HTTP_USERNAME: " + wlan_config.http_username); + } + + else if ((splitted.size() > 1) && (toUpper(splitted[0]) == "HTTP_PASSWORD")){ + tmp = splitted[1]; + if ((tmp[0] == '"') && (tmp[tmp.length()-1] == '"')){ + tmp = tmp.substr(1, tmp.length()-2); + } + wlan_config.http_password = tmp; + #ifndef __HIDE_PASSWORD + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "HTTP_PASSWORD: " + wlan_config.http_password); + #else + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "HTTP_PASSWORD: XXXXXXXX"); + #endif + } + #if (defined WLAN_USE_ROAMING_BY_SCANNING || (defined WLAN_USE_MESH_ROAMING && defined WLAN_USE_MESH_ROAMING_ACTIVATE_CLIENT_TRIGGERED_QUERIES)) else if ((splitted.size() > 1) && (toUpper(splitted[0]) == "RSSITHRESHOLD")){ tmp = trim(splitted[1]); diff --git a/code/components/jomjol_wlan/read_wlanini.h b/code/components/jomjol_wlan/read_wlanini.h index 6a31490f7..759f68332 100644 --- a/code/components/jomjol_wlan/read_wlanini.h +++ b/code/components/jomjol_wlan/read_wlanini.h @@ -13,6 +13,8 @@ struct wlan_config { std::string gateway = ""; std::string netmask = ""; std::string dns = ""; + std::string http_username = ""; + std::string http_password = ""; int rssi_threshold = 0; // Default: 0 -> ROAMING disabled }; extern struct wlan_config wlan_config; diff --git a/code/main/main.cpp b/code/main/main.cpp index 5d0ba9b69..66b32e22f 100644 --- a/code/main/main.cpp +++ b/code/main/main.cpp @@ -33,6 +33,8 @@ #include "configFile.h" #include "server_main.h" #include "server_camera.h" +#include "basic_auth.h" + #ifdef ENABLE_MQTT #include "server_mqtt.h" #endif //ENABLE_MQTT @@ -429,6 +431,8 @@ extern "C" void app_main(void) StatusLED(WLAN_INIT, 3, true); return; } + + init_basic_auth(); } else if (iWLANStatus == -1) { // wlan.ini not available, potentially empty or content not readable StatusLED(WLAN_INIT, 1, true); diff --git a/code/main/server_main.cpp b/code/main/server_main.cpp index 58b55e900..a38a7e129 100644 --- a/code/main/server_main.cpp +++ b/code/main/server_main.cpp @@ -17,6 +17,7 @@ #include "MainFlowControl.h" #include "esp_log.h" +#include "basic_auth.h" #include "esp_chip_info.h" #include @@ -408,7 +409,7 @@ void register_server_main_uri(httpd_handle_t server, const char *base_path) httpd_uri_t info_get_handle = { .uri = "/info", // Match all URIs of type /path/to/file .method = HTTP_GET, - .handler = info_get_handler, + .handler = APPLY_BASIC_AUTH_FILTER(info_get_handler), .user_ctx = (void*) base_path // Pass server data as context }; httpd_register_uri_handler(server, &info_get_handle); @@ -416,7 +417,7 @@ void register_server_main_uri(httpd_handle_t server, const char *base_path) httpd_uri_t sysinfo_handle = { .uri = "/sysinfo", // Match all URIs of type /path/to/file .method = HTTP_GET, - .handler = sysinfo_handler, + .handler = APPLY_BASIC_AUTH_FILTER(sysinfo_handler), .user_ctx = (void*) base_path // Pass server data as context }; httpd_register_uri_handler(server, &sysinfo_handle); @@ -424,7 +425,7 @@ void register_server_main_uri(httpd_handle_t server, const char *base_path) httpd_uri_t starttime_tmp_handle = { .uri = "/starttime", // Match all URIs of type /path/to/file .method = HTTP_GET, - .handler = starttime_get_handler, + .handler = APPLY_BASIC_AUTH_FILTER(starttime_get_handler), .user_ctx = NULL // Pass server data as context }; httpd_register_uri_handler(server, &starttime_tmp_handle); @@ -432,7 +433,7 @@ void register_server_main_uri(httpd_handle_t server, const char *base_path) httpd_uri_t img_tmp_handle = { .uri = "/img_tmp/*", // Match all URIs of type /path/to/file .method = HTTP_GET, - .handler = img_tmp_virtual_handler, + .handler = APPLY_BASIC_AUTH_FILTER(img_tmp_virtual_handler), .user_ctx = (void*) base_path // Pass server data as context }; httpd_register_uri_handler(server, &img_tmp_handle); @@ -440,7 +441,7 @@ void register_server_main_uri(httpd_handle_t server, const char *base_path) httpd_uri_t main_rest_handle = { .uri = "/*", // Match all URIs of type /path/to/file .method = HTTP_GET, - .handler = hello_main_handler, + .handler = APPLY_BASIC_AUTH_FILTER(hello_main_handler), .user_ctx = (void*) base_path // Pass server data as context }; httpd_register_uri_handler(server, &main_rest_handle); diff --git a/code/main/softAP.cpp b/code/main/softAP.cpp index fe903fd11..e1aab5f2d 100644 --- a/code/main/softAP.cpp +++ b/code/main/softAP.cpp @@ -29,6 +29,7 @@ #include "Helper.h" #include "statusled.h" #include "server_ota.h" +#include "basic_auth.h" #include "lwip/err.h" #include "lwip/sys.h" @@ -468,7 +469,7 @@ httpd_handle_t start_webserverAP(void) httpd_uri_t reboot_handle = { .uri = "/reboot", // Match all URIs of type /path/to/file .method = HTTP_GET, - .handler = reboot_handlerAP, + .handler = APPLY_BASIC_AUTH_FILTER(reboot_handlerAP), .user_ctx = NULL // Pass server data as context }; httpd_register_uri_handler(server, &reboot_handle); @@ -476,7 +477,7 @@ httpd_handle_t start_webserverAP(void) httpd_uri_t config_ini_handle = { .uri = "/config", // Match all URIs of type /path/to/file .method = HTTP_GET, - .handler = config_ini_handler, + .handler = APPLY_BASIC_AUTH_FILTER(config_ini_handler), .user_ctx = NULL // Pass server data as context }; httpd_register_uri_handler(server, &config_ini_handle); @@ -485,7 +486,7 @@ httpd_handle_t start_webserverAP(void) httpd_uri_t file_uploadAP = { .uri = "/upload/*", // Match all URIs of type /upload/path/to/file .method = HTTP_POST, - .handler = upload_post_handlerAP, + .handler = APPLY_BASIC_AUTH_FILTER(upload_post_handlerAP), .user_ctx = NULL // Pass server data as context }; httpd_register_uri_handler(server, &file_uploadAP); @@ -493,7 +494,7 @@ httpd_handle_t start_webserverAP(void) httpd_uri_t test_uri = { .uri = "*", .method = HTTP_GET, - .handler = test_handler, + .handler = APPLY_BASIC_AUTH_FILTER(test_handler), .user_ctx = NULL }; httpd_register_uri_handler(server, &test_uri); diff --git a/sd-card/wlan.ini b/sd-card/wlan.ini index a1ba7454a..13eab43b3 100644 --- a/sd-card/wlan.ini +++ b/sd-card/wlan.ini @@ -36,3 +36,14 @@ password = "" ; Default: 0 = Disable client requested roaming query RSSIThreshold = 0 + +;++++++++++++++++++++++++++++++++++ +; Password Protection of the Web Interface and the REST API +; When those parameters are active, the Web Interface and the REST API are protected by a username and password. +; Note: This is be a WEAK and INSECURE way to protect the Web Interface and the REST API. +; There was no audit nor a security review to check the correct implementation of the protection! +; The password gets transmitted unencrypted (plain text), this means it is very easy to extract it +; for somebody who has access to your WIFI! +; USE AT YOUR OWN RISK! +;http_username = "myusername" +;http_password = "mypassword"