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