WebServer doesn't save config as a side-effect of reading the config

This commit is contained in:
Ken Van Hoeylandt 2026-07-28 00:37:25 +02:00
parent 4e97ae46e7
commit 3f34929995
2 changed files with 14 additions and 32 deletions

View File

@ -2,7 +2,6 @@
## Before release
- WebServer service shouldn't save webserver.properties at start, it slows the boot process
- Remove incubating flag from various devices
- Add `// SPDX-License-Identifier: GPL-3.0-only` and `// SPDX-License-Identifier: Apache-2.0` to individual files in the project
- Elecrow Basic & Advance 3.5" memory issue: not enough memory for App Hub

View File

@ -144,23 +144,17 @@ bool load(WebServerSettings& settings) {
? static_cast<uint8_t>(parseInt(ap_channel->second, 1, 13, 1))
: 1;
// Security: If AP password is empty, generate a strong random password.
// Security: If AP password is empty, generate a strong random password in memory.
// Skip this if user explicitly wants an open network.
// Note: We only auto-generate for EMPTY passwords, not user-set ones.
// This is a read-only function: the generated password is NOT persisted here —
// callers that want it saved must call save() explicitly.
if (!settings.apOpenNetwork && isEmptyCredential(settings.apPassword)) {
LOG_I(TAG, "AP password is empty - generating secure random password");
LOG_I(TAG, "AP password is empty - generating secure random password (not persisted)");
// Generate 12-character random password (alphanumeric, ~71 bits of entropy)
// WPA2 requires 8-63 characters, so 12 is well within range
settings.apPassword = generateRandomCredential(12);
// Persist the generated password immediately
map[KEY_AP_PASSWORD] = settings.apPassword;
if (file::savePropertiesFile(getSettingsFilePath(), map)) {
LOG_I(TAG, "Generated and saved new secure AP password");
} else {
LOG_E(TAG, "Failed to save generated AP password");
}
}
// Web server settings
@ -181,27 +175,20 @@ bool load(WebServerSettings& settings) {
settings.webServerUsername = (webserver_username != map.end()) ? webserver_username->second : "";
settings.webServerPassword = (webserver_password != map.end()) ? webserver_password->second : "";
// Security: If auth is enabled but credentials are empty,
// generate strong random credentials and persist them immediately.
// Note: We only auto-generate for EMPTY credentials, allowing users to set their own.
// Security: If auth is enabled but credentials are empty, generate strong random
// credentials in memory. Note: We only auto-generate for EMPTY credentials, allowing
// users to set their own.
// This is a read-only function: the generated credentials are NOT persisted here —
// callers that want them saved (so they're consistent across reboots) must call
// save() explicitly.
if (settings.webServerAuthEnabled &&
(isEmptyCredential(settings.webServerUsername) || isEmptyCredential(settings.webServerPassword))) {
LOG_I(TAG, "Auth enabled with empty credentials - generating secure random credentials");
LOG_I(TAG, "Auth enabled with empty credentials - generating secure random credentials (not persisted)");
// Generate 12-character random credentials (alphanumeric, ~71 bits of entropy each)
settings.webServerUsername = generateRandomCredential(12);
settings.webServerPassword = generateRandomCredential(12);
// Persist the generated credentials immediately
// We need to save these to the file so they're consistent across reboots
map[KEY_WEBSERVER_USERNAME] = settings.webServerUsername;
map[KEY_WEBSERVER_PASSWORD] = settings.webServerPassword;
if (file::savePropertiesFile(getSettingsFilePath(), map)) {
LOG_I(TAG, "Generated and saved new secure credentials");
} else {
LOG_E(TAG, "Failed to save generated credentials - auth may be inconsistent across reboots");
}
}
return true;
@ -228,14 +215,10 @@ WebServerSettings loadOrGetDefault() {
bool loadedFromFlash = load(settings);
if (!loadedFromFlash) {
// First boot - use defaults (WiFi OFF, WebServer OFF)
// No properties file yet (e.g. first boot) - use defaults in memory (WiFi OFF,
// WebServer OFF). Read-only function: does NOT persist these defaults — callers
// that want them saved must call save() explicitly.
settings = getDefault();
// Save defaults to flash so toggle states persist
if (save(settings)) {
LOG_I(TAG, "First boot - saved default settings (WiFi OFF WebServer OFF)");
} else {
LOG_W(TAG, "First boot - failed to save default settings to flash");
}
}
return settings;