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