diff --git a/src/graph.c b/src/graph.c index f5aff5bf..7288f74b 100644 --- a/src/graph.c +++ b/src/graph.c @@ -251,7 +251,7 @@ void sssp_bfs(void) { /* TODO: only clear status.validkey if node is unreachable? */ n->status.validkey = false; - n->status.waitingforkey = false; + n->last_req_key = 0; n->maxmtu = MTU; n->minmtu = 0; diff --git a/src/net_packet.c b/src/net_packet.c index e5011532..dcf8df61 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -353,10 +353,10 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { "No valid key known yet for %s (%s), forwarding via TCP", n->name, n->hostname); - if(!n->status.waitingforkey) + if(n->last_req_key + 10 < now) { send_req_key(n); - - n->status.waitingforkey = true; + n->last_req_key = now; + } send_tcppacket(n->nexthop->connection, origpkt); diff --git a/src/node.h b/src/node.h index a621a0a2..2f68a1ef 100644 --- a/src/node.h +++ b/src/node.h @@ -30,7 +30,7 @@ typedef struct node_status_t { int unused_active:1; /* 1 if active (not used for nodes) */ int validkey:1; /* 1 if we currently have a valid key for him */ - int waitingforkey:1; /* 1 if we already sent out a request */ + int unused_waitingforkey:1; /* 1 if we already sent out a request */ int visited:1; /* 1 if this node has been visited by one of the graph algorithms */ int reachable:1; /* 1 if this node is reachable in the graph */ int indirect:1; /* 1 if this node is not directly reachable by us */ @@ -45,6 +45,7 @@ typedef struct node_t { char *hostname; /* the hostname of its real ip */ node_status_t status; + time_t last_req_key; const EVP_CIPHER *incipher; /* Cipher type for UDP packets received from him */ char *inkey; /* Cipher key and iv */ diff --git a/src/protocol_key.c b/src/protocol_key.c index 92948aa4..ad393d38 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -57,6 +57,11 @@ bool key_changed_h(connection_t *c) { return false; } + if(!check_id(name)) { + logger(LOG_ERR, "Got bad %s from %s (%s): %s", "KEY_CHANGED", c->name, c->hostname, "invalid name"); + return false; + } + if(seen_request(c->buffer)) return true; @@ -65,11 +70,11 @@ bool key_changed_h(connection_t *c) { if(!n) { logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist", "KEY_CHANGED", c->name, c->hostname, name); - return false; + return true; } n->status.validkey = false; - n->status.waitingforkey = false; + n->last_req_key = 0; /* Tell the others */ @@ -94,12 +99,17 @@ bool req_key_h(connection_t *c) { return false; } + if(!check_id(from_name) || !check_id(to_name)) { + logger(LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_KEY", c->name, c->hostname, "invalid name"); + return false; + } + from = lookup_node(from_name); if(!from) { logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", "REQ_KEY", c->name, c->hostname, from_name); - return false; + return true; } to = lookup_node(to_name); @@ -107,7 +117,7 @@ bool req_key_h(connection_t *c) { if(!to) { logger(LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", "REQ_KEY", c->name, c->hostname, to_name); - return false; + return true; } /* Check if this key request is for us */ @@ -116,7 +126,7 @@ bool req_key_h(connection_t *c) { send_ans_key(from); } else { if(tunnelserver) - return false; + return true; if(!to->status.reachable) { logger(LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", @@ -180,12 +190,17 @@ bool ans_key_h(connection_t *c) { return false; } + if(!check_id(from_name) || !check_id(to_name)) { + logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name"); + return false; + } + from = lookup_node(from_name); if(!from) { logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list", "ANS_KEY", c->name, c->hostname, from_name); - return false; + return true; } to = lookup_node(to_name); @@ -193,14 +208,14 @@ bool ans_key_h(connection_t *c) { if(!to) { logger(LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list", "ANS_KEY", c->name, c->hostname, to_name); - return false; + return true; } /* Forward it if necessary */ if(to != myself) { if(tunnelserver) - return false; + return true; if(!to->status.reachable) { logger(LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable", @@ -218,7 +233,6 @@ bool ans_key_h(connection_t *c) { from->outkeylength = strlen(key) / 2; hex2bin(key, from->outkey, from->outkeylength); - from->status.waitingforkey = false; /* Check and lookup cipher and digest algorithms */ if(cipher) { @@ -227,13 +241,13 @@ bool ans_key_h(connection_t *c) { if(!from->outcipher) { logger(LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname); - return false; + return true; } if(from->outkeylength != from->outcipher->key_len + from->outcipher->iv_len) { logger(LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname); - return false; + return true; } } else { from->outcipher = NULL; @@ -247,13 +261,13 @@ bool ans_key_h(connection_t *c) { if(!from->outdigest) { logger(LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname); - return false; + return true; } if(from->outmaclength > from->outdigest->md_size || from->outmaclength < 0) { logger(LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname); - return false; + return true; } } else { from->outdigest = NULL; @@ -261,7 +275,7 @@ bool ans_key_h(connection_t *c) { if(compression < 0 || compression > 11) { logger(LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname); - return false; + return true; } from->outcompression = compression; @@ -270,7 +284,7 @@ bool ans_key_h(connection_t *c) { if(!EVP_EncryptInit_ex(&from->outctx, from->outcipher, NULL, (unsigned char *)from->outkey, (unsigned char *)from->outkey + from->outcipher->key_len)) { logger(LOG_ERR, "Error during initialisation of key from %s (%s): %s", from->name, from->hostname, ERR_error_string(ERR_get_error(), NULL)); - return false; + return true; } from->status.validkey = true;