summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2013-10-29 15:33:14 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2013-10-29 15:33:14 +0100
commit43567141422b99efed48a529fdef384be607fd78 (patch)
tree602c05b35423f476f59a7156702f32f3883a8a90
parentbb324029ad442a1f6dd7049a6e6fc1cbe4a05799 (diff)
downloadfastd-43567141422b99efed48a529fdef384be607fd78.tar
fastd-43567141422b99efed48a529fdef384be607fd78.zip
Handle methods as strings
-rw-r--r--src/config.c75
-rw-r--r--src/fastd.h10
-rw-r--r--src/handshake.c51
-rw-r--r--src/handshake.h2
-rw-r--r--src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c14
5 files changed, 71 insertions, 81 deletions
diff --git a/src/config.c b/src/config.c
index 106f92a..07f680c 100644
--- a/src/config.c
+++ b/src/config.c
@@ -43,7 +43,6 @@
extern const fastd_protocol_t fastd_protocol_ec25519_fhmqvc;
extern const fastd_method_t fastd_method_null;
-
#ifdef WITH_METHOD_XSALSA20_POLY1305
extern const fastd_method_t fastd_method_xsalsa20_poly1305;
#endif
@@ -51,6 +50,17 @@ extern const fastd_method_t fastd_method_xsalsa20_poly1305;
extern const fastd_method_t fastd_method_aes128_gcm;
#endif
+static const fastd_method_t *const METHODS[] = {
+ &fastd_method_null,
+#ifdef WITH_METHOD_XSALSA20_POLY1305
+ &fastd_method_xsalsa20_poly1305,
+#endif
+#ifdef WITH_METHOD_AES128_GCM
+ &fastd_method_aes128_gcm,
+#endif
+ NULL
+};
+
#ifdef USE_CRYPTO_AES128CTR
#ifdef WITH_CRYPTO_AES128CTR_NACL
@@ -106,7 +116,6 @@ static void default_config(fastd_config_t *conf) {
conf->drop_caps = DROP_CAPS_ON;
conf->protocol = &fastd_protocol_ec25519_fhmqvc;
- conf->method_default = &fastd_method_null;
conf->key_valid = 3600; /* 60 minutes */
conf->key_valid_old = 60; /* 1 minute */
conf->key_refresh = 3300; /* 55 minutes */
@@ -133,41 +142,34 @@ bool fastd_config_protocol(fastd_context_t *ctx UNUSED, fastd_config_t *conf, co
return true;
}
-static inline const fastd_method_t* parse_method_name(const char *name) {
- if (!strcmp(name, "null"))
- return &fastd_method_null;
-#ifdef WITH_METHOD_XSALSA20_POLY1305
- else if (!strcmp(name, "xsalsa20-poly1305"))
- return &fastd_method_xsalsa20_poly1305;
-#endif
-#ifdef WITH_METHOD_AES128_GCM
- else if (!strcmp(name, "aes128-gcm"))
- return &fastd_method_aes128_gcm;
-#endif
- else
- return NULL;
+const fastd_method_t* fastd_parse_method_name(const char *name) {
+ int i;
+ for (i = 0; METHODS[i]; i++) {
+ if (!strcmp(METHODS[i]->name, name))
+ return METHODS[i];
+ }
+
+ return NULL;
}
bool fastd_config_method(fastd_context_t *ctx, fastd_config_t *conf, const char *name) {
- const fastd_method_t *method = parse_method_name(name);
+ const fastd_method_t *parsed_method = fastd_parse_method_name(name);
- if (!method)
+ if (!parsed_method)
return false;
- conf->method_default = method;
-
- int i;
- for (i = 0; i < MAX_METHODS; i++) {
- if (conf->methods[i] == method)
- return true;
+ fastd_string_stack_t **method;
- if (conf->methods[i] == NULL) {
- conf->methods[i] = method;
+ for (method = &conf->methods; *method; method = &(*method)->next) {
+ if (!strcmp((*method)->str, name)) {
+ pr_debug(ctx, "duplicate method name `%s', ignoring", name);
return true;
}
}
- exit_bug(ctx, "MAX_METHODS too low");
+ *method = fastd_string_stack_dup(name);
+
+ return true;
}
bool fastd_config_crypto(fastd_context_t *ctx UNUSED, fastd_config_t *conf UNUSED, const char *alg UNUSED, const char *impl UNUSED) {
@@ -590,15 +592,12 @@ static void configure_method_parameters(fastd_context_t *ctx, fastd_config_t *co
conf->min_decrypt_tail_space = 0;
int i;
- for (i = 0; i < MAX_METHODS; i++) {
- if (!conf->methods[i])
- break;
-
- conf->max_packet_size = max_size_t(conf->max_packet_size, conf->methods[i]->max_packet_size(ctx));
- conf->min_encrypt_head_space = max_size_t(conf->min_encrypt_head_space, conf->methods[i]->min_encrypt_head_space(ctx));
- conf->min_decrypt_head_space = max_size_t(conf->min_decrypt_head_space, conf->methods[i]->min_decrypt_head_space(ctx));
- conf->min_encrypt_tail_space = max_size_t(conf->min_encrypt_tail_space, conf->methods[i]->min_encrypt_tail_space(ctx));
- conf->min_decrypt_tail_space = max_size_t(conf->min_decrypt_tail_space, conf->methods[i]->min_decrypt_tail_space(ctx));
+ for (i = 0; METHODS[i]; i++) {
+ conf->max_packet_size = max_size_t(conf->max_packet_size, METHODS[i]->max_packet_size(ctx));
+ conf->min_encrypt_head_space = max_size_t(conf->min_encrypt_head_space, METHODS[i]->min_encrypt_head_space(ctx));
+ conf->min_decrypt_head_space = max_size_t(conf->min_decrypt_head_space, METHODS[i]->min_decrypt_head_space(ctx));
+ conf->min_encrypt_tail_space = max_size_t(conf->min_encrypt_tail_space, METHODS[i]->min_encrypt_tail_space(ctx));
+ conf->min_decrypt_tail_space = max_size_t(conf->min_decrypt_tail_space, METHODS[i]->min_decrypt_tail_space(ctx));
}
conf->min_encrypt_head_space = alignto(conf->min_encrypt_head_space, 16);
@@ -615,9 +614,9 @@ void fastd_configure(fastd_context_t *ctx, fastd_config_t *conf, int argc, char
if (!conf->log_stderr_level && !conf->log_syslog_level && !conf->log_files)
conf->log_stderr_level = FASTD_DEFAULT_LOG_LEVEL;
- if (!conf->methods[0]) {
+ if (!conf->methods) {
pr_warn(ctx, "no encryption method configured, falling back to method `null' (unencrypted)");
- conf->methods[0] = conf->method_default;
+ conf->methods = fastd_string_stack_dup(fastd_method_null.name);
}
ctx->conf = conf;
@@ -752,6 +751,8 @@ void fastd_config_release(fastd_context_t *ctx, fastd_config_t *conf) {
free_peer_group(conf->peer_group);
+ fastd_string_stack_free(conf->methods);
+
free(conf->user);
free(conf->group);
free(conf->groups);
diff --git a/src/fastd.h b/src/fastd.h
index 4c8dcae..fd55a0b 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -41,9 +41,6 @@
#include <sys/uio.h>
-/* This must be adjusted when new methods are added */
-#define MAX_METHODS 3
-
struct fastd_buffer {
void *base;
@@ -66,7 +63,7 @@ struct fastd_protocol {
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 *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer);
- void (*handshake_handle)(fastd_context_t *ctx, fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, 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 *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, const fastd_handshake_t *handshake, const char *method);
void (*handle_recv)(fastd_context_t *ctx, fastd_peer_t *peer, fastd_buffer_t buffer);
void (*send)(fastd_context_t *ctx, fastd_peer_t *peer, fastd_buffer_t buffer);
@@ -212,8 +209,7 @@ struct fastd_config {
gid_t *groups;
const fastd_protocol_t *protocol;
- const fastd_method_t *methods[MAX_METHODS];
- const fastd_method_t *method_default;
+ fastd_string_stack_t *methods;
size_t max_packet_size;
size_t min_encrypt_head_space;
@@ -352,6 +348,8 @@ void fastd_logf(const fastd_context_t *ctx, fastd_loglevel_t level, const char *
void fastd_add_peer_dir(fastd_context_t *ctx, fastd_config_t *conf, const char *dir);
bool fastd_read_config(fastd_context_t *ctx, fastd_config_t *conf, const char *filename, bool peer_config, int depth);
+const fastd_method_t* fastd_parse_method_name(const char *name);
+
bool fastd_config_protocol(fastd_context_t *ctx, fastd_config_t *conf, const char *name);
bool fastd_config_method(fastd_context_t *ctx, fastd_config_t *conf, const char *name);
bool fastd_config_crypto(fastd_context_t *ctx, fastd_config_t *conf, const char *alg, const char *impl);
diff --git a/src/handshake.c b/src/handshake.c
index aecce23..5f25646 100644
--- a/src/handshake.c
+++ b/src/handshake.c
@@ -59,25 +59,17 @@ static const char *const REPLY_TYPES[REPLY_MAX] = {
static uint8_t* create_method_list(fastd_context_t *ctx, size_t *len) {
- *len = strlen(ctx->conf->methods[0]->name);
+ *len = strlen(ctx->conf->methods->str);
- int i;
- for (i = 1; i < MAX_METHODS; i++) {
- if (!ctx->conf->methods[i])
- break;
-
- *len += strlen(ctx->conf->methods[i]->name) + 1;
- }
+ fastd_string_stack_t *method;
+ for (method = ctx->conf->methods->next; method; method = method->next)
+ *len += strlen(method->str) + 1;
uint8_t *ret = malloc(*len+1);
char *ptr = (char*)ret;
- for (i = 0; i < MAX_METHODS; i++) {
- if (!ctx->conf->methods[i])
- break;
-
- ptr = stpcpy(ptr, ctx->conf->methods[i]->name) + 1;
- }
+ for (method = ctx->conf->methods; method; method = method->next)
+ ptr = stpcpy(ptr, method->str) + 1;
return ret;
}
@@ -93,14 +85,11 @@ static inline bool record_equal(const char *str, const fastd_handshake_record_t
return string_equal(str, (const char*)record->data, record->length);
}
-static const fastd_method_t* method_from_name(fastd_context_t *ctx, const char *name, size_t n) {
- int i;
- for (i = 0; i < MAX_METHODS; i++) {
- if (!ctx->conf->methods[i])
- break;
-
- if (string_equal(ctx->conf->methods[i]->name, name, n))
- return ctx->conf->methods[i];
+static const char* method_from_name(fastd_context_t *ctx, const char *name, size_t n) {
+ fastd_string_stack_t *method;
+ for (method = ctx->conf->methods; method; method = method->next) {
+ if (string_equal(method->str, name, n))
+ return method->str;
}
return NULL;
@@ -120,10 +109,10 @@ static fastd_string_stack_t* parse_string_list(const uint8_t *data, size_t len)
return ret;
}
-static fastd_buffer_t new_handshake(fastd_context_t *ctx, uint8_t type, const fastd_method_t *method, bool with_method_list, size_t tail_space) {
+static fastd_buffer_t new_handshake(fastd_context_t *ctx, uint8_t type, const char *method, bool with_method_list, size_t tail_space) {
size_t version_len = strlen(FASTD_VERSION);
size_t protocol_len = strlen(ctx->conf->protocol->name);
- size_t method_len = method ? strlen(method->name) : 0;
+ size_t method_len = method ? strlen(method) : 0;
size_t method_list_len = 0;
uint8_t *method_list = NULL;
@@ -152,7 +141,7 @@ static fastd_buffer_t new_handshake(fastd_context_t *ctx, uint8_t type, const fa
fastd_handshake_add(ctx, &buffer, RECORD_PROTOCOL_NAME, protocol_len, ctx->conf->protocol->name);
if (method && (!with_method_list || !ctx->conf->secure_handshakes))
- fastd_handshake_add(ctx, &buffer, RECORD_METHOD_NAME, method_len, method->name);
+ fastd_handshake_add(ctx, &buffer, RECORD_METHOD_NAME, method_len, method);
if (with_method_list) {
fastd_handshake_add(ctx, &buffer, RECORD_METHOD_LIST, method_list_len, method_list);
@@ -166,10 +155,10 @@ fastd_buffer_t fastd_handshake_new_init(fastd_context_t *ctx, size_t tail_space)
if (ctx->conf->secure_handshakes)
return new_handshake(ctx, 1, NULL, false, tail_space);
else
- return new_handshake(ctx, 1, ctx->conf->method_default, true, tail_space);
+ return new_handshake(ctx, 1, "xsalsa20-poly1305" /* for backwards compatiblity with fastd 0.4 */, true, tail_space);
}
-fastd_buffer_t fastd_handshake_new_reply(fastd_context_t *ctx, const fastd_handshake_t *handshake, const fastd_method_t *method, bool with_method_list, size_t tail_space) {
+fastd_buffer_t fastd_handshake_new_reply(fastd_context_t *ctx, const fastd_handshake_t *handshake, const char *method, bool with_method_list, size_t tail_space) {
fastd_buffer_t buffer = new_handshake(ctx, handshake->type+1, method, with_method_list, tail_space);
fastd_handshake_add_uint8(ctx, &buffer, RECORD_REPLY_CODE, 0);
return buffer;
@@ -307,15 +296,15 @@ static inline bool check_records(fastd_context_t *ctx, fastd_socket_t *sock, con
return true;
}
-static inline const fastd_method_t* get_method(fastd_context_t *ctx, const fastd_handshake_t *handshake) {
+static inline const char* get_method(fastd_context_t *ctx, const fastd_handshake_t *handshake) {
if (handshake->records[RECORD_METHOD_LIST].data && handshake->records[RECORD_METHOD_LIST].length) {
fastd_string_stack_t *method_list = parse_string_list(handshake->records[RECORD_METHOD_LIST].data, handshake->records[RECORD_METHOD_LIST].length);
- const fastd_method_t *method = NULL;
+ const char *method = NULL;
fastd_string_stack_t *method_name = method_list;
while (method_name) {
- const fastd_method_t *cur_method = method_from_name(ctx, method_name->str, SIZE_MAX);
+ const char *cur_method = method_from_name(ctx, method_name->str, SIZE_MAX);
if (cur_method)
method = cur_method;
@@ -336,7 +325,7 @@ static inline const fastd_method_t* get_method(fastd_context_t *ctx, const fastd
void fastd_handshake_handle(fastd_context_t *ctx, fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, fastd_buffer_t buffer) {
char *peer_version = NULL;
- const fastd_method_t *method = NULL;
+ const char *method = NULL;
fastd_handshake_t handshake = parse_tlvs(&buffer);
diff --git a/src/handshake.h b/src/handshake.h
index 0faccba..e3d4960 100644
--- a/src/handshake.h
+++ b/src/handshake.h
@@ -79,7 +79,7 @@ struct fastd_handshake {
fastd_buffer_t fastd_handshake_new_init(fastd_context_t *ctx, size_t tail_space);
-fastd_buffer_t fastd_handshake_new_reply(fastd_context_t *ctx, const fastd_handshake_t *handshake, const fastd_method_t *method, bool with_method_list, size_t tail_space);
+fastd_buffer_t fastd_handshake_new_reply(fastd_context_t *ctx, const fastd_handshake_t *handshake, const char *method, bool with_method_list, size_t tail_space);
void fastd_handshake_handle(fastd_context_t *ctx, fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, fastd_buffer_t buffer);
diff --git a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c
index d894512..ab66f93 100644
--- a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c
+++ b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c
@@ -363,7 +363,7 @@ static void clear_shared_handshake_key(fastd_context_t *ctx UNUSED, const fastd_
}
static void respond_handshake(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer,
- const handshake_key_t *handshake_key, const aligned_int256_t *peer_handshake_key, const fastd_handshake_t *handshake, const fastd_method_t *method) {
+ const handshake_key_t *handshake_key, const aligned_int256_t *peer_handshake_key, const fastd_handshake_t *handshake, const char *method) {
pr_debug(ctx, "responding handshake with %P[%I]...", peer, remote_addr);
if (!update_shared_handshake_key(ctx, peer, handshake_key, peer_handshake_key))
@@ -391,7 +391,7 @@ static void respond_handshake(fastd_context_t *ctx, const fastd_socket_t *sock,
fastd_send_handshake(ctx, sock, local_addr, remote_addr, peer, buffer);
}
-static bool establish(fastd_context_t *ctx, fastd_peer_t *peer, const fastd_method_t *method, fastd_socket_t *sock,
+static bool establish(fastd_context_t *ctx, fastd_peer_t *peer, const char *method_name, fastd_socket_t *sock,
const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, bool initiator,
const aligned_int256_t *A, const aligned_int256_t *B, const aligned_int256_t *X,
const aligned_int256_t *Y, const aligned_int256_t *sigma, uint64_t serial) {
@@ -408,6 +408,8 @@ static bool establish(fastd_context_t *ctx, fastd_peer_t *peer, const fastd_meth
return false;
}
+ const fastd_method_t *method = fastd_parse_method_name(method_name);
+
if (is_session_valid(ctx, &peer->protocol_state->session) && !is_session_valid(ctx, &peer->protocol_state->old_session)) {
if (peer->protocol_state->old_session.method)
peer->protocol_state->old_session.method->session_free(ctx, peer->protocol_state->old_session.method_state);
@@ -443,7 +445,7 @@ static bool establish(fastd_context_t *ctx, fastd_peer_t *peer, const fastd_meth
fastd_peer_set_established(ctx, peer);
- pr_verbose(ctx, "new session with %P established using method `%s'.", peer, method->name);
+ pr_verbose(ctx, "new session with %P established using method `%s'.", peer, method_name);
if (initiator)
fastd_peer_schedule_handshake_default(ctx, peer);
@@ -458,7 +460,7 @@ static inline bool has_field(const fastd_handshake_t *handshake, uint8_t type, s
}
static void finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, const handshake_key_t *handshake_key, const aligned_int256_t *peer_handshake_key,
- const fastd_handshake_t *handshake, const fastd_method_t *method) {
+ const fastd_handshake_t *handshake, const char *method) {
pr_debug(ctx, "finishing handshake with %P[%I]...", peer, remote_addr);
fastd_sha256_t hashbuf;
@@ -555,7 +557,7 @@ static void finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const f
static void handle_finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr,
fastd_peer_t *peer, const handshake_key_t *handshake_key, const aligned_int256_t *peer_handshake_key,
- const fastd_handshake_t *handshake, const fastd_method_t *method) {
+ const fastd_handshake_t *handshake, const char *method) {
pr_debug(ctx, "handling handshake finish with %P[%I]...", peer, remote_addr);
if (!update_shared_handshake_key(ctx, peer, handshake_key, peer_handshake_key))
@@ -668,7 +670,7 @@ static inline keypair_t* get_handshake_keypair(handshake_key_t *handshake_key, u
return (type % 2) ? &handshake_key->key2 : &handshake_key->key1;
}
-static void protocol_handshake_handle(fastd_context_t *ctx, fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, const fastd_handshake_t *handshake, const fastd_method_t *method) {
+static void protocol_handshake_handle(fastd_context_t *ctx, fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, const fastd_handshake_t *handshake, const char *method) {
bool temporary_added = false;
maintenance(ctx);