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