mirror of
https://github.com/jomjol/AI-on-the-edge-device.git
synced 2025-12-06 03:26:53 +03:00
Add Web Interface and REST auth (#3436)
* Ported https://github.com/jomjol/AI-on-the-edge-device/pull/2241 to latest main and extended it for all REST APIs * . * fix compile errors * . * . * Update Changelog.md * Update Changelog.md --------- Co-authored-by: CaCO3 <caco@ruinelli.ch> Co-authored-by: michael <Heinrich-Tuning@web.de>
This commit is contained in:
23
Changelog.md
23
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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -42,6 +42,7 @@ https://docs.espressif.com/projects/esp-idf/en/latest/esp32/migration-guides/rel
|
||||
|
||||
#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);
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
107
code/components/jomjol_wlan/basic_auth.cpp
Normal file
107
code/components/jomjol_wlan/basic_auth.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
#include "basic_auth.h"
|
||||
#include "read_wlanini.h"
|
||||
#include <esp_tls_crypto.h>
|
||||
#include <esp_log.h>
|
||||
|
||||
|
||||
#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<char*>(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<char*>(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;
|
||||
}
|
||||
8
code/components/jomjol_wlan/basic_auth.h
Normal file
8
code/components/jomjol_wlan/basic_auth.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <esp_http_server.h>
|
||||
|
||||
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); }
|
||||
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "MainFlowControl.h"
|
||||
#include "esp_log.h"
|
||||
#include "basic_auth.h"
|
||||
#include "esp_chip_info.h"
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user