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