8a3d1c3831b8464623a1bfbc8605b69990522084
[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.69 2000/12/05 08:59:30 zarq 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((cfg = get_config_val(cl->config, config_publickey)))
259     {
260       cl->rsa_key = RSA_new();
261       if(read_rsa_public_key(&(cl->rsa_key), cfg->data.ptr) < 0)
262         return -1;
263     }
264   else
265     {
266       syslog(LOG_ERR, _("No public key known for %s (%s)"), cl->name, cl->hostname);
267       return -1;
268     }
269 cp
270   return send_challenge(cl);
271 }
272
273 int send_challenge(connection_t *cl)
274 {
275   char *buffer;
276   int len, x;
277 cp
278   len = RSA_size(cl->rsa_key);
279
280   /* Allocate buffers for the challenge */
281
282   buffer = xmalloc(len*2+1);
283
284   if(cl->hischallenge)
285     free(cl->hischallenge);
286     
287   cl->hischallenge = xmalloc(len);
288 cp
289   /* Copy random data to the buffer */
290
291   RAND_bytes(cl->hischallenge, len);
292
293   cl->hischallenge[0] &= 0x7F;  /* Somehow if the first byte is more than 0xD0 or something like that, decryption fails... */
294
295   if(debug_lvl >= DEBUG_SCARY_THINGS)
296     {
297       bin2hex(cl->hischallenge, buffer, len);
298       buffer[len*2] = '\0';
299       syslog(LOG_DEBUG, _("Generated random challenge (unencrypted): %s"), buffer);
300     }
301
302   /* Encrypt the random data */
303   
304   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 */
305     {
306       syslog(LOG_ERR, _("Error during encryption of challenge for %s (%s)"), cl->name, cl->hostname);
307       free(buffer);
308       return -1;
309     }
310 cp
311   /* Convert the encrypted random data to a hexadecimal formatted string */
312
313   bin2hex(buffer, buffer, len);
314   buffer[len*2] = '\0';
315
316   /* Send the challenge */
317
318   cl->allow_request = CHAL_REPLY;
319   x = send_request(cl, "%d %s", CHALLENGE, buffer);
320   free(buffer);
321 cp
322   return x;
323 }
324
325 int challenge_h(connection_t *cl)
326 {
327   char buffer[MAX_STRING_SIZE];
328   int len;
329 cp
330   if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
331     {
332        syslog(LOG_ERR, _("Got bad CHALLENGE from %s (%s)"), cl->name, cl->hostname);
333        return -1;
334     }
335
336   len = RSA_size(myself->rsa_key);
337
338   /* Check if the length of the challenge is all right */
339
340   if(strlen(buffer) != len*2)
341     {
342       syslog(LOG_ERR, _("Intruder: wrong challenge length from %s (%s)"), cl->name, cl->hostname);
343       return -1;
344     }
345
346   /* Allocate buffers for the challenge */
347
348   if(!cl->mychallenge)
349     cl->mychallenge = xmalloc(len);
350
351   /* Convert the challenge from hexadecimal back to binary */
352
353   hex2bin(buffer,buffer,len);
354
355   /* Decrypt the challenge */
356   
357   if(RSA_private_decrypt(len, buffer, cl->mychallenge, myself->rsa_key, RSA_NO_PADDING) != len) /* See challenge() */
358     {
359       syslog(LOG_ERR, _("Error during encryption of challenge for %s (%s)"), cl->name, cl->hostname);
360       return -1;
361     }
362
363   if(debug_lvl >= DEBUG_SCARY_THINGS)
364     {
365       bin2hex(cl->mychallenge, buffer, len);
366       buffer[len*2] = '\0';
367       syslog(LOG_DEBUG, _("Received random challenge (unencrypted): %s"), buffer);
368     }
369
370   /* Rest is done by send_chal_reply() */
371 cp
372   return send_chal_reply(cl);
373 }
374
375 int send_chal_reply(connection_t *cl)
376 {
377   char hash[SHA_DIGEST_LENGTH*2+1];
378 cp
379   if(!cl->mychallenge)
380     {
381       syslog(LOG_ERR, _("Trying to send CHAL_REPLY to %s (%s) without a valid CHALLENGE"), cl->name, cl->hostname);
382       return -1;
383     }
384      
385   /* Calculate the hash from the challenge we received */
386
387   SHA1(cl->mychallenge, RSA_size(myself->rsa_key), hash);
388
389   /* Convert the hash to a hexadecimal formatted string */
390
391   bin2hex(hash,hash,SHA_DIGEST_LENGTH);
392   hash[SHA_DIGEST_LENGTH*2] = '\0';
393
394   /* Send the reply */
395
396   if(cl->status.outgoing)
397     cl->allow_request = ID;
398   else
399     cl->allow_request = METAKEY;
400
401 cp
402   return send_request(cl, "%d %s", CHAL_REPLY, hash);
403 }
404
405 int chal_reply_h(connection_t *cl)
406 {
407   char hishash[MAX_STRING_SIZE];
408   char myhash[SHA_DIGEST_LENGTH];
409 cp
410   if(sscanf(cl->buffer, "%*d "MAX_STRING, hishash) != 1)
411     {
412        syslog(LOG_ERR, _("Got bad CHAL_REPLY from %s (%s)"), cl->name, cl->hostname);
413        return -1;
414     }
415
416   /* Check if the length of the hash is all right */
417
418   if(strlen(hishash) != SHA_DIGEST_LENGTH*2)
419     {
420       syslog(LOG_ERR, _("Intruder: wrong challenge reply length from %s (%s)"), cl->name, cl->hostname);
421       return -1;
422     }
423
424   /* Convert the hash to binary format */
425
426   hex2bin(hishash, hishash, SHA_DIGEST_LENGTH);
427
428   /* Calculate the hash from the challenge we sent */
429
430   SHA1(cl->hischallenge, RSA_size(cl->rsa_key), myhash);
431
432   /* Verify the incoming hash with the calculated hash */
433
434   if(memcmp(hishash, myhash, SHA_DIGEST_LENGTH))
435     {
436       syslog(LOG_ERR, _("Intruder: wrong challenge reply from %s (%s)"), cl->name, cl->hostname);
437       if(debug_lvl >= DEBUG_SCARY_THINGS)
438         {
439           bin2hex(myhash, hishash, SHA_DIGEST_LENGTH);
440           hishash[SHA_DIGEST_LENGTH*2] = '\0';
441           syslog(LOG_DEBUG, _("Expected challenge reply: %s"), hishash);
442         }
443       return -1;
444     }
445
446
447   /* Identity has now been positively verified.
448      If we are accepting this new connection, then send our identity,
449      if we are making this connecting, acknowledge.
450    */
451 cp
452   if(cl->status.outgoing)
453       return send_metakey(cl);
454   else
455       return send_id(cl);
456 }
457
458 int send_metakey(connection_t *cl)
459 {
460   char *buffer;
461   int len, x;
462 cp
463   len = RSA_size(cl->rsa_key);
464
465   /* Allocate buffers for the meta key */
466
467   buffer = xmalloc(len*2+1);
468
469   if(!cl->cipher_outkey)
470     cl->cipher_outkey = xmalloc(len);
471     
472   if(!cl->cipher_outctx)
473     cl->cipher_outctx = xmalloc(sizeof(*cl->cipher_outctx));
474 cp
475   /* Copy random data to the buffer */
476
477   RAND_bytes(cl->cipher_outkey, len);
478
479   cl->cipher_outkey[0] &= 0x7F; /* FIXME: Somehow if the first byte is more than 0xD0 or something like that, decryption fails... */
480
481   if(debug_lvl >= DEBUG_SCARY_THINGS)
482     {
483       bin2hex(cl->cipher_outkey, buffer, len);
484       buffer[len*2] = '\0';
485       syslog(LOG_DEBUG, _("Generated random meta key (unencrypted): %s"), buffer);
486     }
487
488   /* Encrypt the random data */
489   
490   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 */
491     {
492       syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
493       free(buffer);
494       return -1;
495     }
496 cp
497   /* Convert the encrypted random data to a hexadecimal formatted string */
498
499   bin2hex(buffer, buffer, len);
500   buffer[len*2] = '\0';
501
502   /* Send the meta key */
503
504   if(cl->status.outgoing)
505     cl->allow_request = METAKEY;
506   else
507     cl->allow_request = ACK;
508     
509   x = send_request(cl, "%d %s", METAKEY, buffer);
510   free(buffer);
511
512   EVP_EncryptInit(cl->cipher_outctx, EVP_bf_cfb(), cl->cipher_outkey, cl->cipher_outkey + EVP_bf_cfb()->key_len);
513 cp
514   return x;
515 }
516
517 int metakey_h(connection_t *cl)
518 {
519   char buffer[MAX_STRING_SIZE];
520   int len;
521 cp
522   if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
523     {
524        syslog(LOG_ERR, _("Got bad METAKEY from %s (%s)"), cl->name, cl->hostname);
525        return -1;
526     }
527
528   len = RSA_size(myself->rsa_key);
529
530   /* Check if the length of the meta key is all right */
531
532   if(strlen(buffer) != len*2)
533     {
534       syslog(LOG_ERR, _("Intruder: wrong meta key length from %s (%s)"), cl->name, cl->hostname);
535       return -1;
536     }
537
538   /* Allocate buffers for the meta key */
539
540   if(!cl->cipher_inkey)
541     cl->cipher_inkey = xmalloc(len);
542
543   if(!cl->cipher_inctx)
544     cl->cipher_inctx = xmalloc(sizeof(*cl->cipher_inctx));
545
546   /* Convert the challenge from hexadecimal back to binary */
547
548   hex2bin(buffer,buffer,len);
549
550   /* Decrypt the meta key */
551   
552   if(RSA_private_decrypt(len, buffer, cl->cipher_inkey, myself->rsa_key, RSA_NO_PADDING) != len)        /* See challenge() */
553     {
554       syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
555       return -1;
556     }
557
558   if(debug_lvl >= DEBUG_SCARY_THINGS)
559     {
560       bin2hex(cl->cipher_inkey, buffer, len);
561       buffer[len*2] = '\0';
562       syslog(LOG_DEBUG, _("Received random meta key (unencrypted): %s"), buffer);
563     }
564
565   EVP_DecryptInit(cl->cipher_inctx, EVP_bf_cfb(), cl->cipher_inkey, cl->cipher_inkey + EVP_bf_cfb()->key_len);
566   
567 cp
568   if(cl->status.outgoing)
569     return send_ack(cl);
570   else
571     return send_metakey(cl);
572 }
573
574 int send_ack(connection_t *cl)
575 {
576   int x;
577 cp
578   if(cl->status.outgoing)
579     cl->allow_request = ACK;
580
581   x = send_request(cl, "%d", ACK);
582   cl->status.encryptout = 1;
583 cp
584   return x;
585 }
586
587 int ack_h(connection_t *cl)
588 {
589   connection_t *old, *p;
590   subnet_t *subnet;
591   rbl_t *rbl, *rbl2;
592 cp
593   /* Okay, before we active the connection, we check if there is another entry
594      in the connection list with the same name. If so, it presumably is an
595      old connection that has timed out but we don't know it yet.
596    */
597
598   while((old = lookup_id(cl->name)))
599     {
600       if(debug_lvl >= DEBUG_CONNECTIONS)
601         syslog(LOG_NOTICE, _("Removing old entry for %s at %s in favour of new connection from %s"),
602         cl->name, old->hostname, cl->hostname);
603
604       terminate_connection(old);
605     }
606
607   /* Activate this connection */
608
609   cl->allow_request = ALL;
610   cl->status.active = 1;
611   cl->status.decryptin = 1;
612   cl->nexthop = cl;
613   cl->cipher_pkttype = EVP_bf_cfb();
614   cl->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
615
616   if(debug_lvl >= DEBUG_CONNECTIONS)
617     syslog(LOG_NOTICE, _("Connection with %s (%s) activated"), cl->name, cl->hostname);
618
619 cp
620   if(!cl->status.outgoing)
621     send_ack(cl);
622
623   /* Send him our subnets */
624   
625   RBL_FOREACH(myself->subnet_tree, rbl)
626     {
627       subnet = (subnet_t *)rbl->data;
628       send_add_subnet(cl, subnet);
629     }
630   /* And send him all the hosts and their subnets we know... */
631   
632   RBL_FOREACH(connection_tree, rbl)
633     {
634       p = (connection_t *)rbl->data;
635       
636       if(p != cl && p->status.active)
637         {
638           /* Notify others of this connection */
639
640           if(p->status.meta)
641             send_add_host(p, cl);
642
643           /* Notify new connection of everything we know */
644
645           send_add_host(cl, p);
646
647           RBL_FOREACH(p->subnet_tree, rbl2)
648             {
649               subnet = (subnet_t *)rbl2->data;
650               send_add_subnet(cl, subnet);
651             }
652         }
653     }  
654 cp
655   return 0;
656 }
657
658 /* Address and subnet information exchange */
659
660 int send_add_subnet(connection_t *cl, subnet_t *subnet)
661 {
662   int x;
663   char *netstr;
664 cp
665   x = send_request(cl, "%d %s %s", ADD_SUBNET,
666                       subnet->owner->name, netstr = net2str(subnet));
667   free(netstr);
668 cp
669   return x;
670 }
671
672 int add_subnet_h(connection_t *cl)
673 {
674   char subnetstr[MAX_STRING_SIZE];
675   char name[MAX_STRING_SIZE];
676   connection_t *owner, *p;
677   subnet_t *subnet;
678   rbl_t *rbl;
679 cp
680   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
681     {
682       syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s)"), cl->name, cl->hostname);
683       return -1;
684     }
685
686   /* Check if owner name is a valid */
687
688   if(check_id(name))
689     {
690       syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
691       return -1;
692     }
693
694   /* Check if subnet string is valid */
695
696   if(!(subnet = str2net(subnetstr)))
697     {
698       syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
699       return -1;
700     }
701
702   /* Check if somebody tries to add a subnet of ourself */
703
704   if(!strcmp(name, myself->name))
705     {
706       syslog(LOG_ERR, _("Warning: got ADD_SUBNET from %s (%s) for ourself, restarting"),
707              cl->name, cl->hostname);
708       sighup = 1;
709       return 0;
710     }
711
712   /* Check if the owner of the new subnet is in the connection list */
713
714   if(!(owner = lookup_id(name)))
715     {
716       syslog(LOG_ERR, _("Got ADD_SUBNET for %s from %s (%s) which is not in our connection list"),
717              name, cl->name, cl->hostname);
718       return -1;
719     }
720
721   /* If everything is correct, add the subnet to the list of the owner */
722
723   subnet_add(owner, subnet);
724
725   /* Tell the rest */
726   
727   RBL_FOREACH(connection_tree, rbl)
728     {
729       p = (connection_t *)rbl->data;
730       if(p->status.meta && p->status.active && p!= cl)
731         send_add_subnet(p, subnet);
732     }
733 cp
734   return 0;
735 }
736
737 int send_del_subnet(connection_t *cl, subnet_t *subnet)
738 {
739   int x;
740   char *netstr;
741 cp
742   netstr = net2str(subnet);
743   x = send_request(cl, "%d %s %s", DEL_SUBNET, subnet->owner->name, netstr);
744   free(netstr);
745 cp
746   return x;
747 }
748
749 int del_subnet_h(connection_t *cl)
750 {
751   char subnetstr[MAX_STRING_SIZE];
752   char name[MAX_STRING_SIZE];
753   connection_t *owner, *p;
754   subnet_t *subnet;
755   rbl_t *rbl;
756 cp
757   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 3)
758     {
759       syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s)"), cl->name, cl->hostname);
760       return -1;
761     }
762
763   /* Check if owner name is a valid */
764
765   if(check_id(name))
766     {
767       syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
768       return -1;
769     }
770
771   /* Check if subnet string is valid */
772
773   if(!(subnet = str2net(subnetstr)))
774     {
775       syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
776       return -1;
777     }
778
779   free(subnetstr);
780   
781   /* Check if somebody tries to add a subnet of ourself */
782
783   if(!strcmp(name, myself->name))
784     {
785       syslog(LOG_ERR, _("Warning: got DEL_SUBNET from %s (%s) for ourself, restarting"),
786              cl->name, cl->hostname);
787       sighup = 1;
788       return 0;
789     }
790
791   /* Check if the owner of the new subnet is in the connection list */
792
793   if(!(owner = lookup_id(name)))
794     {
795       syslog(LOG_ERR, _("Got DEL_SUBNET for %s from %s (%s) which is not in our connection list"),
796              name, cl->name, cl->hostname);
797       return -1;
798     }
799
800   /* If everything is correct, delete the subnet from the list of the owner */
801
802   subnet_del(subnet);
803
804   /* Tell the rest */
805   
806   RBL_FOREACH(connection_tree, rbl)
807     {
808       p = (connection_t *)rbl->data;
809       if(p->status.meta && p->status.active && p!= cl)
810         send_del_subnet(p, subnet);
811     }
812 cp
813   return 0;
814 }
815
816 /* New and closed connections notification */
817
818 int send_add_host(connection_t *cl, connection_t *other)
819 {
820 cp
821   return send_request(cl, "%d %s %lx:%d %lx", ADD_HOST,
822                       other->name, other->address, other->port, other->options);
823 }
824
825 int add_host_h(connection_t *cl)
826 {
827   connection_t *old, *new, *p;
828   char name[MAX_STRING_SIZE];
829   rbl_t *rbl;
830 cp
831   new = new_connection();
832
833   if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%d %lx", name, &new->address, &new->port, &new->options) != 4)
834     {
835        syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"), cl->name, cl->hostname);
836        return -1;
837     }
838
839   /* Check if identity is a valid name */
840
841   if(check_id(name))
842     {
843       syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
844       free_connection(new);
845       return -1;
846     }
847
848   /* Check if somebody tries to add ourself */
849
850   if(!strcmp(name, myself->name))
851     {
852       syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"), cl->name, cl->hostname);
853       sighup = 1;
854       free_connection(new);
855       return 0;
856     }
857     
858   /* Fill in more of the new connection structure */
859
860   new->hostname = hostlookup(htonl(new->address));
861
862   /* Check if the new host already exists in the connnection list */
863
864   if((old = lookup_id(name)))
865     {
866       if((new->address == old->address) && (new->port == old->port))
867         {
868           if(debug_lvl >= DEBUG_CONNECTIONS)
869             syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
870                    old->name, old->hostname, name, new->hostname);
871           free_connection(new);
872           return 0;
873         }
874       else
875         {
876           if(debug_lvl >= DEBUG_CONNECTIONS)
877             syslog(LOG_NOTICE, _("Removing old entry for %s (%s) in favour of new connection"),
878                    old->name, old->hostname);
879
880           terminate_connection(old);
881         }
882     }
883
884   /* Hook it up into the connection */
885
886   new->name = xstrdup(name);
887   connection_add(new);
888   id_add(new);
889
890   /* Tell the rest about the new host */
891
892   RBL_FOREACH(connection_tree, rbl)
893     {
894       p = (connection_t *)rbl->data;
895       if(p->status.meta && p->status.active && p!=cl)
896         send_add_host(p, new);
897     }
898
899   /* Fill in rest of connection structure */
900
901   new->nexthop = cl;
902   new->status.active = 1;
903   new->cipher_pkttype = EVP_bf_cfb();
904   new->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
905 cp
906   return 0;
907 }
908
909 int send_del_host(connection_t *cl, connection_t *other)
910 {
911 cp
912   return send_request(cl, "%d %s %lx:%d %lx", DEL_HOST,
913                       other->name, other->address, other->port, other->options);
914 }
915
916 int del_host_h(connection_t *cl)
917 {
918   char name[MAX_STRING_SIZE];
919   ip_t address;
920   port_t port;
921   long int options;
922   connection_t *old, *p;
923   rbl_t *rbl;
924 cp
925   if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%d %lx", name, &address, &port, &options) != 4)
926     {
927       syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
928              cl->name, cl->hostname);
929       return -1;
930     }
931
932   /* Check if identity is a valid name */
933
934   if(check_id(name))
935     {
936       syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
937       return -1;
938     }
939
940   /* Check if somebody tries to delete ourself */
941
942   if(!strcmp(name, myself->name))
943     {
944       syslog(LOG_ERR, _("Warning: got DEL_HOST from %s (%s) for ourself, restarting"),
945              cl->name, cl->hostname);
946       sighup = 1;
947       return 0;
948     }
949
950   /* Check if the new host already exists in the connnection list */
951
952   if(!(old = lookup_id(name)))
953     {
954       syslog(LOG_ERR, _("Got DEL_HOST from %s (%s) for %s which is not in our connection list"),
955              name, cl->name, cl->hostname);
956       return -1;
957     }
958   
959   /* Check if the rest matches */
960   
961   if(address!=old->address || port!=old->port || options!=old->options || cl!=old->nexthop)
962     {
963       syslog(LOG_WARNING, _("Got DEL_HOST from %s (%s) for %s which doesn't match"), cl->name, cl->hostname, old->name);
964       return 0;
965     }
966
967   /* Ok, since EVERYTHING seems to check out all right, delete it */
968
969   old->status.active = 0;
970   terminate_connection(old);
971
972   /* Tell the rest about the new host */
973
974   RBL_FOREACH(connection_tree, rbl)
975     {
976       p = (connection_t *)rbl->data;
977       if(p->status.meta && p->status.active && p!=cl)
978         send_del_host(p, old);
979     }
980 cp
981   return 0;
982 }
983
984 /* Status and error notification routines */
985
986 int send_status(connection_t *cl, int statusno, char *statusstring)
987 {
988 cp
989   if(!statusstring)
990     statusstring = status_text[statusno];
991 cp
992   return send_request(cl, "%d %d %s", STATUS, statusno, statusstring);
993 }
994
995 int status_h(connection_t *cl)
996 {
997   int statusno;
998   char statusstring[MAX_STRING_SIZE];
999 cp
1000   if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &statusno, statusstring) != 2)
1001     {
1002        syslog(LOG_ERR, _("Got bad STATUS from %s (%s)"),
1003               cl->name, cl->hostname);
1004        return -1;
1005     }
1006
1007   if(debug_lvl >= DEBUG_STATUS)
1008     {
1009       syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"),
1010              cl->name, cl->hostname, status_text[statusno], statusstring);
1011     }
1012
1013 cp
1014   return 0;
1015 }
1016
1017 int send_error(connection_t *cl, int errno, char *errstring)
1018 {
1019 cp
1020   if(!errstring)
1021     errstring = strerror(errno);
1022   return send_request(cl, "%d %d %s", ERROR, errno, errstring);
1023 }
1024
1025 int error_h(connection_t *cl)
1026 {
1027   int errno;
1028   char errorstring[MAX_STRING_SIZE];
1029 cp
1030   if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &errno, errorstring) != 2)
1031     {
1032        syslog(LOG_ERR, _("Got bad ERROR from %s (%s)"),
1033               cl->name, cl->hostname);
1034        return -1;
1035     }
1036
1037   if(debug_lvl >= DEBUG_ERROR)
1038     {
1039       syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"),
1040              cl->name, cl->hostname, strerror(errno), errorstring);
1041     }
1042
1043   terminate_connection(cl);
1044 cp
1045   return 0;
1046 }
1047
1048 int send_termreq(connection_t *cl)
1049 {
1050 cp
1051   return send_request(cl, "%d", TERMREQ);
1052 }
1053
1054 int termreq_h(connection_t *cl)
1055 {
1056 cp
1057   terminate_connection(cl);
1058 cp
1059   return 0;
1060 }
1061
1062 /* Keepalive routines - FIXME: needs a closer look */
1063
1064 int send_ping(connection_t *cl)
1065 {
1066 cp
1067   cl->status.pinged = 1;
1068   cl->last_ping_time = time(NULL);
1069 cp
1070   return send_request(cl, "%d", PING);
1071 }
1072
1073 int ping_h(connection_t *cl)
1074 {
1075 cp
1076   return send_pong(cl);
1077 }
1078
1079 int send_pong(connection_t *cl)
1080 {
1081 cp
1082   return send_request(cl, "%d", PONG);
1083 }
1084
1085 int pong_h(connection_t *cl)
1086 {
1087 cp
1088   cl->status.pinged = 0;
1089 cp
1090   return 0;
1091 }
1092
1093 /* Key exchange */
1094
1095 int send_key_changed(connection_t *from, connection_t *cl)
1096 {
1097   connection_t *p;
1098   rbl_t *rbl;
1099 cp
1100   RBL_FOREACH(connection_tree, rbl)
1101     {
1102       p = (connection_t *)rbl->data;
1103       if(p != cl && p->status.meta && p->status.active)
1104         send_request(p, "%d %s", KEY_CHANGED, from->name);
1105     }
1106 cp
1107   return 0;
1108 }
1109
1110 int key_changed_h(connection_t *cl)
1111 {
1112   char from_id[MAX_STRING_SIZE];
1113   connection_t *from;
1114 cp
1115   if(sscanf(cl->buffer, "%*d "MAX_STRING, from_id) != 1)
1116     {
1117       syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
1118              cl->name, cl->hostname);
1119       return -1;
1120     }
1121
1122   if(!(from = lookup_id(from_id)))
1123     {
1124       syslog(LOG_ERR, _("Got KEY_CHANGED from %s (%s) origin %s which does not exist in our connection list"),
1125              cl->name, cl->hostname, from_id);
1126       return -1;
1127     }
1128
1129   from->status.validkey = 0;
1130   from->status.waitingforkey = 0;
1131
1132   send_key_changed(from, cl);
1133 cp
1134   return 0;
1135 }
1136
1137 int send_req_key(connection_t *from, connection_t *to)
1138 {
1139 cp
1140   return send_request(to->nexthop, "%d %s %s", REQ_KEY,
1141                       from->name, to->name);
1142 }
1143
1144 int req_key_h(connection_t *cl)
1145 {
1146   char from_id[MAX_STRING_SIZE];
1147   char to_id[MAX_STRING_SIZE];
1148   connection_t *from, *to;
1149   char pktkey[129];
1150 cp
1151   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, from_id, to_id) != 2)
1152     {
1153        syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
1154               cl->name, cl->hostname);
1155        return -1;
1156     }
1157
1158   if(!(from = lookup_id(from_id)))
1159     {
1160       syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) origin %s which does not exist in our connection list"),
1161              cl->name, cl->hostname, from_id);
1162       return -1;
1163     }
1164
1165   /* Check if this key request is for us */
1166
1167   if(!strcmp(to_id, myself->name))
1168     {
1169       bin2hex(myself->cipher_pktkey, pktkey, myself->cipher_pktkeylength);
1170       pktkey[myself->cipher_pktkeylength*2] = '\0';
1171       send_ans_key(myself, from, pktkey);
1172     }
1173   else
1174     {
1175       if(!(to = lookup_id(to_id)))
1176         {
1177           syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) destination %s which does not exist in our connection list"),
1178                  cl->name, cl->hostname, to_id);
1179           return -1;
1180         }
1181         
1182       if(to->status.validkey)   /* Proxy keys */
1183         {
1184           bin2hex(to->cipher_pktkey, pktkey, to->cipher_pktkeylength);
1185           pktkey[to->cipher_pktkeylength*2] = '\0';
1186           send_ans_key(to, from, pktkey);
1187         }
1188       else
1189         send_req_key(from, to);
1190     }
1191
1192 cp
1193   return 0;
1194 }
1195
1196 int send_ans_key(connection_t *from, connection_t *to, char *pktkey)
1197 {
1198 cp
1199   return send_request(to->nexthop, "%d %s %s %s", ANS_KEY,
1200                       from->name, to->name, pktkey);
1201 }
1202
1203 int ans_key_h(connection_t *cl)
1204 {
1205   char from_id[MAX_STRING_SIZE];
1206   char to_id[MAX_STRING_SIZE];
1207   char pktkey[MAX_STRING_SIZE];
1208   int keylength;
1209   connection_t *from, *to;
1210 cp
1211   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING, from_id, to_id, pktkey) != 3)
1212     {
1213        syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
1214               cl->name, cl->hostname);
1215        return -1;
1216     }
1217
1218   if(!(from = lookup_id(from_id)))
1219     {
1220       syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) origin %s which does not exist in our connection list"),
1221              cl->name, cl->hostname, from_id);
1222       return -1;
1223     }
1224
1225   /* Check correctness of packet key */
1226
1227   keylength = strlen(pktkey);
1228
1229   if(keylength != from->cipher_pktkeylength*2)
1230     {
1231       syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s) origin %s: invalid key length"),
1232              cl->name, cl->hostname, from->name);
1233       return -1;
1234     }
1235
1236   /* Forward it if necessary */
1237
1238   if(strcmp(to_id, myself->name))
1239     {
1240       if(!(to = lookup_id(to_id)))
1241         {
1242           syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) destination %s which does not exist in our connection list"),
1243                  cl->name, cl->hostname, to_id);
1244           return -1;
1245         }
1246       send_ans_key(from, to, pktkey);
1247     }
1248
1249   /* Update our copy of the origin's packet key */
1250
1251   if(from->cipher_pktkey)
1252     free(from->cipher_pktkey);
1253
1254   from->cipher_pktkey = xstrdup(pktkey);
1255   keylength /= 2;
1256   hex2bin(from->cipher_pktkey, from->cipher_pktkey, keylength);
1257   from->cipher_pktkey[keylength] = '\0';
1258
1259   from->status.validkey = 1;
1260   from->status.waitingforkey = 0;
1261 cp
1262   return 0;
1263 }
1264
1265 /* Jumptable for the request handlers */
1266
1267 int (*request_handlers[])(connection_t*) = {
1268   id_h, challenge_h, chal_reply_h, metakey_h, ack_h,
1269   status_h, error_h, termreq_h,
1270   ping_h, pong_h,
1271   add_host_h, del_host_h,
1272   add_subnet_h, del_subnet_h,
1273   key_changed_h, req_key_h, ans_key_h,
1274 };
1275
1276 /* Request names */
1277
1278 char (*request_name[]) = {
1279   "ID", "CHALLENGE", "CHAL_REPLY", "METAKEY", "ACK",
1280   "STATUS", "ERROR", "TERMREQ",
1281   "PING", "PONG",
1282   "ADD_HOST", "DEL_HOST",
1283   "ADD_SUBNET", "DEL_SUBNET",
1284   "KEY_CHANGED", "REQ_KEY", "ANS_KEY",
1285 };
1286
1287 /* Status strings */
1288
1289 char (*status_text[]) = {
1290   "Warning",
1291 };
1292
1293 /* Error strings */
1294
1295 char (*error_text[]) = {
1296   "Error",
1297 };