Read public keys the right way (tm).
[tinc] / src / protocol.c
1 /*
2     protocol.c -- handle the meta-protocol
3     Copyright (C) 1999 Ivo Timmermans <zarq@iname.com>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include "config.h"
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <syslog.h>
25 #include <sys/socket.h>
26 #include <unistd.h>
27
28 #include <utils.h>
29 #include <xalloc.h>
30
31 #include "conf.h"
32 #include "encr.h"
33 #include "net.h"
34 #include "netutl.h"
35 #include "protocol.h"
36
37 int send_ack(conn_list_t *cl)
38 {
39   unsigned char tmp = ACK;
40 cp
41   if(debug_lvl > 2)
42     syslog(LOG_DEBUG, "Send ACK to %s", cl->hostname);
43
44   syslog(LOG_NOTICE, "Connection with %s activated.", cl->hostname);
45   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
46     {
47       syslog(LOG_ERR, "send failed: %d:%d: %m", __FILE__, __LINE__);
48       return -1;
49     }
50 cp
51   return 0;
52 }
53
54 int send_termreq(conn_list_t *cl)
55 {
56   termreq_t tmp;
57 cp
58   memset(&tmp, 0, sizeof(tmp));
59   tmp.type = TERMREQ;
60   tmp.vpn_ip = myself->vpn_ip;
61
62   if(debug_lvl > 2)
63     syslog(LOG_DEBUG, "Send TERMREQ(" IP_ADDR_S ") to " IP_ADDR_S, IP_ADDR_V(tmp.vpn_ip),
64            IP_ADDR_V(cl->vpn_ip));
65
66   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
67     {
68       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
69       return -1;
70     }
71 cp
72   return 0;
73 }
74
75 int send_timeout(conn_list_t *cl)
76 {
77   termreq_t tmp;
78 cp
79   memset(&tmp, 0, sizeof(tmp));
80   tmp.type = PINGTIMEOUT;
81   tmp.vpn_ip = myself->vpn_ip;
82
83   if(debug_lvl > 2)
84     syslog(LOG_DEBUG, "Send TIMEOUT(" IP_ADDR_S ") to " IP_ADDR_S, IP_ADDR_V(tmp.vpn_ip),
85            IP_ADDR_V(cl->vpn_ip));
86
87   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
88     {
89       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
90       return -1;
91     }
92 cp
93   return 0;
94 }
95
96 int send_del_host(conn_list_t *cl, conn_list_t *new_host)
97 {
98   del_host_t tmp;
99 cp
100   memset(&tmp, 0, sizeof(tmp));
101   tmp.type = DEL_HOST;
102   tmp.vpn_ip = new_host->vpn_ip;
103
104   if(debug_lvl > 2)
105     syslog(LOG_DEBUG, "Sending delete host %lx to " IP_ADDR_S,
106            tmp.vpn_ip, IP_ADDR_V(cl->vpn_ip));
107
108   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
109     {
110       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
111       return -1;
112     }
113 cp
114   return 0;
115 }
116
117 int send_ping(conn_list_t *cl)
118 {
119   unsigned char tmp = PING;
120 cp
121   if(debug_lvl > 3)
122     syslog(LOG_DEBUG, "pinging " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
123
124   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
125     {
126       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
127       return -1;
128     }
129 cp
130   return 0;
131 }
132
133 int send_pong(conn_list_t *cl)
134 {
135   unsigned char tmp = PONG;
136 cp
137   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
138     {
139       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
140       return -1;
141     }
142 cp
143   return 0;
144 }
145
146 int send_add_host(conn_list_t *cl, conn_list_t *new_host)
147 {
148   add_host_t tmp;
149 cp
150   memset(&tmp, 0, sizeof(tmp));
151   tmp.type = ADD_HOST;
152   tmp.real_ip = new_host->real_ip;
153   tmp.vpn_ip = new_host->vpn_ip;
154   tmp.vpn_mask = new_host->vpn_mask;
155   tmp.portnr = new_host->port;
156
157   if(debug_lvl > 2)
158     syslog(LOG_DEBUG, "Sending add host (%lx/%lx %lx:%hd) to " IP_ADDR_S,
159            tmp.vpn_ip, tmp.vpn_mask, tmp.real_ip, tmp.portnr,
160            IP_ADDR_V(cl->vpn_ip));
161
162   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
163     {
164       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
165       return -1;
166     }
167 cp
168   return 0;
169 }
170
171 int send_key_changed(conn_list_t *cl, conn_list_t *src)
172 {
173   key_changed_t tmp;
174 cp
175   memset(&tmp, 0, sizeof(tmp));
176   tmp.type = KEY_CHANGED;
177   tmp.from = src->vpn_ip;
178
179   if(debug_lvl > 2)
180     syslog(LOG_DEBUG, "Sending KEY_CHANGED (%lx) to " IP_ADDR_S,
181            tmp.from, IP_ADDR_V(cl->vpn_ip));
182
183   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
184     {
185       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
186       return -1;
187     }
188 cp
189   return 0;
190 }
191
192 void send_key_changed2(void)
193 {
194   conn_list_t *p;
195 cp
196   for(p = conn_list; p != NULL; p = p->next)
197     if(p->status.meta && p->protocol_version > PROT_3)
198       send_key_changed(p, myself);
199 cp
200 }
201
202 int send_basic_info(conn_list_t *cl)
203 {
204   basic_info_t tmp;
205 cp
206   memset(&tmp, 0, sizeof(tmp));
207   tmp.type = BASIC_INFO;
208   tmp.protocol = PROT_CURRENT;
209
210   tmp.portnr = myself->port;
211   tmp.vpn_ip = myself->vpn_ip;
212   tmp.vpn_mask = myself->vpn_mask;
213
214   if(debug_lvl > 2)
215     syslog(LOG_DEBUG, "Send BASIC_INFO(%d,%hd," IP_ADDR_S "," IP_ADDR_S ") to " IP_ADDR_S,
216            tmp.protocol, tmp.portnr, IP_ADDR_V(tmp.vpn_ip), IP_ADDR_V(tmp.vpn_mask),
217            IP_ADDR_V(cl->real_ip));
218
219   if((write(cl->meta_socket, &tmp, sizeof(tmp))) < 0)
220     {
221       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
222       return -1;
223     }
224 cp
225   return 0;
226 }
227
228 int send_passphrase(conn_list_t *cl)
229 {
230   passphrase_t tmp;
231 cp
232   memset(&tmp, 0, sizeof(tmp));
233   tmp.type = PASSPHRASE;
234   encrypt_passphrase(&tmp);
235
236   if(debug_lvl > 2)
237     syslog(LOG_DEBUG, "Send PASSPHRASE(%hd,...) to " IP_ADDR_S, tmp.len,
238            IP_ADDR_V(cl->vpn_ip));
239
240   if((write(cl->meta_socket, &tmp, tmp.len+3)) < 0)
241     {
242       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
243       return -1;
244     }
245 cp
246   return 0;
247 }
248
249 int send_public_key(conn_list_t *cl)
250 {
251   public_key_t *tmp;
252 cp
253   tmp = (public_key_t*)xmalloc(strlen(my_public_key_base36)+sizeof(*tmp));
254   memset(tmp, 0, sizeof(*tmp));
255   tmp->type = PUBLIC_KEY;
256   tmp->len = strlen(my_public_key_base36);
257   strcpy(&tmp->key, my_public_key_base36);
258
259   if(debug_lvl > 2)
260     syslog(LOG_DEBUG, "Send PUBLIC_KEY(%hd,%s) to " IP_ADDR_S, tmp->len, &tmp->key,
261            IP_ADDR_V(cl->vpn_ip));
262
263   if((write(cl->meta_socket, tmp, tmp->len+sizeof(*tmp))) < 0)
264     {
265       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
266       return -1;
267     }
268 cp
269   return 0;
270 }
271
272 int send_calculate(conn_list_t *cl, char *k)
273 {
274   calculate_t *tmp;
275 cp
276   tmp = xmalloc(strlen(k)+sizeof(*tmp));
277   memset(tmp, 0, sizeof(*tmp));
278   tmp->type = CALCULATE;
279   tmp->len = strlen(k);
280   strcpy(&tmp->key, k);
281
282   if((write(cl->meta_socket, tmp, tmp->len+sizeof(*tmp))) < 0)
283     {
284       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
285       return -1;
286     }
287 cp
288   return 0;
289 }
290
291 int send_key_request(ip_t to)
292 {
293   key_req_t *tmp;
294   conn_list_t *fw;
295 cp
296   tmp = xmalloc(sizeof(*tmp));
297   memset(tmp, 0, sizeof(*tmp));
298   tmp->type = REQ_KEY;
299   tmp->to = to;
300   tmp->from = myself->vpn_ip;
301   tmp->len = 0;
302
303   fw = lookup_conn(to);
304   if(!fw)
305     {
306       syslog(LOG_ERR, "Attempting to send key request to " IP_ADDR_S ", which does not exist?",
307              IP_ADDR_V(to));
308       return -1;
309     }
310
311   if(debug_lvl > 2)
312     syslog(LOG_DEBUG, "Sending out request for public key to " IP_ADDR_S,
313            IP_ADDR_V(fw->nexthop->vpn_ip));
314   if(write(fw->nexthop->meta_socket, tmp, sizeof(*tmp)) < 0)
315     {
316       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
317       return -1;
318     }
319   fw->status.waitingforkey = 1;
320 cp
321   return 0;
322 }
323
324 int send_key_answer(conn_list_t *cl, ip_t to)
325 {
326   key_req_t *tmp;
327   conn_list_t *fw;
328 cp
329   tmp = xmalloc(sizeof(*tmp)+strlen(my_public_key_base36));
330   memset(tmp, 0, sizeof(*tmp));
331   tmp->type = ANS_KEY;
332   tmp->to = to;
333   tmp->from = myself->vpn_ip;
334   tmp->expiry = my_key_expiry;
335   tmp->len = strlen(my_public_key_base36);
336   strcpy(&(tmp->key), my_public_key_base36);
337
338 cp
339   syslog(LOG_DEBUG, "key sent = %s", my_public_key_base36);
340 cp
341  fw = lookup_conn(to);
342   
343 cp
344   if(!fw)
345     {
346       syslog(LOG_ERR, "Attempting to send key answer to " IP_ADDR_S ", which does not exist?",
347              IP_ADDR_V(to));
348       return -1;
349     }
350 cp
351   syslog(LOG_DEBUG, "key sent = %s", &(tmp->key));
352
353 cp
354  if(debug_lvl > 2)
355     syslog(LOG_DEBUG, "Sending public key to " IP_ADDR_S,
356            IP_ADDR_V(fw->nexthop->vpn_ip));
357 cp
358   if(write(fw->nexthop->meta_socket, tmp, sizeof(*tmp)+tmp->len) < 0)
359     {
360       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
361       return -1;
362     }
363 cp
364   return 0;
365 }
366
367 /*
368   notify all my direct connections of a new host
369   that was added to the vpn, with the exception
370   of the source of the announcement.
371 */
372 int notify_others(conn_list_t *new, conn_list_t *source,
373                   int (*function)(conn_list_t*, conn_list_t*))
374 {
375   conn_list_t *p;
376 cp
377   for(p = conn_list; p != NULL; p = p->next)
378     if(p != new && p != source && p->status.meta && p->protocol_version > PROT_3)
379       function(p, new);
380 cp
381   return 0;
382 }
383
384 /*
385   notify one connection of everything
386   i have connected
387 */
388 int notify_one(conn_list_t *new)
389 {
390   conn_list_t *p;
391 cp
392   for(p = conn_list; p != NULL; p = p->next)
393     if(p != new && p->protocol_version > PROT_3)
394       send_add_host(new, p);
395 cp
396   return 0;
397 }
398
399 /*
400   The incoming request handlers
401 */
402
403 int basic_info_h(conn_list_t *cl)
404 {
405   basic_info_t tmp;
406 cp
407   if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-1) <= 0)
408     {
409       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
410       return -1;
411     }
412
413   cl->protocol_version = tmp.protocol;
414   cl->port = tmp.portnr;
415   cl->vpn_ip = tmp.vpn_ip;
416   cl->vpn_mask = tmp.vpn_mask;
417
418   if(cl->protocol_version < PROT_CURRENT)
419     {
420       syslog(LOG_ERR, "Peer uses protocol version %d which is too old.",
421              cl->protocol_version);
422       return -1;
423     }
424
425   if(debug_lvl > 2)
426     syslog(LOG_DEBUG, "got BASIC_INFO(%hd," IP_ADDR_S "," IP_ADDR_S ")", cl->port,
427            IP_ADDR_V(cl->vpn_ip), IP_ADDR_V(cl->vpn_mask));
428   if(debug_lvl > 1)
429     syslog(LOG_DEBUG, "Peer uses protocol version %d",
430            cl->protocol_version);
431
432   if(cl->status.outgoing)
433     {
434       if(setup_vpn_connection(cl) < 0)
435         return -1;
436       send_basic_info(cl);
437     }
438   else
439     {
440       if(setup_vpn_connection(cl) < 0)
441         return -1;
442       send_passphrase(cl);
443     }
444
445   cl->status.active = 0;
446 cp
447   return 0;
448 }
449
450 int passphrase_h(conn_list_t *cl)
451 {
452   char unused;
453   unsigned short int len;
454 cp
455   if(read(cl->meta_socket, &unused, sizeof(unused)) <= 0)
456     {
457       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
458       return -1;
459     }
460
461   if(read(cl->meta_socket, &len, sizeof(len)) <= 0)
462     {
463       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
464       return -1;
465     }
466   
467   cl->pp = xmalloc(len+4);
468
469   cl->pp->len = len;
470   if(read(cl->meta_socket, &(cl->pp->phrase), len) <= 0)
471     {
472       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
473       return -1;
474     }
475   
476   if(debug_lvl > 2)
477     syslog(LOG_DEBUG, "got PASSPHRASE(%hd,...)", len);
478
479   if(cl->status.outgoing)
480     send_passphrase(cl);
481   else
482     send_public_key(cl);
483 cp
484   return 0;
485 }
486
487 int public_key_h(conn_list_t *cl)
488 {
489   char *g_n;
490   unsigned short int len;
491   char unused;
492 cp
493   if(read(cl->meta_socket, &unused, sizeof(unused)) <= 0)
494     {
495       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
496       return -1;
497     }
498   if(read(cl->meta_socket, &len, sizeof(len)) <= 0)
499     {
500       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
501       return -1;
502     }
503
504   g_n = xmalloc(len+2);
505
506   if(read(cl->meta_socket, g_n, len+2) <= 0)
507     {
508       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
509       return -1;
510     }
511
512   if(debug_lvl > 2)
513     syslog(LOG_DEBUG, "got PUBLIC_KEY(%hd,%s)", len, g_n);
514
515   if(verify_passphrase(cl, g_n))
516     {
517       /* intruder! */
518       syslog(LOG_ERR, "Intruder: passphrase does not match.");
519       return -1;
520     }
521
522   if(debug_lvl > 2)
523     syslog(LOG_INFO, "Passphrase OK");
524
525   if(cl->status.outgoing)
526     send_public_key(cl);
527   else
528     send_ack(cl);
529
530   cl->status.active = 1;
531   notify_others(cl, NULL, send_add_host);
532   notify_one(cl);
533 cp
534   return 0;
535 }
536
537 int ack_h(conn_list_t *cl)
538 {
539 cp
540   if(debug_lvl > 2)
541     syslog(LOG_DEBUG, "got ACK");
542   
543   cl->status.active = 1;
544   syslog(LOG_NOTICE, "Connection with %s activated.", cl->hostname);
545 cp
546   return 0;
547 }
548
549 int termreq_h(conn_list_t *cl)
550 {
551 cp
552   syslog(LOG_NOTICE, IP_ADDR_S " wants to quit", IP_ADDR_V(cl->vpn_ip));
553   cl->status.termreq = 1;
554   terminate_connection(cl);
555
556   notify_others(cl, NULL, send_del_host);
557 cp
558   return 0;
559 }
560
561 int timeout_h(conn_list_t *cl)
562 {
563 cp
564   syslog(LOG_NOTICE, IP_ADDR_S " says it's gotten a timeout from us", IP_ADDR_V(cl->vpn_ip));
565   cl->status.termreq = 1;
566   terminate_connection(cl);
567 cp
568   return 0;
569 }
570
571 int del_host_h(conn_list_t *cl)
572 {
573   del_host_t tmp;
574   conn_list_t *fw;
575 cp
576   if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-1) <= 0)
577     {
578       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
579       return -1;
580     }
581
582   if(debug_lvl > 2)
583     syslog(LOG_DEBUG, "got DEL_HOST for " IP_ADDR_S,
584            IP_ADDR_V(tmp.vpn_ip));
585
586   if(!(fw = lookup_conn(tmp.vpn_ip)))
587     {
588       syslog(LOG_ERR, "Somebody wanted to delete " IP_ADDR_S " which does not exist?",
589              IP_ADDR_V(tmp.vpn_ip));
590       return 0;
591     }
592
593   notify_others(cl, fw, send_del_host);
594
595   fw->status.termreq = 1;
596   terminate_connection(fw);
597 cp
598   return 0;
599 }
600
601 int ping_h(conn_list_t *cl)
602 {
603 cp
604   if(debug_lvl > 3)
605     syslog(LOG_DEBUG, "responding to ping from " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
606   cl->status.pinged = 0;
607   cl->status.got_pong = 1;
608
609   send_pong(cl);
610 cp
611   return 0;
612 }
613
614 int pong_h(conn_list_t *cl)
615 {
616 cp
617   if(debug_lvl > 3)
618     syslog(LOG_DEBUG, "ok, got pong from " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
619   cl->status.got_pong = 1;
620 cp
621   return 0;
622 }
623
624 int add_host_h(conn_list_t *cl)
625 {
626   add_host_t tmp;
627   conn_list_t *ncn, *fw;
628 cp
629   if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-1) <= 0)
630     {
631       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
632       return -1;
633     }
634
635   if(debug_lvl > 2)
636     syslog(LOG_DEBUG, "Add host request from " IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
637   if(debug_lvl > 3)
638     syslog(LOG_DEBUG, "got ADD_HOST(" IP_ADDR_S "," IP_ADDR_S ",%hd)",
639            IP_ADDR_V(tmp.vpn_ip), IP_ADDR_V(tmp.vpn_mask), tmp.portnr);
640
641   /*
642     Suggestion of Hans Bayle
643   */
644   if((fw = lookup_conn(tmp.vpn_ip)))
645     {
646       notify_others(fw, cl, send_add_host);
647       return 0;
648     }
649
650   ncn = new_conn_list();
651   ncn->real_ip = tmp.real_ip;
652   ncn->vpn_ip = tmp.vpn_ip;
653   ncn->vpn_mask = tmp.vpn_mask;
654   ncn->port = tmp.portnr;
655   ncn->hostname = hostlookup(tmp.real_ip);
656   ncn->nexthop = cl;
657   ncn->next = conn_list;
658   conn_list = ncn;
659   ncn->status.active = 1;
660   notify_others(ncn, cl, send_add_host);
661 cp
662   return 0;
663 }
664
665 int req_key_h(conn_list_t *cl)
666 {
667   key_req_t tmp;
668   conn_list_t *fw;
669 cp
670   if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-1) <= 0)
671     {
672       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
673       return -1;
674     }
675
676   if(debug_lvl > 2)
677     syslog(LOG_DEBUG, "got REQ_KEY from " IP_ADDR_S " for " IP_ADDR_S,
678            IP_ADDR_V(tmp.from), IP_ADDR_V(tmp.to));
679
680   if((tmp.to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
681     {  /* hey! they want something from ME! :) */
682       send_key_answer(cl, tmp.from);
683       return 0;
684     }
685
686   fw = lookup_conn(tmp.to);
687   
688   if(!fw)
689     {
690       syslog(LOG_ERR, "Attempting to forward key request to " IP_ADDR_S ", which does not exist?",
691              IP_ADDR_V(tmp.to));
692       return -1;
693     }
694
695   if(debug_lvl > 3)
696     syslog(LOG_DEBUG, "Forwarding request for public key to " IP_ADDR_S,
697            IP_ADDR_V(fw->nexthop->vpn_ip));
698   
699   tmp.type = REQ_KEY;
700   tmp.key = 0;
701   if(write(fw->nexthop->meta_socket, &tmp, sizeof(tmp)) < 0)
702     {
703       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
704       return -1;
705     }
706 cp
707   return 0;
708 }
709
710 void set_keys(conn_list_t *cl, key_req_t *k, char *key)
711 {
712   char *ek;
713 cp
714   if(!cl->public_key)
715     {
716       cl->public_key = xmalloc(sizeof(*cl->key));
717       cl->public_key->key = NULL;
718     }
719   if(cl->public_key->key)
720     free(cl->public_key->key);
721   cl->public_key->length = k->len;
722   cl->public_key->expiry = k->expiry;
723   cl->public_key->key = xmalloc(k->len + 1);
724   strcpy(cl->public_key->key, key);
725
726   ek = make_shared_key(key);
727   if(!cl->key)
728     {
729       cl->key = xmalloc(sizeof(*cl->key));
730       cl->key->key = NULL;
731     }
732   if(cl->key->key)
733     free(cl->key->key);
734   cl->key->length = strlen(ek);
735   cl->key->expiry = k->expiry;
736   cl->key->key = xmalloc(strlen(ek) + 1);
737   strcpy(cl->key->key, ek);
738 cp
739 }
740
741 int ans_key_h(conn_list_t *cl)
742 {
743   key_req_t tmp;
744   conn_list_t *fw, *gk;
745   char *key;
746 cp
747   if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-2) <= 0)
748     {
749       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
750       return -1;
751     }
752
753   key = xmalloc(tmp.len);
754
755   if(read(cl->meta_socket, key, tmp.len + 1) <= 0)
756     {
757       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
758       return -1;
759     }
760
761   syslog(LOG_DEBUG, "key = %s", key);
762
763   if(debug_lvl > 3)
764     syslog(LOG_DEBUG, "got ANS_KEY from " IP_ADDR_S " for " IP_ADDR_S,
765            IP_ADDR_V(tmp.from), IP_ADDR_V(tmp.to));
766
767   if(tmp.to == myself->vpn_ip)
768     {  /* hey! that key's for ME! :) */
769       if(debug_lvl > 2)
770         syslog(LOG_DEBUG, "Yeah! key arrived. Now do something with it.");
771       gk = lookup_conn(tmp.from);
772
773       if(!gk)
774         {
775           syslog(LOG_ERR, "Receiving key from " IP_ADDR_S ", which does not exist?",
776                  IP_ADDR_V(tmp.from));
777           return -1;
778         }
779
780       set_keys(gk, &tmp, key);
781       gk->status.validkey = 1;
782       gk->status.waitingforkey = 0;
783       flush_queues(gk);
784       return 0;
785     }
786
787   fw = lookup_conn(tmp.to);
788   
789   if(!fw)
790     {
791       syslog(LOG_ERR, "Attempting to forward key to " IP_ADDR_S ", which does not exist?",
792              IP_ADDR_V(tmp.to));
793       return -1;
794     }
795
796   if(debug_lvl > 2)
797     syslog(LOG_DEBUG, "Forwarding public key to " IP_ADDR_S,
798            IP_ADDR_V(fw->nexthop->vpn_ip));
799   tmp.type = ANS_KEY;
800   if(write(fw->nexthop->meta_socket, &tmp, sizeof(tmp) -1) < 0)
801     {
802       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
803       return -1;
804     }
805   if(write(fw->nexthop->meta_socket, key, tmp.len + 1) < 0)
806     {
807       syslog(LOG_ERR, "send failed: %s:%d: %m", __FILE__, __LINE__);
808       return -1;
809     }
810 cp
811   return 0;
812 }
813
814 int key_changed_h(conn_list_t *cl)
815 {
816   key_changed_t tmp;
817   conn_list_t *ik;
818 cp
819   if(read(cl->meta_socket, &((char*)(&tmp))[1], sizeof(tmp)-1) <= 0)
820     {
821       syslog(LOG_ERR, "%d: Receive failed: %m", __LINE__);
822       return -1;
823     }
824
825   if(debug_lvl > 2)
826     syslog(LOG_DEBUG, "got KEY_CHANGED from " IP_ADDR_S,
827            IP_ADDR_V(tmp.from));
828
829   ik = lookup_conn(tmp.from);
830
831   if(!ik)
832     {
833       syslog(LOG_ERR, "Got changed key from " IP_ADDR_S ", which does not exist?",
834              IP_ADDR_V(tmp.from));
835       return -1;
836     }
837
838   ik->status.validkey = 0;
839   ik->status.waitingforkey = 0;
840
841   if(debug_lvl > 3)
842     syslog(LOG_DEBUG, "Forwarding key invalidation request");
843
844   notify_others(cl, ik, send_key_changed);
845 cp
846   return 0;
847 }
848
849 int (*request_handlers[256])(conn_list_t*) = {
850   0, ack_h, 0, 0, 0, 0, 0, 0, 0, 0,
851   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
852   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
853   termreq_h, timeout_h, del_host_h, 0, 0, 0, 0, 0, 0, 0,
854   ping_h, pong_h, 0, 0, 0, 0, 0, 0, 0, 0,
855   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
856   add_host_h, basic_info_h, passphrase_h, public_key_h, 0, 0, 0, 0, 0, 0,
857   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
858   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
859   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
860   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
861   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
862   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
863   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
864   req_key_h, ans_key_h, key_changed_h, 0, 0, 0, 0, 0, 0, 0,
865   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
866   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
867   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
868   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
869   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0
870 };