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