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