mirror of
https://github.com/neocturne/fastd.git
synced 2025-05-14 20:25:08 +02:00
Handle duplicate keys
When two peers are configured with the same key, disable both. When a temporary peer's key is configured, delete the temporary key.
This commit is contained in:
parent
56255a15a3
commit
103133c2fc
3 changed files with 73 additions and 23 deletions
24
src/fastd.c
24
src/fastd.c
|
@ -615,23 +615,31 @@ static void delete_peer_groups(fastd_context_t *ctx) {
|
||||||
|
|
||||||
static void init_peers(fastd_context_t *ctx) {
|
static void init_peers(fastd_context_t *ctx) {
|
||||||
fastd_peer_config_t *peer_conf;
|
fastd_peer_config_t *peer_conf;
|
||||||
for (peer_conf = ctx->conf->peers; peer_conf; peer_conf = peer_conf->next) {
|
for (peer_conf = ctx->conf->peers; peer_conf; peer_conf = peer_conf->next)
|
||||||
bool was_enabled = peer_conf->enabled;
|
|
||||||
|
|
||||||
peer_conf->enabled = true;
|
|
||||||
ctx->conf->protocol->peer_configure(ctx, peer_conf);
|
ctx->conf->protocol->peer_configure(ctx, peer_conf);
|
||||||
|
|
||||||
if (peer_conf->enabled && !was_enabled)
|
for (peer_conf = ctx->conf->peers; peer_conf; peer_conf = peer_conf->next) {
|
||||||
|
bool enable = ctx->conf->protocol->peer_check(ctx, peer_conf);
|
||||||
|
|
||||||
|
if (enable && !peer_conf->enabled)
|
||||||
fastd_peer_add(ctx, peer_conf);
|
fastd_peer_add(ctx, peer_conf);
|
||||||
|
|
||||||
|
peer_conf->enabled = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
fastd_peer_t *peer, *next;
|
fastd_peer_t *peer, *next;
|
||||||
for (peer = ctx->peers; peer; peer = next) {
|
for (peer = ctx->peers; peer; peer = next) {
|
||||||
next = peer->next;
|
next = peer->next;
|
||||||
|
|
||||||
if (!peer->config->enabled) {
|
if (peer->config) {
|
||||||
pr_info(ctx, "previously enabled peer %P disabled, deleting.", peer);
|
if (!peer->config->enabled) {
|
||||||
fastd_peer_delete(ctx, peer);
|
pr_info(ctx, "previously enabled peer %P disabled, deleting.", peer);
|
||||||
|
fastd_peer_delete(ctx, peer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!ctx->conf->protocol->peer_check_temporary(ctx, peer))
|
||||||
|
fastd_peer_delete(ctx, peer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,8 @@ struct fastd_protocol {
|
||||||
|
|
||||||
fastd_protocol_config_t* (*init)(fastd_context_t *ctx);
|
fastd_protocol_config_t* (*init)(fastd_context_t *ctx);
|
||||||
void (*peer_configure)(fastd_context_t *ctx, fastd_peer_config_t *peer_conf);
|
void (*peer_configure)(fastd_context_t *ctx, fastd_peer_config_t *peer_conf);
|
||||||
|
bool (*peer_check)(fastd_context_t *ctx, fastd_peer_config_t *peer_conf);
|
||||||
|
bool (*peer_check_temporary)(fastd_context_t *ctx, fastd_peer_t *peer);
|
||||||
|
|
||||||
void (*handshake_init)(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *address, fastd_peer_t *peer);
|
void (*handshake_init)(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *address, fastd_peer_t *peer);
|
||||||
void (*handshake_handle)(fastd_context_t *ctx, fastd_socket_t *sock, const fastd_peer_address_t *address, fastd_peer_t *peer, const fastd_handshake_t *handshake, const fastd_method_t *method);
|
void (*handshake_handle)(fastd_context_t *ctx, fastd_socket_t *sock, const fastd_peer_address_t *address, fastd_peer_t *peer, const fastd_handshake_t *handshake, const fastd_method_t *method);
|
||||||
|
|
|
@ -159,19 +159,38 @@ static fastd_protocol_config_t* protocol_init(fastd_context_t *ctx) {
|
||||||
return protocol_config;
|
return protocol_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void hexdump(char out[65], unsigned char d[32]) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
snprintf(out+2*i, 3, "%02x", d[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t key_count(fastd_context_t *ctx, const ecc_int256_t *key) {
|
||||||
|
size_t ret = 0;
|
||||||
|
|
||||||
|
fastd_peer_config_t *p;
|
||||||
|
for (p = ctx->conf->peers; p; p = p->next) {
|
||||||
|
if (!p->protocol_config)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (memcmp(p->protocol_config->public_key.p, key->p, 32) == 0)
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void protocol_peer_configure(fastd_context_t *ctx, fastd_peer_config_t *peer_conf) {
|
static void protocol_peer_configure(fastd_context_t *ctx, fastd_peer_config_t *peer_conf) {
|
||||||
if (!peer_conf->protocol_config) {
|
if (!peer_conf->protocol_config) {
|
||||||
if (!peer_conf->key) {
|
if (!peer_conf->key) {
|
||||||
pr_warn(ctx, "no key configured for `%s', disabling peer", peer_conf->name);
|
pr_warn(ctx, "no key configured for `%s', disabling peer", peer_conf->name);
|
||||||
peer_conf->enabled = false;
|
goto disable;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ecc_int256_t key;
|
ecc_int256_t key;
|
||||||
if (!read_key(key.p, peer_conf->key)) {
|
if (!read_key(key.p, peer_conf->key)) {
|
||||||
pr_warn(ctx, "invalid key configured for `%s', disabling peer", peer_conf->name);
|
pr_warn(ctx, "invalid key configured for `%s', disabling peer", peer_conf->name);
|
||||||
peer_conf->enabled = false;
|
goto disable;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
peer_conf->protocol_config = malloc(sizeof(fastd_protocol_peer_config_t));
|
peer_conf->protocol_config = malloc(sizeof(fastd_protocol_peer_config_t));
|
||||||
|
@ -179,14 +198,39 @@ static void protocol_peer_configure(fastd_context_t *ctx, fastd_peer_config_t *p
|
||||||
|
|
||||||
if (memcmp(peer_conf->protocol_config->public_key.p, ctx->conf->protocol_config->public_key.p, 32) == 0) {
|
if (memcmp(peer_conf->protocol_config->public_key.p, ctx->conf->protocol_config->public_key.p, 32) == 0) {
|
||||||
pr_debug(ctx, "found own key as `%s', ignoring peer", peer_conf->name);
|
pr_debug(ctx, "found own key as `%s', ignoring peer", peer_conf->name);
|
||||||
peer_conf->enabled = false;
|
goto disable;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (memcmp(peer_conf->protocol_config->public_key.p, ctx->conf->protocol_config->public_key.p, 32) == 0) {
|
|
||||||
peer_conf->enabled = false;
|
return;
|
||||||
return;
|
|
||||||
|
disable:
|
||||||
|
peer_conf->enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool protocol_peer_check(fastd_context_t *ctx, fastd_peer_config_t *peer_conf) {
|
||||||
|
if (memcmp(peer_conf->protocol_config->public_key.p, ctx->conf->protocol_config->public_key.p, 32) == 0) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
if (key_count(ctx, &peer_conf->protocol_config->public_key) > 1) {
|
||||||
|
char buf[65];
|
||||||
|
hexdump(buf, peer_conf->protocol_config->public_key.p);
|
||||||
|
pr_warn(ctx, "more than one peer is configured with key %s, disabling %s", buf, peer_conf->name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool protocol_peer_check_temporary(fastd_context_t *ctx, fastd_peer_t *peer) {
|
||||||
|
if (key_count(ctx, &peer->protocol_config->public_key)) {
|
||||||
|
char buf[65];
|
||||||
|
hexdump(buf, peer->protocol_config->public_key.p);
|
||||||
|
pr_info(ctx, "key %s is configured now, deleting temporary peer.", buf);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_protocol_state(fastd_context_t *ctx) {
|
static void init_protocol_state(fastd_context_t *ctx) {
|
||||||
|
@ -859,12 +903,6 @@ static void protocol_free_peer_state(fastd_context_t *ctx, fastd_peer_t *peer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void hexdump(char out[65], unsigned char d[32]) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 32; i++)
|
|
||||||
snprintf(out+2*i, 3, "%02x", d[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void print_hexdump(const char *desc, unsigned char d[32]) {
|
static inline void print_hexdump(const char *desc, unsigned char d[32]) {
|
||||||
char buf[65];
|
char buf[65];
|
||||||
hexdump(buf, d);
|
hexdump(buf, d);
|
||||||
|
@ -935,6 +973,8 @@ const fastd_protocol_t fastd_protocol_ec25519_fhmqvc = {
|
||||||
|
|
||||||
.init = protocol_init,
|
.init = protocol_init,
|
||||||
.peer_configure = protocol_peer_configure,
|
.peer_configure = protocol_peer_configure,
|
||||||
|
.peer_check = protocol_peer_check,
|
||||||
|
.peer_check_temporary = protocol_peer_check_temporary,
|
||||||
|
|
||||||
.handshake_init = protocol_handshake_init,
|
.handshake_init = protocol_handshake_init,
|
||||||
.handshake_handle = protocol_handshake_handle,
|
.handshake_handle = protocol_handshake_handle,
|
||||||
|
|
Loading…
Add table
Reference in a new issue