Document strict parser ownership and validate provided peer keys
This commit is contained in:
1 parent
1041849030
commit
9a7091b595
2 files changed
+35
-18
No files matched your search
@@ -360,6 +360,9 @@ static struct CFG_SERVER* find_server_by_name(struct CFG_SERVER *servers, const
|
||||
}
|
||||
|
||||
static int parse_global(const char *key, const char *value, struct global_config *global, const char *filename, int line_num) {
|
||||
if ((!strcmp(key, "my_private_key") || !strcmp(key, "my_public_key")) && *value && config_ini_hex(value, NULL, SC_PRIVKEY_SIZE)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "%s:%d: %s requires 64 HEX characters", filename, line_num, key); return -1;
|
||||
}
|
||||
if (!strcmp(key, "my_node_name")) {
|
||||
if (strlen(value) >= sizeof(global->name))
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CONFIG, "%s:%d: my_node_name truncated to %zu bytes", filename, line_num, sizeof(global->name) - 1);
|
||||
@@ -735,6 +738,9 @@ static int parse_client(const char *key, const char *value, struct CFG_CLIENT *c
|
||||
}
|
||||
|
||||
if (strcmp(key, "peer_public_key") == 0) {
|
||||
if (*value && config_ini_hex(value, NULL, SC_PUBKEY_SIZE)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "%s:%d: peer_public_key requires 64 HEX characters", filename, line_num); return -1;
|
||||
}
|
||||
return assign_string(cli->peer_public_key_hex, MAX_KEY_LEN, value);
|
||||
}
|
||||
|
||||
|
||||
+29
-18
@@ -3,9 +3,13 @@
|
||||
* Успех возвращает выделенную utun_config со списками; освобождение — только free_config.
|
||||
* Файл и буфер проходят один разбор. Пробелы вокруг секций, ключей и значений удаляются;
|
||||
* имена секций нечувствительны к регистру, имена ключей чувствительны. Комментарий — #.
|
||||
* HEX проверяется целиком; ошибочный список REALITY short_ids не применяется частично.
|
||||
* Ошибка обработчика известной опции отклоняет весь конфиг с освобождением частичной модели.
|
||||
* HEX проверяется целиком; network требует оба ключа. Неизвестные секции игнорируются с WARN;
|
||||
* [gui] обрабатывает только utun_enabled. Числа проверяются до сужения, bool — yes/no/true/false/1/0.
|
||||
* Повторные значения применяются по порядку; ошибочный ранний дубль также отклоняется.
|
||||
* Встроенный NUL и строки >1022 байтов до LF запрещены (CR входит в этот предел).
|
||||
* Парсер заполняет модель, запуск сетевых ресурсов выполняет utun_instance. */
|
||||
* Парсер не открывает сетевые сокеты, но синхронно разрешает addr/control через getaddrinfo;
|
||||
* на Windows вызывающий заранее инициализирует socket subsystem. Сервисы запускает utun_instance. */
|
||||
#ifndef CONFIG_PARSER_H
|
||||
#define CONFIG_PARSER_H
|
||||
|
||||
@@ -26,7 +30,7 @@ extern "C" {
|
||||
#define MAX_ADDR_LEN 64
|
||||
|
||||
struct IP {
|
||||
sa_family_t family;
|
||||
sa_family_t family; // AF_INET/AF_INET6, 0 — адрес не задан; байты addr в сетевом порядке
|
||||
union {
|
||||
struct in_addr v4;
|
||||
struct in6_addr v6;
|
||||
@@ -55,32 +59,32 @@ struct IP {
|
||||
#define CFG_IPV6_MODE_PERMANENT 2 // permanent IPv6 from interface
|
||||
|
||||
struct CFG_SERVER {
|
||||
struct CFG_SERVER* next;
|
||||
char name[MAX_CONN_NAME_LEN];
|
||||
struct CFG_SERVER* next; // собственная цепочка конфигурации; список в обратном порядке секций
|
||||
char name[MAX_CONN_NAME_LEN]; // имя [server:name], до 63 байт
|
||||
struct sockaddr_storage ip; // ip:port
|
||||
uint32_t netif_index;// if_nameindex, 0 - no interface specified
|
||||
int so_mark;
|
||||
int fib; // FreeBSD FIB (routing table), -1 = don't set
|
||||
uint8_t type; // public/nat/private
|
||||
uint8_t type; // CFG_SERVER_TYPE_*; 0 если явно не задан
|
||||
uint8_t transport; // 0=udp (default), 1=tcp
|
||||
uint8_t reality_enabled; // 1 = TCP-порт с REALITY-камуфляжем (только transport=1)
|
||||
uint8_t socks_enabled; // 1 = UDP-сокет туннелировать через SOCKS5 (только transport=0)
|
||||
uint8_t ipv6_mode; // CFG_IPV6_MODE_*
|
||||
int mtu;
|
||||
int mtu; // 0 — не задан, при явной опции 0..65535; ресурс проверяет применимость
|
||||
uint8_t only_local; // 1 = only local connections, no forwarding
|
||||
};
|
||||
|
||||
struct CFG_CLIENT_LINK {
|
||||
struct CFG_CLIENT_LINK *next; // Next link in linked list
|
||||
struct CFG_SERVER* local_srv;
|
||||
char server_name[MAX_CONN_NAME_LEN]; // Name of local server for this link
|
||||
struct CFG_SERVER* local_srv; // заимствован у того же utun_config; NULL — remote-only
|
||||
char server_name[MAX_CONN_NAME_LEN]; // копия имени local_srv; пуста для remote-only
|
||||
struct sockaddr_storage remote_addr; // ip:port
|
||||
};
|
||||
|
||||
struct CFG_CLIENT {
|
||||
char name[MAX_CONN_NAME_LEN];
|
||||
char peer_public_key_hex[MAX_KEY_LEN];
|
||||
int keepalive;
|
||||
int keepalive; // необязательная клиентская настройка; 0 по умолчанию, неотрицательный int
|
||||
struct CFG_CLIENT_LINK *links; // Linked list of links
|
||||
struct CFG_CLIENT *next; // Next client in linked list
|
||||
uint8_t reality_enabled; // 1 = TCP-линк с REALITY-камуфляжем
|
||||
@@ -97,8 +101,8 @@ struct CFG_NETWORK {
|
||||
|
||||
struct CFG_ROUTE_ENTRY {
|
||||
struct CFG_ROUTE_ENTRY* next;
|
||||
struct IP ip;
|
||||
uint8_t netmask;
|
||||
struct IP ip; // исходный адрес подсети (host-биты парсер не нормализует)
|
||||
uint8_t netmask; // префикс 0..32/0..128; без / по умолчанию 32/128 по семейству
|
||||
};
|
||||
|
||||
struct CFG_FIREWALL_RULE {
|
||||
@@ -117,15 +121,15 @@ struct CFG_ALLOWED_KEY {
|
||||
};
|
||||
|
||||
struct CFG_NTP_SERVER {
|
||||
char name[256];
|
||||
char name[256]; // NUL-terminated hostname/IP; парсер не разрешает его, список идёт в обратном порядке
|
||||
struct CFG_NTP_SERVER *next;
|
||||
};
|
||||
|
||||
/* STUN-серверы обходятся в порядке конфигурации; DNS выполняет модуль stun_nat. */
|
||||
struct CFG_STUN_SERVER {
|
||||
struct CFG_STUN_SERVER* next;
|
||||
char host[256];
|
||||
uint16_t port;
|
||||
char host[256]; // IPv4/имя A-сервера; DNS выполняет stun_nat
|
||||
uint16_t port; // 1..65535, по умолчанию 3478
|
||||
};
|
||||
|
||||
#define MAX_TCP_PROXY_CLIENT_MAPPINGS 32
|
||||
@@ -273,16 +277,23 @@ struct utun_config {
|
||||
struct CFG_NETWORK* networks;
|
||||
};
|
||||
|
||||
/* Непустой путь; результат освобождать free_config. NULL при ошибке открытия, чтения,
|
||||
* закрытия, памяти или обязательной проверки формата, включая ошибки [global]. Часть опций других секций только
|
||||
* логируется и пропускается; ненулевой результат не гарантирует корректность всех полей. */
|
||||
/* Непустой путь; результат освобождать free_config. NULL при ошибке открытия/чтения/закрытия,
|
||||
* памяти, формата или обработчика известной опции. Значения по умолчанию и полноту настройки
|
||||
* для конкретного сервиса дополнительно проверяет его start; ненулевой результат не гарантирует запуск.
|
||||
* Файл не изменяется, ключи не генерируются: для этого отдельно вызвать config_ensure_keys_and_node_id. */
|
||||
struct utun_config* parse_config(const char *filename);
|
||||
/* buf — len байтов без завершающего NUL (NULL допустим при len=0), буфер не меняется.
|
||||
* filename — источник для диагностики, NULL означает <buffer>. Возврат как у parse_config. */
|
||||
struct utun_config* parse_config_from_buf(const char *buf, size_t len, const char *filename);
|
||||
// Освобождает модель и все собственные списки/массивы; заимствованные ссылки становятся недействительны; NULL допустим.
|
||||
void free_config(struct utun_config *config);
|
||||
// Пишет диагностический снимок в config/INFO; private/signing keys не выводятся; NULL — no-op.
|
||||
void print_config(const struct utun_config *config);
|
||||
// Печатает в config/INFO и stderr bootstrap utun:// v3 с channel_id/join_key=0 по адресам servers (до 32).
|
||||
// Чат должен быть включён; используются конфигурационные адреса, не фактический bind/NAT. NULL — no-op.
|
||||
void print_chatserver_invite_link(const struct utun_config *config, const struct CFG_SERVER *servers);
|
||||
// Устаревшее добавление [global] с двумя 32-byte HEX ключами в конец файла; 0/-1 с логом.
|
||||
// Не атомарно, частичная запись возможна. Для согласованных ключей/node_id использовать config_updater.
|
||||
int update_config_keys(const char *filename, const char *priv_key, const char *pub_key);
|
||||
|
||||
/* Узел (по pubkey, 32 байта) присутствует в списке [client] конфига? 1=да, 0=нет. */
|
||||
|
||||
Reference in new issue
Block a user