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