Proactively restart the SPTPS tunnel if we get receive errors.
[tinc] / src / protocol_key.c
1 /*
2     protocol_key.c -- handle the meta-protocol, key exchange
3     Copyright (C) 1999-2005 Ivo Timmermans,
4                   2000-2014 Guus Sliepen <guus@tinc-vpn.org>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License along
17     with this program; if not, write to the Free Software Foundation, Inc.,
18     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "system.h"
22
23 #include "cipher.h"
24 #include "connection.h"
25 #include "crypto.h"
26 #include "logger.h"
27 #include "net.h"
28 #include "netutl.h"
29 #include "node.h"
30 #include "prf.h"
31 #include "protocol.h"
32 #include "sptps.h"
33 #include "utils.h"
34 #include "xalloc.h"
35
36 static bool mykeyused = false;
37
38 void send_key_changed(void) {
39         send_request(everyone, "%d %x %s", KEY_CHANGED, rand(), myself->name);
40
41         /* Immediately send new keys to directly connected nodes to keep UDP mappings alive */
42
43         for list_each(connection_t, c, connection_list)
44                 if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps)
45                         send_ans_key(c->node);
46
47         /* Force key exchange for connections using SPTPS */
48
49         if(experimental) {
50                 for splay_each(node_t, n, node_tree)
51                         if(n->status.reachable && n->status.validkey && n->status.sptps)
52                                 sptps_force_kex(&n->sptps);
53         }
54 }
55
56 bool key_changed_h(connection_t *c, const char *request) {
57         char name[MAX_STRING_SIZE];
58         node_t *n;
59
60         if(sscanf(request, "%*d %*x " MAX_STRING, name) != 1) {
61                 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "KEY_CHANGED",
62                            c->name, c->hostname);
63                 return false;
64         }
65
66         if(seen_request(request))
67                 return true;
68
69         n = lookup_node(name);
70
71         if(!n) {
72                 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist",
73                            "KEY_CHANGED", c->name, c->hostname, name);
74                 return true;
75         }
76
77         if(!n->status.sptps) {
78                 n->status.validkey = false;
79                 n->last_req_key = 0;
80         }
81
82         /* Tell the others */
83
84         if(!tunnelserver)
85                 forward_request(c, request);
86
87         return true;
88 }
89
90 static bool send_sptps_data_myself(void *handle, uint8_t type, const void *data, size_t len) {
91         return send_sptps_data(handle, myself, type, data, len);
92 }
93
94 static bool send_initial_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
95         node_t *to = handle;
96         to->sptps.send_data = send_sptps_data_myself;
97         char buf[len * 4 / 3 + 5];
98         b64encode(data, buf, len);
99         return send_request(to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, to->name, REQ_KEY, buf);
100 }
101
102 bool send_req_key(node_t *to) {
103         if(to->status.sptps) {
104                 if(!node_read_ecdsa_public_key(to)) {
105                         logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", to->name, to->hostname);
106                         send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, to->name, REQ_PUBKEY);
107                         return true;
108                 }
109
110                 char label[25 + strlen(myself->name) + strlen(to->name)];
111                 snprintf(label, sizeof label, "tinc UDP key expansion %s %s", myself->name, to->name);
112                 sptps_stop(&to->sptps);
113                 to->status.validkey = false;
114                 to->status.waitingforkey = true;
115                 to->last_req_key = now.tv_sec;
116                 to->incompression = myself->incompression;
117                 return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof label, send_initial_sptps_data, receive_sptps_record);
118         }
119
120         return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name);
121 }
122
123 /* REQ_KEY is overloaded to allow arbitrary requests to be routed between two nodes. */
124
125 static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, node_t *to, int reqno) {
126         /* If this is a SPTPS packet, see if sending UDP info helps.
127            Note that we only do this if we're the destination or the static relay;
128            otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */
129         if((reqno == REQ_KEY || reqno == SPTPS_PACKET) && to->via == myself)
130                 send_udp_info(myself, from);
131
132         if(reqno == SPTPS_PACKET) {
133                 /* This is a SPTPS data packet. */
134
135                 char buf[MAX_STRING_SIZE];
136                 int len;
137                 if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
138                         logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s) to %s (%s): %s", "SPTPS_PACKET", from->name, from->hostname, to->name, to->hostname, "invalid SPTPS data");
139                         return true;
140                 }
141
142                 if(to != myself) {
143                         /* We don't just forward the request, because we want to use UDP if it's available. */
144                         send_sptps_data(to, from, 0, buf, len);
145                         try_tx(to, true);
146                 } else {
147                         /* The packet is for us */
148                         if(!sptps_receive_data(&from->sptps, buf, len)) {
149                                 /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
150                                    so let's restart SPTPS in case that helps. But don't do that too often
151                                    to prevent storms. */
152                                 if(from->last_req_key < now.tv_sec - 10) {
153                                         logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
154                                         send_req_key(from);
155                                 }
156                                 return true;
157                         }
158                         send_mtu_info(myself, from, MTU);
159                 }
160
161                 return true;
162         }
163
164         /* Requests that are not SPTPS data packets are forwarded as-is. */
165
166         if (to != myself)
167                 return send_request(to->nexthop->connection, "%s", request);
168
169         /* The request is for us */
170
171         switch(reqno) {
172                 case REQ_PUBKEY: {
173                         if(!node_read_ecdsa_public_key(from)) {
174                                 /* Request their key *before* we send our key back. Otherwise the first SPTPS packet from them will get dropped. */
175                                 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Preemptively requesting Ed25519 key for %s (%s)", from->name, from->hostname);
176                                 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
177                         }
178                         char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa);
179                         send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey);
180                         free(pubkey);
181                         return true;
182                 }
183
184                 case ANS_PUBKEY: {
185                         if(node_read_ecdsa_public_key(from)) {
186                                 logger(DEBUG_PROTOCOL, LOG_WARNING, "Got ANS_PUBKEY from %s (%s) even though we already have his pubkey", from->name, from->hostname);
187                                 return true;
188                         }
189
190                         char pubkey[MAX_STRING_SIZE];
191                         if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) {
192                                 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey");
193                                 return true;
194                         }
195
196                         logger(DEBUG_PROTOCOL, LOG_INFO, "Learned Ed25519 public key from %s (%s)", from->name, from->hostname);
197                         append_config_file(from->name, "Ed25519PublicKey", pubkey);
198                         return true;
199                 }
200
201                 case REQ_KEY: {
202                         if(!node_read_ecdsa_public_key(from)) {
203                                 logger(DEBUG_PROTOCOL, LOG_DEBUG, "No Ed25519 key known for %s (%s)", from->name, from->hostname);
204                                 send_request(from->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, from->name, REQ_PUBKEY);
205                                 return true;
206                         }
207
208                         if(from->sptps.label)
209                                 logger(DEBUG_ALWAYS, LOG_DEBUG, "Got REQ_KEY from %s while we already started a SPTPS session!", from->name);
210
211                         char buf[MAX_STRING_SIZE];
212                         int len;
213
214                         if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, buf) != 1 || !(len = b64decode(buf, buf, strlen(buf)))) {
215                                 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_SPTPS_START", from->name, from->hostname, "invalid SPTPS data");
216                                 return true;
217                         }
218
219                         char label[25 + strlen(from->name) + strlen(myself->name)];
220                         snprintf(label, sizeof label, "tinc UDP key expansion %s %s", from->name, myself->name);
221                         sptps_stop(&from->sptps);
222                         from->status.validkey = false;
223                         from->status.waitingforkey = true;
224                         from->last_req_key = now.tv_sec;
225                         sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof label, send_sptps_data_myself, receive_sptps_record);
226                         sptps_receive_data(&from->sptps, buf, len);
227                         send_mtu_info(myself, from, MTU);
228                         return true;
229                 }
230
231                 default:
232                         logger(DEBUG_ALWAYS, LOG_ERR, "Unknown extended REQ_KEY request from %s (%s): %s", from->name, from->hostname, request);
233                         return true;
234         }
235 }
236
237 bool req_key_h(connection_t *c, const char *request) {
238         char from_name[MAX_STRING_SIZE];
239         char to_name[MAX_STRING_SIZE];
240         node_t *from, *to;
241         int reqno = 0;
242
243         if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING " %d", from_name, to_name, &reqno) < 2) {
244                 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "REQ_KEY", c->name,
245                            c->hostname);
246                 return false;
247         }
248
249         if(!check_id(from_name) || !check_id(to_name)) {
250                 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_KEY", c->name, c->hostname, "invalid name");
251                 return false;
252         }
253
254         from = lookup_node(from_name);
255
256         if(!from) {
257                 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
258                            "REQ_KEY", c->name, c->hostname, from_name);
259                 return true;
260         }
261
262         to = lookup_node(to_name);
263
264         if(!to) {
265                 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
266                            "REQ_KEY", c->name, c->hostname, to_name);
267                 return true;
268         }
269
270         /* Check if this key request is for us */
271
272         if(to == myself) {                      /* Yes */
273                 /* Is this an extended REQ_KEY message? */
274                 if(experimental && reqno)
275                         return req_key_ext_h(c, request, from, to, reqno);
276
277                 /* No, just send our key back */
278                 send_ans_key(from);
279         } else {
280                 if(tunnelserver)
281                         return true;
282
283                 if(!to->status.reachable) {
284                         logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
285                                 "REQ_KEY", c->name, c->hostname, to_name);
286                         return true;
287                 }
288
289                 /* Is this an extended REQ_KEY message? */
290                 if(experimental && reqno)
291                         return req_key_ext_h(c, request, from, to, reqno);
292
293                 send_request(to->nexthop->connection, "%s", request);
294         }
295
296         return true;
297 }
298
299 bool send_ans_key(node_t *to) {
300         if(to->status.sptps)
301                 abort();
302
303 #ifdef DISABLE_LEGACY
304         return false;
305 #else
306         size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1;
307         char key[keylen * 2 + 1];
308
309         randomize(key, keylen);
310
311         cipher_close(to->incipher);
312         digest_close(to->indigest);
313
314         if(myself->incipher) {
315                 to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher));
316                 if(!to->incipher)
317                         abort();
318                 if(!cipher_set_key(to->incipher, key, false))
319                         abort();
320         }
321
322         if(myself->indigest) {
323                 to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest), digest_length(myself->indigest));
324                 if(!to->indigest)
325                         abort();
326                 if(!digest_set_key(to->indigest, key, keylen))
327                         abort();
328         }
329
330         to->incompression = myself->incompression;
331
332         bin2hex(key, key, keylen);
333
334         // Reset sequence number and late packet window
335         mykeyused = true;
336         to->received_seqno = 0;
337         to->received = 0;
338         if(replaywin) memset(to->late, 0, replaywin);
339
340         to->status.validkey_in = true;
341
342         return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY,
343                                                 myself->name, to->name, key,
344                                                 cipher_get_nid(to->incipher),
345                                                 digest_get_nid(to->indigest),
346                                                 (int)digest_length(to->indigest),
347                                                 to->incompression);
348 #endif
349 }
350
351 bool ans_key_h(connection_t *c, const char *request) {
352         char from_name[MAX_STRING_SIZE];
353         char to_name[MAX_STRING_SIZE];
354         char key[MAX_STRING_SIZE];
355         char address[MAX_STRING_SIZE] = "";
356         char port[MAX_STRING_SIZE] = "";
357         int cipher, digest, maclength, compression, keylen;
358         node_t *from, *to;
359
360         if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING,
361                 from_name, to_name, key, &cipher, &digest, &maclength,
362                 &compression, address, port) < 7) {
363                 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
364                            c->hostname);
365                 return false;
366         }
367
368         if(!check_id(from_name) || !check_id(to_name)) {
369                 logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name");
370                 return false;
371         }
372
373         from = lookup_node(from_name);
374
375         if(!from) {
376                 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
377                            "ANS_KEY", c->name, c->hostname, from_name);
378                 return true;
379         }
380
381         to = lookup_node(to_name);
382
383         if(!to) {
384                 logger(DEBUG_ALWAYS, LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
385                            "ANS_KEY", c->name, c->hostname, to_name);
386                 return true;
387         }
388
389         /* Forward it if necessary */
390
391         if(to != myself) {
392                 if(tunnelserver)
393                         return true;
394
395                 if(!to->status.reachable) {
396                         logger(DEBUG_ALWAYS, LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
397                                    "ANS_KEY", c->name, c->hostname, to_name);
398                         return true;
399                 }
400
401                 if(!*address && from->address.sa.sa_family != AF_UNSPEC) {
402                         char *address, *port;
403                         logger(DEBUG_PROTOCOL, LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
404                         sockaddr2str(&from->address, &address, &port);
405                         send_request(to->nexthop->connection, "%s %s %s", request, address, port);
406                         free(address);
407                         free(port);
408                         return true;
409                 }
410
411                 return send_request(to->nexthop->connection, "%s", request);
412         }
413
414 #ifndef DISABLE_LEGACY
415         /* Don't use key material until every check has passed. */
416         cipher_close(from->outcipher);
417         digest_close(from->outdigest);
418 #endif
419         from->status.validkey = false;
420
421         if(compression < 0 || compression > 11) {
422                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
423                 return true;
424         }
425
426         from->outcompression = compression;
427
428         /* SPTPS or old-style key exchange? */
429
430         if(from->status.sptps) {
431                 char buf[strlen(key)];
432                 int len = b64decode(key, buf, strlen(key));
433                 if(!len || !sptps_receive_data(&from->sptps, buf, len)) {
434                         /* Uh-oh. It might be that the tunnel is stuck in some corrupted state,
435                            so let's restart SPTPS in case that helps. But don't do that too often
436                            to prevent storms.
437                            Note that simply relying on handshake timeout is not enough, because
438                            that doesn't apply to key regeneration. */
439                         if(from->last_req_key < now.tv_sec - 10) {
440                                 logger(DEBUG_PROTOCOL, LOG_ERR, "Failed to decode handshake TCP packet from %s (%s), restarting SPTPS", from->name, from->hostname);
441                                 send_req_key(from);
442                         }
443                         return true;
444                 }
445
446                 if(from->status.validkey) {
447                         if(*address && *port) {
448                                 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
449                                 sockaddr_t sa = str2sockaddr(address, port);
450                                 update_node_udp(from, &sa);
451                         }
452                 }
453
454                 send_mtu_info(myself, from, MTU);
455
456                 return true;
457         }
458
459 #ifdef DISABLE_LEGACY
460         logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses legacy protocol!", from->name, from->hostname);
461         return false;
462 #else
463         /* Check and lookup cipher and digest algorithms */
464
465         if(cipher) {
466                 if(!(from->outcipher = cipher_open_by_nid(cipher))) {
467                         logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname);
468                         return false;
469                 }
470         } else {
471                 from->outcipher = NULL;
472         }
473
474         if(digest) {
475                 if(!(from->outdigest = digest_open_by_nid(digest, maclength))) {
476                         logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname);
477                         return false;
478                 }
479         } else {
480                 from->outdigest = NULL;
481         }
482
483         if(maclength != digest_length(from->outdigest)) {
484                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname);
485                 return false;
486         }
487
488         /* Process key */
489
490         keylen = hex2bin(key, key, sizeof key);
491
492         if(keylen != (from->outcipher ? cipher_keylength(from->outcipher) : 1)) {
493                 logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
494                 return true;
495         }
496
497         /* Update our copy of the origin's packet key */
498
499         if(from->outcipher && !cipher_set_key(from->outcipher, key, true))
500                 return false;
501         if(from->outdigest && !digest_set_key(from->outdigest, key, keylen))
502                 return false;
503
504         from->status.validkey = true;
505         from->sent_seqno = 0;
506
507         if(*address && *port) {
508                 logger(DEBUG_PROTOCOL, LOG_DEBUG, "Using reflexive UDP address from %s: %s port %s", from->name, address, port);
509                 sockaddr_t sa = str2sockaddr(address, port);
510                 update_node_udp(from, &sa);
511         }
512
513         return true;
514 #endif
515 }