- Make sure METAKEY is smaller than the modulus of the RSA key
[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.82 2001/02/26 11:37:20 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 send_challenge(connection_t *cl)
275 {
276   char *buffer;
277   int len, x;
278 cp
279   /* CHECKME: what is most reasonable value for len? */
280
281   len = RSA_size(cl->rsa_key);
282
283   /* Allocate buffers for the challenge */
284
285   buffer = xmalloc(len*2+1);
286
287   if(cl->hischallenge)
288     free(cl->hischallenge);
289     
290   cl->hischallenge = xmalloc(len);
291 cp
292   /* Copy random data to the buffer */
293
294   RAND_bytes(cl->hischallenge, len);
295
296 cp
297   /* Convert to hex */
298
299   bin2hex(cl->hischallenge, buffer, len);
300   buffer[len*2] = '\0';
301
302 cp
303   /* Send the challenge */
304
305   x = send_request(cl, "%d %s", CHALLENGE, buffer);
306   free(buffer);
307 cp
308   return x;
309 }
310
311 int challenge_h(connection_t *cl)
312 {
313   char buffer[MAX_STRING_SIZE];
314   int len;
315 cp
316   if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
317     {
318        syslog(LOG_ERR, _("Got bad CHALLENGE from %s (%s)"), cl->name, cl->hostname);
319        return -1;
320     }
321
322   len = RSA_size(myself->rsa_key);
323
324   /* Check if the length of the challenge is all right */
325
326   if(strlen(buffer) != len*2)
327     {
328       syslog(LOG_ERR, _("Intruder: wrong challenge length from %s (%s)"), cl->name, cl->hostname);
329       return -1;
330     }
331
332   /* Allocate buffers for the challenge */
333
334   if(!cl->mychallenge)
335     cl->mychallenge = xmalloc(len);
336
337   /* Convert the challenge from hexadecimal back to binary */
338
339   hex2bin(buffer,cl->mychallenge,len);
340
341   cl->allow_request = CHAL_REPLY;
342
343   /* Rest is done by send_chal_reply() */
344 cp
345   return send_chal_reply(cl);
346 }
347
348 int send_chal_reply(connection_t *cl)
349 {
350   char hash[SHA_DIGEST_LENGTH*2+1];
351 cp
352   if(!cl->mychallenge)
353     {
354       syslog(LOG_ERR, _("Trying to send CHAL_REPLY to %s (%s) without a valid CHALLENGE"), cl->name, cl->hostname);
355       return -1;
356     }
357      
358   /* Calculate the hash from the challenge we received */
359
360   SHA1(cl->mychallenge, RSA_size(myself->rsa_key), hash);
361
362   /* Convert the hash to a hexadecimal formatted string */
363
364   bin2hex(hash,hash,SHA_DIGEST_LENGTH);
365   hash[SHA_DIGEST_LENGTH*2] = '\0';
366
367   /* Send the reply */
368
369 cp
370   return send_request(cl, "%d %s", CHAL_REPLY, hash);
371 }
372
373 int chal_reply_h(connection_t *cl)
374 {
375   char hishash[MAX_STRING_SIZE];
376   char myhash[SHA_DIGEST_LENGTH];
377 cp
378   if(sscanf(cl->buffer, "%*d "MAX_STRING, hishash) != 1)
379     {
380        syslog(LOG_ERR, _("Got bad CHAL_REPLY from %s (%s)"), cl->name, cl->hostname);
381        return -1;
382     }
383
384   /* Check if the length of the hash is all right */
385
386   if(strlen(hishash) != SHA_DIGEST_LENGTH*2)
387     {
388       syslog(LOG_ERR, _("Intruder: wrong challenge reply length from %s (%s)"), cl->name, cl->hostname);
389       return -1;
390     }
391
392   /* Convert the hash to binary format */
393
394   hex2bin(hishash, hishash, SHA_DIGEST_LENGTH);
395
396   /* Calculate the hash from the challenge we sent */
397
398   SHA1(cl->hischallenge, RSA_size(cl->rsa_key), myhash);
399
400   /* Verify the incoming hash with the calculated hash */
401
402   if(memcmp(hishash, myhash, SHA_DIGEST_LENGTH))
403     {
404       syslog(LOG_ERR, _("Intruder: wrong challenge reply from %s (%s)"), cl->name, cl->hostname);
405       if(debug_lvl >= DEBUG_SCARY_THINGS)
406         {
407           bin2hex(myhash, hishash, SHA_DIGEST_LENGTH);
408           hishash[SHA_DIGEST_LENGTH*2] = '\0';
409           syslog(LOG_DEBUG, _("Expected challenge reply: %s"), hishash);
410         }
411       return -1;
412     }
413
414   /* Identity has now been positively verified.
415      ack_h() handles the rest from now on.
416    */
417 cp
418   return ack_h(cl);
419 }
420
421 int send_metakey(connection_t *cl)
422 {
423   char *buffer;
424   int len, x;
425 cp
426   len = RSA_size(cl->rsa_key);
427
428   /* Allocate buffers for the meta key */
429
430   buffer = xmalloc(len*2+1);
431
432   if(!cl->cipher_outkey)
433     cl->cipher_outkey = xmalloc(len);
434     
435   if(!cl->cipher_outctx)
436     cl->cipher_outctx = xmalloc(sizeof(*cl->cipher_outctx));
437 cp
438   /* Copy random data to the buffer */
439
440   RAND_bytes(cl->cipher_outkey, len);
441
442   cl->cipher_outkey[0] &= 0x0F; /* Make sure that the random data is smaller than the modulus of the RSA key */
443   
444   if(debug_lvl >= DEBUG_SCARY_THINGS)
445     {
446       bin2hex(cl->cipher_outkey, buffer, len);
447       buffer[len*2] = '\0';
448       syslog(LOG_DEBUG, _("Generated random meta key (unencrypted): %s"), buffer);
449     }
450
451   /* Encrypt the random data */
452   
453   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 */
454     {
455       syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
456       free(buffer);
457       return -1;
458     }
459 cp
460   /* Convert the encrypted random data to a hexadecimal formatted string */
461
462   bin2hex(buffer, buffer, len);
463   buffer[len*2] = '\0';
464
465   /* Send the meta key */
466
467   x = send_request(cl, "%d %s", METAKEY, buffer);
468   free(buffer);
469
470   /* Further outgoing requests are encrypted with the key we just generated */
471
472   EVP_EncryptInit(cl->cipher_outctx, EVP_bf_cfb(),
473                   cl->cipher_outkey + len - EVP_bf_cfb()->key_len,
474                   cl->cipher_outkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
475
476   cl->status.encryptout = 1;
477 cp
478   return x;
479 }
480
481 int metakey_h(connection_t *cl)
482 {
483   char buffer[MAX_STRING_SIZE];
484   int len;
485 cp
486   if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
487     {
488        syslog(LOG_ERR, _("Got bad METAKEY from %s (%s)"), cl->name, cl->hostname);
489        return -1;
490     }
491
492   len = RSA_size(myself->rsa_key);
493
494   /* Check if the length of the meta key is all right */
495
496   if(strlen(buffer) != len*2)
497     {
498       syslog(LOG_ERR, _("Intruder: wrong meta key length from %s (%s)"), cl->name, cl->hostname);
499       return -1;
500     }
501
502   /* Allocate buffers for the meta key */
503
504   if(!cl->cipher_inkey)
505     cl->cipher_inkey = xmalloc(len);
506
507   if(!cl->cipher_inctx)
508     cl->cipher_inctx = xmalloc(sizeof(*cl->cipher_inctx));
509
510   /* Convert the challenge from hexadecimal back to binary */
511
512   hex2bin(buffer,buffer,len);
513
514   /* Decrypt the meta key */
515   
516   if(RSA_private_decrypt(len, buffer, cl->cipher_inkey, myself->rsa_key, RSA_NO_PADDING) != len)        /* See challenge() */
517     {
518       syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
519       return -1;
520     }
521
522   if(debug_lvl >= DEBUG_SCARY_THINGS)
523     {
524       bin2hex(cl->cipher_inkey, buffer, len);
525       buffer[len*2] = '\0';
526       syslog(LOG_DEBUG, _("Received random meta key (unencrypted): %s"), buffer);
527     }
528
529   /* All incoming requests will now be encrypted. */
530
531   EVP_DecryptInit(cl->cipher_inctx, EVP_bf_cfb(),
532                   cl->cipher_inkey + len - EVP_bf_cfb()->key_len,
533                   cl->cipher_inkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
534   
535   cl->status.decryptin = 1;
536
537   cl->allow_request = CHALLENGE;
538 cp
539   return send_challenge(cl);
540 }
541
542 int ack_h(connection_t *cl)
543 {
544   config_t const *cfg;
545   connection_t *old, *p;
546   subnet_t *subnet;
547   avl_node_t *node, *node2;
548 cp
549   /* Okay, before we active the connection, we check if there is another entry
550      in the connection list with the same name. If so, it presumably is an
551      old connection that has timed out but we don't know it yet.
552    */
553
554   while((old = lookup_id(cl->name)))
555     {
556       if(debug_lvl >= DEBUG_CONNECTIONS)
557         syslog(LOG_NOTICE, _("Removing old entry for %s at %s in favour of new connection from %s"),
558         cl->name, old->hostname, cl->hostname);
559
560       terminate_connection(old);
561     }
562
563   /* Activate this connection */
564
565   cl->allow_request = ALL;
566   cl->status.active = 1;
567   cl->nexthop = cl;
568   cl->cipher_pkttype = EVP_bf_cbc();
569   cl->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
570
571   if(debug_lvl >= DEBUG_CONNECTIONS)
572     syslog(LOG_NOTICE, _("Connection with %s (%s) activated"), cl->name, cl->hostname);
573
574 cp
575   /* Check some options */
576   
577   if((cfg = get_config_val(cl->config, config_indirectdata)))
578     {
579       if(cfg->data.val == stupid_true)
580         cl->options |= OPTION_INDIRECT;
581     }
582
583   if((cfg = get_config_val(cl->config, config_tcponly)))
584     {
585       if(cfg->data.val == stupid_true)
586         cl->options |= OPTION_TCPONLY;
587     }
588
589   /* Send him our subnets */
590   
591   for(node = myself->subnet_tree->head; node; node = node->next)
592     {
593       subnet = (subnet_t *)node->data;
594       send_add_subnet(cl, subnet);
595     }
596   /* And send him all the hosts and their subnets we know... */
597   
598   for(node = connection_tree->head; node; node = node->next)
599     {
600       p = (connection_t *)node->data;
601       
602       if(p != cl && p->status.active)
603         {
604           /* Notify others of this connection */
605
606           if(p->status.meta)
607             send_add_host(p, cl);
608
609           /* Notify new connection of everything we know */
610
611           send_add_host(cl, p);
612
613           for(node2 = p->subnet_tree->head; node2; node2 = node2->next)
614             {
615               subnet = (subnet_t *)node2->data;
616               send_add_subnet(cl, subnet);
617             }
618         }
619     }  
620 cp
621   return 0;
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 }
802
803 int add_host_h(connection_t *cl)
804 {
805   connection_t *old, *new, *p;
806   char name[MAX_STRING_SIZE];
807   avl_node_t *node;
808 cp
809   new = new_connection();
810
811   if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%d %lx", name, &new->address, &new->port, &new->options) != 4)
812     {
813        syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"), cl->name, cl->hostname);
814        return -1;
815     }
816
817   /* Check if identity is a valid name */
818
819   if(check_id(name))
820     {
821       syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
822       free_connection(new);
823       return -1;
824     }
825
826   /* Check if somebody tries to add ourself */
827
828   if(!strcmp(name, myself->name))
829     {
830       syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"), cl->name, cl->hostname);
831       sighup = 1;
832       free_connection(new);
833       return 0;
834     }
835     
836   /* Fill in more of the new connection structure */
837
838   new->hostname = hostlookup(htonl(new->address));
839
840   /* Check if the new host already exists in the connnection list */
841
842   if((old = lookup_id(name)))
843     {
844       if((new->address == old->address) && (new->port == old->port))
845         {
846           if(debug_lvl >= DEBUG_CONNECTIONS)
847             syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
848                    old->name, old->hostname, name, new->hostname);
849           free_connection(new);
850           return 0;
851         }
852       else
853         {
854           if(debug_lvl >= DEBUG_CONNECTIONS)
855             syslog(LOG_NOTICE, _("Removing old entry for %s (%s) in favour of new connection"),
856                    old->name, old->hostname);
857
858           terminate_connection(old);
859         }
860     }
861
862   /* Hook it up into the connection */
863
864   new->name = xstrdup(name);
865   connection_add(new);
866   id_add(new);
867
868   /* Tell the rest about the new host */
869
870   for(node = connection_tree->head; node; node = node->next)
871     {
872       p = (connection_t *)node->data;
873       if(p->status.meta && p->status.active && p!=cl)
874         send_add_host(p, new);
875     }
876
877   /* Fill in rest of connection structure */
878
879   new->nexthop = cl;
880   new->status.active = 1;
881   new->cipher_pkttype = EVP_bf_cbc();
882   new->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
883 cp
884   return 0;
885 }
886
887 int send_del_host(connection_t *cl, connection_t *other)
888 {
889 cp
890   if(!(cl->options & OPTION_INDIRECT))
891     return send_request(cl, "%d %s %lx:%d %lx", DEL_HOST,
892                       other->name, other->address, other->port, other->options);
893 }
894
895 int del_host_h(connection_t *cl)
896 {
897   char name[MAX_STRING_SIZE];
898   ip_t address;
899   port_t port;
900   long int options;
901   connection_t *old, *p;
902   avl_node_t *node;
903 cp
904   if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%d %lx", name, &address, &port, &options) != 4)
905     {
906       syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
907              cl->name, cl->hostname);
908       return -1;
909     }
910
911   /* Check if identity is a valid name */
912
913   if(check_id(name))
914     {
915       syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
916       return -1;
917     }
918
919   /* Check if somebody tries to delete ourself */
920
921   if(!strcmp(name, myself->name))
922     {
923       syslog(LOG_ERR, _("Warning: got DEL_HOST from %s (%s) for ourself, restarting"),
924              cl->name, cl->hostname);
925       sighup = 1;
926       return 0;
927     }
928
929   /* Check if the new host already exists in the connnection list */
930
931   if(!(old = lookup_id(name)))
932     {
933       syslog(LOG_ERR, _("Got DEL_HOST from %s (%s) for %s which is not in our connection list"),
934              name, cl->name, cl->hostname);
935       return -1;
936     }
937   
938   /* Check if the rest matches */
939   
940   if(address!=old->address || port!=old->port || options!=old->options || cl!=old->nexthop)
941     {
942       syslog(LOG_WARNING, _("Got DEL_HOST from %s (%s) for %s which doesn't match"), cl->name, cl->hostname, old->name);
943       return 0;
944     }
945
946   /* Ok, since EVERYTHING seems to check out all right, delete it */
947
948   old->status.active = 0;
949   terminate_connection(old);
950
951   /* Tell the rest about the new host */
952
953   for(node = connection_tree->head; node; node = node->next)
954     {
955       p = (connection_t *)node->data;
956       if(p->status.meta && p->status.active && p!=cl)
957         send_del_host(p, old);
958     }
959 cp
960   return 0;
961 }
962
963 /* Status and error notification routines */
964
965 int send_status(connection_t *cl, int statusno, char *statusstring)
966 {
967 cp
968   if(!statusstring)
969     statusstring = status_text[statusno];
970 cp
971   return send_request(cl, "%d %d %s", STATUS, statusno, statusstring);
972 }
973
974 int status_h(connection_t *cl)
975 {
976   int statusno;
977   char statusstring[MAX_STRING_SIZE];
978 cp
979   if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &statusno, statusstring) != 2)
980     {
981        syslog(LOG_ERR, _("Got bad STATUS from %s (%s)"),
982               cl->name, cl->hostname);
983        return -1;
984     }
985
986   if(debug_lvl >= DEBUG_STATUS)
987     {
988       syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"),
989              cl->name, cl->hostname, status_text[statusno], statusstring);
990     }
991
992 cp
993   return 0;
994 }
995
996 int send_error(connection_t *cl, int err, char *errstring)
997 {
998 cp
999   if(!errstring)
1000     errstring = strerror(err);
1001   return send_request(cl, "%d %d %s", ERROR, err, errstring);
1002 }
1003
1004 int error_h(connection_t *cl)
1005 {
1006   int err;
1007   char errorstring[MAX_STRING_SIZE];
1008 cp
1009   if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &err, errorstring) != 2)
1010     {
1011        syslog(LOG_ERR, _("Got bad ERROR from %s (%s)"),
1012               cl->name, cl->hostname);
1013        return -1;
1014     }
1015
1016   if(debug_lvl >= DEBUG_ERROR)
1017     {
1018       syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"),
1019              cl->name, cl->hostname, strerror(err), errorstring);
1020     }
1021
1022   terminate_connection(cl);
1023 cp
1024   return 0;
1025 }
1026
1027 int send_termreq(connection_t *cl)
1028 {
1029 cp
1030   return send_request(cl, "%d", TERMREQ);
1031 }
1032
1033 int termreq_h(connection_t *cl)
1034 {
1035 cp
1036   terminate_connection(cl);
1037 cp
1038   return 0;
1039 }
1040
1041 int send_ping(connection_t *cl)
1042 {
1043 cp
1044   cl->status.pinged = 1;
1045   cl->last_ping_time = time(NULL);
1046 cp
1047   return send_request(cl, "%d", PING);
1048 }
1049
1050 int ping_h(connection_t *cl)
1051 {
1052 cp
1053   return send_pong(cl);
1054 }
1055
1056 int send_pong(connection_t *cl)
1057 {
1058 cp
1059   return send_request(cl, "%d", PONG);
1060 }
1061
1062 int pong_h(connection_t *cl)
1063 {
1064 cp
1065   cl->status.pinged = 0;
1066 cp
1067   return 0;
1068 }
1069
1070 /* Key exchange */
1071
1072 int send_key_changed(connection_t *from, connection_t *cl)
1073 {
1074   connection_t *p;
1075   avl_node_t *node;
1076 cp
1077   for(node = connection_tree->head; node; node = node->next)
1078     {
1079       p = (connection_t *)node->data;
1080       if(p != cl && p->status.meta && p->status.active)
1081         if(!(p->options & OPTION_INDIRECT) || from == myself)
1082           send_request(p, "%d %s", KEY_CHANGED, from->name);
1083     }
1084 cp
1085   return 0;
1086 }
1087
1088 int key_changed_h(connection_t *cl)
1089 {
1090   char from_id[MAX_STRING_SIZE];
1091   connection_t *from;
1092 cp
1093   if(sscanf(cl->buffer, "%*d "MAX_STRING, from_id) != 1)
1094     {
1095       syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
1096              cl->name, cl->hostname);
1097       return -1;
1098     }
1099
1100   if(!(from = lookup_id(from_id)))
1101     {
1102       syslog(LOG_ERR, _("Got KEY_CHANGED from %s (%s) origin %s which does not exist in our connection list"),
1103              cl->name, cl->hostname, from_id);
1104       return -1;
1105     }
1106
1107   from->status.validkey = 0;
1108   from->status.waitingforkey = 0;
1109
1110   send_key_changed(from, cl);
1111 cp
1112   return 0;
1113 }
1114
1115 int send_req_key(connection_t *from, connection_t *to)
1116 {
1117 cp
1118   return send_request(to->nexthop, "%d %s %s", REQ_KEY,
1119                       from->name, to->name);
1120 }
1121
1122 int req_key_h(connection_t *cl)
1123 {
1124   char from_id[MAX_STRING_SIZE];
1125   char to_id[MAX_STRING_SIZE];
1126   connection_t *from, *to;
1127   char pktkey[129];
1128 cp
1129   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, from_id, to_id) != 2)
1130     {
1131        syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
1132               cl->name, cl->hostname);
1133        return -1;
1134     }
1135
1136   if(!(from = lookup_id(from_id)))
1137     {
1138       syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) origin %s which does not exist in our connection list"),
1139              cl->name, cl->hostname, from_id);
1140       return -1;
1141     }
1142
1143   /* Check if this key request is for us */
1144
1145   if(!strcmp(to_id, myself->name))
1146     {
1147       bin2hex(myself->cipher_pktkey, pktkey, myself->cipher_pktkeylength);
1148       pktkey[myself->cipher_pktkeylength*2] = '\0';
1149       send_ans_key(myself, from, pktkey);
1150     }
1151   else
1152     {
1153       if(!(to = lookup_id(to_id)))
1154         {
1155           syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) destination %s which does not exist in our connection list"),
1156                  cl->name, cl->hostname, to_id);
1157           return -1;
1158         }
1159         
1160       if(to->status.validkey)   /* Proxy keys */
1161         {
1162           bin2hex(to->cipher_pktkey, pktkey, to->cipher_pktkeylength);
1163           pktkey[to->cipher_pktkeylength*2] = '\0';
1164           send_ans_key(to, from, pktkey);
1165         }
1166       else
1167         send_req_key(from, to);
1168     }
1169
1170 cp
1171   return 0;
1172 }
1173
1174 int send_ans_key(connection_t *from, connection_t *to, char *pktkey)
1175 {
1176 cp
1177   return send_request(to->nexthop, "%d %s %s %s", ANS_KEY,
1178                       from->name, to->name, pktkey);
1179 }
1180
1181 int ans_key_h(connection_t *cl)
1182 {
1183   char from_id[MAX_STRING_SIZE];
1184   char to_id[MAX_STRING_SIZE];
1185   char pktkey[MAX_STRING_SIZE];
1186   int keylength;
1187   connection_t *from, *to;
1188 cp
1189   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING, from_id, to_id, pktkey) != 3)
1190     {
1191        syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
1192               cl->name, cl->hostname);
1193        return -1;
1194     }
1195
1196   if(!(from = lookup_id(from_id)))
1197     {
1198       syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) origin %s which does not exist in our connection list"),
1199              cl->name, cl->hostname, from_id);
1200       return -1;
1201     }
1202
1203   /* Check correctness of packet key */
1204
1205   keylength = strlen(pktkey);
1206
1207   if(keylength != from->cipher_pktkeylength*2)
1208     {
1209       syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s) origin %s: invalid key length"),
1210              cl->name, cl->hostname, from->name);
1211       return -1;
1212     }
1213
1214   /* Forward it if necessary */
1215
1216   if(strcmp(to_id, myself->name))
1217     {
1218       if(!(to = lookup_id(to_id)))
1219         {
1220           syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) destination %s which does not exist in our connection list"),
1221                  cl->name, cl->hostname, to_id);
1222           return -1;
1223         }
1224       send_ans_key(from, to, pktkey);
1225     }
1226
1227   /* Update our copy of the origin's packet key */
1228
1229   if(from->cipher_pktkey)
1230     free(from->cipher_pktkey);
1231
1232   from->cipher_pktkey = xstrdup(pktkey);
1233   keylength /= 2;
1234   hex2bin(from->cipher_pktkey, from->cipher_pktkey, keylength);
1235   from->cipher_pktkey[keylength] = '\0';
1236
1237   from->status.validkey = 1;
1238   from->status.waitingforkey = 0;
1239   
1240   flush_queue(from);
1241 cp
1242   return 0;
1243 }
1244
1245 int send_tcppacket(connection_t *cl, vpn_packet_t *packet)
1246 {
1247   int x;
1248   
1249   x = send_request(cl->nexthop, "%d %hd", PACKET, packet->len);
1250
1251   if(x)
1252     return x;
1253   
1254   return send_meta(cl->nexthop, packet->data, packet->len);  
1255 }
1256
1257 int tcppacket_h(connection_t *cl)
1258 {
1259   vpn_packet_t packet;
1260   char *p;
1261   int todo, x;
1262   
1263   if(sscanf(cl->buffer, "%*d %hd", packet.len) != 1)
1264     {
1265       syslog(LOG_ERR, _("Got bad PACKET from %s (%s)"), cl->name, cl->hostname);
1266       return -1;
1267     }
1268
1269   /* Evil hack. */
1270
1271   p = packet.data;
1272   todo = packet.len;
1273   
1274   while(todo)
1275     {
1276       x = read(cl->meta_socket, p, todo);
1277
1278       if(x<=0)
1279         {
1280           if(x==0)
1281             syslog(LOG_NOTICE, _("Connection closed by %s (%s)"), cl->name, cl->hostname);
1282           else
1283             if(errno==EINTR)
1284               continue;
1285             else
1286               syslog(LOG_ERR, _("Error during reception of PACKET from %s (%s): %m"), cl->name, cl->hostname);
1287
1288           return -1;
1289         }
1290       
1291       todo -= x;
1292       p += x;
1293     }
1294
1295   return receive_packet(cl, &packet);
1296 }
1297
1298 /* Jumptable for the request handlers */
1299
1300 int (*request_handlers[])(connection_t*) = {
1301   id_h, metakey_h, challenge_h, chal_reply_h,
1302   status_h, error_h, termreq_h,
1303   ping_h, pong_h,
1304   add_host_h, del_host_h,
1305   add_subnet_h, del_subnet_h,
1306   key_changed_h, req_key_h, ans_key_h,
1307   tcppacket_h,
1308 };
1309
1310 /* Request names */
1311
1312 char (*request_name[]) = {
1313   "ID", "METAKEY", "CHALLENGE", "CHAL_REPLY",
1314   "STATUS", "ERROR", "TERMREQ",
1315   "PING", "PONG",
1316   "ADD_HOST", "DEL_HOST",
1317   "ADD_SUBNET", "DEL_SUBNET",
1318   "KEY_CHANGED", "REQ_KEY", "ANS_KEY",
1319   "PACKET",
1320 };
1321
1322 /* Status strings */
1323
1324 char (*status_text[]) = {
1325   "Warning",
1326 };
1327
1328 /* Error strings */
1329
1330 char (*error_text[]) = {
1331   "Error",
1332 };