- More porting to FreeBSD and Solaris.
[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.66 2000/11/22 22:05:37 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   setup_vpn_connection(cl);
579
580   x = send_request(cl, "%d", ACK);
581   cl->status.encryptout = 1;
582 cp
583   return x;
584 }
585
586 int ack_h(connection_t *cl)
587 {
588   connection_t *old, *p;
589   subnet_t *subnet;
590   rbl_t *rbl, *rbl2;
591 cp
592   /* Okay, before we active the connection, we check if there is another entry
593      in the connection list with the same name. If so, it presumably is an
594      old connection that has timed out but we don't know it yet.
595    */
596
597   while((old = lookup_id(cl->name)))
598     {
599       if(debug_lvl >= DEBUG_CONNECTIONS)
600         syslog(LOG_NOTICE, _("Removing old entry for %s at %s in favour of new connection from %s"),
601         cl->name, old->hostname, cl->hostname);
602
603       terminate_connection(old);
604     }
605
606   /* Activate this connection */
607
608   cl->allow_request = ALL;
609   cl->status.active = 1;
610   cl->status.decryptin = 1;
611   cl->nexthop = cl;
612   cl->cipher_pkttype = EVP_bf_cfb();
613   cl->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
614
615   if(debug_lvl >= DEBUG_CONNECTIONS)
616     syslog(LOG_NOTICE, _("Connection with %s (%s) activated"), cl->name, cl->hostname);
617
618 cp
619   if(!cl->status.outgoing)
620     send_ack(cl);
621
622   /* Send him our subnets */
623   
624   RBL_FOREACH(myself->subnet_tree, rbl)
625     {
626       subnet = (subnet_t *)rbl->data;
627       send_add_subnet(cl, subnet);
628     }
629   /* And send him all the hosts and their subnets we know... */
630   
631   RBL_FOREACH(connection_tree, rbl)
632     {
633       p = (connection_t *)rbl->data;
634       
635       if(p != cl && p->status.active)
636         {
637           /* Notify others of this connection */
638
639           if(p->status.meta)
640             send_add_host(p, cl);
641
642           /* Notify new connection of everything we know */
643
644           send_add_host(cl, p);
645
646           RBL_FOREACH(p->subnet_tree, rbl2)
647             {
648               subnet = (subnet_t *)rbl2->data;
649               send_add_subnet(cl, subnet);
650             }
651         }
652     }  
653 cp
654   return 0;
655 }
656
657 /* Address and subnet information exchange */
658
659 int send_add_subnet(connection_t *cl, subnet_t *subnet)
660 {
661   int x;
662   char *netstr;
663 cp
664   x = send_request(cl, "%d %s %s", ADD_SUBNET,
665                       subnet->owner->name, netstr = net2str(subnet));
666   free(netstr);
667 cp
668   return x;
669 }
670
671 int add_subnet_h(connection_t *cl)
672 {
673   char subnetstr[MAX_STRING_SIZE];
674   char name[MAX_STRING_SIZE];
675   connection_t *owner, *p;
676   subnet_t *subnet;
677   rbl_t *rbl;
678 cp
679   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
680     {
681       syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s)"), cl->name, cl->hostname);
682       return -1;
683     }
684
685   /* Check if owner name is a valid */
686
687   if(check_id(name))
688     {
689       syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
690       return -1;
691     }
692
693   /* Check if subnet string is valid */
694
695   if(!(subnet = str2net(subnetstr)))
696     {
697       syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
698       return -1;
699     }
700
701   /* Check if somebody tries to add a subnet of ourself */
702
703   if(!strcmp(name, myself->name))
704     {
705       syslog(LOG_ERR, _("Warning: got ADD_SUBNET from %s (%s) for ourself, restarting"),
706              cl->name, cl->hostname);
707       sighup = 1;
708       return 0;
709     }
710
711   /* Check if the owner of the new subnet is in the connection list */
712
713   if(!(owner = lookup_id(name)))
714     {
715       syslog(LOG_ERR, _("Got ADD_SUBNET for %s from %s (%s) which is not in our connection list"),
716              name, cl->name, cl->hostname);
717       return -1;
718     }
719
720   /* If everything is correct, add the subnet to the list of the owner */
721
722   subnet_add(owner, subnet);
723
724   /* Tell the rest */
725   
726   RBL_FOREACH(connection_tree, rbl)
727     {
728       p = (connection_t *)rbl->data;
729       if(p->status.meta && p->status.active && p!= cl)
730         send_add_subnet(p, subnet);
731     }
732 cp
733   return 0;
734 }
735
736 int send_del_subnet(connection_t *cl, subnet_t *subnet)
737 {
738   int x;
739   char *netstr;
740 cp
741   netstr = net2str(subnet);
742   x = send_request(cl, "%d %s %s", DEL_SUBNET, subnet->owner->name, netstr);
743   free(netstr);
744 cp
745   return x;
746 }
747
748 int del_subnet_h(connection_t *cl)
749 {
750   char subnetstr[MAX_STRING_SIZE];
751   char name[MAX_STRING_SIZE];
752   connection_t *owner, *p;
753   subnet_t *subnet;
754   rbl_t *rbl;
755 cp
756   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 3)
757     {
758       syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s)"), cl->name, cl->hostname);
759       return -1;
760     }
761
762   /* Check if owner name is a valid */
763
764   if(check_id(name))
765     {
766       syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
767       return -1;
768     }
769
770   /* Check if subnet string is valid */
771
772   if(!(subnet = str2net(subnetstr)))
773     {
774       syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
775       return -1;
776     }
777
778   free(subnetstr);
779   
780   /* Check if somebody tries to add a subnet of ourself */
781
782   if(!strcmp(name, myself->name))
783     {
784       syslog(LOG_ERR, _("Warning: got DEL_SUBNET from %s (%s) for ourself, restarting"),
785              cl->name, cl->hostname);
786       sighup = 1;
787       return 0;
788     }
789
790   /* Check if the owner of the new subnet is in the connection list */
791
792   if(!(owner = lookup_id(name)))
793     {
794       syslog(LOG_ERR, _("Got DEL_SUBNET for %s from %s (%s) which is not in our connection list"),
795              name, cl->name, cl->hostname);
796       return -1;
797     }
798
799   /* If everything is correct, delete the subnet from the list of the owner */
800
801   subnet_del(subnet);
802
803   /* Tell the rest */
804   
805   RBL_FOREACH(connection_tree, rbl)
806     {
807       p = (connection_t *)rbl->data;
808       if(p->status.meta && p->status.active && p!= cl)
809         send_del_subnet(p, subnet);
810     }
811 cp
812   return 0;
813 }
814
815 /* New and closed connections notification */
816
817 int send_add_host(connection_t *cl, connection_t *other)
818 {
819 cp
820   return send_request(cl, "%d %s %lx:%d %lx", ADD_HOST,
821                       other->name, other->address, other->port, other->options);
822 }
823
824 int add_host_h(connection_t *cl)
825 {
826   connection_t *old, *new, *p;
827   char name[MAX_STRING_SIZE];
828   rbl_t *rbl;
829 cp
830   new = new_connection();
831
832   if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%d %lx", name, &new->address, &new->port, &new->options) != 4)
833     {
834        syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"), cl->name, cl->hostname);
835        return -1;
836     }
837
838   /* Check if identity is a valid name */
839
840   if(check_id(name))
841     {
842       syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
843       free_connection(new);
844       return -1;
845     }
846
847   /* Check if somebody tries to add ourself */
848
849   if(!strcmp(name, myself->name))
850     {
851       syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"), cl->name, cl->hostname);
852       sighup = 1;
853       free_connection(new);
854       return 0;
855     }
856     
857   /* Fill in more of the new connection structure */
858
859   new->hostname = hostlookup(htonl(new->address));
860
861   /* Check if the new host already exists in the connnection list */
862
863   if((old = lookup_id(name)))
864     {
865       if((new->address == old->address) && (new->port == old->port))
866         {
867           if(debug_lvl >= DEBUG_CONNECTIONS)
868             syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
869                    old->name, old->hostname, name, new->hostname);
870           free_connection(new);
871           return 0;
872         }
873       else
874         {
875           if(debug_lvl >= DEBUG_CONNECTIONS)
876             syslog(LOG_NOTICE, _("Removing old entry for %s (%s) in favour of new connection"),
877                    old->name, old->hostname);
878
879           terminate_connection(old);
880         }
881     }
882
883   /* Hook it up into the connection */
884
885   new->name = xstrdup(name);
886   connection_add(new);
887   id_add(new);
888
889   /* Tell the rest about the new host */
890
891   RBL_FOREACH(connection_tree, rbl)
892     {
893       p = (connection_t *)rbl->data;
894       if(p->status.meta && p->status.active && p!=cl)
895         send_add_host(p, new);
896     }
897
898   /* Fill in rest of connection structure */
899
900   new->nexthop = cl;
901   new->status.active = 1;
902   new->cipher_pkttype = EVP_bf_cfb();
903   new->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
904
905   /* Okay this is a bit ugly... it would be better to setup UDP sockets dynamically, or
906    * perhaps just one UDP socket... but then again, this has benefits too...
907    */
908    
909   setup_vpn_connection(new);
910 cp
911   return 0;
912 }
913
914 int send_del_host(connection_t *cl, connection_t *other)
915 {
916 cp
917   return send_request(cl, "%d %s %lx:%d %lx", DEL_HOST,
918                       other->name, other->address, other->port, other->options);
919 }
920
921 int del_host_h(connection_t *cl)
922 {
923   char name[MAX_STRING_SIZE];
924   ip_t address;
925   port_t port;
926   long int options;
927   connection_t *old, *p;
928   rbl_t *rbl;
929 cp
930   if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%d %lx", name, &address, &port, &options) != 4)
931     {
932       syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
933              cl->name, cl->hostname);
934       return -1;
935     }
936
937   /* Check if identity is a valid name */
938
939   if(check_id(name))
940     {
941       syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
942       return -1;
943     }
944
945   /* Check if somebody tries to delete ourself */
946
947   if(!strcmp(name, myself->name))
948     {
949       syslog(LOG_ERR, _("Warning: got DEL_HOST from %s (%s) for ourself, restarting"),
950              cl->name, cl->hostname);
951       sighup = 1;
952       return 0;
953     }
954
955   /* Check if the new host already exists in the connnection list */
956
957   if(!(old = lookup_id(name)))
958     {
959       syslog(LOG_ERR, _("Got DEL_HOST from %s (%s) for %s which is not in our connection list"),
960              name, cl->name, cl->hostname);
961       return -1;
962     }
963   
964   /* Check if the rest matches */
965   
966   if(address!=old->address || port!=old->port || options!=old->options || cl!=old->nexthop)
967     {
968       syslog(LOG_WARNING, _("Got DEL_HOST from %s (%s) for %s which doesn't match"), cl->name, cl->hostname, old->name);
969       return 0;
970     }
971
972   /* Ok, since EVERYTHING seems to check out all right, delete it */
973
974   old->status.active = 0;
975   terminate_connection(old);
976
977   /* Tell the rest about the new host */
978
979   RBL_FOREACH(connection_tree, rbl)
980     {
981       p = (connection_t *)rbl->data;
982       if(p->status.meta && p->status.active && p!=cl)
983         send_del_host(p, old);
984     }
985 cp
986   return 0;
987 }
988
989 /* Status and error notification routines */
990
991 int send_status(connection_t *cl, int statusno, char *statusstring)
992 {
993 cp
994   if(!statusstring)
995     statusstring = status_text[statusno];
996 cp
997   return send_request(cl, "%d %d %s", STATUS, statusno, statusstring);
998 }
999
1000 int status_h(connection_t *cl)
1001 {
1002   int statusno;
1003   char statusstring[MAX_STRING_SIZE];
1004 cp
1005   if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &statusno, statusstring) != 2)
1006     {
1007        syslog(LOG_ERR, _("Got bad STATUS from %s (%s)"),
1008               cl->name, cl->hostname);
1009        return -1;
1010     }
1011
1012   if(debug_lvl >= DEBUG_STATUS)
1013     {
1014       syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"),
1015              cl->name, cl->hostname, status_text[statusno], statusstring);
1016     }
1017
1018 cp
1019   return 0;
1020 }
1021
1022 int send_error(connection_t *cl, int errno, char *errstring)
1023 {
1024 cp
1025   if(!errstring)
1026     errstring = strerror(errno);
1027   return send_request(cl, "%d %d %s", ERROR, errno, errstring);
1028 }
1029
1030 int error_h(connection_t *cl)
1031 {
1032   int errno;
1033   char errorstring[MAX_STRING_SIZE];
1034 cp
1035   if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &errno, errorstring) != 2)
1036     {
1037        syslog(LOG_ERR, _("Got bad ERROR from %s (%s)"),
1038               cl->name, cl->hostname);
1039        return -1;
1040     }
1041
1042   if(debug_lvl >= DEBUG_ERROR)
1043     {
1044       syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"),
1045              cl->name, cl->hostname, strerror(errno), errorstring);
1046     }
1047
1048   terminate_connection(cl);
1049 cp
1050   return 0;
1051 }
1052
1053 int send_termreq(connection_t *cl)
1054 {
1055 cp
1056   return send_request(cl, "%d", TERMREQ);
1057 }
1058
1059 int termreq_h(connection_t *cl)
1060 {
1061 cp
1062   terminate_connection(cl);
1063 cp
1064   return 0;
1065 }
1066
1067 /* Keepalive routines - FIXME: needs a closer look */
1068
1069 int send_ping(connection_t *cl)
1070 {
1071 cp
1072   cl->status.pinged = 1;
1073   cl->last_ping_time = time(NULL);
1074 cp
1075   return send_request(cl, "%d", PING);
1076 }
1077
1078 int ping_h(connection_t *cl)
1079 {
1080 cp
1081   return send_pong(cl);
1082 }
1083
1084 int send_pong(connection_t *cl)
1085 {
1086 cp
1087   return send_request(cl, "%d", PONG);
1088 }
1089
1090 int pong_h(connection_t *cl)
1091 {
1092 cp
1093   cl->status.pinged = 0;
1094 cp
1095   return 0;
1096 }
1097
1098 /* Key exchange */
1099
1100 int send_key_changed(connection_t *from, connection_t *cl)
1101 {
1102   connection_t *p;
1103   rbl_t *rbl;
1104 cp
1105   RBL_FOREACH(connection_tree, rbl)
1106     {
1107       p = (connection_t *)rbl->data;
1108       if(p != cl && p->status.meta && p->status.active)
1109         send_request(p, "%d %s", KEY_CHANGED, from->name);
1110     }
1111 cp
1112   return 0;
1113 }
1114
1115 int key_changed_h(connection_t *cl)
1116 {
1117   char from_id[MAX_STRING_SIZE];
1118   connection_t *from;
1119 cp
1120   if(sscanf(cl->buffer, "%*d "MAX_STRING, from_id) != 1)
1121     {
1122       syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
1123              cl->name, cl->hostname);
1124       return -1;
1125     }
1126
1127   if(!(from = lookup_id(from_id)))
1128     {
1129       syslog(LOG_ERR, _("Got KEY_CHANGED from %s (%s) origin %s which does not exist in our connection list"),
1130              cl->name, cl->hostname, from_id);
1131       return -1;
1132     }
1133
1134   from->status.validkey = 0;
1135   from->status.waitingforkey = 0;
1136
1137   send_key_changed(from, cl);
1138 cp
1139   return 0;
1140 }
1141
1142 int send_req_key(connection_t *from, connection_t *to)
1143 {
1144 cp
1145   return send_request(to->nexthop, "%d %s %s", REQ_KEY,
1146                       from->name, to->name);
1147 }
1148
1149 int req_key_h(connection_t *cl)
1150 {
1151   char from_id[MAX_STRING_SIZE];
1152   char to_id[MAX_STRING_SIZE];
1153   connection_t *from, *to;
1154   char pktkey[129];
1155 cp
1156   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, from_id, to_id) != 2)
1157     {
1158        syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
1159               cl->name, cl->hostname);
1160        return -1;
1161     }
1162
1163   if(!(from = lookup_id(from_id)))
1164     {
1165       syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) origin %s which does not exist in our connection list"),
1166              cl->name, cl->hostname, from_id);
1167       return -1;
1168     }
1169
1170   /* Check if this key request is for us */
1171
1172   if(!strcmp(to_id, myself->name))
1173     {
1174       bin2hex(myself->cipher_pktkey, pktkey, myself->cipher_pktkeylength);
1175       pktkey[myself->cipher_pktkeylength*2] = '\0';
1176       send_ans_key(myself, from, pktkey);
1177     }
1178   else
1179     {
1180       if(!(to = lookup_id(to_id)))
1181         {
1182           syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) destination %s which does not exist in our connection list"),
1183                  cl->name, cl->hostname, to_id);
1184           return -1;
1185         }
1186         
1187       if(to->status.validkey)   /* Proxy keys */
1188         {
1189           bin2hex(to->cipher_pktkey, pktkey, to->cipher_pktkeylength);
1190           pktkey[to->cipher_pktkeylength*2] = '\0';
1191           send_ans_key(to, from, pktkey);
1192         }
1193       else
1194         send_req_key(from, to);
1195     }
1196
1197 cp
1198   return 0;
1199 }
1200
1201 int send_ans_key(connection_t *from, connection_t *to, char *pktkey)
1202 {
1203 cp
1204   return send_request(to->nexthop, "%d %s %s %s", ANS_KEY,
1205                       from->name, to->name, pktkey);
1206 }
1207
1208 int ans_key_h(connection_t *cl)
1209 {
1210   char from_id[MAX_STRING_SIZE];
1211   char to_id[MAX_STRING_SIZE];
1212   char pktkey[MAX_STRING_SIZE];
1213   int keylength;
1214   connection_t *from, *to;
1215 cp
1216   if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING, from_id, to_id, pktkey) != 3)
1217     {
1218        syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
1219               cl->name, cl->hostname);
1220        return -1;
1221     }
1222
1223   if(!(from = lookup_id(from_id)))
1224     {
1225       syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) origin %s which does not exist in our connection list"),
1226              cl->name, cl->hostname, from_id);
1227       return -1;
1228     }
1229
1230   /* Check correctness of packet key */
1231
1232   keylength = strlen(pktkey);
1233
1234   if(keylength != from->cipher_pktkeylength*2)
1235     {
1236       syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s) origin %s: invalid key length"),
1237              cl->name, cl->hostname, from->name);
1238       return -1;
1239     }
1240
1241   /* Forward it if necessary */
1242
1243   if(strcmp(to_id, myself->name))
1244     {
1245       if(!(to = lookup_id(to_id)))
1246         {
1247           syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) destination %s which does not exist in our connection list"),
1248                  cl->name, cl->hostname, to_id);
1249           return -1;
1250         }
1251       send_ans_key(from, to, pktkey);
1252     }
1253
1254   /* Update our copy of the origin's packet key */
1255
1256   if(from->cipher_pktkey)
1257     free(from->cipher_pktkey);
1258
1259   from->cipher_pktkey = xstrdup(pktkey);
1260   keylength /= 2;
1261   hex2bin(from->cipher_pktkey, from->cipher_pktkey, keylength);
1262   from->cipher_pktkey[keylength] = '\0';
1263
1264   from->status.validkey = 1;
1265   from->status.waitingforkey = 0;
1266 cp
1267   return 0;
1268 }
1269
1270 /* Jumptable for the request handlers */
1271
1272 int (*request_handlers[])(connection_t*) = {
1273   id_h, challenge_h, chal_reply_h, metakey_h, ack_h,
1274   status_h, error_h, termreq_h,
1275   ping_h, pong_h,
1276   add_host_h, del_host_h,
1277   add_subnet_h, del_subnet_h,
1278   key_changed_h, req_key_h, ans_key_h,
1279 };
1280
1281 /* Request names */
1282
1283 char (*request_name[]) = {
1284   "ID", "CHALLENGE", "CHAL_REPLY", "METAKEY", "ACK",
1285   "STATUS", "ERROR", "TERMREQ",
1286   "PING", "PONG",
1287   "ADD_HOST", "DEL_HOST",
1288   "ADD_SUBNET", "DEL_SUBNET",
1289   "KEY_CHANGED", "REQ_KEY", "ANS_KEY",
1290 };
1291
1292 /* Status strings */
1293
1294 char (*status_text[]) = {
1295   "Warning",
1296 };
1297
1298 /* Error strings */
1299
1300 char (*error_text[]) = {
1301   "Error",
1302 };