diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2013-02-26 01:02:35 +0100 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2013-02-26 01:02:35 +0100 |
commit | 4ab4858d5473c816cc526b296ae9da6c6956219d (patch) | |
tree | 67ac9253e6aa74a68699aa2a9e8e43d89e14c088 | |
parent | 87b9b80a55d3567e76fc86d3abc7f3cfd6d92e6f (diff) | |
download | fastd-4ab4858d5473c816cc526b296ae9da6c6956219d.tar fastd-4ab4858d5473c816cc526b296ae9da6c6956219d.zip |
Experimental support for accepting connections from unknown peers
-rw-r--r-- | src/config.c | 11 | ||||
-rw-r--r-- | src/config.l | 1 | ||||
-rw-r--r-- | src/config.y | 11 | ||||
-rw-r--r-- | src/fastd.c | 19 | ||||
-rw-r--r-- | src/fastd.h | 4 | ||||
-rw-r--r-- | src/peer.c | 68 | ||||
-rw-r--r-- | src/peer.h | 16 | ||||
-rw-r--r-- | src/protocol_ec25519_fhmqvc.c | 103 | ||||
-rw-r--r-- | src/resolve.c | 3 |
9 files changed, 196 insertions, 40 deletions
diff --git a/src/config.c b/src/config.c index c866b14..001cc2e 100644 --- a/src/config.c +++ b/src/config.c @@ -549,6 +549,7 @@ static void count_peers(fastd_context_t *ctx, fastd_config_t *conf) { OPTION_ARG(option_on_down, "--on-down", "<command>", "Sets a shell command to execute before interface destruction") \ OPTION_ARG(option_on_establish, "--on-establish", "<command>", "Sets a shell command to execute when a new connection is established") \ OPTION_ARG(option_on_disestablish, "--on-disestablish", "<command>", "Sets a shell command to execute when a connection is lost") \ + OPTION_ARG(option_on_verify, "--on-verify", "<command>", "Sets a shell command to execute to check an connection attempt by an unknown peer") \ OPTION(option_generate_key, "--generate-key", "Generates a new keypair") \ OPTION(option_show_key, "--show-key", "Shows the public key corresponding to the configured secret") \ OPTION(option_machine_readable, "--machine-readable", "Suppresses output of explaining text in the --show-key and --generate-key commands") @@ -781,6 +782,14 @@ static void option_on_disestablish(fastd_context_t *ctx, fastd_config_t *conf, c conf->on_disestablish_dir = get_current_dir_name(); } +static void option_on_verify(fastd_context_t *ctx, fastd_config_t *conf, const char *arg) { + free(conf->on_verify); + free(conf->on_verify_dir); + + conf->on_verify = strdup(arg); + conf->on_verify_dir = get_current_dir_name(); +} + static void option_daemon(fastd_context_t *ctx, fastd_config_t *conf) { conf->daemon = true; } @@ -1062,6 +1071,8 @@ void fastd_config_release(fastd_context_t *ctx, fastd_config_t *conf) { free(conf->on_establish_dir); free(conf->on_disestablish); free(conf->on_disestablish_dir); + free(conf->on_verify); + free(conf->on_verify_dir); free(conf->protocol_config); free(conf->log_syslog_ident); } diff --git a/src/config.l b/src/config.l index b4e77a0..1ff90c8 100644 --- a/src/config.l +++ b/src/config.l @@ -79,6 +79,7 @@ up { TOKEN(TOK_UP); } down { TOKEN(TOK_DOWN); } establish { TOKEN(TOK_ESTABLISH); } disestablish { TOKEN(TOK_DISESTABLISH); } +verify { TOKEN(TOK_VERIFY); } peers { TOKEN(TOK_PEERS); } from { TOKEN(TOK_FROM); } log { TOKEN(TOK_LOG); } diff --git a/src/config.y b/src/config.y index 228ba01..8db6efe 100644 --- a/src/config.y +++ b/src/config.y @@ -79,6 +79,7 @@ %token TOK_DOWN %token TOK_ESTABLISH %token TOK_DISESTABLISH +%token TOK_VERIFY %token TOK_PEERS %token TOK_FROM %token TOK_LOG @@ -167,6 +168,7 @@ statement: peer_group_statement | TOK_ON TOK_DOWN on_down ';' | TOK_ON TOK_ESTABLISH on_establish ';' | TOK_ON TOK_DISESTABLISH on_disestablish ';' + | TOK_ON TOK_VERIFY on_verify ';' | TOK_FORWARD forward ';' ; @@ -356,6 +358,15 @@ on_disestablish: TOK_STRING { } ; +on_verify: TOK_STRING { + free(conf->on_verify); + free(conf->on_verify_dir); + + conf->on_verify = strdup($1->str); + conf->on_verify_dir = get_current_dir_name(); + } + ; + peer: TOK_STRING { fastd_peer_config_new(ctx, conf); conf->peers->name = strdup($1->str); diff --git a/src/fastd.c b/src/fastd.c index ce297f7..89125a9 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -975,14 +975,27 @@ static void cleanup_peers(fastd_context_t *ctx) { for (peer = ctx->peers; peer; peer = next) { next = peer->next; - if (fastd_peer_is_established(peer)) { - if (timespec_diff(&ctx->now, &peer->seen) > ctx->conf->peer_stale_time*1000) - fastd_peer_reset(ctx, peer); + if (fastd_peer_is_temporary(peer) || fastd_peer_is_established(peer)) { + if (timespec_diff(&ctx->now, &peer->seen) > ctx->conf->peer_stale_time*1000) { + if (fastd_peer_is_temporary(peer)) { + fastd_peer_delete(ctx, peer); + } + else { + fastd_peer_reset(ctx, peer); + } + } } } } static void maintenance(fastd_context_t *ctx) { + while (ctx->peers_temp) { + fastd_peer_t *peer = ctx->peers_temp; + ctx->peers_temp = ctx->peers_temp->next; + + fastd_peer_enable_temporary(ctx, peer); + } + cleanup_peers(ctx); fastd_peer_eth_addr_cleanup(ctx); diff --git a/src/fastd.h b/src/fastd.h index ac27905..3ee445f 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -242,6 +242,9 @@ struct fastd_config { char *on_disestablish; char *on_disestablish_dir; + char *on_verify; + char *on_verify_dir; + bool daemon; char *pid_file; @@ -262,6 +265,7 @@ struct fastd_context { unsigned n_peers; fastd_peer_group_t *peer_group; fastd_peer_t *peers; + fastd_peer_t *peers_temp; fastd_queue_t task_queue; int resolverfd; @@ -151,7 +151,7 @@ static void reset_peer(fastd_context_t *ctx, fastd_peer_t *peer) { } static void setup_peer(fastd_context_t *ctx, fastd_peer_t *peer) { - if (peer->config->hostname) + if (!peer->config || peer->config->hostname) peer->address.sa.sa_family = AF_UNSPEC; else peer->address = peer->config->address; @@ -187,13 +187,25 @@ static void delete_peer(fastd_context_t *ctx, fastd_peer_t *peer) { for (cur_peer = &ctx->peers; *cur_peer; cur_peer = &(*cur_peer)->next) { if ((*cur_peer) == peer) { *cur_peer = peer->next; + ctx->n_peers--; break; } } + if (!*cur_peer) { + for (cur_peer = &ctx->peers_temp; *cur_peer; cur_peer = &(*cur_peer)->next) { + if ((*cur_peer) == peer) { + *cur_peer = peer->next; + break; + } + } + } ctx->conf->protocol->free_peer_state(ctx, peer); + + if (!peer->config) + free(peer->protocol_config); + free(peer); - ctx->n_peers--; } @@ -387,6 +399,7 @@ fastd_peer_t* fastd_peer_add(fastd_context_t *ctx, fastd_peer_config_t *peer_con peer->config = peer_conf; peer->group = find_peer_group(ctx->peer_group, peer_conf->group); + peer->protocol_config = peer_conf->protocol_config; peer->protocol_state = NULL; peer->sock = NULL; setup_peer(ctx, peer); @@ -397,6 +410,57 @@ fastd_peer_t* fastd_peer_add(fastd_context_t *ctx, fastd_peer_config_t *peer_con return peer; } +fastd_peer_t* fastd_peer_add_temporary(fastd_context_t *ctx, fastd_socket_t *sock, const fastd_peer_address_t *addr) { + if (!ctx->conf->on_verify) + exit_bug(ctx, "tried to add temporary peer without on-verify command"); + + fastd_peer_t *peer = malloc(sizeof(fastd_peer_t)); + + peer->next = ctx->peers_temp; + ctx->peers_temp = peer; + + peer->config = NULL; + peer->group = ctx->peer_group; + peer->protocol_state = NULL; + peer->sock = sock; + setup_peer(ctx, peer); + + peer->address = *addr; + + pr_debug(ctx, "adding temporary peer for %I", addr); + + return peer; +} + +bool fastd_peer_verify_temporary(fastd_context_t *ctx, fastd_peer_t *peer) { + if (!ctx->conf->on_verify) + exit_bug(ctx, "tried to verify temporary peer without on-verify command"); + + int ret; + if (!fastd_shell_exec(ctx, peer, ctx->conf->on_verify, ctx->conf->on_verify_dir, &ret)) + return false; + + if (WIFSIGNALED(ret)) { + pr_error(ctx, "verify command exited with signal %i", WTERMSIG(ret)); + return false; + } + else if (WEXITSTATUS(ret)) { + pr_debug(ctx, "verify command exited with status %i", WEXITSTATUS(ret)); + return false; + } + + return true; +} + +void fastd_peer_enable_temporary(fastd_context_t *ctx, fastd_peer_t *peer) { + if (peer->config) + exit_bug(ctx, "trying to re-enable non-temporary peer"); + + peer->next = ctx->peers; + ctx->peers = peer; + ctx->n_peers++; +} + void fastd_peer_set_established(fastd_context_t *ctx, fastd_peer_t *peer) { if (!peer->established) { peer->established = true; @@ -51,6 +51,7 @@ struct fastd_peer { struct timespec last_handshake_response; fastd_peer_address_t last_handshake_response_address; + fastd_protocol_peer_config_t *protocol_config; fastd_protocol_peer_state_t *protocol_state; }; @@ -90,6 +91,9 @@ bool fastd_peer_config_equal(const fastd_peer_config_t *peer1, const fastd_peer_ void fastd_peer_reset(fastd_context_t *ctx, fastd_peer_t *peer); void fastd_peer_delete(fastd_context_t *ctx, fastd_peer_t *peer); fastd_peer_t* fastd_peer_add(fastd_context_t *ctx, fastd_peer_config_t *conf); +fastd_peer_t* fastd_peer_add_temporary(fastd_context_t *ctx, fastd_socket_t *sock, const fastd_peer_address_t *addr); +bool fastd_peer_verify_temporary(fastd_context_t *ctx, fastd_peer_t *peer); +void fastd_peer_enable_temporary(fastd_context_t *ctx, fastd_peer_t *peer); void fastd_peer_set_established(fastd_context_t *ctx, fastd_peer_t *peer); bool fastd_peer_may_connect(fastd_context_t *ctx, fastd_peer_t *peer); bool fastd_peer_claim_address(fastd_context_t *ctx, fastd_peer_t *peer, fastd_socket_t *sock, const fastd_peer_address_t *addr); @@ -98,6 +102,10 @@ void fastd_peer_reset_socket(fastd_context_t *ctx, fastd_peer_t *peer); const fastd_eth_addr_t* fastd_get_source_address(const fastd_context_t *ctx, fastd_buffer_t buffer); const fastd_eth_addr_t* fastd_get_dest_address(const fastd_context_t *ctx, fastd_buffer_t buffer); +static inline bool fastd_peer_allow_unknown(fastd_context_t *ctx) { + return ctx->conf->on_verify; +} + static inline bool fastd_peer_config_is_floating(const fastd_peer_config_t *config) { return ((config->hostname == NULL && config->address.sa.sa_family == AF_UNSPEC) || config->dynamic_float); } @@ -109,11 +117,15 @@ static inline bool fastd_peer_config_is_dynamic(const fastd_peer_config_t *confi bool fastd_peer_config_matches_dynamic(const fastd_peer_config_t *config, const fastd_peer_address_t *addr); static inline bool fastd_peer_is_floating(const fastd_peer_t *peer) { - return fastd_peer_config_is_floating(peer->config); + return peer->config ? fastd_peer_config_is_floating(peer->config) : true; } static inline bool fastd_peer_is_dynamic(const fastd_peer_t *peer) { - return fastd_peer_config_is_dynamic(peer->config); + return peer->config ? fastd_peer_config_is_dynamic(peer->config) : false; +} + +static inline bool fastd_peer_is_temporary(const fastd_peer_t *peer) { + return (!peer->config); } static inline bool fastd_peer_is_established(const fastd_peer_t *peer) { diff --git a/src/protocol_ec25519_fhmqvc.c b/src/protocol_ec25519_fhmqvc.c index d0b6861..4b0e997 100644 --- a/src/protocol_ec25519_fhmqvc.c +++ b/src/protocol_ec25519_fhmqvc.c @@ -222,7 +222,7 @@ static void protocol_handshake_init(fastd_context_t *ctx, const fastd_socket_t * fastd_handshake_add(ctx, &buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, ctx->conf->protocol_config->public_key.p); if (peer) - fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_KEY, PUBLICKEYBYTES, peer->config->protocol_config->public_key.p); + fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_KEY, PUBLICKEYBYTES, peer->protocol_config->public_key.p); else pr_debug(ctx, "sending handshake to unknown peer %I", address); @@ -242,7 +242,7 @@ static void respond_handshake(fastd_context_t *ctx, const fastd_socket_t *sock, memcpy(hashinput, handshake_key->public_key.p, PUBLICKEYBYTES); memcpy(hashinput+PUBLICKEYBYTES, peer_handshake_key->p, PUBLICKEYBYTES); memcpy(hashinput+2*PUBLICKEYBYTES, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES); - memcpy(hashinput+3*PUBLICKEYBYTES, peer->config->protocol_config->public_key.p, PUBLICKEYBYTES); + memcpy(hashinput+3*PUBLICKEYBYTES, peer->protocol_config->public_key.p, PUBLICKEYBYTES); crypto_hash_sha256(hashbuf, hashinput, 4*PUBLICKEYBYTES); @@ -265,7 +265,7 @@ static void respond_handshake(fastd_context_t *ctx, const fastd_socket_t *sock, if (!ecc_25519_is_identity(&work)) return; - if (!ecc_25519_load_packed(&work, &peer->config->protocol_config->public_key)) + if (!ecc_25519_load_packed(&work, &peer->protocol_config->public_key)) return; ecc_25519_scalarmult(&work, &d, &work); @@ -290,7 +290,7 @@ static void respond_handshake(fastd_context_t *ctx, const fastd_socket_t *sock, fastd_buffer_t buffer = fastd_handshake_new_reply(ctx, handshake, method, 4*(4+PUBLICKEYBYTES) + 4+HMACBYTES); fastd_handshake_add(ctx, &buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, ctx->conf->protocol_config->public_key.p); - fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_KEY, PUBLICKEYBYTES, peer->config->protocol_config->public_key.p); + fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_KEY, PUBLICKEYBYTES, peer->protocol_config->public_key.p); fastd_handshake_add(ctx, &buffer, RECORD_SENDER_HANDSHAKE_KEY, PUBLICKEYBYTES, handshake_key->public_key.p); fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_HANDSHAKE_KEY, PUBLICKEYBYTES, peer_handshake_key->p); fastd_handshake_add(ctx, &buffer, RECORD_T, HMACBYTES, hmacbuf); @@ -365,7 +365,7 @@ static void finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const f memcpy(hashinput, peer_handshake_key->p, PUBLICKEYBYTES); memcpy(hashinput+PUBLICKEYBYTES, handshake_key->public_key.p, PUBLICKEYBYTES); - memcpy(hashinput+2*PUBLICKEYBYTES, peer->config->protocol_config->public_key.p, PUBLICKEYBYTES); + memcpy(hashinput+2*PUBLICKEYBYTES, peer->protocol_config->public_key.p, PUBLICKEYBYTES); memcpy(hashinput+3*PUBLICKEYBYTES, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES); crypto_hash_sha256(hashbuf, hashinput, 4*PUBLICKEYBYTES); @@ -389,7 +389,7 @@ static void finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const f if (!ecc_25519_is_identity(&work)) return; - if (!ecc_25519_load_packed(&work, &peer->config->protocol_config->public_key)) + if (!ecc_25519_load_packed(&work, &peer->protocol_config->public_key)) return; ecc_25519_scalarmult(&work, &e, &work); @@ -406,7 +406,7 @@ static void finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const f memcpy(hashinput+4*PUBLICKEYBYTES, sigma.p, PUBLICKEYBYTES); crypto_hash_sha256(shared_handshake_key, hashinput, 5*PUBLICKEYBYTES); - memcpy(hashinput, peer->config->protocol_config->public_key.p, PUBLICKEYBYTES); + memcpy(hashinput, peer->protocol_config->public_key.p, PUBLICKEYBYTES); memcpy(hashinput+PUBLICKEYBYTES, peer_handshake_key->p, PUBLICKEYBYTES); if(crypto_auth_hmacsha256_verify(handshake->records[RECORD_T].data, hashinput, 2*PUBLICKEYBYTES, shared_handshake_key) != 0) { @@ -419,13 +419,13 @@ static void finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const f crypto_auth_hmacsha256(hmacbuf, hashinput, 2*PUBLICKEYBYTES, shared_handshake_key); if (!establish(ctx, peer, method, sock, address, true, &handshake_key->public_key, peer_handshake_key, &ctx->conf->protocol_config->public_key, - &peer->config->protocol_config->public_key, &sigma, handshake_key->serial)) + &peer->protocol_config->public_key, &sigma, handshake_key->serial)) return; fastd_buffer_t buffer = fastd_handshake_new_reply(ctx, handshake, method, 4*(4+PUBLICKEYBYTES) + 4+HMACBYTES); fastd_handshake_add(ctx, &buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, ctx->conf->protocol_config->public_key.p); - fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_KEY, PUBLICKEYBYTES, peer->config->protocol_config->public_key.p); + fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_KEY, PUBLICKEYBYTES, peer->protocol_config->public_key.p); fastd_handshake_add(ctx, &buffer, RECORD_SENDER_HANDSHAKE_KEY, PUBLICKEYBYTES, handshake_key->public_key.p); fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_HANDSHAKE_KEY, PUBLICKEYBYTES, peer_handshake_key->p); fastd_handshake_add(ctx, &buffer, RECORD_T, HMACBYTES, hmacbuf); @@ -443,7 +443,7 @@ static void handle_finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, memcpy(hashinput, handshake_key->public_key.p, PUBLICKEYBYTES); memcpy(hashinput+PUBLICKEYBYTES, peer_handshake_key->p, PUBLICKEYBYTES); memcpy(hashinput+2*PUBLICKEYBYTES, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES); - memcpy(hashinput+3*PUBLICKEYBYTES, peer->config->protocol_config->public_key.p, PUBLICKEYBYTES); + memcpy(hashinput+3*PUBLICKEYBYTES, peer->protocol_config->public_key.p, PUBLICKEYBYTES); crypto_hash_sha256(hashbuf, hashinput, 4*PUBLICKEYBYTES); @@ -466,7 +466,7 @@ static void handle_finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, if (!ecc_25519_is_identity(&work)) return; - if (!ecc_25519_load_packed(&work, &peer->config->protocol_config->public_key)) + if (!ecc_25519_load_packed(&work, &peer->protocol_config->public_key)) return; ecc_25519_scalarmult(&work, &d, &work); @@ -483,7 +483,7 @@ static void handle_finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, memcpy(hashinput+4*PUBLICKEYBYTES, sigma.p, PUBLICKEYBYTES); crypto_hash_sha256(shared_handshake_key, hashinput, 5*PUBLICKEYBYTES); - memcpy(hashinput, peer->config->protocol_config->public_key.p, PUBLICKEYBYTES); + memcpy(hashinput, peer->protocol_config->public_key.p, PUBLICKEYBYTES); memcpy(hashinput+PUBLICKEYBYTES, peer_handshake_key->p, PUBLICKEYBYTES); if(crypto_auth_hmacsha256_verify(handshake->records[RECORD_T].data, hashinput, 2*PUBLICKEYBYTES, shared_handshake_key) != 0) { @@ -491,10 +491,33 @@ static void handle_finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, return; } - establish(ctx, peer, method, sock, address, false, peer_handshake_key, &handshake_key->public_key, &peer->config->protocol_config->public_key, + establish(ctx, peer, method, sock, address, false, peer_handshake_key, &handshake_key->public_key, &peer->protocol_config->public_key, &ctx->conf->protocol_config->public_key, &sigma, handshake_key->serial); } +static fastd_peer_t* find_sender_key(fastd_context_t *ctx, const fastd_peer_address_t *address, const unsigned char key[32], fastd_peer_t *peers) { + fastd_peer_t *peer; + for (peer = peers; peer; peer = peer->next) { + if (memcmp(peer->protocol_config->public_key.p, key, PUBLICKEYBYTES) != 0) + continue; + + if (peer->config && fastd_peer_config_matches_dynamic(peer->config, address)) { + fastd_resolve_peer(ctx, peer); + errno = EAGAIN; + return NULL; + } + + if (fastd_peer_is_floating(peer)) + return peer; + + errno = EPERM; + return NULL; + } + + errno = ENOENT; + return NULL; +} + static fastd_peer_t* match_sender_key(fastd_context_t *ctx, const fastd_socket_t *sock, const fastd_peer_address_t *address, fastd_peer_t *peer, const unsigned char key[32]) { errno = 0; @@ -510,7 +533,7 @@ static fastd_peer_t* match_sender_key(fastd_context_t *ctx, const fastd_socket_t } if (peer) { - if (memcmp(peer->config->protocol_config->public_key.p, key, PUBLICKEYBYTES) == 0) { + if (memcmp(peer->protocol_config->public_key.p, key, PUBLICKEYBYTES) == 0) { if (sock->peer && sock->peer != peer) { errno = EPERM; return NULL; @@ -525,31 +548,42 @@ static fastd_peer_t* match_sender_key(fastd_context_t *ctx, const fastd_socket_t return NULL; } - for (peer = ctx->peers; peer; peer = peer->next) { - if (memcmp(peer->config->protocol_config->public_key.p, key, PUBLICKEYBYTES) != 0) - continue; + peer = find_sender_key(ctx, address, key, ctx->peers); - if (fastd_peer_config_matches_dynamic(peer->config, address)) { - fastd_resolve_peer(ctx, peer); - errno = EAGAIN; - return NULL; - } - - if (fastd_peer_is_floating(peer)) - return peer; - - errno = EPERM; - return NULL; + if (!peer && errno == ENOENT) { + errno = 0; + peer = find_sender_key(ctx, address, key, ctx->peers_temp); } - errno = ENOENT; - return NULL; + return peer; } static inline bool has_field(const fastd_handshake_t *handshake, uint8_t type, size_t length) { return (handshake->records[type].length == length); } +static inline fastd_peer_t* add_temporary(fastd_context_t *ctx, fastd_socket_t *sock, const fastd_peer_address_t *address, const unsigned char key[32]) { + if (!fastd_peer_allow_unknown(ctx)) { + pr_debug(ctx, "ignoring handshake from %I (unknown key)", address); + return NULL; + } + + fastd_peer_t *peer = fastd_peer_add_temporary(ctx, sock, address); + + peer->protocol_config = malloc(sizeof(fastd_protocol_peer_config_t)); + memcpy(peer->protocol_config->public_key.p, key, PUBLICKEYBYTES); + + /* Ugly hack */ + peer->protocol_state->last_serial--; + + if (!fastd_peer_verify_temporary(ctx, peer)) { + fastd_peer_delete(ctx, peer); + return NULL; + } + + return peer; +} + static void protocol_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) { handshake_key_t *handshake_key; char *peer_version_name = NULL; @@ -573,7 +607,10 @@ static void protocol_handshake_handle(fastd_context_t *ctx, fastd_socket_t *sock return; case ENOENT: - pr_debug(ctx, "ignoring handshake from %I (unknown key)", address); + peer = add_temporary(ctx, sock, address, handshake->records[RECORD_SENDER_KEY].data); + if (peer) + break; + return; default: @@ -855,8 +892,8 @@ static void protocol_set_shell_env(fastd_context_t *ctx, const fastd_peer_t *pee hexdump(buf, ctx->conf->protocol_config->public_key.p); setenv("LOCAL_KEY", buf, 1); - if (peer && peer->config && peer->config->protocol_config) { - hexdump(buf, peer->config->protocol_config->public_key.p); + if (peer && peer->protocol_config) { + hexdump(buf, peer->protocol_config->public_key.p); setenv("PEER_KEY", buf, 1); } else { diff --git a/src/resolve.c b/src/resolve.c index c01a88f..3b15f57 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -101,6 +101,9 @@ static void* resolve_peer(void *varg) { } void fastd_resolve_peer(fastd_context_t *ctx, fastd_peer_t *peer) { + if (!peer->config) + exit_bug(ctx, "trying to resolve temporary peer"); + if (timespec_after(&peer->last_resolve, &peer->last_resolve_return)) { pr_debug(ctx, "not resolving %P as there is already a resolve running", peer); return; |