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