Added explaination of our key exchange using RSA encryption.
[oweals/tinc.git] / 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.84 2001/03/02 11:25:56 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   /* The message we send must be smaller than the modulus of the RSA key.
525      By definition, for a key of k bits, the following formula holds:
526      
527        2^(k-1) <= modulus < 2^(k)
528      
529      Where ^ means "to the power of", not "xor".
530      This means that to be sure, we must choose our message < 2^(k-1).
531      This can be done by setting the most significant bit to zero.
532   */
533   
534   cl->cipher_outkey[0] &= 0x7F;
535   
536   if(debug_lvl >= DEBUG_SCARY_THINGS)
537     {
538       bin2hex(cl->cipher_outkey, buffer, len);
539       buffer[len*2] = '\0';
540       syslog(LOG_DEBUG, _("Generated random meta key (unencrypted): %s"), buffer);
541     }
542
543   /* Encrypt the random data
544   
545      We do not use one of the PKCS padding schemes here.
546      This is allowed, because we encrypt a totally random string
547      with a length equal to that of the modulus of the RSA key.
548   */
549   
550   if(RSA_public_encrypt(len, cl->cipher_outkey, buffer, cl->rsa_key, RSA_NO_PADDING) != len)
551     {
552       syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
553       free(buffer);
554       return -1;
555     }
556 cp
557   /* Convert the encrypted random data to a hexadecimal formatted string */
558
559   bin2hex(buffer, buffer, len);
560   buffer[len*2] = '\0';
561
562   /* Send the meta key */
563
564   x = send_request(cl, "%d %s", METAKEY, buffer);
565   free(buffer);
566
567   /* Further outgoing requests are encrypted with the key we just generated */
568
569   EVP_EncryptInit(cl->cipher_outctx, EVP_bf_cfb(),
570                   cl->cipher_outkey + len - EVP_bf_cfb()->key_len,
571                   cl->cipher_outkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
572
573   cl->status.encryptout = 1;
574 cp
575   return x;
576 }
577
578 int metakey_h(connection_t *cl)
579 {
580   char buffer[MAX_STRING_SIZE];
581   int len;
582 cp
583   if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
584     {
585        syslog(LOG_ERR, _("Got bad METAKEY from %s (%s)"), cl->name, cl->hostname);
586        return -1;
587     }
588
589   len = RSA_size(myself->rsa_key);
590
591   /* Check if the length of the meta key is all right */
592
593   if(strlen(buffer) != len*2)
594     {
595       syslog(LOG_ERR, _("Intruder: wrong meta key length from %s (%s)"), cl->name, cl->hostname);
596       return -1;
597     }
598
599   /* Allocate buffers for the meta key */
600
601   if(!cl->cipher_inkey)
602     cl->cipher_inkey = xmalloc(len);
603
604   if(!cl->cipher_inctx)
605     cl->cipher_inctx = xmalloc(sizeof(*cl->cipher_inctx));
606
607   /* Convert the challenge from hexadecimal back to binary */
608
609   hex2bin(buffer,buffer,len);
610
611   /* Decrypt the meta key */
612   
613   if(RSA_private_decrypt(len, buffer, cl->cipher_inkey, myself->rsa_key, RSA_NO_PADDING) != len)        /* See challenge() */
614     {
615       syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
616       return -1;
617     }
618
619   if(debug_lvl >= DEBUG_SCARY_THINGS)
620     {
621       bin2hex(cl->cipher_inkey, buffer, len);
622       buffer[len*2] = '\0';
623       syslog(LOG_DEBUG, _("Received random meta key (unencrypted): %s"), buffer);
624     }
625
626   /* All incoming requests will now be encrypted. */
627
628   EVP_DecryptInit(cl->cipher_inctx, EVP_bf_cfb(),
629                   cl->cipher_inkey + len - EVP_bf_cfb()->key_len,
630                   cl->cipher_inkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
631   
632   cl->status.decryptin = 1;
633
634   cl->allow_request = CHALLENGE;
635 cp
636   return send_challenge(cl);
637 }
638
639 /* Address and subnet information exchange */
640
641 int send_add_subnet(connection_t *cl, subnet_t *subnet)
642 {
643   int x;
644   char *netstr;
645   char *owner;
646 cp
647   if(cl->options & OPTION_INDIRECT)
648     owner = myself->name;
649   else
650     owner = subnet->owner->name;
651
652   x = send_request(cl, "%d %s %s", ADD_SUBNET,
653                       owner, netstr = net2str(subnet));
654   free(netstr);
655 cp
656   return x;
657 }
658
659 int add_subnet_h(connection_t *cl)
660 {
661   char subnetstr[MAX_STRING_SIZE];
662   char name[MAX_STRING_SIZE];
663   connection_t *owner, *p;
664   subnet_t *subnet;
665   avl_node_t *node;
666 cp
667   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
668     {
669       syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s)"), cl->name, cl->hostname);
670       return -1;
671     }
672
673   /* Check if owner name is a valid */
674
675   if(check_id(name))
676     {
677       syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
678       return -1;
679     }
680
681   /* Check if subnet string is valid */
682
683   if(!(subnet = str2net(subnetstr)))
684     {
685       syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
686       return -1;
687     }
688
689   /* Check if somebody tries to add a subnet of ourself */
690
691   if(!strcmp(name, myself->name))
692     {
693       syslog(LOG_ERR, _("Warning: got ADD_SUBNET from %s (%s) for ourself, restarting"),
694              cl->name, cl->hostname);
695       sighup = 1;
696       return 0;
697     }
698
699   /* Check if the owner of the new subnet is in the connection list */
700
701   if(!(owner = lookup_id(name)))
702     {
703       syslog(LOG_ERR, _("Got ADD_SUBNET for %s from %s (%s) which is not in our connection list"),
704              name, cl->name, cl->hostname);
705       return -1;
706     }
707
708   /* If everything is correct, add the subnet to the list of the owner */
709
710   subnet_add(owner, subnet);
711
712   /* Tell the rest */
713   
714   for(node = connection_tree->head; node; node = node->next)
715     {
716       p = (connection_t *)node->data;
717       if(p->status.meta && p->status.active && p!= cl)
718         send_add_subnet(p, subnet);
719     }
720 cp
721   return 0;
722 }
723
724 int send_del_subnet(connection_t *cl, subnet_t *subnet)
725 {
726   int x;
727   char *netstr;
728   char *owner;
729 cp
730   if(cl->options & OPTION_INDIRECT)
731     owner = myself->name;
732   else
733     owner = subnet->owner->name;
734
735   x = send_request(cl, "%d %s %s", DEL_SUBNET, owner, netstr = net2str(subnet));
736   free(netstr);
737 cp
738   return x;
739 }
740
741 int del_subnet_h(connection_t *cl)
742 {
743   char subnetstr[MAX_STRING_SIZE];
744   char name[MAX_STRING_SIZE];
745   connection_t *owner, *p;
746   subnet_t *subnet;
747   avl_node_t *node;
748 cp
749   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 3)
750     {
751       syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s)"), cl->name, cl->hostname);
752       return -1;
753     }
754
755   /* Check if owner name is a valid */
756
757   if(check_id(name))
758     {
759       syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
760       return -1;
761     }
762
763   /* Check if subnet string is valid */
764
765   if(!(subnet = str2net(subnetstr)))
766     {
767       syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
768       return -1;
769     }
770
771   free(subnetstr);
772   
773   /* Check if somebody tries to add a subnet of ourself */
774
775   if(!strcmp(name, myself->name))
776     {
777       syslog(LOG_ERR, _("Warning: got DEL_SUBNET from %s (%s) for ourself, restarting"),
778              cl->name, cl->hostname);
779       sighup = 1;
780       return 0;
781     }
782
783   /* Check if the owner of the new subnet is in the connection list */
784
785   if(!(owner = lookup_id(name)))
786     {
787       syslog(LOG_ERR, _("Got DEL_SUBNET for %s from %s (%s) which is not in our connection list"),
788              name, cl->name, cl->hostname);
789       return -1;
790     }
791
792   /* If everything is correct, delete the subnet from the list of the owner */
793
794   subnet_del(subnet);
795
796   /* Tell the rest */
797   
798   for(node = connection_tree->head; node; node = node->next)
799     {
800       p = (connection_t *)node->data;
801       if(p->status.meta && p->status.active && p!= cl)
802         send_del_subnet(p, subnet);
803     }
804 cp
805   return 0;
806 }
807
808 /* New and closed connections notification */
809
810 int send_add_host(connection_t *cl, connection_t *other)
811 {
812 cp
813   if(!(cl->options & OPTION_INDIRECT))
814     return send_request(cl, "%d %s %lx:%d %lx", ADD_HOST,
815                       other->name, other->address, other->port, other->options);
816   else
817     return 0;
818 }
819
820 int add_host_h(connection_t *cl)
821 {
822   connection_t *old, *new, *p;
823   char name[MAX_STRING_SIZE];
824   avl_node_t *node;
825 cp
826   new = new_connection();
827
828   if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%hd %lx", name, &new->address, &new->port, &new->options) != 4)
829     {
830        syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"), cl->name, cl->hostname);
831        return -1;
832     }
833
834   /* Check if identity is a valid name */
835
836   if(check_id(name))
837     {
838       syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
839       free_connection(new);
840       return -1;
841     }
842
843   /* Check if somebody tries to add ourself */
844
845   if(!strcmp(name, myself->name))
846     {
847       syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"), cl->name, cl->hostname);
848       sighup = 1;
849       free_connection(new);
850       return 0;
851     }
852     
853   /* Fill in more of the new connection structure */
854
855   new->hostname = hostlookup(htonl(new->address));
856
857   /* Check if the new host already exists in the connnection list */
858
859   if((old = lookup_id(name)))
860     {
861       if((new->address == old->address) && (new->port == old->port))
862         {
863           if(debug_lvl >= DEBUG_CONNECTIONS)
864             syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
865                    old->name, old->hostname, name, new->hostname);
866           free_connection(new);
867           return 0;
868         }
869       else
870         {
871           if(debug_lvl >= DEBUG_CONNECTIONS)
872             syslog(LOG_NOTICE, _("Removing old entry for %s (%s) in favour of new connection"),
873                    old->name, old->hostname);
874
875           terminate_connection(old);
876         }
877     }
878
879   /* Hook it up into the connection */
880
881   new->name = xstrdup(name);
882   connection_add(new);
883   id_add(new);
884
885   /* Tell the rest about the new host */
886
887   for(node = connection_tree->head; node; node = node->next)
888     {
889       p = (connection_t *)node->data;
890       if(p->status.meta && p->status.active && p!=cl)
891         send_add_host(p, new);
892     }
893
894   /* Fill in rest of connection structure */
895
896   new->nexthop = cl;
897   new->status.active = 1;
898   new->cipher_pkttype = EVP_bf_cbc();
899   new->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
900 cp
901   return 0;
902 }
903
904 int send_del_host(connection_t *cl, connection_t *other)
905 {
906 cp
907   if(!(cl->options & OPTION_INDIRECT))
908     return send_request(cl, "%d %s %lx:%d %lx", DEL_HOST,
909                       other->name, other->address, other->port, other->options);
910   else
911     return 0;
912 }
913
914 int del_host_h(connection_t *cl)
915 {
916   char name[MAX_STRING_SIZE];
917   ip_t address;
918   port_t port;
919   long int options;
920   connection_t *old, *p;
921   avl_node_t *node;
922 cp
923   if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%hd %lx", name, &address, &port, &options) != 4)
924     {
925       syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
926              cl->name, cl->hostname);
927       return -1;
928     }
929
930   /* Check if identity is a valid name */
931
932   if(check_id(name))
933     {
934       syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
935       return -1;
936     }
937
938   /* Check if somebody tries to delete ourself */
939
940   if(!strcmp(name, myself->name))
941     {
942       syslog(LOG_ERR, _("Warning: got DEL_HOST from %s (%s) for ourself, restarting"),
943              cl->name, cl->hostname);
944       sighup = 1;
945       return 0;
946     }
947
948   /* Check if the new host already exists in the connnection list */
949
950   if(!(old = lookup_id(name)))
951     {
952       syslog(LOG_ERR, _("Got DEL_HOST from %s (%s) for %s which is not in our connection list"),
953              name, cl->name, cl->hostname);
954       return -1;
955     }
956   
957   /* Check if the rest matches */
958   
959   if(address!=old->address || port!=old->port || options!=old->options || cl!=old->nexthop)
960     {
961       syslog(LOG_WARNING, _("Got DEL_HOST from %s (%s) for %s which doesn't match"), cl->name, cl->hostname, old->name);
962       return 0;
963     }
964
965   /* Ok, since EVERYTHING seems to check out all right, delete it */
966
967   old->status.active = 0;
968   terminate_connection(old);
969
970   /* Tell the rest about the new host */
971
972   for(node = connection_tree->head; node; node = node->next)
973     {
974       p = (connection_t *)node->data;
975       if(p->status.meta && p->status.active && p!=cl)
976         send_del_host(p, old);
977     }
978 cp
979   return 0;
980 }
981
982 /* Status and error notification routines */
983
984 int send_status(connection_t *cl, int statusno, char *statusstring)
985 {
986 cp
987   if(!statusstring)
988     statusstring = status_text[statusno];
989 cp
990   return send_request(cl, "%d %d %s", STATUS, statusno, statusstring);
991 }
992
993 int status_h(connection_t *cl)
994 {
995   int statusno;
996   char statusstring[MAX_STRING_SIZE];
997 cp
998   if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &statusno, statusstring) != 2)
999     {
1000        syslog(LOG_ERR, _("Got bad STATUS from %s (%s)"),
1001               cl->name, cl->hostname);
1002        return -1;
1003     }
1004
1005   if(debug_lvl >= DEBUG_STATUS)
1006     {
1007       syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"),
1008              cl->name, cl->hostname, status_text[statusno], statusstring);
1009     }
1010
1011 cp
1012   return 0;
1013 }
1014
1015 int send_error(connection_t *cl, int err, char *errstring)
1016 {
1017 cp
1018   if(!errstring)
1019     errstring = strerror(err);
1020   return send_request(cl, "%d %d %s", ERROR, err, errstring);
1021 }
1022
1023 int error_h(connection_t *cl)
1024 {
1025   int err;
1026   char errorstring[MAX_STRING_SIZE];
1027 cp
1028   if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &err, errorstring) != 2)
1029     {
1030        syslog(LOG_ERR, _("Got bad ERROR from %s (%s)"),
1031               cl->name, cl->hostname);
1032        return -1;
1033     }
1034
1035   if(debug_lvl >= DEBUG_ERROR)
1036     {
1037       syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"),
1038              cl->name, cl->hostname, strerror(err), errorstring);
1039     }
1040
1041   terminate_connection(cl);
1042 cp
1043   return 0;
1044 }
1045
1046 int send_termreq(connection_t *cl)
1047 {
1048 cp
1049   return send_request(cl, "%d", TERMREQ);
1050 }
1051
1052 int termreq_h(connection_t *cl)
1053 {
1054 cp
1055   terminate_connection(cl);
1056 cp
1057   return 0;
1058 }
1059
1060 int send_ping(connection_t *cl)
1061 {
1062 cp
1063   cl->status.pinged = 1;
1064   cl->last_ping_time = time(NULL);
1065 cp
1066   return send_request(cl, "%d", PING);
1067 }
1068
1069 int ping_h(connection_t *cl)
1070 {
1071 cp
1072   return send_pong(cl);
1073 }
1074
1075 int send_pong(connection_t *cl)
1076 {
1077 cp
1078   return send_request(cl, "%d", PONG);
1079 }
1080
1081 int pong_h(connection_t *cl)
1082 {
1083 cp
1084   cl->status.pinged = 0;
1085 cp
1086   return 0;
1087 }
1088
1089 /* Key exchange */
1090
1091 int send_key_changed(connection_t *from, connection_t *cl)
1092 {
1093   connection_t *p;
1094   avl_node_t *node;
1095 cp
1096   for(node = connection_tree->head; node; node = node->next)
1097     {
1098       p = (connection_t *)node->data;
1099       if(p != cl && p->status.meta && p->status.active)
1100         if(!(p->options & OPTION_INDIRECT) || from == myself)
1101           send_request(p, "%d %s", KEY_CHANGED, from->name);
1102     }
1103 cp
1104   return 0;
1105 }
1106
1107 int key_changed_h(connection_t *cl)
1108 {
1109   char from_id[MAX_STRING_SIZE];
1110   connection_t *from;
1111 cp
1112   if(sscanf(cl->buffer, "%*d "MAX_STRING, from_id) != 1)
1113     {
1114       syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
1115              cl->name, cl->hostname);
1116       return -1;
1117     }
1118
1119   if(!(from = lookup_id(from_id)))
1120     {
1121       syslog(LOG_ERR, _("Got KEY_CHANGED from %s (%s) origin %s which does not exist in our connection list"),
1122              cl->name, cl->hostname, from_id);
1123       return -1;
1124     }
1125
1126   from->status.validkey = 0;
1127   from->status.waitingforkey = 0;
1128
1129   send_key_changed(from, cl);
1130 cp
1131   return 0;
1132 }
1133
1134 int send_req_key(connection_t *from, connection_t *to)
1135 {
1136 cp
1137   return send_request(to->nexthop, "%d %s %s", REQ_KEY,
1138                       from->name, to->name);
1139 }
1140
1141 int req_key_h(connection_t *cl)
1142 {
1143   char from_id[MAX_STRING_SIZE];
1144   char to_id[MAX_STRING_SIZE];
1145   connection_t *from, *to;
1146   char pktkey[129];
1147 cp
1148   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, from_id, to_id) != 2)
1149     {
1150        syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
1151               cl->name, cl->hostname);
1152        return -1;
1153     }
1154
1155   if(!(from = lookup_id(from_id)))
1156     {
1157       syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) origin %s which does not exist in our connection list"),
1158              cl->name, cl->hostname, from_id);
1159       return -1;
1160     }
1161
1162   /* Check if this key request is for us */
1163
1164   if(!strcmp(to_id, myself->name))
1165     {
1166       bin2hex(myself->cipher_pktkey, pktkey, myself->cipher_pktkeylength);
1167       pktkey[myself->cipher_pktkeylength*2] = '\0';
1168       send_ans_key(myself, from, pktkey);
1169     }
1170   else
1171     {
1172       if(!(to = lookup_id(to_id)))
1173         {
1174           syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) destination %s which does not exist in our connection list"),
1175                  cl->name, cl->hostname, to_id);
1176           return -1;
1177         }
1178         
1179       if(to->status.validkey)   /* Proxy keys */
1180         {
1181           bin2hex(to->cipher_pktkey, pktkey, to->cipher_pktkeylength);
1182           pktkey[to->cipher_pktkeylength*2] = '\0';
1183           send_ans_key(to, from, pktkey);
1184         }
1185       else
1186         send_req_key(from, to);
1187     }
1188
1189 cp
1190   return 0;
1191 }
1192
1193 int send_ans_key(connection_t *from, connection_t *to, char *pktkey)
1194 {
1195 cp
1196   return send_request(to->nexthop, "%d %s %s %s", ANS_KEY,
1197                       from->name, to->name, pktkey);
1198 }
1199
1200 int ans_key_h(connection_t *cl)
1201 {
1202   char from_id[MAX_STRING_SIZE];
1203   char to_id[MAX_STRING_SIZE];
1204   char pktkey[MAX_STRING_SIZE];
1205   int keylength;
1206   connection_t *from, *to;
1207 cp
1208   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING, from_id, to_id, pktkey) != 3)
1209     {
1210        syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
1211               cl->name, cl->hostname);
1212        return -1;
1213     }
1214
1215   if(!(from = lookup_id(from_id)))
1216     {
1217       syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) origin %s which does not exist in our connection list"),
1218              cl->name, cl->hostname, from_id);
1219       return -1;
1220     }
1221
1222   /* Check correctness of packet key */
1223
1224   keylength = strlen(pktkey);
1225
1226   if(keylength != from->cipher_pktkeylength*2)
1227     {
1228       syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s) origin %s: invalid key length"),
1229              cl->name, cl->hostname, from->name);
1230       return -1;
1231     }
1232
1233   /* Forward it if necessary */
1234
1235   if(strcmp(to_id, myself->name))
1236     {
1237       if(!(to = lookup_id(to_id)))
1238         {
1239           syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) destination %s which does not exist in our connection list"),
1240                  cl->name, cl->hostname, to_id);
1241           return -1;
1242         }
1243       send_ans_key(from, to, pktkey);
1244     }
1245
1246   /* Update our copy of the origin's packet key */
1247
1248   if(from->cipher_pktkey)
1249     free(from->cipher_pktkey);
1250
1251   from->cipher_pktkey = xstrdup(pktkey);
1252   keylength /= 2;
1253   hex2bin(from->cipher_pktkey, from->cipher_pktkey, keylength);
1254   from->cipher_pktkey[keylength] = '\0';
1255
1256   from->status.validkey = 1;
1257   from->status.waitingforkey = 0;
1258   
1259   flush_queue(from);
1260 cp
1261   return 0;
1262 }
1263
1264 int send_tcppacket(connection_t *cl, vpn_packet_t *packet)
1265 {
1266   int x;
1267   
1268   x = send_request(cl->nexthop, "%d %hd", PACKET, packet->len);
1269
1270   if(x)
1271     return x;
1272   
1273   return send_meta(cl->nexthop, packet->data, packet->len);  
1274 }
1275
1276 int tcppacket_h(connection_t *cl)
1277 {
1278   vpn_packet_t packet;
1279   char *p;
1280   int todo, x;
1281   
1282   if(sscanf(cl->buffer, "%*d %hd", packet.len) != 1)
1283     {
1284       syslog(LOG_ERR, _("Got bad PACKET from %s (%s)"), cl->name, cl->hostname);
1285       return -1;
1286     }
1287
1288   /* Evil hack. */
1289
1290   p = packet.data;
1291   todo = packet.len;
1292   
1293   while(todo)
1294     {
1295       x = read(cl->meta_socket, p, todo);
1296
1297       if(x<=0)
1298         {
1299           if(x==0)
1300             syslog(LOG_NOTICE, _("Connection closed by %s (%s)"), cl->name, cl->hostname);
1301           else
1302             if(errno==EINTR)
1303               continue;
1304             else
1305               syslog(LOG_ERR, _("Error during reception of PACKET from %s (%s): %m"), cl->name, cl->hostname);
1306
1307           return -1;
1308         }
1309       
1310       todo -= x;
1311       p += x;
1312     }
1313
1314   return receive_packet(cl, &packet);
1315 }
1316
1317 /* Jumptable for the request handlers */
1318
1319 int (*request_handlers[])(connection_t*) = {
1320   id_h, metakey_h, challenge_h, chal_reply_h,
1321   status_h, error_h, termreq_h,
1322   ping_h, pong_h,
1323   add_host_h, del_host_h,
1324   add_subnet_h, del_subnet_h,
1325   key_changed_h, req_key_h, ans_key_h,
1326   tcppacket_h,
1327 };
1328
1329 /* Request names */
1330
1331 char (*request_name[]) = {
1332   "ID", "METAKEY", "CHALLENGE", "CHAL_REPLY",
1333   "STATUS", "ERROR", "TERMREQ",
1334   "PING", "PONG",
1335   "ADD_HOST", "DEL_HOST",
1336   "ADD_SUBNET", "DEL_SUBNET",
1337   "KEY_CHANGED", "REQ_KEY", "ANS_KEY",
1338   "PACKET",
1339 };
1340
1341 /* Status strings */
1342
1343 char (*status_text[]) = {
1344   "Warning",
1345 };
1346
1347 /* Error strings */
1348
1349 char (*error_text[]) = {
1350   "Error",
1351 };