Bind Serial Transports To Web Sessions

This commit is contained in:
2026-09-05 18:01:39 +02:00
parent 93eef0e676
commit a62a655ac1
18 changed files with 528 additions and 35 deletions
+50 -4
View File
@@ -164,7 +164,8 @@ void web_session_store_stop(void)
/* Never enter the database while holding our lock. On return, re-find the
* non-reused ID and deadline: logout/stop/slot reuse may have raced the call. */
static esp_err_t resolve(web_session_id_t id, web_session_view_t *view)
static esp_err_t resolve(web_session_id_t id, web_session_view_t *view,
const user_principal_t *expected)
{
session_entry_t candidate = {0};
int64_t now = esp_timer_get_time();
@@ -178,6 +179,16 @@ static esp_err_t resolve(web_session_id_t id, web_session_view_t *view)
}
taskEXIT_CRITICAL(&s_lock);
if (error == ESP_OK && expected != NULL &&
(candidate.principal.user_id != expected->user_id ||
candidate.principal.auth_generation != expected->auth_generation ||
candidate.principal.role != expected->role ||
candidate.principal.method != expected->method ||
candidate.principal.username_length != expected->username_length ||
memcmp(candidate.principal.username, expected->username,
candidate.principal.username_length) != 0)) {
error = ESP_ERR_NOT_FOUND;
}
if (error == ESP_OK) {
bool current = false;
error = user_database_principal_is_current(&candidate.principal, &current);
@@ -214,7 +225,7 @@ void web_session_store_prune(void)
web_session_id_t id = s_state.entries[i].id;
taskEXIT_CRITICAL(&s_lock);
if (id != 0U) {
(void)resolve(id, NULL);
(void)resolve(id, NULL, NULL);
}
}
}
@@ -347,7 +358,7 @@ esp_err_t web_session_store_lookup(
}
}
taskEXIT_CRITICAL(&s_lock);
error = resolve(id, view);
error = resolve(id, view, NULL);
}
secure_wipe(token_hash, sizeof(token_hash));
secure_wipe(origin_hash, sizeof(origin_hash));
@@ -360,13 +371,48 @@ esp_err_t web_session_store_is_current(web_session_id_t id, bool *current)
return ESP_ERR_INVALID_ARG;
}
*current = false;
esp_err_t error = resolve(id, NULL);
esp_err_t error = resolve(id, NULL, NULL);
if (error == ESP_OK) {
*current = true;
}
return error;
}
esp_err_t web_session_store_check_principal(web_session_id_t id,
const user_principal_t *principal,
bool *current)
{
if (current == NULL) {
return ESP_ERR_INVALID_ARG;
}
*current = false;
if (principal == NULL) {
return ESP_ERR_INVALID_ARG;
}
esp_err_t error = resolve(id, NULL, principal);
*current = error == ESP_OK;
return error;
}
void web_session_store_invalidate_username(const uint8_t *username, size_t length)
{
if ((username == NULL && length != 0U) ||
(username != NULL && !user_database_username_valid(username, length))) {
return;
}
taskENTER_CRITICAL(&s_lock);
advance_epoch_locked();
for (size_t i = 0U; i < WEB_SESSION_STORE_CAPACITY; ++i) {
session_entry_t *entry = &s_state.entries[i];
if (username == NULL ||
(entry->principal.username_length == length &&
memcmp(entry->principal.username, username, length) == 0)) {
retire_locked(entry, false);
}
}
taskEXIT_CRITICAL(&s_lock);
}
void web_session_store_invalidate(web_session_id_t id)
{
if (id == 0U) {