From 43567141422b99efed48a529fdef384be607fd78 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 29 Oct 2013 15:33:14 +0100 Subject: Handle methods as strings --- src/config.c | 75 ++++++++++++++------------- src/fastd.h | 10 ++-- src/handshake.c | 51 +++++++----------- src/handshake.h | 2 +- src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c | 14 ++--- 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 -/* 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); -- cgit v1.2.3