summaryrefslogtreecommitdiffstats
path: root/src/protocols
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2014-08-24 01:00:45 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2014-08-24 01:00:45 +0200
commita04bcf247f4be7e3da4fe3895200f0b9709fc0bb (patch)
tree5e749b81799bb82a751ed632d91b801abe624008 /src/protocols
parentad4999488eadac3a10de99caf50b732af8b771b9 (diff)
downloadfastd-a04bcf247f4be7e3da4fe3895200f0b9709fc0bb.tar
fastd-a04bcf247f4be7e3da4fe3895200f0b9709fc0bb.zip
Merge peer config into peer structure
With this refactoring, the structure fastd_peer_config_t is merged into fastd_peer_t, and fastd_remote_config_t into fastd_remote_t. This also means we now create peers directly when reading their configurations, which significantly simplifies the whole reload process, and prepares for some future optimizations like a key hash table. Note: This commit is too big, but I couldn't come up with a nice way to split it into smaller pieces...
Diffstat (limited to 'src/protocols')
-rw-r--r--src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c51
-rw-r--r--src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h12
-rw-r--r--src/protocols/ec25519_fhmqvc/handshake.c104
-rw-r--r--src/protocols/ec25519_fhmqvc/util.c20
4 files changed, 73 insertions, 114 deletions
diff --git a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c
index d952a5e..080c555 100644
--- a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c
+++ b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c
@@ -74,37 +74,26 @@ static fastd_protocol_config_t* protocol_init(void) {
return protocol_config;
}
-/** Checks if a peer configuration is valid */
-static void protocol_peer_verify(fastd_peer_config_t *peer_conf) {
- if (!peer_conf->key)
- exit_error("no key configured for peer `%s'", peer_conf->name);
-
- aligned_int256_t key;
- if (!read_key(key.u8, peer_conf->key))
- exit_error("invalid key configured for peer `%s'", peer_conf->name);
-}
-
-/** Initializes the protocol-specific peer configuration */
-static void protocol_peer_configure(fastd_peer_config_t *peer_conf) {
- if (peer_conf->protocol_config)
- return;
+/** Parses a peer's key */
+static fastd_protocol_key_t * protocol_read_key(const char *key) {
+ fastd_protocol_key_t *ret = fastd_new(fastd_protocol_key_t);
- if (!peer_conf->key) {
- pr_warn("no key configured for `%s', disabling peer", peer_conf->name);
- return;
+ if (!read_key(ret->key.u8, key)) {
+ free(ret);
+ return NULL;
}
- aligned_int256_t key;
- if (!read_key(key.u8, peer_conf->key)) {
- pr_warn("invalid key configured for `%s', disabling peer", peer_conf->name);
- return;
- }
+ return ret;
+}
- peer_conf->protocol_config = fastd_new(fastd_protocol_peer_config_t);
- peer_conf->protocol_config->public_key = key;
+/** Checks if a peer is configured using our own key */
+static bool protocol_check_peer(const fastd_peer_t *peer) {
+ if (memcmp(conf.protocol_config->key.public.u8, peer->key->key.u8, PUBLICKEYBYTES) == 0) {
+ pr_verbose("found own key as %P, ignoring peer", peer);
+ return false;
+ }
- if (memcmp(&peer_conf->protocol_config->public_key, &conf.protocol_config->key.public, PUBLICKEYBYTES) == 0)
- pr_debug("found own key as `%s', ignoring peer", peer_conf->name);
+ return true;
}
/** Checks if the current session with a peer is valid and resets the connection if not */
@@ -215,11 +204,6 @@ const fastd_protocol_t fastd_protocol_ec25519_fhmqvc = {
.name = "ec25519-fhmqvc",
.init = protocol_init,
- .peer_verify = protocol_peer_verify,
- .peer_configure = protocol_peer_configure,
-
- .peer_check = fastd_protocol_ec25519_fhmqvc_peer_check,
- .peer_check_dynamic = fastd_protocol_ec25519_fhmqvc_peer_check_dynamic,
.handshake_init = fastd_protocol_ec25519_fhmqvc_handshake_init,
.handshake_handle = fastd_protocol_ec25519_fhmqvc_handshake_handle,
@@ -234,8 +218,13 @@ const fastd_protocol_t fastd_protocol_ec25519_fhmqvc = {
.reset_peer_state = fastd_protocol_ec25519_fhmqvc_reset_peer_state,
.free_peer_state = fastd_protocol_ec25519_fhmqvc_free_peer_state,
+ .read_key = protocol_read_key,
+ .check_peer = protocol_check_peer,
+ .find_peer = fastd_protocol_ec25519_fhmqvc_find_peer,
+
.generate_key = fastd_protocol_ec25519_fhmqvc_generate_key,
.show_key = fastd_protocol_ec25519_fhmqvc_show_key,
+
.set_shell_env = fastd_protocol_ec25519_fhmqvc_set_shell_env,
.describe_peer = fastd_protocol_ec25519_fhmqvc_describe_peer,
};
diff --git a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h
index 529dd15..55696c1 100644
--- a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h
+++ b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h
@@ -65,9 +65,9 @@ struct fastd_protocol_config {
keypair_t key; /**< The own keypair */
};
-/** The protocol-specific peer configuration */
-struct fastd_protocol_peer_config {
- aligned_int256_t public_key; /**< The peer's public key */
+/** A peer's public key */
+struct fastd_protocol_key {
+ aligned_int256_t key; /**< The peer's public key */
};
/** Session state */
@@ -101,9 +101,6 @@ struct fastd_protocol_peer_state {
};
-bool fastd_protocol_ec25519_fhmqvc_peer_check(fastd_peer_config_t *peer_conf);
-bool fastd_protocol_ec25519_fhmqvc_peer_check_dynamic(fastd_peer_t *peer);
-
void fastd_protocol_ec25519_fhmqvc_maintenance(void);
void fastd_protocol_ec25519_fhmqvc_init_peer_state(fastd_peer_t *peer);
void fastd_protocol_ec25519_fhmqvc_reset_peer_state(fastd_peer_t *peer);
@@ -118,8 +115,11 @@ void fastd_protocol_ec25519_fhmqvc_handle_verify_return(fastd_peer_t *peer, fast
void fastd_protocol_ec25519_fhmqvc_send_empty(fastd_peer_t *peer, protocol_session_t *session);
+fastd_peer_t * fastd_protocol_ec25519_fhmqvc_find_peer(const fastd_protocol_key_t *key);
+
void fastd_protocol_ec25519_fhmqvc_generate_key(void);
void fastd_protocol_ec25519_fhmqvc_show_key(void);
+
void fastd_protocol_ec25519_fhmqvc_set_shell_env(fastd_shell_env_t *env, const fastd_peer_t *peer);
bool fastd_protocol_ec25519_fhmqvc_describe_peer(const fastd_peer_t *peer, char *buf, size_t len);
diff --git a/src/protocols/ec25519_fhmqvc/handshake.c b/src/protocols/ec25519_fhmqvc/handshake.c
index 86f9f9e..8f468cd 100644
--- a/src/protocols/ec25519_fhmqvc/handshake.c
+++ b/src/protocols/ec25519_fhmqvc/handshake.c
@@ -277,7 +277,7 @@ static bool update_shared_handshake_key(const fastd_peer_t *peer, const handshak
bool compat = !conf.secure_handshakes;
if (!make_shared_handshake_key(&handshake_key->key.secret, false,
- &peer->config->protocol_config->public_key,
+ &peer->key->key,
&conf.protocol_config->key.public,
peer_handshake_key,
&handshake_key->key.public,
@@ -315,7 +315,7 @@ static void respond_handshake(const fastd_socket_t *sock, const fastd_peer_addre
fastd_buffer_t buffer = fastd_handshake_new_reply(2, method, true, 4*(4+PUBLICKEYBYTES) + 2*(4+HASHBYTES));
fastd_handshake_add(&buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, &conf.protocol_config->key.public);
- fastd_handshake_add(&buffer, RECORD_RECIPIENT_KEY, PUBLICKEYBYTES, &peer->config->protocol_config->public_key);
+ fastd_handshake_add(&buffer, RECORD_RECIPIENT_KEY, PUBLICKEYBYTES, &peer->key->key);
fastd_handshake_add(&buffer, RECORD_SENDER_HANDSHAKE_KEY, PUBLICKEYBYTES, &handshake_key->key.public);
fastd_handshake_add(&buffer, RECORD_RECIPIENT_HANDSHAKE_KEY, PUBLICKEYBYTES, peer_handshake_key);
@@ -344,7 +344,7 @@ static void finish_handshake(fastd_socket_t *sock, const fastd_peer_address_t *l
fastd_sha256_t shared_handshake_key, shared_handshake_key_compat;
if (!make_shared_handshake_key(&handshake_key->key.secret, true,
&conf.protocol_config->key.public,
- &peer->config->protocol_config->public_key,
+ &peer->key->key,
&handshake_key->key.public,
peer_handshake_key,
&sigma,
@@ -361,7 +361,7 @@ static void finish_handshake(fastd_socket_t *sock, const fastd_peer_address_t *l
valid = fastd_hmacsha256_verify(mac, shared_handshake_key.w, handshake->tlv_data, handshake->tlv_len);
}
else {
- valid = fastd_hmacsha256_blocks_verify(handshake->records[RECORD_T].data, shared_handshake_key_compat.w, peer->config->protocol_config->public_key.u32, peer_handshake_key->u32, NULL);
+ valid = fastd_hmacsha256_blocks_verify(handshake->records[RECORD_T].data, shared_handshake_key_compat.w, peer->key->key.u32, peer_handshake_key->u32, NULL);
}
if (!valid) {
@@ -370,13 +370,13 @@ static void finish_handshake(fastd_socket_t *sock, const fastd_peer_address_t *l
}
if (!establish(peer, method, sock, local_addr, remote_addr, true, &handshake_key->key.public, peer_handshake_key, &conf.protocol_config->key.public,
- &peer->config->protocol_config->public_key, &sigma, compat ? NULL : shared_handshake_key.w, handshake_key->serial))
+ &peer->key->key, &sigma, compat ? NULL : shared_handshake_key.w, handshake_key->serial))
return;
fastd_buffer_t buffer = fastd_handshake_new_reply(3, method, false, 4*(4+PUBLICKEYBYTES) + 2*(4+HASHBYTES));
fastd_handshake_add(&buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, &conf.protocol_config->key.public);
- fastd_handshake_add(&buffer, RECORD_RECIPIENT_KEY, PUBLICKEYBYTES, &peer->config->protocol_config->public_key);
+ fastd_handshake_add(&buffer, RECORD_RECIPIENT_KEY, PUBLICKEYBYTES, &peer->key->key);
fastd_handshake_add(&buffer, RECORD_SENDER_HANDSHAKE_KEY, PUBLICKEYBYTES, &handshake_key->key.public);
fastd_handshake_add(&buffer, RECORD_RECIPIENT_HANDSHAKE_KEY, PUBLICKEYBYTES, peer_handshake_key);
@@ -415,7 +415,7 @@ static void handle_finish_handshake(fastd_socket_t *sock, const fastd_peer_addre
valid = fastd_hmacsha256_verify(mac, peer->protocol_state->shared_handshake_key.w, handshake->tlv_data, handshake->tlv_len);
}
else {
- valid = fastd_hmacsha256_blocks_verify(handshake->records[RECORD_T].data, peer->protocol_state->shared_handshake_key_compat.w, peer->config->protocol_config->public_key.u32, peer_handshake_key->u32, NULL);
+ valid = fastd_hmacsha256_blocks_verify(handshake->records[RECORD_T].data, peer->protocol_state->shared_handshake_key_compat.w, peer->key->key.u32, peer_handshake_key->u32, NULL);
}
if (!valid) {
@@ -423,14 +423,14 @@ static void handle_finish_handshake(fastd_socket_t *sock, const fastd_peer_addre
return;
}
- establish(peer, method, sock, local_addr, remote_addr, false, peer_handshake_key, &handshake_key->key.public, &peer->config->protocol_config->public_key,
+ establish(peer, method, sock, local_addr, remote_addr, false, peer_handshake_key, &handshake_key->key.public, &peer->key->key,
&conf.protocol_config->key.public, &peer->protocol_state->sigma, compat ? NULL : peer->protocol_state->shared_handshake_key.w, handshake_key->serial);
clear_shared_handshake_key(peer);
}
-/** Searches the peer a public key belongs to */
-static fastd_peer_t* find_sender_key(const fastd_peer_address_t *address, const unsigned char key[PUBLICKEYBYTES]) {
+/** Searches the peer a public key belongs to, optionally restricting matches to a specific sender address */
+static fastd_peer_t * find_key(const uint8_t key[PUBLICKEYBYTES], const fastd_peer_address_t *address) {
errno = 0;
fastd_peer_t *ret = NULL;
@@ -439,10 +439,13 @@ static fastd_peer_t* find_sender_key(const fastd_peer_address_t *address, const
for (i = 0; i < VECTOR_LEN(ctx.peers); i++) {
fastd_peer_t *peer = VECTOR_INDEX(ctx.peers, i);
- if (!fastd_peer_is_enabled(peer))
+ if (address && !fastd_peer_is_enabled(peer))
continue;
- if (memcmp(&peer->config->protocol_config->public_key, key, PUBLICKEYBYTES) == 0) {
+ if (memcmp(&peer->key->key, key, PUBLICKEYBYTES) == 0) {
+ if (!address)
+ return peer;
+
if (!fastd_peer_matches_address(peer, address)) {
errno = EPERM;
return NULL;
@@ -464,15 +467,20 @@ static fastd_peer_t* find_sender_key(const fastd_peer_address_t *address, const
return ret;
}
+/** Searches the peer a public key belongs to (including disabled peers) */
+fastd_peer_t * fastd_protocol_ec25519_fhmqvc_find_peer(const fastd_protocol_key_t *key) {
+ return find_key(key->key.u8, NULL);
+}
+
/** Checks if a key matches a peer and searches the correct peer if it doesn't */
-static fastd_peer_t* match_sender_key(const fastd_socket_t *sock, const fastd_peer_address_t *address, fastd_peer_t *peer, const unsigned char key[PUBLICKEYBYTES]) {
+static fastd_peer_t * match_sender_key(const fastd_socket_t *sock, const fastd_peer_address_t *address, fastd_peer_t *peer, const uint8_t key[PUBLICKEYBYTES]) {
errno = 0;
if (sock->peer && peer != sock->peer)
exit_bug("packet without correct peer set on dynamic socket");
if (peer) {
- if (memcmp(&peer->config->protocol_config->public_key, key, PUBLICKEYBYTES) == 0)
+ if (memcmp(&peer->key->key, key, PUBLICKEYBYTES) == 0)
return peer;
if (fastd_peer_owns_address(peer, address)) {
@@ -481,41 +489,7 @@ static fastd_peer_t* match_sender_key(const fastd_socket_t *sock, const fastd_pe
}
}
- return find_sender_key(address, key);
-}
-
-/** Counts how many peers with a key are configured */
-static size_t key_count(const unsigned char key[PUBLICKEYBYTES]) {
- size_t ret = 0;
-
- fastd_peer_config_t *p;
- for (p = ctx.peer_configs; p; p = p->next) {
- if (!p->protocol_config)
- continue;
-
- if (memcmp(&p->protocol_config->public_key, key, PUBLICKEYBYTES) == 0)
- ret++;
- }
-
- return ret;
-}
-
-/** Validates a peer config */
-bool fastd_protocol_ec25519_fhmqvc_peer_check(fastd_peer_config_t *peer_conf) {
- if (!peer_conf->protocol_config)
- return false;
-
- if (memcmp(&peer_conf->protocol_config->public_key, &conf.protocol_config->key.public, PUBLICKEYBYTES) == 0)
- return false;
-
- if (key_count(peer_conf->protocol_config->public_key.u8) > 1) {
- char buf[65];
- hexdump(buf, peer_conf->protocol_config->public_key.u8);
- pr_warn("more than one peer is configured with key %s, disabling %s", buf, peer_conf->name);
- return false;
- }
-
- return true;
+ return find_key(key, address);
}
/** Sends an initial handshake (type 1) to a peer */
@@ -527,7 +501,7 @@ void fastd_protocol_ec25519_fhmqvc_handshake_init(fastd_socket_t *sock, const fa
fastd_handshake_add(&buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, &conf.protocol_config->key.public);
if (peer) {
- fastd_handshake_add(&buffer, RECORD_RECIPIENT_KEY, PUBLICKEYBYTES, &peer->config->protocol_config->public_key);
+ fastd_handshake_add(&buffer, RECORD_RECIPIENT_KEY, PUBLICKEYBYTES, &peer->key->key);
pr_verbose("sending handshake to %P[%I]...", peer, remote_addr);
}
@@ -543,18 +517,6 @@ void fastd_protocol_ec25519_fhmqvc_handshake_init(fastd_socket_t *sock, const fa
fastd_send_handshake(sock, local_addr, remote_addr, peer, buffer);
}
-/** Checks if a dynamic peer (added after an on-verify command) can stay after new peers have been configured */
-bool fastd_protocol_ec25519_fhmqvc_peer_check_dynamic(fastd_peer_t *peer) {
- if (key_count(peer->config->protocol_config->public_key.u8)) {
- char buf[65];
- hexdump(buf, peer->config->protocol_config->public_key.u8);
- pr_info("key %s is configured now, deleting dynamic peer.", buf);
- return false;
- }
-
- return true;
-}
-
#ifdef WITH_DYNAMIC_PEERS
@@ -576,15 +538,25 @@ static fastd_peer_t * add_dynamic(fastd_socket_t *sock, const fastd_peer_address
return NULL;
}
- if (key_count(key)) {
+ if (memcmp(&conf.protocol_config->key.public, key, PUBLICKEYBYTES) == 0) {
+ pr_debug("ignoring handshake from %I (used our own key)", addr);
+ return NULL;
+ }
+
+ if (find_key(key, NULL)) {
pr_debug("ignoring handshake from %I (disabled key)", addr);
return NULL;
}
- fastd_peer_t *peer = fastd_peer_add(NULL);
+ fastd_peer_t *peer = fastd_new0(fastd_peer_t);
+ peer->group = conf.peer_group;
+ peer->config_state = CONFIG_DYNAMIC;
+
+ peer->key = fastd_new(fastd_protocol_key_t);
+ memcpy(&peer->key->key, key, PUBLICKEYBYTES);
- peer->config->protocol_config = fastd_new(fastd_protocol_peer_config_t);
- memcpy(&peer->config->protocol_config->public_key, key, PUBLICKEYBYTES);
+ if (!fastd_peer_add(peer))
+ exit_bug("failed to add dynamic peer");
/* Ugly hack */
peer->protocol_state->last_serial--;
diff --git a/src/protocols/ec25519_fhmqvc/util.c b/src/protocols/ec25519_fhmqvc/util.c
index c716916..f34f709 100644
--- a/src/protocols/ec25519_fhmqvc/util.c
+++ b/src/protocols/ec25519_fhmqvc/util.c
@@ -80,8 +80,8 @@ void fastd_protocol_ec25519_fhmqvc_set_shell_env(fastd_shell_env_t *env, const f
hexdump(buf, conf.protocol_config->key.public.u8);
fastd_shell_env_set(env, "LOCAL_KEY", buf);
- if (peer && peer->config->protocol_config) {
- hexdump(buf, peer->config->protocol_config->public_key.u8);
+ if (peer) {
+ hexdump(buf, peer->key->key.u8);
fastd_shell_env_set(env, "PEER_KEY", buf);
}
else {
@@ -97,14 +97,12 @@ void fastd_protocol_ec25519_fhmqvc_set_shell_env(fastd_shell_env_t *env, const f
public key.
*/
bool fastd_protocol_ec25519_fhmqvc_describe_peer(const fastd_peer_t *peer, char *buf, size_t len) {
- if (peer && peer->config->protocol_config) {
- char dumpbuf[65];
-
- hexdump(dumpbuf, peer->config->protocol_config->public_key.u8);
- snprintf(buf, len, "%.16s", dumpbuf);
- return true;
- }
- else {
+ if (!peer->key)
return false;
- }
+
+ char dumpbuf[65];
+ hexdump(dumpbuf, peer->key->key.u8);
+ snprintf(buf, len, "%.16s", dumpbuf);
+
+ return true;
}