Normalize malformed key duplicates before strict config verification

This commit is contained in:
evgeny committed 2026-10-26 09:08:23 +01:00
1 parent 70b7823993
commit 4abeafa20e
3 files changed
+27 -5

No files matched your search

+17 -1
View File
@@ -20,9 +20,12 @@ struct config_field {
int section;
int present;
int update;
int invalid; // хотя бы одно вхождение поля содержит ошибочный синтаксис
char value[CONFIG_INI_LINE_SIZE];
};
static int config_node_id(const char* text, uint64_t* id);
/* Форматировать без усечения; проверка ёмкости не переполняет size_t. */
void bytes_to_hex(const uint8_t *bytes, size_t len, char *hex_str, size_t hex_len) {
static const char digits[] = "0123456789abcdef";
@@ -77,7 +80,17 @@ static void config_scan(const char *text, size_t length, struct config_field fie
while (isspace((unsigned char)*start)) start++;
if (*start == '[') ends[section] = pos;
int index = config_field_line(line, &section, fields, value);
if (index >= 0) { strcpy(fields[index].value, value); fields[index].present = 1; }
if (index >= 0) {
strcpy(fields[index].value, value); fields[index].present = 1;
if (index == CFG_REALITY_IDS) {
int count;
if (config_ini_hex_list(value, NULL, REALITY_SHORT_ID_SIZE, REALITY_MAX_SHORT_IDS, &count) || !count)
fields[index].invalid = 1;
} else if (index == CFG_NODE_ID) {
uint64_t id;
if (config_node_id(value, &id)) fields[index].invalid = 1;
} else if (index != CFG_REALITY_ENABLED && config_ini_hex(value, NULL, SC_PRIVKEY_SIZE)) fields[index].invalid = 1;
}
pos = end;
}
ends[section] = length;
@@ -356,6 +369,7 @@ int config_ensure_keys_and_node_id(const char *filename) {
fields[CFG_NODE_ID].update = 1;
snprintf(fields[CFG_NODE_ID].value, sizeof(fields[CFG_NODE_ID].value), "%016llx", (unsigned long long)node_id);
}
for (int i = CFG_PRIVATE; i <= CFG_NODE_ID; i++) if (fields[i].invalid) fields[i].update = 1;
int reality_enabled = atoi(fields[CFG_REALITY_ENABLED].value) != 0;
if (reality_enabled) {
if (config_ini_hex(fields[CFG_REALITY_PRIVATE].value, reality_private, sizeof(reality_private))) {
@@ -378,6 +392,8 @@ int config_ensure_keys_and_node_id(const char *filename) {
}
fields[CFG_REALITY_IDS].update = 1;
}
if (fields[CFG_REALITY_PRIVATE].invalid) fields[CFG_REALITY_PRIVATE].update = 1;
if (fields[CFG_REALITY_IDS].invalid) fields[CFG_REALITY_IDS].update = 1;
}
for (int i = 0; i < CFG_FIELD_COUNT; i++) {
if (!fields[i].update) continue;
+3 -1
View File
@@ -5,7 +5,9 @@
* или отсутствующем приватном ключе создаётся новая идентичность. HEX сравнивается по байтам.
* REALITY: недостающий/ошибочный private_key генерируется; пустой/ошибочный short_ids
* заменяется четырьмя новыми ID. Корректные параметры и выключенный REALITY сохраняются.
* Исправный файл остаётся побайтно неизменным. При правке сохраняются посторонний текст,
* Ошибочные ранние дубли этих полей заменяются выбранным последним значением, даже если оно корректно:
* штатный парсер проверяет каждое вхождение. Файл без таких ошибок остаётся побайтно неизменным.
* При правке сохраняются посторонний текст,
* комментарии и существующие окончания строк; обновляются все дубли исправляемого поля.
* Новый файл создаётся только при ENOENT. Встроенный NUL и строки >1022 байтов до LF запрещены. */
#ifndef CONFIG_UPDATER_H
+7 -3
View File
@@ -27,7 +27,10 @@ HEX проверяется посимвольно до декодировани
## Изменение текста
Исправный файл остаётся побайтно неизменным. Если поле требует исправления,
Синтаксически ошибочный ранний дубль поля идентичности или включённого REALITY также исправляется
по выбранному последнему значению: штатный парсер проверяет каждое вхождение.
Корректная итоговая идентичность/REALITY не меняется и не генерируется заново только из-за раннего дубля.
Файл без таких ошибок остаётся побайтно неизменным. Если поле требует исправления,
обновляются все его вхождения в соответствующих секциях. Недостающие поля добавляются
в конец последней подходящей секции; отсутствующая секция создаётся в конце файла.
@@ -37,8 +40,9 @@ HEX проверяется посимвольно до декодировани
после последней строки без LF. Новый или пустой файл получает [global] с тремя полями идентичности.
Перед записью итоговый текст проверяется строгими декодерами и штатным парсером.
Это проверка полей идентичности и необходимых параметров REALITY; парсер продолжает
логировать и пропускать некоторые ошибки прочих опций.
Штатный парсер отклоняет ошибки обработчиков известных опций; при таком отказе исходный файл сохраняется.
Отсутствие необходимости правки идентичности/REALITY не означает проверки остальных настроек:
вызывающая сторона всё равно загружает файл через parse_config.
## Запись и ошибки