Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic auth filter new #2241

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion code/components/jomjol_controlGPIO/server_GPIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#endif //ENABLE_MQTT


#include "basic_auth.h"

static const char *TAG = "GPIO";
QueueHandle_t gpio_queue_handle = NULL;

Expand Down Expand Up @@ -458,7 +460,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);
}
Expand Down
12 changes: 7 additions & 5 deletions code/components/jomjol_controlcamera/server_camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "ClassLogFile.h"
#include "esp_log.h"

#include "basic_auth.h"

#include "../../include/defines.h"

static const char *TAG = "server_cam";
Expand Down Expand Up @@ -264,27 +266,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);
}
15 changes: 8 additions & 7 deletions code/components/jomjol_fileserver_ota/server_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ extern "C" {

#include "Helper.h"
#include "miniz.h"
#include "basic_auth.h"

static const char *TAG = "OTA FILE";

Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -1192,15 +1193,15 @@ 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);

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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down
6 changes: 4 additions & 2 deletions code/components/jomjol_fileserver_ota/server_ota.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@

#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*/
static char ota_write_data[SERVER_OTA_SCRATCH_BUFSIZE + 1] = { 0 };

Expand Down Expand Up @@ -690,13 +692,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);

Expand Down
3 changes: 2 additions & 1 deletion code/components/jomjol_mqtt/server_mqtt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "interface_mqtt.h"
#include "time_sntp.h"
#include "../../include/defines.h"
#include "basic_auth.h"



Expand Down Expand Up @@ -308,7 +309,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);
}
Expand Down
27 changes: 25 additions & 2 deletions code/components/jomjol_wlan/read_wlanini.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand All @@ -157,8 +180,8 @@ int LoadWlanFromFile(std::string fn)
#endif
}

/* read next line */
if (fgets(zw, sizeof(zw), pFile) == NULL) {
if (fgets(zw, 1024, pFile) == NULL)
caco3 marked this conversation as resolved.
Show resolved Hide resolved
{
line = "";
}
else {
Expand Down
2 changes: 2 additions & 0 deletions code/components/jomjol_wlan/read_wlanini.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions code/include/basic_auth.h
Original file line number Diff line number Diff line change
@@ -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); }
105 changes: 105 additions & 0 deletions code/main/basic_auth.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#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;

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, "application/json");
httpd_resp_set_hdr(req, "Connection", "keep-alive");
httpd_resp_set_hdr(req, "WWW-Authenticate", "Basic realm=\"Hello\"");
httpd_resp_send(req, NULL, 0);
} 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, "application/json");
httpd_resp_set_hdr(req, "Connection", "keep-alive");
httpd_resp_set_hdr(req, "WWW-Authenticate", "Basic realm=\"Hello\"");
httpd_resp_send(req, NULL, 0);
}
}

return ret;
}
5 changes: 5 additions & 0 deletions code/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
//#include "ClassControllCamera.h"
#include "server_main.h"
#include "server_camera.h"
#include "basic_auth.h"

#ifdef ENABLE_MQTT
#include "server_mqtt.h"
#endif //ENABLE_MQTT
Expand Down Expand Up @@ -86,6 +88,7 @@
static heap_trace_record_t trace_record[NUM_RECORDS]; // This buffer must be in internal RAM
#endif


extern const char* GIT_TAG;
extern const char* GIT_REV;
extern const char* GIT_BRANCH;
Expand Down Expand Up @@ -421,6 +424,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);
Expand Down
Loading