/* SPDX-License-Identifier: GPL-3.0-only */ /* Internal session primitives; no HTTP authorization is enabled by this module. */ #pragma once #include #include #include #include "esp_err.h" #include "user_database.h" #define WEB_SESSION_STORE_CAPACITY 4U #define WEB_SESSION_STORE_SECRET_BYTES 32U #define WEB_SESSION_STORE_TOKEN_LENGTH 64U #define WEB_SESSION_STORE_ORIGIN_MAX_LENGTH 128U #define WEB_SESSION_STORE_LIFETIME_US 3600000000LL typedef uint64_t web_session_id_t; /* Sensitive request-local result, NOT a routine snapshot. Wipe after use. */ typedef struct { web_session_id_t id; int64_t expires_at_us; user_principal_t principal; char csrf[WEB_SESSION_STORE_TOKEN_LENGTH + 1U]; } web_session_view_t; typedef struct { bool initialized; uint32_t active; uint32_t issued; uint32_t capacity_rejections; uint32_t expired; uint32_t invalidated; uint32_t lookup_rejections; uint32_t init_failures; size_t storage_bytes; size_t slot_bytes; } web_session_store_snapshot_t; /* Idempotent; probes the already-seeded shared RNG, never seeds it here. * Stop cancels in-flight initialization/issuance and wipes all records. IDs and * invalidation epochs never reset within a boot, even across stop/init. */ esp_err_t web_session_store_init(void); void web_session_store_stop(void); /* Trusted callers only. principal must be a current password-authenticated * principal. origin is the canonical, already HTTP-policy-validated HTTPS * origin, not an unchecked Host header; this module only binds its digest. * No live eviction. ESP_ERR_NO_MEM means fixed session capacity exhausted. * Raw token is returned only by issue; both outputs must be wiped by caller. * Output buffers must not alias inputs or each other. */ esp_err_t web_session_store_issue( const user_principal_t *principal, const char *origin, size_t origin_length, char token[WEB_SESSION_STORE_TOKEN_LENGTH + 1U], web_session_view_t *view); esp_err_t web_session_store_lookup( const char *token, size_t token_length, const char *origin, size_t origin_length, web_session_view_t *view); /* Trusted transport identity check, not a replacement for HTTP cookie/origin * authorization. Every successful lookup/check revalidates the principal. * No API result is a lease: recheck at later sensitive boundaries. */ esp_err_t web_session_store_is_current(web_session_id_t id, bool *current); /* Also verifies that the transport's copied principal belongs to this ID. */ esp_err_t web_session_store_check_principal(web_session_id_t id, const user_principal_t *principal, bool *current); void web_session_store_invalidate(web_session_id_t id); void web_session_store_invalidate_user(uint32_t user_id); /* Command notifications use names, including after account deletion. NULL/0 * invalidates all records without disabling the store. */ void web_session_store_invalidate_username(const uint8_t *username, size_t length); void web_session_store_prune(void); /* Counts only: never token/digest/CSRF/principal material. Expired records are * reclaimed here; stale principals are reclaimed by prune or lookup/check. */ esp_err_t web_session_store_get_snapshot(web_session_store_snapshot_t *snapshot);