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