summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2015-01-20 23:47:41 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2015-01-20 23:47:41 +0100
commiteece4529cbc27eb8266cd9f47cf84c0d0a6b742a (patch)
tree8d33bfdf766c8ff2579c3f2c0de621af82aeb956
parent972dd90499fd19fcd2c31cf15bb26231d0a862aa (diff)
downloadfastd-eece4529cbc27eb8266cd9f47cf84c0d0a6b742a.tar
fastd-eece4529cbc27eb8266cd9f47cf84c0d0a6b742a.zip
handshake: delay method parsing until the sender key has been handled
Otherwise fastd won't use the correct peer group's method list for handshakes incoming on generic sockets.
-rw-r--r--src/fastd.h2
-rw-r--r--src/handshake.c22
-rw-r--r--src/handshake.h2
-rw-r--r--src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h2
-rw-r--r--src/protocols/ec25519_fhmqvc/handshake.c9
5 files changed, 20 insertions, 17 deletions
diff --git a/src/fastd.h b/src/fastd.h
index 60b675a..56a099a 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -78,7 +78,7 @@ struct fastd_protocol {
void (*handshake_init)(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer);
/** Handles a handshake for the given peer */
- void (*handshake_handle)(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_info_t *method);
+ void (*handshake_handle)(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);
#ifdef WITH_DYNAMIC_PEERS
/** Handles an asynchronous on-verify command return */
diff --git a/src/handshake.c b/src/handshake.c
index 66f9e9a..14de253 100644
--- a/src/handshake.c
+++ b/src/handshake.c
@@ -265,7 +265,7 @@ static void print_error(const char *prefix, const fastd_peer_address_t *remote_a
}
/** Sends an error reply to a peer */
-static void send_error(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, uint8_t reply_code, uint16_t error_detail) {
+void fastd_handshake_send_error(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, uint8_t reply_code, uint16_t error_detail) {
print_error("sending", remote_addr, reply_code, error_detail);
fastd_handshake_buffer_t buffer = {
@@ -354,14 +354,14 @@ static inline void print_error_reply(const fastd_peer_address_t *remote_addr, co
static inline bool check_records(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) {
if (handshake->records[RECORD_PROTOCOL_NAME].data) {
if (!record_equal(conf.protocol->name, &handshake->records[RECORD_PROTOCOL_NAME])) {
- send_error(sock, local_addr, remote_addr, peer, handshake, REPLY_UNACCEPTABLE_VALUE, RECORD_PROTOCOL_NAME);
+ fastd_handshake_send_error(sock, local_addr, remote_addr, peer, handshake, REPLY_UNACCEPTABLE_VALUE, RECORD_PROTOCOL_NAME);
return false;
}
}
if (handshake->records[RECORD_MODE].data) {
if (handshake->records[RECORD_MODE].length != 1 || as_uint8(&handshake->records[RECORD_MODE]) != conf.mode) {
- send_error(sock, local_addr, remote_addr, peer, handshake, REPLY_UNACCEPTABLE_VALUE, RECORD_MODE);
+ fastd_handshake_send_error(sock, local_addr, remote_addr, peer, handshake, REPLY_UNACCEPTABLE_VALUE, RECORD_MODE);
return false;
}
}
@@ -369,7 +369,7 @@ static inline bool check_records(fastd_socket_t *sock, const fastd_peer_address_
if (!conf.secure_handshakes || handshake->type > 1) {
if (handshake->records[RECORD_MTU].length == 2) {
if (as_uint16_endian(&handshake->records[RECORD_MTU], handshake->little_endian) != conf.mtu) {
- send_error(sock, local_addr, remote_addr, peer, handshake, REPLY_UNACCEPTABLE_VALUE, RECORD_MTU);
+ fastd_handshake_send_error(sock, local_addr, remote_addr, peer, handshake, REPLY_UNACCEPTABLE_VALUE, RECORD_MTU);
return false;
}
}
@@ -403,7 +403,9 @@ static inline const fastd_method_info_t * get_method_by_name(const fastd_string_
}
/** Returns the most appropriate method to negotiate with a peer a handshake was received from */
-static inline const fastd_method_info_t * get_method(const fastd_string_stack_t *methods, const fastd_handshake_t *handshake) {
+const fastd_method_info_t * fastd_handshake_get_method(const fastd_peer_t *peer, const fastd_handshake_t *handshake) {
+ const fastd_string_stack_t *methods = fastd_peer_get_methods(peer);
+
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);
@@ -433,7 +435,6 @@ static inline const fastd_method_info_t * get_method(const fastd_string_stack_t
/** Handles a handshake packet */
void fastd_handshake_handle(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_info_t *method = NULL;
fastd_handshake_t handshake = parse_tlvs(&buffer);
@@ -453,18 +454,11 @@ void fastd_handshake_handle(fastd_socket_t *sock, const fastd_peer_address_t *lo
goto end_free;
if (!conf.secure_handshakes || handshake.type > 1) {
- method = get_method(fastd_peer_get_methods(peer), &handshake);
-
if (handshake.records[RECORD_VERSION_NAME].data)
handshake.peer_version = peer_version = fastd_strndup((const char *)handshake.records[RECORD_VERSION_NAME].data, handshake.records[RECORD_VERSION_NAME].length);
}
- if (handshake.type > 1 && !method) {
- send_error(sock, local_addr, remote_addr, peer, &handshake, REPLY_UNACCEPTABLE_VALUE, RECORD_METHOD_LIST);
- goto end_free;
- }
-
- conf.protocol->handshake_handle(sock, local_addr, remote_addr, peer, &handshake, method);
+ conf.protocol->handshake_handle(sock, local_addr, remote_addr, peer, &handshake);
end_free:
free(peer_version);
diff --git a/src/handshake.h b/src/handshake.h
index 5ad65a3..ccd1da5 100644
--- a/src/handshake.h
+++ b/src/handshake.h
@@ -102,6 +102,8 @@ struct fastd_handshake_buffer {
fastd_handshake_buffer_t fastd_handshake_new_init(size_t tail_space);
fastd_handshake_buffer_t fastd_handshake_new_reply(uint8_t type, bool little_endian, const fastd_method_info_t *method, const fastd_string_stack_t *methods, size_t tail_space);
+void fastd_handshake_send_error(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, uint8_t reply_code, uint16_t error_detail);
+const fastd_method_info_t * fastd_handshake_get_method(const fastd_peer_t *peer, const fastd_handshake_t *handshake);
void fastd_handshake_handle(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.h b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h
index b24593c..25e7bb3 100644
--- a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h
+++ b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h
@@ -109,7 +109,7 @@ void fastd_protocol_ec25519_fhmqvc_reset_peer_state(fastd_peer_t *peer);
void fastd_protocol_ec25519_fhmqvc_free_peer_state(fastd_peer_t *peer);
void fastd_protocol_ec25519_fhmqvc_handshake_init(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer);
-void fastd_protocol_ec25519_fhmqvc_handshake_handle(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_info_t *method);
+void fastd_protocol_ec25519_fhmqvc_handshake_handle(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);
#ifdef WITH_DYNAMIC_PEERS
void fastd_protocol_ec25519_fhmqvc_handle_verify_return(fastd_peer_t *peer, fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, const fastd_method_info_t *method, const void *protocol_data, bool ok);
diff --git a/src/protocols/ec25519_fhmqvc/handshake.c b/src/protocols/ec25519_fhmqvc/handshake.c
index 4d03725..8e3c67a 100644
--- a/src/protocols/ec25519_fhmqvc/handshake.c
+++ b/src/protocols/ec25519_fhmqvc/handshake.c
@@ -627,7 +627,7 @@ static inline fastd_peer_t * add_dynamic(UNUSED fastd_socket_t *sock, const fast
/** Handles a received handshake packet */
void fastd_protocol_ec25519_fhmqvc_handshake_handle(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_info_t *method) {
+ fastd_peer_t *peer, const fastd_handshake_t *handshake) {
fastd_protocol_ec25519_fhmqvc_maintenance();
if (!has_field(handshake, RECORD_SENDER_KEY, PUBLICKEYBYTES)) {
@@ -676,6 +676,8 @@ void fastd_protocol_ec25519_fhmqvc_handshake_handle(fastd_socket_t *sock, const
}
}
+ const fastd_method_info_t *method = fastd_handshake_get_method(peer, handshake);
+
#ifdef WITH_DYNAMIC_PEERS
if (fastd_peer_is_dynamic(peer)) {
if (!handle_dynamic(sock, local_addr, remote_addr, peer, handshake, method))
@@ -701,6 +703,11 @@ void fastd_protocol_ec25519_fhmqvc_handshake_handle(fastd_socket_t *sock, const
return;
}
+ if (!method) {
+ fastd_handshake_send_error(sock, local_addr, remote_addr, peer, handshake, REPLY_UNACCEPTABLE_VALUE, RECORD_METHOD_LIST);
+ return;
+ }
+
if (!has_field(handshake, RECORD_RECIPIENT_KEY, PUBLICKEYBYTES)) {
pr_debug("recived handshake reply without recipient key from %P[%I]", peer, remote_addr);
return;