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