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