# Config Updater (config_updater.c/h) ## 1. Назначение Утилита автоматической инициализации и обновления ключей в конфигурационном файле uTun. Основная задача — гарантировать, что в конфиге всегда присутствуют корректные и согласованные: - `my_private_key` (X25519, 64 hex символа) - `my_public_key` (производный от private, 64 hex) - `my_node_id` (SHA256-идентификатор узла, 16 hex символов, вычисляется из private key) Если чего-то нет или значение неконсистентно — модуль генерирует недостающее через `secure_channel.h` и атомарно перезаписывает конфиг, сохраняя всё остальное содержимое файла нетронутым. ## 2. Как пользоваться ```c #include "config_updater.h" int ret = config_ensure_keys_and_node_id("/etc/utun/config.ini"); if (ret == 0) { // Конфиг готов: ключи и node_id гарантированно на месте } else { // Ошибка — смотри DEBUG_*(DEBUG_CATEGORY_CONFIG) } ``` **Типовой сценарий (первый запуск):** 1. Файла нет → создаётся минимальный `[global]` с `my_node_name`, сгенерированными ключами и `my_node_id`. 2. Файл есть, но нет `my_private_key` → генерируется новая X25519-пара, записываются все три поля. 3. Файл есть с `my_private_key`, но нет `my_public_key` или `my_node_id` → вычисляются из private key, дописываются. 4. Все поля есть, но `my_public_key` не соответствует `my_private_key` или `my_node_id` не совпадает → перезаписываются на корректные. **Нюансы:** - Вычисление pubkey: `sc_compute_public_key_from_private(priv_bin, pub_bin)`. - Вычисление node_id: `sc_derive_node_id(priv_bin)`. - Генерация новой пары ключей: `sc_generate_keypair(&mykeys)`. - Файл читается целиком в память, модифицируется через `insert_or_replace_option`, затем пишется обратно. Это атомарно: либо файл полностью перезаписан, либо остался нетронутым (при ошибке). - Редактирование in-place через `memmove`: строки не сдвигают остальной конфиг, только вставляются/заменяются нужные опции внутри секции `[global]`. - Для нового файла создаётся минимальный `[global]` с именем узла из `my_node_name` (или `"utun"` если не задано). ## 3. API ### Функции | Функция | Назначение | |---------|------------| | `config_ensure_keys_and_node_id(filename)` | **Основная функция.** Читает конфиг, проверяет/генерирует ключи и node_id, записывает обратно. Возвращает 0 при успехе, -1 при ошибке. | | `bytes_to_hex(bytes, len, hex_str, hex_len)` | Вспомогательная: конвертация бинарного массива в hex-строку. Безопасна для нулевых указателей и маленьких буферов. | ### Внутренние функции (static) | Функция | Назначение | |---------|------------| | `is_valid_priv_key(key)` | Проверяет, что строка — 64 hex-символа | | `is_valid_pub_key(key)` | То же для публичного ключа | | `is_valid_node_id(node_id)` | Проверяет `node_id != 0` | | `write_mem_to_file(filename, buffer, size)` | Пишет буфер в файл (одной операцией) | | `find_section_global(buf, buf_len)` | Ищет позицию после `[global]` в текстовом буфере | | `find_option(buf, buf_len, option)` | Ищет строку `option=...` в буфере | | `insert_or_replace_option(buf, buf_len, buf_capacity, option, value)` | Заменяет значение опции при наличии, либо вставляет новую строку после `[global]`. Работает с `memmove`/`memcpy`, перевыделяет буфер при необходимости. | ### Зависимости - `secure_channel.h` — `sc_generate_keypair()`, `sc_compute_public_key_from_private()`, `sc_derive_node_id()` - `config_parser.h` — `parse_config_from_buf()`, `free_config()`, структуры `utun_config`/`global_config` - `lib/mem.h` — `u_malloc`, `u_realloc`, `u_free` - `lib/debug_config.h` — `DEBUG_*`