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