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