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