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