Implement authenticated HTTPS OTA uploads with bounded streaming, image validation, reboot coordination, and lifecycle exclusion. Add the admin UI, regression tests, and Phase 10 acceptance documentation.
97 lines
3.7 KiB
C
97 lines
3.7 KiB
C
/* SPDX-License-Identifier: GPL-3.0-only */
|
|
#pragma once
|
|
#include <assert.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <strings.h>
|
|
|
|
typedef int esp_err_t;
|
|
#define ESP_OK 0
|
|
#define ESP_FAIL -1
|
|
#define ESP_ERR_NOT_FOUND 2
|
|
#define ESP_ERR_INVALID_STATE 3
|
|
#define ESP_ERR_TIMEOUT 4
|
|
#define ESP_ERR_INVALID_ARG 5
|
|
#define ESP_ERR_NO_MEM 6
|
|
#define ESP_ERR_INVALID_SIZE 7
|
|
#define ESP_ERR_HTTPD_INVALID_REQ 8
|
|
#define ESP_ERR_HTTPD_RESULT_TRUNC 9
|
|
#define HTTPD_SOCK_ERR_TIMEOUT -3
|
|
#define HTTP_POST 1
|
|
#define HTTP_GET 0
|
|
#define USER_ROLE_ADMIN 1
|
|
#define USER_ROLE_USER 0
|
|
#define pdPASS 1
|
|
#define pdTRUE 1
|
|
#define portMAX_DELAY UINT32_MAX
|
|
#define pdMS_TO_TICKS(n) (n)
|
|
#define taskENTER_CRITICAL(p) ((void)(p))
|
|
#define taskEXIT_CRITICAL(p) ((void)(p))
|
|
|
|
typedef void *httpd_handle_t;
|
|
typedef struct { const char *name, *value; } test_header_t;
|
|
struct httpd_req_aux { char *scratch; size_t scratch_cur_size; unsigned req_hdrs_count; };
|
|
typedef struct {
|
|
const char *uri;
|
|
int method;
|
|
size_t content_len, received;
|
|
httpd_handle_t handle;
|
|
struct httpd_req_aux *aux;
|
|
test_header_t headers[12];
|
|
size_t header_count;
|
|
bool headers_valid;
|
|
} httpd_req_t;
|
|
typedef struct { int role; uint32_t user_id; } user_principal_t;
|
|
typedef uint64_t web_session_id_t;
|
|
typedef struct { web_session_id_t id; user_principal_t principal; char csrf[65]; } web_session_view_t;
|
|
typedef struct {
|
|
uint32_t security_rejections, login_failures, throttled, capacity_rejections;
|
|
} web_cookie_auth_snapshot_t;
|
|
|
|
typedef void *TaskHandle_t;
|
|
typedef void *SemaphoreHandle_t;
|
|
#define eSetValueWithOverwrite 1
|
|
int xTaskCreate(void (*)(void *), const char *, unsigned, void *, unsigned, TaskHandle_t *);
|
|
int xTaskNotify(TaskHandle_t, uint32_t, int);
|
|
int xTaskNotifyWait(uint32_t, uint32_t, uint32_t *, uint32_t);
|
|
void vTaskDelay(unsigned);
|
|
void vTaskDelete(TaskHandle_t);
|
|
int xSemaphoreTake(SemaphoreHandle_t, unsigned);
|
|
void xSemaphoreGive(SemaphoreHandle_t);
|
|
void esp_restart(void);
|
|
int64_t esp_timer_get_time(void);
|
|
void secure_wipe(void *, size_t);
|
|
|
|
size_t httpd_req_get_hdr_value_len(httpd_req_t *, const char *);
|
|
esp_err_t httpd_req_get_hdr_value_str(httpd_req_t *, const char *, char *, size_t);
|
|
esp_err_t httpd_resp_set_status(httpd_req_t *, const char *);
|
|
esp_err_t httpd_resp_set_type(httpd_req_t *, const char *);
|
|
esp_err_t httpd_resp_set_hdr(httpd_req_t *, const char *, const char *);
|
|
esp_err_t httpd_resp_sendstr(httpd_req_t *, const char *);
|
|
int httpd_req_recv(httpd_req_t *, char *, size_t);
|
|
bool web_httpd_headers_valid(httpd_req_t *);
|
|
bool web_httpd_unread_body(httpd_req_t *);
|
|
void web_httpd_wipe_request(httpd_req_t *, bool);
|
|
esp_err_t web_session_store_lookup(const char *, size_t, const char *, size_t, web_session_view_t *);
|
|
esp_err_t web_session_store_check_principal(web_session_id_t, const user_principal_t *, bool *);
|
|
esp_err_t web_cookie_auth_require_body(httpd_req_t *, size_t, web_session_view_t *, bool *);
|
|
esp_err_t web_security_reserve_identity(uint32_t, bool, uint32_t *);
|
|
void web_security_release_identity(uint32_t);
|
|
|
|
typedef uint32_t esp_ota_handle_t;
|
|
typedef struct { uint32_t type, subtype, address, size, erase_size; } esp_partition_t;
|
|
#define ESP_PARTITION_TYPE_APP 0
|
|
#define ESP_PARTITION_SUBTYPE_APP_OTA_0 0x10
|
|
#define ESP_PARTITION_SUBTYPE_APP_OTA_15 0x1f
|
|
const esp_partition_t *esp_ota_get_running_partition(void);
|
|
const esp_partition_t *esp_ota_get_next_update_partition(const esp_partition_t *);
|
|
esp_err_t esp_ota_begin(const esp_partition_t *, size_t, esp_ota_handle_t *);
|
|
esp_err_t esp_ota_write(esp_ota_handle_t, const void *, size_t);
|
|
esp_err_t esp_ota_end(esp_ota_handle_t);
|
|
esp_err_t esp_ota_abort(esp_ota_handle_t);
|
|
esp_err_t esp_ota_set_boot_partition(const esp_partition_t *);
|