]> git.meshlink.io Git - meshlink/blob - src/protocol.c
Always close all sockets in terminate_connection().
[meshlink] / src / protocol.c
1 /*
2     protocol.c -- handle the meta-protocol
3     Copyright (C) 1999-2001 Ivo Timmermans <itimmermans@bigfoot.com>,
4                   2000,2001 Guus Sliepen <guus@sliepen.warande.net>
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
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20     $Id: protocol.c,v 1.28.4.103 2001/07/21 15:34:18 guus Exp $
21 */
22
23 #include "config.h"
24
25 #include <sys/types.h>
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include <syslog.h>
30 #include <sys/socket.h>
31 #include <unistd.h>
32 #include <stdio.h>
33 #include <stdarg.h>
34 #include <errno.h>
35
36 #include <utils.h>
37 #include <xalloc.h>
38 #include <avl_tree.h>
39 #include <list.h>
40
41 #include <netinet/in.h>
42
43 #include <openssl/sha.h>
44 #include <openssl/rand.h>
45 #include <openssl/evp.h>
46
47 #ifndef HAVE_RAND_PSEUDO_BYTES
48 #define RAND_pseudo_bytes RAND_bytes
49 #endif
50
51 #include "conf.h"
52 #include "net.h"
53 #include "netutl.h"
54 #include "protocol.h"
55 #include "meta.h"
56 #include "connection.h"
57
58 #include "system.h"
59
60 int mykeyused = 0;
61
62 int check_id(char *id)
63 {
64   int i;
65
66   for (i = 0; i < strlen(id); i++)
67     if(!isalnum(id[i]) && id[i] != '_')
68       return -1;
69   
70   return 0;
71 }
72
73 /* Generic request routines - takes care of logging and error
74    detection as well */
75
76 int send_request(connection_t *cl, const char *format, ...)
77 {
78   va_list args;
79   char buffer[MAXBUFSIZE];
80   int len, request;
81
82 cp
83   /* Use vsnprintf instead of vasprintf: faster, no memory
84      fragmentation, cleanup is automatic, and there is a limit on the
85      input buffer anyway */
86
87   va_start(args, format);
88   len = vsnprintf(buffer, MAXBUFSIZE, format, args);
89   request = va_arg(args, int);
90   va_end(args);
91
92   if(len < 0 || len > MAXBUFSIZE-1)
93     {
94       syslog(LOG_ERR, _("Output buffer overflow while sending %s to %s (%s)"), request_name[request], cl->name, cl->hostname);
95       return -1;
96     }
97
98   if(debug_lvl >= DEBUG_PROTOCOL)
99     {
100       if(debug_lvl >= DEBUG_META)
101         syslog(LOG_DEBUG, _("Sending %s to %s (%s): %s"), request_name[request], cl->name, cl->hostname, buffer);
102       else
103         syslog(LOG_DEBUG, _("Sending %s to %s (%s)"), request_name[request], cl->name, cl->hostname);
104     }
105
106   buffer[len++] = '\n';
107 cp
108   return send_meta(cl, buffer, len);
109 }
110
111 int receive_request(connection_t *cl)
112 {
113   int request;
114 cp
115   if(sscanf(cl->buffer, "%d", &request) == 1)
116     {
117       if((request < 0) || (request >= LAST) || (request_handlers[request] == NULL))
118         {
119           if(debug_lvl >= DEBUG_META)
120             syslog(LOG_DEBUG, _("Unknown request from %s (%s): %s"),
121                    cl->name, cl->hostname, cl->buffer);
122           else
123             syslog(LOG_ERR, _("Unknown request from %s (%s)"),
124                    cl->name, cl->hostname);
125                    
126           return -1;
127         }
128       else
129         {
130           if(debug_lvl >= DEBUG_PROTOCOL)
131             {
132               if(debug_lvl >= DEBUG_META)
133                 syslog(LOG_DEBUG, _("Got %s from %s (%s): %s"),
134                        request_name[request], cl->name, cl->hostname, cl->buffer);
135               else
136                 syslog(LOG_DEBUG, _("Got %s from %s (%s)"),
137                        request_name[request], cl->name, cl->hostname);
138             }
139         }
140
141       if((cl->allow_request != ALL) && (cl->allow_request != request))
142         {
143           syslog(LOG_ERR, _("Unauthorized request from %s (%s)"), cl->name, cl->hostname);
144           return -1;
145         }
146
147       if(request_handlers[request](cl))
148         /* Something went wrong. Probably scriptkiddies. Terminate. */
149         {
150           syslog(LOG_ERR, _("Error while processing %s from %s (%s)"),
151                  request_name[request], cl->name, cl->hostname);
152           return -1;
153         }
154     }
155   else
156     {
157       syslog(LOG_ERR, _("Bogus data received from %s (%s)"),
158              cl->name, cl->hostname);
159       return -1;
160     }
161 cp
162   return 0;
163 }
164
165 /* The authentication protocol is described in detail in doc/SECURITY2,
166    the rest will be described in doc/PROTOCOL. */
167
168 int send_id(connection_t *cl)
169 {
170 cp
171   return send_request(cl, "%d %s %d %lx %hd", ID, myself->name, myself->protocol_version, myself->options, myself->port);
172 }
173
174 int id_h(connection_t *cl)
175 {
176   char name[MAX_STRING_SIZE];
177 cp
178   if(sscanf(cl->buffer, "%*d "MAX_STRING" %d %lx %hd", name, &cl->protocol_version, &cl->options, &cl->port) != 4)
179     {
180        syslog(LOG_ERR, _("Got bad ID from %s"), cl->hostname);
181        return -1;
182     }
183
184   /* Check if version matches */
185
186   if(cl->protocol_version != myself->protocol_version)
187     {
188       syslog(LOG_ERR, _("Peer %s (%s) uses incompatible version %d"),
189              cl->name, cl->hostname, cl->protocol_version);
190       return -1;
191     }
192
193   /* Check if identity is a valid name */
194
195   if(check_id(name))
196     {
197       syslog(LOG_ERR, _("Peer %s uses invalid identity name"), cl->hostname);
198       return -1;
199     }
200   
201   /* Copy string to cl */
202   
203   if(cl->name)
204     free(cl->name);
205     
206   cl->name = xstrdup(name);
207
208   /* Load information about peer */
209
210   if(read_host_config(cl))
211     {
212       syslog(LOG_ERR, _("Peer %s had unknown identity (%s)"), cl->hostname, cl->name);
213       return -1;
214     }
215
216   /* Read in the public key, so that we can send a metakey */
217
218   if(read_rsa_public_key(cl))
219     return -1;
220
221   cl->allow_request = METAKEY;
222 cp
223   return send_metakey(cl);
224 }
225
226 int ack_h(connection_t *cl)
227 {
228   config_t const *cfg;
229   connection_t *old, *p;
230   subnet_t *subnet;
231   avl_node_t *node, *node2;
232 cp
233   /* Okay, before we active the connection, we check if there is another entry
234      in the connection list with the same name. If so, it presumably is an
235      old connection that has timed out but we don't know it yet.
236    */
237
238   if((old = lookup_id(cl->name)))
239     {
240       if(debug_lvl >= DEBUG_CONNECTIONS)
241         syslog(LOG_NOTICE, _("Removing old connection for %s at %s in favour of new connection from %s"),
242                cl->name, old->hostname, cl->hostname);
243       if(old->status.outgoing)
244         {
245           cl->status.outgoing = 1;
246           old->status.outgoing = 0;
247         }
248       terminate_connection(old, 0);
249       return 0;
250     }
251     
252   /* Also check if no other tinc daemon uses the same IP and port for UDP traffic */
253   
254   old = avl_search(active_tree, cl);
255   if(old)
256   {
257     syslog(LOG_ERR, _("%s is listening on %s:%hd, which is already in use by %s!"),
258            cl->name, cl->hostname, cl->port, old->name);
259     return -1;
260   }
261     
262   /* Activate this connection */
263
264   cl->allow_request = ALL;
265   cl->nexthop = cl;
266   cl->cipher_pkttype = EVP_bf_cbc();
267   cl->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
268
269   active_add(cl);
270
271   if(debug_lvl >= DEBUG_CONNECTIONS)
272     syslog(LOG_NOTICE, _("Connection with %s (%s) activated"), cl->name, cl->hostname);
273
274   if(cl->status.outgoing)
275     seconds_till_retry = 5;     /* Reset retry timeout */
276 cp
277   /* Check some options */
278   
279   if((cfg = get_config_val(cl->config, config_indirectdata)))
280     {
281       if(cfg->data.val == stupid_true)
282         cl->options |= OPTION_INDIRECT;
283     }
284
285   if((cfg = get_config_val(cl->config, config_tcponly)))
286     {
287       if(cfg->data.val == stupid_true)
288         cl->options |= OPTION_TCPONLY;
289     }
290
291   /* Send him our subnets */
292   
293   for(node = myself->subnet_tree->head; node; node = node->next)
294     {
295       subnet = (subnet_t *)node->data;
296       send_add_subnet(cl, subnet);
297     }
298
299   /* And send him all the hosts and their subnets we know... */
300   
301   for(node = active_tree->head; node; node = node->next)
302     {
303       p = (connection_t *)node->data;
304       
305       if(p != cl)
306         {
307           /* Notify others of this connection */
308
309           if(p->status.meta)
310             send_add_host(p, cl);
311
312           /* Notify new connection of everything we know */
313
314           send_add_host(cl, p);
315
316           for(node2 = p->subnet_tree->head; node2; node2 = node2->next)
317             {
318               subnet = (subnet_t *)node2->data;
319               send_add_subnet(cl, subnet);
320             }
321         }
322     }
323 cp
324   return 0;
325 }
326
327 int send_challenge(connection_t *cl)
328 {
329   char *buffer;
330   int len, x;
331 cp
332   /* CHECKME: what is most reasonable value for len? */
333
334   len = RSA_size(cl->rsa_key);
335
336   /* Allocate buffers for the challenge */
337
338   buffer = xmalloc(len*2+1);
339
340   if(cl->hischallenge)
341     free(cl->hischallenge);
342     
343   cl->hischallenge = xmalloc(len);
344 cp
345   /* Copy random data to the buffer */
346
347   RAND_bytes(cl->hischallenge, len);
348
349 cp
350   /* Convert to hex */
351
352   bin2hex(cl->hischallenge, buffer, len);
353   buffer[len*2] = '\0';
354
355 cp
356   /* Send the challenge */
357
358   x = send_request(cl, "%d %s", CHALLENGE, buffer);
359   free(buffer);
360 cp
361   return x;
362 }
363
364 int challenge_h(connection_t *cl)
365 {
366   char buffer[MAX_STRING_SIZE];
367   int len;
368 cp
369   if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
370     {
371        syslog(LOG_ERR, _("Got bad CHALLENGE from %s (%s)"), cl->name, cl->hostname);
372        return -1;
373     }
374
375   len = RSA_size(myself->rsa_key);
376
377   /* Check if the length of the challenge is all right */
378
379   if(strlen(buffer) != len*2)
380     {
381       syslog(LOG_ERR, _("Intruder: wrong challenge length from %s (%s)"), cl->name, cl->hostname);
382       return -1;
383     }
384
385   /* Allocate buffers for the challenge */
386
387   if(!cl->mychallenge)
388     cl->mychallenge = xmalloc(len);
389
390   /* Convert the challenge from hexadecimal back to binary */
391
392   hex2bin(buffer,cl->mychallenge,len);
393
394   cl->allow_request = CHAL_REPLY;
395
396   /* Rest is done by send_chal_reply() */
397 cp
398   return send_chal_reply(cl);
399 }
400
401 int send_chal_reply(connection_t *cl)
402 {
403   char hash[SHA_DIGEST_LENGTH*2+1];
404 cp
405   if(!cl->mychallenge)
406     {
407       syslog(LOG_ERR, _("Trying to send CHAL_REPLY to %s (%s) without a valid CHALLENGE"), cl->name, cl->hostname);
408       return -1;
409     }
410      
411   /* Calculate the hash from the challenge we received */
412
413   SHA1(cl->mychallenge, RSA_size(myself->rsa_key), hash);
414
415   /* Convert the hash to a hexadecimal formatted string */
416
417   bin2hex(hash,hash,SHA_DIGEST_LENGTH);
418   hash[SHA_DIGEST_LENGTH*2] = '\0';
419
420   /* Send the reply */
421
422 cp
423   return send_request(cl, "%d %s", CHAL_REPLY, hash);
424 }
425
426 int chal_reply_h(connection_t *cl)
427 {
428   char hishash[MAX_STRING_SIZE];
429   char myhash[SHA_DIGEST_LENGTH];
430 cp
431   if(sscanf(cl->buffer, "%*d "MAX_STRING, hishash) != 1)
432     {
433        syslog(LOG_ERR, _("Got bad CHAL_REPLY from %s (%s)"), cl->name, cl->hostname);
434        return -1;
435     }
436
437   /* Check if the length of the hash is all right */
438
439   if(strlen(hishash) != SHA_DIGEST_LENGTH*2)
440     {
441       syslog(LOG_ERR, _("Intruder: wrong challenge reply length from %s (%s)"), cl->name, cl->hostname);
442       return -1;
443     }
444
445   /* Convert the hash to binary format */
446
447   hex2bin(hishash, hishash, SHA_DIGEST_LENGTH);
448
449   /* Calculate the hash from the challenge we sent */
450
451   SHA1(cl->hischallenge, RSA_size(cl->rsa_key), myhash);
452
453   /* Verify the incoming hash with the calculated hash */
454
455   if(memcmp(hishash, myhash, SHA_DIGEST_LENGTH))
456     {
457       syslog(LOG_ERR, _("Intruder: wrong challenge reply from %s (%s)"), cl->name, cl->hostname);
458       if(debug_lvl >= DEBUG_SCARY_THINGS)
459         {
460           bin2hex(myhash, hishash, SHA_DIGEST_LENGTH);
461           hishash[SHA_DIGEST_LENGTH*2] = '\0';
462           syslog(LOG_DEBUG, _("Expected challenge reply: %s"), hishash);
463         }
464       return -1;
465     }
466
467   /* Identity has now been positively verified.
468      ack_h() handles the rest from now on.
469    */
470 cp
471   return ack_h(cl);
472 }
473
474 int send_metakey(connection_t *cl)
475 {
476   char *buffer;
477   int len, x;
478 cp
479   len = RSA_size(cl->rsa_key);
480
481   /* Allocate buffers for the meta key */
482
483   buffer = xmalloc(len*2+1);
484
485   if(!cl->cipher_outkey)
486     cl->cipher_outkey = xmalloc(len);
487     
488   if(!cl->cipher_outctx)
489     cl->cipher_outctx = xmalloc(sizeof(*cl->cipher_outctx));
490 cp
491   /* Copy random data to the buffer */
492
493   RAND_bytes(cl->cipher_outkey, len);
494
495   /* The message we send must be smaller than the modulus of the RSA key.
496      By definition, for a key of k bits, the following formula holds:
497      
498        2^(k-1) <= modulus < 2^(k)
499      
500      Where ^ means "to the power of", not "xor".
501      This means that to be sure, we must choose our message < 2^(k-1).
502      This can be done by setting the most significant bit to zero.
503   */
504   
505   cl->cipher_outkey[0] &= 0x7F;
506   
507   if(debug_lvl >= DEBUG_SCARY_THINGS)
508     {
509       bin2hex(cl->cipher_outkey, buffer, len);
510       buffer[len*2] = '\0';
511       syslog(LOG_DEBUG, _("Generated random meta key (unencrypted): %s"), buffer);
512     }
513
514   /* Encrypt the random data
515   
516      We do not use one of the PKCS padding schemes here.
517      This is allowed, because we encrypt a totally random string
518      with a length equal to that of the modulus of the RSA key.
519   */
520   
521   if(RSA_public_encrypt(len, cl->cipher_outkey, buffer, cl->rsa_key, RSA_NO_PADDING) != len)
522     {
523       syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
524       free(buffer);
525       return -1;
526     }
527 cp
528   /* Convert the encrypted random data to a hexadecimal formatted string */
529
530   bin2hex(buffer, buffer, len);
531   buffer[len*2] = '\0';
532
533   /* Send the meta key */
534
535   x = send_request(cl, "%d %s", METAKEY, buffer);
536   free(buffer);
537
538   /* Further outgoing requests are encrypted with the key we just generated */
539
540   EVP_EncryptInit(cl->cipher_outctx, EVP_bf_cfb(),
541                   cl->cipher_outkey + len - EVP_bf_cfb()->key_len,
542                   cl->cipher_outkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
543
544   cl->status.encryptout = 1;
545 cp
546   return x;
547 }
548
549 int metakey_h(connection_t *cl)
550 {
551   char buffer[MAX_STRING_SIZE];
552   int len;
553 cp
554   if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
555     {
556        syslog(LOG_ERR, _("Got bad METAKEY from %s (%s)"), cl->name, cl->hostname);
557        return -1;
558     }
559
560   len = RSA_size(myself->rsa_key);
561
562   /* Check if the length of the meta key is all right */
563
564   if(strlen(buffer) != len*2)
565     {
566       syslog(LOG_ERR, _("Intruder: wrong meta key length from %s (%s)"), cl->name, cl->hostname);
567       return -1;
568     }
569
570   /* Allocate buffers for the meta key */
571
572   if(!cl->cipher_inkey)
573     cl->cipher_inkey = xmalloc(len);
574
575   if(!cl->cipher_inctx)
576     cl->cipher_inctx = xmalloc(sizeof(*cl->cipher_inctx));
577
578   /* Convert the challenge from hexadecimal back to binary */
579
580   hex2bin(buffer,buffer,len);
581
582   /* Decrypt the meta key */
583   
584   if(RSA_private_decrypt(len, buffer, cl->cipher_inkey, myself->rsa_key, RSA_NO_PADDING) != len)        /* See challenge() */
585     {
586       syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
587       return -1;
588     }
589
590   if(debug_lvl >= DEBUG_SCARY_THINGS)
591     {
592       bin2hex(cl->cipher_inkey, buffer, len);
593       buffer[len*2] = '\0';
594       syslog(LOG_DEBUG, _("Received random meta key (unencrypted): %s"), buffer);
595     }
596
597   /* All incoming requests will now be encrypted. */
598
599   EVP_DecryptInit(cl->cipher_inctx, EVP_bf_cfb(),
600                   cl->cipher_inkey + len - EVP_bf_cfb()->key_len,
601                   cl->cipher_inkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
602   
603   cl->status.decryptin = 1;
604
605   cl->allow_request = CHALLENGE;
606 cp
607   return send_challenge(cl);
608 }
609
610 /* Address and subnet information exchange */
611
612 int send_add_subnet(connection_t *cl, subnet_t *subnet)
613 {
614   int x;
615   char *netstr;
616   char *owner;
617 cp
618   if((cl->options | myself->options | subnet->owner->options) & OPTION_INDIRECT)
619     owner = myself->name;
620   else
621     owner = subnet->owner->name;
622
623   x = send_request(cl, "%d %s %s", ADD_SUBNET,
624                       owner, netstr = net2str(subnet));
625   free(netstr);
626 cp
627   return x;
628 }
629
630 int add_subnet_h(connection_t *cl)
631 {
632   char subnetstr[MAX_STRING_SIZE];
633   char name[MAX_STRING_SIZE];
634   connection_t *owner, *p;
635   subnet_t *subnet;
636   avl_node_t *node;
637 cp
638   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
639     {
640       syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s)"), cl->name, cl->hostname);
641       return -1;
642     }
643
644   /* Check if owner name is a valid */
645
646   if(check_id(name))
647     {
648       syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
649       return -1;
650     }
651
652   /* Check if subnet string is valid */
653
654   if(!(subnet = str2net(subnetstr)))
655     {
656       syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
657       return -1;
658     }
659
660   /* Check if somebody tries to add a subnet of ourself */
661
662   if(!strcmp(name, myself->name))
663     {
664       syslog(LOG_ERR, _("Warning: got ADD_SUBNET from %s (%s) for ourself, restarting"),
665              cl->name, cl->hostname);
666       sighup = 1;
667       return 0;
668     }
669
670   /* Check if the owner of the new subnet is in the connection list */
671
672   if(!(owner = lookup_id(name)))
673     {
674       syslog(LOG_ERR, _("Got ADD_SUBNET for %s from %s (%s) which is not in our connection list"),
675              name, cl->name, cl->hostname);
676       return -1;
677     }
678
679   /* If everything is correct, add the subnet to the list of the owner */
680
681   subnet_add(owner, subnet);
682
683   /* Tell the rest */
684   
685   for(node = connection_tree->head; node; node = node->next)
686     {
687       p = (connection_t *)node->data;
688       if(p->status.active && p!= cl)
689         send_add_subnet(p, subnet);
690     }
691 cp
692   return 0;
693 }
694
695 int send_del_subnet(connection_t *cl, subnet_t *subnet)
696 {
697   int x;
698   char *netstr;
699   char *owner;
700 cp
701   if(cl->options & OPTION_INDIRECT)
702     owner = myself->name;
703   else
704     owner = subnet->owner->name;
705
706   x = send_request(cl, "%d %s %s", DEL_SUBNET, owner, netstr = net2str(subnet));
707   free(netstr);
708 cp
709   return x;
710 }
711
712 int del_subnet_h(connection_t *cl)
713 {
714   char subnetstr[MAX_STRING_SIZE];
715   char name[MAX_STRING_SIZE];
716   connection_t *owner, *p;
717   subnet_t *subnet;
718   avl_node_t *node;
719 cp
720   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 3)
721     {
722       syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s)"), cl->name, cl->hostname);
723       return -1;
724     }
725
726   /* Check if owner name is a valid */
727
728   if(check_id(name))
729     {
730       syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
731       return -1;
732     }
733
734   /* Check if subnet string is valid */
735
736   if(!(subnet = str2net(subnetstr)))
737     {
738       syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
739       return -1;
740     }
741
742   free(subnetstr);
743   
744   /* Check if somebody tries to add a subnet of ourself */
745
746   if(!strcmp(name, myself->name))
747     {
748       syslog(LOG_ERR, _("Warning: got DEL_SUBNET from %s (%s) for ourself, restarting"),
749              cl->name, cl->hostname);
750       sighup = 1;
751       return 0;
752     }
753
754   /* Check if the owner of the new subnet is in the connection list */
755
756   if(!(owner = lookup_id(name)))
757     {
758       syslog(LOG_ERR, _("Got DEL_SUBNET for %s from %s (%s) which is not in our connection list"),
759              name, cl->name, cl->hostname);
760       return -1;
761     }
762
763   /* If everything is correct, delete the subnet from the list of the owner */
764
765   subnet_del(subnet);
766
767   /* Tell the rest */
768   
769   for(node = connection_tree->head; node; node = node->next)
770     {
771       p = (connection_t *)node->data;
772       if(p->status.active && p!= cl)
773         send_del_subnet(p, subnet);
774     }
775 cp
776   return 0;
777 }
778
779 /* New and closed connections notification */
780
781 int send_add_host(connection_t *cl, connection_t *other)
782 {
783 cp
784   if(!((cl->options | myself->options | other->options) & OPTION_INDIRECT))
785     return send_request(cl, "%d %s %lx:%d %lx", ADD_HOST,
786                       other->name, other->address, other->port, other->options);
787   else
788     return 0;
789 }
790
791 int add_host_h(connection_t *cl)
792 {
793   connection_t *old, *new, *p;
794   char name[MAX_STRING_SIZE];
795   avl_node_t *node;
796 cp
797   new = new_connection();
798
799   if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%hd %lx", name, &new->address, &new->port, &new->options) != 4)
800     {
801        syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"), cl->name, cl->hostname);
802        return -1;
803     }
804
805   /* Check if identity is a valid name */
806
807   if(check_id(name))
808     {
809       syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
810       free_connection(new);
811       return -1;
812     }
813
814   /* Check if somebody tries to add ourself */
815
816   if(!strcmp(name, myself->name))
817     {
818       syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"), cl->name, cl->hostname);
819       sighup = 1;
820       free_connection(new);
821       return 0;
822     }
823     
824   /* Fill in more of the new connection structure */
825
826   new->hostname = hostlookup(htonl(new->address));
827
828   /* Check if the new host already exists in the connnection list */
829
830   if((old = lookup_id(name)))
831     {
832       if((new->address == old->address) && (new->port == old->port) && (cl == old->nexthop))
833         {
834           if(debug_lvl >= DEBUG_CONNECTIONS)
835             syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
836                    old->name, old->hostname, cl->name, cl->hostname);
837           free_connection(new);
838           return 0;
839         }
840       else
841         {
842           if(debug_lvl >= DEBUG_CONNECTIONS)
843             syslog(LOG_NOTICE, _("Removing old entry for %s (%s) in favour of new connection"),
844                    old->name, old->hostname);
845
846           terminate_connection(old, 0);
847         }
848     }
849
850   /* Hook it up into the active tree */
851
852   new->name = xstrdup(name);
853   active_add(new);
854
855   /* Tell the rest about the new host */
856
857   for(node = connection_tree->head; node; node = node->next)
858     {
859       p = (connection_t *)node->data;
860       if(p->status.active && p!=cl)
861         send_add_host(p, new);
862     }
863
864   /* Fill in rest of connection structure */
865
866   new->nexthop = cl;
867   new->cipher_pkttype = EVP_bf_cbc();
868   new->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
869 cp
870   return 0;
871 }
872
873 int send_del_host(connection_t *cl, connection_t *other)
874 {
875 cp
876   if(!((cl->options | myself->options) & OPTION_INDIRECT))
877     return send_request(cl, "%d %s %lx:%d %lx", DEL_HOST,
878                       other->name, other->address, other->port, other->options);
879   else
880     return 0;
881 }
882
883 int del_host_h(connection_t *cl)
884 {
885   char name[MAX_STRING_SIZE];
886   ipv4_t address;
887   port_t port;
888   long int options;
889   connection_t *old, *p;
890   avl_node_t *node;
891 cp
892   if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%hd %lx", name, &address, &port, &options) != 4)
893     {
894       syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
895              cl->name, cl->hostname);
896       return -1;
897     }
898
899   /* Check if identity is a valid name */
900
901   if(check_id(name))
902     {
903       syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
904       return -1;
905     }
906
907   /* Check if somebody tries to delete ourself */
908
909   if(!strcmp(name, myself->name))
910     {
911       syslog(LOG_ERR, _("Warning: got DEL_HOST from %s (%s) for ourself, restarting"),
912              cl->name, cl->hostname);
913       sighup = 1;
914       return 0;
915     }
916
917   /* Check if the deleted host already exists in the connnection list */
918
919   if(!(old = lookup_id(name)))
920     {
921       syslog(LOG_ERR, _("Got DEL_HOST from %s (%s) for %s which is not in our connection list"),
922              cl->name, cl->hostname, name);
923       return -1;
924     }
925   
926   /* Check if the rest matches */
927   
928   if(address!=old->address || port!=old->port || options!=old->options || cl!=old->nexthop)
929     {
930       syslog(LOG_WARNING, _("Got DEL_HOST from %s (%s) for %s which doesn't match"), cl->name, cl->hostname, old->name);
931       return 0;
932     }
933
934   /* Ok, since EVERYTHING seems to check out all right, delete it */
935
936   terminate_connection(old, 0);
937
938   /* Tell the rest about the deleted host */
939
940   for(node = connection_tree->head; node; node = node->next)
941     {
942       p = (connection_t *)node->data;
943       if(p->status.active && p!=cl)
944         send_del_host(p, old);
945     }
946 cp
947   return 0;
948 }
949
950 /* Status and error notification routines */
951
952 int send_status(connection_t *cl, int statusno, char *statusstring)
953 {
954 cp
955   if(!statusstring)
956     statusstring = status_text[statusno];
957 cp
958   return send_request(cl, "%d %d %s", STATUS, statusno, statusstring);
959 }
960
961 int status_h(connection_t *cl)
962 {
963   int statusno;
964   char statusstring[MAX_STRING_SIZE];
965 cp
966   if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &statusno, statusstring) != 2)
967     {
968        syslog(LOG_ERR, _("Got bad STATUS from %s (%s)"),
969               cl->name, cl->hostname);
970        return -1;
971     }
972
973   if(debug_lvl >= DEBUG_STATUS)
974     {
975       syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"),
976              cl->name, cl->hostname, status_text[statusno], statusstring);
977     }
978
979 cp
980   return 0;
981 }
982
983 int send_error(connection_t *cl, int err, char *errstring)
984 {
985 cp
986   if(!errstring)
987     errstring = strerror(err);
988   return send_request(cl, "%d %d %s", ERROR, err, errstring);
989 }
990
991 int error_h(connection_t *cl)
992 {
993   int err;
994   char errorstring[MAX_STRING_SIZE];
995 cp
996   if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &err, errorstring) != 2)
997     {
998        syslog(LOG_ERR, _("Got bad ERROR from %s (%s)"),
999               cl->name, cl->hostname);
1000        return -1;
1001     }
1002
1003   if(debug_lvl >= DEBUG_ERROR)
1004     {
1005       syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"),
1006              cl->name, cl->hostname, strerror(err), errorstring);
1007     }
1008
1009   terminate_connection(cl, 1);
1010 cp
1011   return 0;
1012 }
1013
1014 int send_termreq(connection_t *cl)
1015 {
1016 cp
1017   return send_request(cl, "%d", TERMREQ);
1018 }
1019
1020 int termreq_h(connection_t *cl)
1021 {
1022 cp
1023   terminate_connection(cl, 1);
1024 cp
1025   return 0;
1026 }
1027
1028 int send_ping(connection_t *cl)
1029 {
1030   char salt[SALTLEN*2+1];
1031 cp
1032   cl->status.pinged = 1;
1033   cl->last_ping_time = time(NULL);
1034   RAND_pseudo_bytes(salt, SALTLEN);
1035   bin2hex(salt, salt, SALTLEN);
1036   salt[SALTLEN*2] = '\0';
1037 cp
1038   return send_request(cl, "%d %s", PING, salt);
1039 }
1040
1041 int ping_h(connection_t *cl)
1042 {
1043 cp
1044   return send_pong(cl);
1045 }
1046
1047 int send_pong(connection_t *cl)
1048 {
1049   char salt[SALTLEN*2+1];
1050 cp
1051   RAND_pseudo_bytes(salt, SALTLEN);
1052   bin2hex(salt, salt, SALTLEN);
1053   salt[SALTLEN*2] = '\0';
1054 cp
1055   return send_request(cl, "%d %s", PONG, salt);
1056 }
1057
1058 int pong_h(connection_t *cl)
1059 {
1060 cp
1061   cl->status.pinged = 0;
1062 cp
1063   return 0;
1064 }
1065
1066 /* Key exchange */
1067
1068 int send_key_changed(connection_t *from, connection_t *cl)
1069 {
1070   connection_t *p;
1071   avl_node_t *node;
1072 cp
1073   /* Only send this message if some other daemon requested our key previously.
1074      This reduces unnecessary key_changed broadcasts.
1075   */
1076
1077   if(from==myself && !mykeyused)
1078     return 0;
1079
1080   for(node = connection_tree->head; node; node = node->next)
1081     {
1082       p = (connection_t *)node->data;
1083       if(p != cl && p->status.active)
1084         if(!(p->options & OPTION_INDIRECT) || from == myself)
1085           send_request(p, "%d %s", KEY_CHANGED, from->name);
1086     }
1087 cp
1088   return 0;
1089 }
1090
1091 int key_changed_h(connection_t *cl)
1092 {
1093   char from_id[MAX_STRING_SIZE];
1094   connection_t *from;
1095 cp
1096   if(sscanf(cl->buffer, "%*d "MAX_STRING, from_id) != 1)
1097     {
1098       syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
1099              cl->name, cl->hostname);
1100       return -1;
1101     }
1102
1103   if(!(from = lookup_id(from_id)))
1104     {
1105       syslog(LOG_ERR, _("Got KEY_CHANGED from %s (%s) origin %s which does not exist in our connection list"),
1106              cl->name, cl->hostname, from_id);
1107       return -1;
1108     }
1109
1110   from->status.validkey = 0;
1111   from->status.waitingforkey = 0;
1112
1113   if(!(from->options | cl->options | myself->options) & OPTION_INDIRECT)
1114     send_key_changed(from, cl);
1115 cp
1116   return 0;
1117 }
1118
1119 int send_req_key(connection_t *from, connection_t *to)
1120 {
1121 cp
1122   return send_request(to->nexthop, "%d %s %s", REQ_KEY,
1123                       from->name, to->name);
1124 }
1125
1126 int req_key_h(connection_t *cl)
1127 {
1128   char from_id[MAX_STRING_SIZE];
1129   char to_id[MAX_STRING_SIZE];
1130   connection_t *from, *to;
1131   char pktkey[129];
1132 cp
1133   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, from_id, to_id) != 2)
1134     {
1135        syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
1136               cl->name, cl->hostname);
1137        return -1;
1138     }
1139
1140   if(!(from = lookup_id(from_id)))
1141     {
1142       syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) origin %s which does not exist in our connection list"),
1143              cl->name, cl->hostname, from_id);
1144       return -1;
1145     }
1146
1147   /* Check if this key request is for us */
1148
1149   if(!strcmp(to_id, myself->name))      /* Yes, send our own key back */
1150     {
1151       bin2hex(myself->cipher_pktkey, pktkey, myself->cipher_pktkeylength);
1152       pktkey[myself->cipher_pktkeylength*2] = '\0';
1153       send_ans_key(myself, from, pktkey);
1154       mykeyused = 1;
1155     }
1156   else
1157     {
1158       if(!(to = lookup_id(to_id)))
1159         {
1160           syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) destination %s which does not exist in our connection list"),
1161                  cl->name, cl->hostname, to_id);
1162           return -1;
1163         }
1164         
1165       if(to->status.validkey)   /* Proxy keys */
1166         {
1167           bin2hex(to->cipher_pktkey, pktkey, to->cipher_pktkeylength);
1168           pktkey[to->cipher_pktkeylength*2] = '\0';
1169           send_ans_key(to, from, pktkey);
1170         }
1171       else
1172         send_req_key(from, to);
1173     }
1174
1175 cp
1176   return 0;
1177 }
1178
1179 int send_ans_key(connection_t *from, connection_t *to, char *pktkey)
1180 {
1181 cp
1182   return send_request(to->nexthop, "%d %s %s %s", ANS_KEY,
1183                       from->name, to->name, pktkey);
1184 }
1185
1186 int ans_key_h(connection_t *cl)
1187 {
1188   char from_id[MAX_STRING_SIZE];
1189   char to_id[MAX_STRING_SIZE];
1190   char pktkey[MAX_STRING_SIZE];
1191   int keylength;
1192   connection_t *from, *to;
1193 cp
1194   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING, from_id, to_id, pktkey) != 3)
1195     {
1196        syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
1197               cl->name, cl->hostname);
1198        return -1;
1199     }
1200
1201   if(!(from = lookup_id(from_id)))
1202     {
1203       syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) origin %s which does not exist in our connection list"),
1204              cl->name, cl->hostname, from_id);
1205       return -1;
1206     }
1207
1208   /* Check correctness of packet key */
1209
1210   keylength = strlen(pktkey);
1211
1212   if(keylength != from->cipher_pktkeylength*2)
1213     {
1214       syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s) origin %s: invalid key length"),
1215              cl->name, cl->hostname, from->name);
1216       return -1;
1217     }
1218
1219   /* Forward it if necessary */
1220
1221   if(strcmp(to_id, myself->name))
1222     {
1223       if(!(to = lookup_id(to_id)))
1224         {
1225           syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) destination %s which does not exist in our connection list"),
1226                  cl->name, cl->hostname, to_id);
1227           return -1;
1228         }
1229       send_ans_key(from, to, pktkey);
1230     }
1231
1232   /* Update our copy of the origin's packet key */
1233
1234   if(from->cipher_pktkey)
1235     free(from->cipher_pktkey);
1236
1237   from->cipher_pktkey = xstrdup(pktkey);
1238   keylength /= 2;
1239   hex2bin(from->cipher_pktkey, from->cipher_pktkey, keylength);
1240   from->cipher_pktkey[keylength] = '\0';
1241
1242   from->status.validkey = 1;
1243   from->status.waitingforkey = 0;
1244   
1245   flush_queue(from);
1246 cp
1247   return 0;
1248 }
1249
1250 int send_tcppacket(connection_t *cl, vpn_packet_t *packet)
1251 {
1252   int x;
1253 cp  
1254   /* Evil hack. */
1255
1256   x = send_request(cl->nexthop, "%d %hd", PACKET, packet->len);
1257
1258   if(x)
1259     return x;
1260 cp
1261   return send_meta(cl, packet->data, packet->len);
1262 }
1263
1264 int tcppacket_h(connection_t *cl)
1265 {
1266   short int len;
1267 cp  
1268   if(sscanf(cl->buffer, "%*d %hd", &len) != 1)
1269     {
1270       syslog(LOG_ERR, _("Got bad PACKET from %s (%s)"), cl->name, cl->hostname);
1271       return -1;
1272     }
1273
1274   /* Set reqlen to len, this will tell receive_meta() that a tcppacket is coming. */
1275
1276   cl->tcplen = len;
1277 cp
1278   return 0;
1279 }
1280
1281 /* Jumptable for the request handlers */
1282
1283 int (*request_handlers[])(connection_t*) = {
1284   id_h, metakey_h, challenge_h, chal_reply_h,
1285   status_h, error_h, termreq_h,
1286   ping_h, pong_h,
1287   add_host_h, del_host_h,
1288   add_subnet_h, del_subnet_h,
1289   key_changed_h, req_key_h, ans_key_h,
1290   tcppacket_h,
1291 };
1292
1293 /* Request names */
1294
1295 char (*request_name[]) = {
1296   "ID", "METAKEY", "CHALLENGE", "CHAL_REPLY",
1297   "STATUS", "ERROR", "TERMREQ",
1298   "PING", "PONG",
1299   "ADD_HOST", "DEL_HOST",
1300   "ADD_SUBNET", "DEL_SUBNET",
1301   "KEY_CHANGED", "REQ_KEY", "ANS_KEY",
1302   "PACKET",
1303 };
1304
1305 /* Status strings */
1306
1307 char (*status_text[]) = {
1308   "Warning",
1309 };
1310
1311 /* Error strings */
1312
1313 char (*error_text[]) = {
1314   "Error",
1315 };