Signed-off-by: YoungSoo Shin <shinys000114@gmail.com>
This commit is contained in:
2025-09-26 12:09:36 +09:00
parent 358090db5d
commit e07aad2d7d
7 changed files with 73 additions and 44 deletions

View File

@@ -1,3 +1,4 @@
#include "auth.h"
#include "cJSON.h" #include "cJSON.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#include "esp_http_server.h" #include "esp_http_server.h"
@@ -5,12 +6,12 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "sw.h" #include "sw.h"
#include "webserver.h" #include "webserver.h"
#include "auth.h"
static esp_err_t control_get_handler(httpd_req_t* req) static esp_err_t control_get_handler(httpd_req_t* req)
{ {
esp_err_t err = api_auth_check(req); esp_err_t err = api_auth_check(req);
if (err != ESP_OK) { if (err != ESP_OK)
{
return err; return err;
} }
@@ -32,7 +33,8 @@ static esp_err_t control_get_handler(httpd_req_t* req)
static esp_err_t control_post_handler(httpd_req_t* req) static esp_err_t control_post_handler(httpd_req_t* req)
{ {
esp_err_t err = api_auth_check(req); esp_err_t err = api_auth_check(req);
if (err != ESP_OK) { if (err != ESP_OK)
{
return err; return err;
} }

View File

@@ -280,13 +280,14 @@ void init_status_monitor()
.name = "sensor_reading_timer"}; .name = "sensor_reading_timer"};
const esp_timer_create_args_t wifi_timer_args = {.callback = &status_wifi_callback, .name = "wifi_status_timer"}; const esp_timer_create_args_t wifi_timer_args = {.callback = &status_wifi_callback, .name = "wifi_status_timer"};
const esp_timer_create_args_t long_press_timer_args = {.callback = &long_press_timer_callback, const esp_timer_create_args_t long_press_timer_args = {.callback = &long_press_timer_callback,
.name = "long_press_timer"}; .name = "long_press_timer"};
ESP_ERROR_CHECK(esp_timer_create(&sensor_timer_args, &sensor_timer)); ESP_ERROR_CHECK(esp_timer_create(&sensor_timer_args, &sensor_timer));
ESP_ERROR_CHECK(esp_timer_create(&wifi_timer_args, &wifi_status_timer)); ESP_ERROR_CHECK(esp_timer_create(&wifi_timer_args, &wifi_status_timer));
ESP_ERROR_CHECK(esp_timer_create(&long_press_timer_args, &long_press_timer)); ESP_ERROR_CHECK(esp_timer_create(&long_press_timer_args, &long_press_timer));
xTaskCreate(shutdown_load_sw_task, "shutdown_sw_task", configMINIMAL_STACK_SIZE * 3, NULL, 15, &shutdown_task_handle); xTaskCreate(shutdown_load_sw_task, "shutdown_sw_task", configMINIMAL_STACK_SIZE * 3, NULL, 15,
&shutdown_task_handle);
ESP_ERROR_CHECK(esp_timer_start_periodic(sensor_timer, 1000000)); ESP_ERROR_CHECK(esp_timer_start_periodic(sensor_timer, 1000000));
ESP_ERROR_CHECK(esp_timer_start_periodic(wifi_status_timer, 1000000 * 5)); ESP_ERROR_CHECK(esp_timer_start_periodic(wifi_status_timer, 1000000 * 5));

View File

@@ -1,4 +1,5 @@
#include <stdlib.h> #include <stdlib.h>
#include "auth.h"
#include "cJSON.h" #include "cJSON.h"
#include "climit.h" #include "climit.h"
#include "esp_http_server.h" #include "esp_http_server.h"
@@ -8,14 +9,14 @@
#include "nconfig.h" #include "nconfig.h"
#include "webserver.h" #include "webserver.h"
#include "wifi.h" #include "wifi.h"
#include "auth.h"
static const char* TAG = "webserver"; static const char* TAG = "webserver";
static esp_err_t setting_get_handler(httpd_req_t* req) static esp_err_t setting_get_handler(httpd_req_t* req)
{ {
esp_err_t err = api_auth_check(req); esp_err_t err = api_auth_check(req);
if (err != ESP_OK) { if (err != ESP_OK)
{
return err; return err;
} }
@@ -110,7 +111,8 @@ static esp_err_t setting_get_handler(httpd_req_t* req)
static esp_err_t wifi_scan(httpd_req_t* req) static esp_err_t wifi_scan(httpd_req_t* req)
{ {
esp_err_t err = api_auth_check(req); esp_err_t err = api_auth_check(req);
if (err != ESP_OK) { if (err != ESP_OK)
{
return err; return err;
} }
@@ -145,7 +147,8 @@ static esp_err_t wifi_scan(httpd_req_t* req)
static esp_err_t setting_post_handler(httpd_req_t* req) static esp_err_t setting_post_handler(httpd_req_t* req)
{ {
esp_err_t err = api_auth_check(req); esp_err_t err = api_auth_check(req);
if (err != ESP_OK) { if (err != ESP_OK)
{
return err; return err;
} }

View File

@@ -7,9 +7,9 @@
#include <esp_log.h> #include <esp_log.h>
#include <esp_timer.h> #include <esp_timer.h>
#include <string.h> #include <string.h>
#include "auth.h"
#include "esp_http_server.h" #include "esp_http_server.h"
#include "esp_system.h" #include "esp_system.h"
#include "auth.h"
static const char* TAG = "odroid"; static const char* TAG = "odroid";
@@ -52,7 +52,8 @@ void start_reboot_timer(int sec)
static esp_err_t reboot_post_handler(httpd_req_t* req) static esp_err_t reboot_post_handler(httpd_req_t* req)
{ {
esp_err_t err = api_auth_check(req); esp_err_t err = api_auth_check(req);
if (err != ESP_OK) { if (err != ESP_OK)
{
return err; return err;
} }
@@ -87,7 +88,8 @@ void register_reboot_endpoint(httpd_handle_t server)
static esp_err_t version_get_handler(httpd_req_t* req) static esp_err_t version_get_handler(httpd_req_t* req)
{ {
esp_err_t err = api_auth_check(req); esp_err_t err = api_auth_check(req);
if (err != ESP_OK) { if (err != ESP_OK)
{
return err; return err;
} }
@@ -103,4 +105,4 @@ void register_version_endpoint(httpd_handle_t server)
httpd_uri_t post_uri = { httpd_uri_t post_uri = {
.uri = "/api/version", .method = HTTP_GET, .handler = version_get_handler, .user_ctx = NULL}; .uri = "/api/version", .method = HTTP_GET, .handler = version_get_handler, .user_ctx = NULL};
httpd_register_uri_handler(server, &post_uri); httpd_register_uri_handler(server, &post_uri);
} }

View File

@@ -1,6 +1,8 @@
#include "webserver.h" #include "webserver.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "auth.h"
#include "cJSON.h"
#include "esp_http_server.h" #include "esp_http_server.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_wifi.h" #include "esp_wifi.h"
@@ -11,8 +13,6 @@
#include "monitor.h" #include "monitor.h"
#include "nconfig.h" #include "nconfig.h"
#include "system.h" #include "system.h"
#include "cJSON.h"
#include "auth.h"
static const char* TAG = "WEBSERVER"; static const char* TAG = "WEBSERVER";
@@ -28,9 +28,11 @@ static esp_err_t index_handler(httpd_req_t* req)
size_t remaining = index_html_size; size_t remaining = index_html_size;
const char* ptr = (const char*)index_html_start; const char* ptr = (const char*)index_html_start;
while (remaining > 0) { while (remaining > 0)
{
size_t to_send = remaining < 2048 ? remaining : 2048; size_t to_send = remaining < 2048 ? remaining : 2048;
if (httpd_resp_send_chunk(req, ptr, to_send) != ESP_OK) { if (httpd_resp_send_chunk(req, ptr, to_send) != ESP_OK)
{
ESP_LOGE(TAG, "File sending failed!"); ESP_LOGE(TAG, "File sending failed!");
httpd_resp_send_chunk(req, NULL, 0); httpd_resp_send_chunk(req, NULL, 0);
httpd_resp_send_500(req); httpd_resp_send_500(req);
@@ -48,8 +50,10 @@ static esp_err_t login_handler(httpd_req_t* req)
{ {
char content[100]; // Adjust size as needed for username/password char content[100]; // Adjust size as needed for username/password
int ret = httpd_req_recv(req, content, sizeof(content) - 1); // -1 for null terminator int ret = httpd_req_recv(req, content, sizeof(content) - 1); // -1 for null terminator
if (ret <= 0) { // 0 means connection closed, < 0 means error if (ret <= 0)
if (ret == HTTPD_SOCK_ERR_TIMEOUT) { { // 0 means connection closed, < 0 means error
if (ret == HTTPD_SOCK_ERR_TIMEOUT)
{
httpd_resp_send_408(req); httpd_resp_send_408(req);
} }
return ESP_FAIL; return ESP_FAIL;
@@ -58,33 +62,37 @@ static esp_err_t login_handler(httpd_req_t* req)
ESP_LOGI(TAG, "Received login request: %s", content); ESP_LOGI(TAG, "Received login request: %s", content);
cJSON *root = cJSON_Parse(content); cJSON* root = cJSON_Parse(content);
if (root == NULL) { if (root == NULL)
{
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON"); httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON");
return ESP_FAIL; return ESP_FAIL;
} }
cJSON *username_json = cJSON_GetObjectItemCaseSensitive(root, "username"); cJSON* username_json = cJSON_GetObjectItemCaseSensitive(root, "username");
cJSON *password_json = cJSON_GetObjectItemCaseSensitive(root, "password"); cJSON* password_json = cJSON_GetObjectItemCaseSensitive(root, "password");
if (!cJSON_IsString(username_json) || (username_json->valuestring == NULL) || if (!cJSON_IsString(username_json) || (username_json->valuestring == NULL) || !cJSON_IsString(password_json) ||
!cJSON_IsString(password_json) || (password_json->valuestring == NULL)) { (password_json->valuestring == NULL))
{
cJSON_Delete(root); cJSON_Delete(root);
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Missing username or password"); httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Missing username or password");
return ESP_FAIL; return ESP_FAIL;
} }
const char *username = username_json->valuestring; const char* username = username_json->valuestring;
const char *password = password_json->valuestring; const char* password = password_json->valuestring;
// TODO: Implement actual credential validation // TODO: Implement actual credential validation
// For now, a simple hardcoded check // For now, a simple hardcoded check
if (strcmp(username, "admin") == 0 && strcmp(password, "password") == 0) { if (strcmp(username, "admin") == 0 && strcmp(password, "password") == 0)
char *token = auth_generate_token(); {
if (token) { char* token = auth_generate_token();
cJSON *response_root = cJSON_CreateObject(); if (token)
{
cJSON* response_root = cJSON_CreateObject();
cJSON_AddStringToObject(response_root, "token", token); cJSON_AddStringToObject(response_root, "token", token);
char *json_response = cJSON_Print(response_root); char* json_response = cJSON_Print(response_root);
httpd_resp_set_type(req, "application/json"); httpd_resp_set_type(req, "application/json");
httpd_resp_sendstr(req, json_response); httpd_resp_sendstr(req, json_response);
@@ -92,10 +100,14 @@ static esp_err_t login_handler(httpd_req_t* req)
free(token); // Free the token generated by auth_generate_token free(token); // Free the token generated by auth_generate_token
free(json_response); free(json_response);
cJSON_Delete(response_root); cJSON_Delete(response_root);
} else { }
else
{
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to generate token"); httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to generate token");
} }
} else { }
else
{
httpd_resp_send_err(req, HTTPD_401_UNAUTHORIZED, "Invalid credentials"); httpd_resp_send_err(req, HTTPD_401_UNAUTHORIZED, "Invalid credentials");
} }

View File

@@ -5,9 +5,9 @@
#ifndef ODROID_REMOTE_HTTP_WEBSERVER_H #ifndef ODROID_REMOTE_HTTP_WEBSERVER_H
#define ODROID_REMOTE_HTTP_WEBSERVER_H #define ODROID_REMOTE_HTTP_WEBSERVER_H
#include "esp_http_server.h"
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "esp_http_server.h"
void register_wifi_endpoint(httpd_handle_t server); void register_wifi_endpoint(httpd_handle_t server);
void register_ws_endpoint(httpd_handle_t server); void register_ws_endpoint(httpd_handle_t server);

View File

@@ -2,6 +2,7 @@
// Created by shinys on 25. 8. 18.. // Created by shinys on 25. 8. 18..
// //
#include "auth.h"
#include "driver/uart.h" #include "driver/uart.h"
#include "esp_err.h" #include "esp_err.h"
#include "esp_http_server.h" #include "esp_http_server.h"
@@ -13,7 +14,6 @@
#include "pb_encode.h" #include "pb_encode.h"
#include "status.pb.h" #include "status.pb.h"
#include "webserver.h" #include "webserver.h"
#include "auth.h"
#define UART_NUM UART_NUM_1 #define UART_NUM UART_NUM_1
#define BUF_SIZE (2048) #define BUF_SIZE (2048)
@@ -210,14 +210,17 @@ static esp_err_t ws_handler(httpd_req_t* req)
char* query_str = NULL; char* query_str = NULL;
size_t query_len = httpd_req_get_url_query_len(req) + 1; size_t query_len = httpd_req_get_url_query_len(req) + 1;
if (query_len > 1) { if (query_len > 1)
{
query_str = malloc(query_len); query_str = malloc(query_len);
if (query_str == NULL) { if (query_str == NULL)
{
ESP_LOGE(TAG, "Failed to allocate memory for query string"); ESP_LOGE(TAG, "Failed to allocate memory for query string");
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Internal Server Error"); httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Internal Server Error");
return ESP_FAIL; return ESP_FAIL;
} }
if (httpd_req_get_url_query_str(req, query_str, query_len) != ESP_OK) { if (httpd_req_get_url_query_str(req, query_str, query_len) != ESP_OK)
{
ESP_LOGE(TAG, "Failed to get query string from URI: %s", req->uri); ESP_LOGE(TAG, "Failed to get query string from URI: %s", req->uri);
free(query_str); free(query_str);
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Internal Server Error"); httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Internal Server Error");
@@ -229,21 +232,27 @@ static esp_err_t ws_handler(httpd_req_t* req)
char token_str[TOKEN_LENGTH]; char token_str[TOKEN_LENGTH];
esp_err_t err = ESP_FAIL; // Default to fail esp_err_t err = ESP_FAIL; // Default to fail
if (query_str) { if (query_str)
{
err = httpd_query_key_value(query_str, "token", token_str, sizeof(token_str)); err = httpd_query_key_value(query_str, "token", token_str, sizeof(token_str));
free(query_str); // Free allocated query string free(query_str); // Free allocated query string
} }
if (err == ESP_OK) { if (err == ESP_OK)
{
ESP_LOGI(TAG, "Token extracted from query string, value: %s", token_str); ESP_LOGI(TAG, "Token extracted from query string, value: %s", token_str);
if (!auth_validate_token(token_str)) { if (!auth_validate_token(token_str))
{
ESP_LOGW(TAG, "WebSocket connection attempt with invalid token for URI: %s", req->uri); ESP_LOGW(TAG, "WebSocket connection attempt with invalid token for URI: %s", req->uri);
httpd_resp_send_err(req, HTTPD_401_UNAUTHORIZED, "Invalid or expired token"); httpd_resp_send_err(req, HTTPD_401_UNAUTHORIZED, "Invalid or expired token");
return ESP_FAIL; return ESP_FAIL;
} }
ESP_LOGD(TAG, "WebSocket token validated for URI: %s", req->uri); ESP_LOGD(TAG, "WebSocket token validated for URI: %s", req->uri);
} else { }
ESP_LOGW(TAG, "Failed to extract token from query string or query string not found, error: %s", esp_err_to_name(err)); else
{
ESP_LOGW(TAG, "Failed to extract token from query string or query string not found, error: %s",
esp_err_to_name(err));
httpd_resp_send_err(req, HTTPD_401_UNAUTHORIZED, "Authorization token required"); httpd_resp_send_err(req, HTTPD_401_UNAUTHORIZED, "Authorization token required");
return ESP_FAIL; return ESP_FAIL;
} }