Prevent oracle attacks in the legacy protocol (CVE-2018-16737, CVE-2018-16738)
[tinc] / src / net.c
1 /*
2     net.c -- most of the network code
3     Copyright (C) 1998-2005 Ivo Timmermans,
4                   2000-2017 Guus Sliepen <guus@tinc-vpn.org>
5                   2006      Scott Lamb <slamb@slamb.org>
6                   2011      Loïc Grenié <loic.grenie@gmail.com>
7
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17
18     You should have received a copy of the GNU General Public License along
19     with this program; if not, write to the Free Software Foundation, Inc.,
20     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23 #include "system.h"
24
25 #include "autoconnect.h"
26 #include "conf.h"
27 #include "connection.h"
28 #include "device.h"
29 #include "graph.h"
30 #include "logger.h"
31 #include "meta.h"
32 #include "names.h"
33 #include "net.h"
34 #include "netutl.h"
35 #include "protocol.h"
36 #include "subnet.h"
37 #include "utils.h"
38 #include "xalloc.h"
39
40 int contradicting_add_edge = 0;
41 int contradicting_del_edge = 0;
42 static int sleeptime = 10;
43 time_t last_config_check = 0;
44 static timeout_t pingtimer;
45 static timeout_t periodictimer;
46 static struct timeval last_periodic_run_time;
47
48 /* Purge edges and subnets of unreachable nodes. Use carefully. */
49
50 void purge(void) {
51         logger(DEBUG_PROTOCOL, LOG_DEBUG, "Purging unreachable nodes");
52
53         /* Remove all edges and subnets owned by unreachable nodes. */
54
55         for splay_each(node_t, n, node_tree) {
56                 if(!n->status.reachable) {
57                         logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Purging node %s (%s)", n->name, n->hostname);
58
59                         for splay_each(subnet_t, s, n->subnet_tree) {
60                                 send_del_subnet(everyone, s);
61
62                                 if(!strictsubnets) {
63                                         subnet_del(n, s);
64                                 }
65                         }
66
67                         for splay_each(edge_t, e, n->edge_tree) {
68                                 if(!tunnelserver) {
69                                         send_del_edge(everyone, e);
70                                 }
71
72                                 edge_del(e);
73                         }
74                 }
75         }
76
77         /* Check if anyone else claims to have an edge to an unreachable node. If not, delete node. */
78
79         for splay_each(node_t, n, node_tree) {
80                 if(!n->status.reachable) {
81                         for splay_each(edge_t, e, edge_weight_tree)
82                                 if(e->to == n) {
83                                         return;
84                                 }
85
86                         if(!autoconnect && (!strictsubnets || !n->subnet_tree->head))
87                                 /* in strictsubnets mode do not delete nodes with subnets */
88                         {
89                                 node_del(n);
90                         }
91                 }
92         }
93 }
94
95 /* Put a misbehaving connection in the tarpit */
96 void tarpit(int fd) {
97         static int pits[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
98         static int next_pit = 0;
99
100         if(pits[next_pit] != -1) {
101                 closesocket(pits[next_pit]);
102         }
103
104         pits[next_pit++] = fd;
105
106         if(next_pit >= sizeof pits / sizeof pits[0]) {
107                 next_pit = 0;
108         }
109 }
110
111 /*
112   Terminate a connection:
113   - Mark it as inactive
114   - Remove the edge representing this connection
115   - Kill it with fire
116   - Check if we need to retry making an outgoing connection
117 */
118 void terminate_connection(connection_t *c, bool report) {
119         logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Closing connection with %s (%s)", c->name, c->hostname);
120
121         if(c->node) {
122                 if(c->node->connection == c) {
123                         c->node->connection = NULL;
124                 }
125
126                 if(c->edge) {
127                         if(report && !tunnelserver) {
128                                 send_del_edge(everyone, c->edge);
129                         }
130
131                         edge_del(c->edge);
132                         c->edge = NULL;
133
134                         /* Run MST and SSSP algorithms */
135
136                         graph();
137
138                         /* If the node is not reachable anymore but we remember it had an edge to us, clean it up */
139
140                         if(report && !c->node->status.reachable) {
141                                 edge_t *e;
142                                 e = lookup_edge(c->node, myself);
143
144                                 if(e) {
145                                         if(!tunnelserver) {
146                                                 send_del_edge(everyone, e);
147                                         }
148
149                                         edge_del(e);
150                                 }
151                         }
152                 }
153         }
154
155         outgoing_t *outgoing = c->outgoing;
156         connection_del(c);
157
158         /* Check if this was our outgoing connection */
159
160         if(outgoing) {
161                 do_outgoing_connection(outgoing);
162         }
163
164 #ifndef HAVE_MINGW
165         /* Clean up dead proxy processes */
166
167         while(waitpid(-1, NULL, WNOHANG) > 0);
168
169 #endif
170 }
171
172 /*
173   Check if the other end is active.
174   If we have sent packets, but didn't receive any,
175   then possibly the other end is dead. We send a
176   PING request over the meta connection. If the other
177   end does not reply in time, we consider them dead
178   and close the connection.
179 */
180 static void timeout_handler(void *data) {
181
182         bool close_all_connections = false;
183
184         /*
185                  timeout_handler will start after 30 seconds from start of tincd
186                  hold information about the elapsed time since last time the handler
187                  has been run
188         */
189         long sleep_time = now.tv_sec - last_periodic_run_time.tv_sec;
190
191         /*
192                  It seems that finding sane default value is harder than expected
193                  Since we send every second a UDP packet to make holepunching work
194                  And default UDP state expire on firewalls is between 15-30 seconds
195                  we drop all connections after 60 Seconds - UDPDiscoveryTimeout=30
196                  by default
197         */
198         if(sleep_time > 2 * udp_discovery_timeout) {
199                 logger(DEBUG_ALWAYS, LOG_ERR, "Awaking from dead after %ld seconds of sleep", sleep_time);
200                 /*
201                         Do not send any packets to tinc after we wake up.
202                         The other node probably closed our connection but we still
203                         are holding context information to them. This may happen on
204                         laptops or any other hardware which can be suspended for some time.
205                         Sending any data to node that wasn't expecting it will produce
206                         annoying and misleading errors on the other side about failed signature
207                         verification and or about missing sptps context
208                 */
209                 close_all_connections = true;
210         }
211
212         last_periodic_run_time = now;
213
214         for list_each(connection_t, c, connection_list) {
215                 // control connections (eg. tinc ctl) do not have any timeout
216                 if(c->status.control) {
217                         continue;
218                 }
219
220                 if(close_all_connections) {
221                         logger(DEBUG_ALWAYS, LOG_ERR, "Forcing connection close after sleep time %s (%s)", c->name, c->hostname);
222                         terminate_connection(c, c->edge);
223                         continue;
224                 }
225
226                 // Bail out early if we haven't reached the ping timeout for this node yet
227                 if(c->last_ping_time + pingtimeout > now.tv_sec) {
228                         continue;
229                 }
230
231                 // timeout during connection establishing
232                 if(!c->edge) {
233                         if(c->status.connecting) {
234                                 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout while connecting to %s (%s)", c->name, c->hostname);
235                         } else {
236                                 logger(DEBUG_CONNECTIONS, LOG_WARNING, "Timeout from %s (%s) during authentication", c->name, c->hostname);
237                                 c->status.tarpit = true;
238                         }
239
240                         terminate_connection(c, c->edge);
241                         continue;
242                 }
243
244                 // helps in UDP holepunching
245                 try_tx(c->node, false);
246
247                 // timeout during ping
248                 if(c->status.pinged) {
249                         logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)(now.tv_sec - c->last_ping_time));
250                         terminate_connection(c, c->edge);
251                         continue;
252                 }
253
254                 // check whether we need to send a new ping
255                 if(c->last_ping_time + pinginterval <= now.tv_sec) {
256                         send_ping(c);
257                 }
258         }
259
260         timeout_set(data, &(struct timeval) {
261                 1, rand() % 100000
262         });
263 }
264
265 static void periodic_handler(void *data) {
266         /* Check if there are too many contradicting ADD_EDGE and DEL_EDGE messages.
267            This usually only happens when another node has the same Name as this node.
268            If so, sleep for a short while to prevent a storm of contradicting messages.
269         */
270
271         if(contradicting_del_edge > 100 && contradicting_add_edge > 100) {
272                 logger(DEBUG_ALWAYS, LOG_WARNING, "Possible node with same Name as us! Sleeping %d seconds.", sleeptime);
273                 nanosleep(&(struct timespec) {
274                         sleeptime, 0
275                 }, NULL);
276                 sleeptime *= 2;
277
278                 if(sleeptime < 0) {
279                         sleeptime = 3600;
280                 }
281         } else {
282                 sleeptime /= 2;
283
284                 if(sleeptime < 10) {
285                         sleeptime = 10;
286                 }
287         }
288
289         contradicting_add_edge = 0;
290         contradicting_del_edge = 0;
291
292         /* If AutoConnect is set, check if we need to make or break connections. */
293
294         if(autoconnect && node_tree->count > 1) {
295                 do_autoconnect();
296         }
297
298         timeout_set(data, &(struct timeval) {
299                 5, rand() % 100000
300         });
301 }
302
303 void handle_meta_connection_data(connection_t *c) {
304         if(!receive_meta(c)) {
305                 if(!c->status.control) {
306                         c->status.tarpit = true;
307                 }
308
309                 terminate_connection(c, c->edge);
310                 return;
311         }
312 }
313
314 #ifndef HAVE_MINGW
315 static void sigterm_handler(void *data) {
316         logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
317         event_exit();
318 }
319
320 static void sighup_handler(void *data) {
321         logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
322         reopenlogger();
323
324         if(reload_configuration()) {
325                 exit(1);
326         }
327 }
328
329 static void sigalrm_handler(void *data) {
330         logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
331         retry();
332 }
333 #endif
334
335 int reload_configuration(void) {
336         char fname[PATH_MAX];
337
338         /* Reread our own configuration file */
339
340         exit_configuration(&config_tree);
341         init_configuration(&config_tree);
342
343         if(!read_server_config()) {
344                 logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reread configuration file.");
345                 return EINVAL;
346         }
347
348         read_config_options(config_tree, NULL);
349
350         snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, myself->name);
351         read_config_file(config_tree, fname, true);
352
353         /* Parse some options that are allowed to be changed while tinc is running */
354
355         setup_myself_reloadable();
356
357         /* If StrictSubnet is set, expire deleted Subnets and read new ones in */
358
359         if(strictsubnets) {
360                 for splay_each(subnet_t, subnet, subnet_tree)
361                         if(subnet->owner) {
362                                 subnet->expires = 1;
363                         }
364         }
365
366         for splay_each(node_t, n, node_tree) {
367                 n->status.has_address = false;
368         }
369
370         load_all_nodes();
371
372         if(strictsubnets) {
373                 for splay_each(subnet_t, subnet, subnet_tree) {
374                         if(!subnet->owner) {
375                                 continue;
376                         }
377
378                         if(subnet->expires == 1) {
379                                 send_del_subnet(everyone, subnet);
380
381                                 if(subnet->owner->status.reachable) {
382                                         subnet_update(subnet->owner, subnet, false);
383                                 }
384
385                                 subnet_del(subnet->owner, subnet);
386                         } else if(subnet->expires == -1) {
387                                 subnet->expires = 0;
388                         } else {
389                                 send_add_subnet(everyone, subnet);
390
391                                 if(subnet->owner->status.reachable) {
392                                         subnet_update(subnet->owner, subnet, true);
393                                 }
394                         }
395                 }
396         } else { /* Only read our own subnets back in */
397                 for splay_each(subnet_t, subnet, myself->subnet_tree)
398                         if(!subnet->expires) {
399                                 subnet->expires = 1;
400                         }
401
402                 config_t *cfg = lookup_config(config_tree, "Subnet");
403
404                 while(cfg) {
405                         subnet_t *subnet, *s2;
406
407                         if(!get_config_subnet(cfg, &subnet)) {
408                                 continue;
409                         }
410
411                         if((s2 = lookup_subnet(myself, subnet))) {
412                                 if(s2->expires == 1) {
413                                         s2->expires = 0;
414                                 }
415
416                                 free_subnet(subnet);
417                         } else {
418                                 subnet_add(myself, subnet);
419                                 send_add_subnet(everyone, subnet);
420                                 subnet_update(myself, subnet, true);
421                         }
422
423                         cfg = lookup_config_next(config_tree, cfg);
424                 }
425
426                 for splay_each(subnet_t, subnet, myself->subnet_tree) {
427                         if(subnet->expires == 1) {
428                                 send_del_subnet(everyone, subnet);
429                                 subnet_update(myself, subnet, false);
430                                 subnet_del(myself, subnet);
431                         }
432                 }
433         }
434
435         /* Try to make outgoing connections */
436
437         try_outgoing_connections();
438
439         /* Close connections to hosts that have a changed or deleted host config file */
440
441         for list_each(connection_t, c, connection_list) {
442                 if(c->status.control) {
443                         continue;
444                 }
445
446                 snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, c->name);
447                 struct stat s;
448
449                 if(stat(fname, &s) || s.st_mtime > last_config_check) {
450                         logger(DEBUG_CONNECTIONS, LOG_INFO, "Host config file of %s has been changed", c->name);
451                         terminate_connection(c, c->edge);
452                 }
453         }
454
455         last_config_check = now.tv_sec;
456
457         return 0;
458 }
459
460 void retry(void) {
461         /* Reset the reconnection timers for all outgoing connections */
462         for list_each(outgoing_t, outgoing, outgoing_list) {
463                 outgoing->timeout = 0;
464
465                 if(outgoing->ev.cb)
466                         timeout_set(&outgoing->ev, &(struct timeval) {
467                         0, 0
468                 });
469         }
470
471         /* Check for outgoing connections that are in progress, and reset their ping timers */
472         for list_each(connection_t, c, connection_list) {
473                 if(c->outgoing && !c->node) {
474                         c->last_ping_time = 0;
475                 }
476         }
477
478         /* Kick the ping timeout handler */
479         timeout_set(&pingtimer, &(struct timeval) {
480                 0, 0
481         });
482 }
483
484 /*
485   this is where it all happens...
486 */
487 int main_loop(void) {
488         last_periodic_run_time = now;
489         timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval) {
490                 pingtimeout, rand() % 100000
491         });
492         timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval) {
493                 0, 0
494         });
495
496 #ifndef HAVE_MINGW
497         signal_t sighup = {0};
498         signal_t sigterm = {0};
499         signal_t sigquit = {0};
500         signal_t sigint = {0};
501         signal_t sigalrm = {0};
502
503         signal_add(&sighup, sighup_handler, &sighup, SIGHUP);
504         signal_add(&sigterm, sigterm_handler, &sigterm, SIGTERM);
505         signal_add(&sigquit, sigterm_handler, &sigquit, SIGQUIT);
506         signal_add(&sigint, sigterm_handler, &sigint, SIGINT);
507         signal_add(&sigalrm, sigalrm_handler, &sigalrm, SIGALRM);
508 #endif
509
510         if(!event_loop()) {
511                 logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", sockstrerror(sockerrno));
512                 return 1;
513         }
514
515 #ifndef HAVE_MINGW
516         signal_del(&sighup);
517         signal_del(&sigterm);
518         signal_del(&sigquit);
519         signal_del(&sigint);
520         signal_del(&sigalrm);
521 #endif
522
523         timeout_del(&periodictimer);
524         timeout_del(&pingtimer);
525
526         return 0;
527 }