- Moved all connection messages to debug level 1, without -d's only the
[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.9 2000/06/26 20:30:21 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 "conf.h"
38 #include "encr.h"
39 #include "net.h"
40 #include "netutl.h"
41 #include "protocol.h"
42
43 #include "system.h"
44
45 char buffer[MAXBUFSIZE+1];
46 int buflen;
47
48 /* Outgoing request routines */
49
50 int send_ack(conn_list_t *cl)
51 {
52 cp
53   if(debug_lvl > 1)
54     syslog(LOG_DEBUG, _("Sending ACK to " IP_ADDR_S " (%s)"),
55            IP_ADDR_V(cl->vpn_ip), cl->hostname);
56
57   buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", ACK);
58
59   if((write(cl->meta_socket, buffer, buflen)) < 0)
60     {
61       syslog(LOG_ERR, _("Send failed: %d:%d: %m"), __FILE__, __LINE__);
62       return -1;
63     }
64
65   if(debug_lvl > 0)
66     syslog(LOG_NOTICE, _("Connection with " IP_ADDR_S " (%s) activated"),
67                        IP_ADDR_V(cl->vpn_ip), cl->hostname);
68 cp
69   return 0;
70 }
71
72 int send_termreq(conn_list_t *cl)
73 {
74 cp
75   if(debug_lvl > 1)
76     syslog(LOG_DEBUG, _("Sending TERMREQ to " IP_ADDR_S " (%s)"),
77            IP_ADDR_V(cl->vpn_ip), cl->hostname);
78
79   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", TERMREQ, myself->vpn_ip);
80
81   if(write(cl->meta_socket, buffer, buflen) < 0)
82     {
83       if(debug_lvl > 1)
84         syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
85       return -1;
86     }
87 cp
88   return 0;
89 }
90
91 int send_timeout(conn_list_t *cl)
92 {
93 cp
94   if(debug_lvl > 1)
95     syslog(LOG_DEBUG, _("Sending TIMEOUT to " IP_ADDR_S " (%s)"),
96            IP_ADDR_V(cl->vpn_ip), cl->hostname);
97
98   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", PINGTIMEOUT, myself->vpn_ip);
99
100   if((write(cl->meta_socket, buffer, buflen)) < 0)
101     {
102       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
103       return -1;
104     }
105 cp
106   return 0;
107 }
108
109 int send_del_host(conn_list_t *cl, conn_list_t *new_host)
110 {
111 cp
112   if(debug_lvl > 1)
113     syslog(LOG_DEBUG, _("Sending DEL_HOST for " IP_ADDR_S " to " IP_ADDR_S " (%s)"),
114            IP_ADDR_V(new_host->vpn_ip), IP_ADDR_V(cl->vpn_ip), cl->hostname);
115
116   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", DEL_HOST, new_host->vpn_ip);
117
118   if((write(cl->meta_socket, buffer, buflen)) < 0)
119     {
120       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
121       return -1;
122     }
123 cp
124   return 0;
125 }
126
127 int send_ping(conn_list_t *cl)
128 {
129 cp
130   if(debug_lvl > 1)
131     syslog(LOG_DEBUG, _("Sending PING to " IP_ADDR_S " (%s)"),
132            IP_ADDR_V(cl->vpn_ip), cl->hostname);
133
134   buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PING);
135
136   if((write(cl->meta_socket, buffer, buflen)) < 0)
137     {
138       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
139       return -1;
140     }
141 cp
142   return 0;
143 }
144
145 int send_pong(conn_list_t *cl)
146 {
147 cp
148   if(debug_lvl > 1)
149     syslog(LOG_DEBUG, _("Sending PONG to " IP_ADDR_S " (%s)"),
150            IP_ADDR_V(cl->vpn_ip), cl->hostname);
151
152   buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PONG);
153
154   if((write(cl->meta_socket, buffer, buflen)) < 0)
155     {
156       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
157       return -1;
158     }
159 cp
160   return 0;
161 }
162
163 int send_add_host(conn_list_t *cl, conn_list_t *new_host)
164 {
165   ip_t real_ip;
166   int flags;
167   char *hostname;
168 cp
169   real_ip = new_host->real_ip;
170   hostname = new_host->hostname;
171   flags = new_host->flags;
172   
173   /* If we need to propagate information about a new host that wants us to export
174    * it's indirectdata flag, we set the INDIRECTDATA flag and unset the EXPORT...
175    * flag, and set it's real_ip to our vpn_ip, so that net.c send_packet() will
176    * work correctly.
177    */
178      
179   if(flags & EXPORTINDIRECTDATA)
180     {
181       flags &= ~EXPORTINDIRECTDATA;
182       flags |= INDIRECTDATA;
183       real_ip = myself->vpn_ip;
184       hostname = myself->hostname;
185     }
186
187   if(debug_lvl > 1)
188     syslog(LOG_DEBUG, _("Sending ADD_HOST for " IP_ADDR_S " (%s) to " IP_ADDR_S " (%s)"),
189            IP_ADDR_V(new_host->vpn_ip), hostname, IP_ADDR_V(cl->vpn_ip), cl->hostname);
190
191   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx/%lx:%x %d\n", ADD_HOST, real_ip, new_host->vpn_ip, new_host->vpn_mask, new_host->port, flags);
192
193   if((write(cl->meta_socket, buffer, buflen)) < 0)
194     {
195       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
196       return -1;
197     }
198 cp
199   return 0;
200 }
201
202 int send_key_changed(conn_list_t *cl, conn_list_t *src)
203 {
204 cp
205   if(debug_lvl > 1)
206     syslog(LOG_DEBUG, _("Sending KEY_CHANGED origin " IP_ADDR_S " to " IP_ADDR_S " (%s)"),
207            IP_ADDR_V(src->vpn_ip), IP_ADDR_V(cl->vpn_ip), cl->hostname);
208
209   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", KEY_CHANGED, src->vpn_ip);
210
211   if((write(cl->meta_socket, buffer, buflen)) < 0)
212     {
213       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
214       return -1;
215     }
216 cp
217   return 0;
218 }
219
220 void send_key_changed_all(void)
221 {
222   conn_list_t *p;
223 cp
224   for(p = conn_list; p != NULL; p = p->next)
225     if(p->status.meta && p->status.active)
226       send_key_changed(p, myself);
227 cp
228 }
229
230 int send_basic_info(conn_list_t *cl)
231 {
232 cp
233   if(debug_lvl > 1)
234     syslog(LOG_DEBUG, _("Sending BASIC_INFO to %s"),
235            cl->hostname);
236
237   buflen = snprintf(buffer, MAXBUFSIZE, "%d %d %lx/%lx:%x %d\n", BASIC_INFO, PROT_CURRENT, myself->vpn_ip, myself->vpn_mask, myself->port, myself->flags);
238
239   if((write(cl->meta_socket, buffer, buflen)) < 0)
240     {
241       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
242       return -1;
243     }
244 cp
245   return 0;
246 }
247
248 int send_passphrase(conn_list_t *cl)
249 {
250   passphrase_t tmp;
251 cp
252   encrypt_passphrase(&tmp);
253
254   if(debug_lvl > 1)
255     syslog(LOG_DEBUG, _("Sending PASSPHRASE to " IP_ADDR_S " (%s)"),
256            IP_ADDR_V(cl->vpn_ip), cl->hostname);
257
258   buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PASSPHRASE, tmp.phrase);
259
260   if((write(cl->meta_socket, buffer, buflen)) < 0)
261     {
262       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
263       return -1;
264     }
265 cp
266   return 0;
267 }
268
269 int send_public_key(conn_list_t *cl)
270 {
271 cp
272   if(debug_lvl > 1)
273     syslog(LOG_DEBUG, _("Sending PUBLIC_KEY to " IP_ADDR_S " (%s)"),
274            IP_ADDR_V(cl->vpn_ip), cl->hostname);
275
276   buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PUBLIC_KEY, my_public_key_base36);
277
278   if((write(cl->meta_socket, buffer, buflen)) < 0)
279     {
280       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
281       return -1;
282     }
283 cp
284   return 0;
285 }
286
287 /* WDN doet deze functie? (GS)
288 int send_calculate(conn_list_t *cl, char *k)
289 {
290 cp
291   buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", CALCULATE, k);
292
293   if((write(cl->meta_socket, buffer, buflen)) < 0)
294     {
295       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
296       return -1;
297     }
298 cp
299   return 0;
300 }
301 */
302
303 int send_key_request(ip_t to)
304 {
305   conn_list_t *fw;
306 cp
307   fw = lookup_conn(to);
308   if(!fw)
309     {
310       syslog(LOG_ERR, _("Attempting to send REQ_KEY to " IP_ADDR_S ", which does not exist?"),
311              IP_ADDR_V(to));
312       return -1;
313     }
314
315   if(debug_lvl > 1)
316     syslog(LOG_DEBUG, _("Sending REQ_KEY to " IP_ADDR_S " (%s)"),
317            IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
318
319   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx\n", REQ_KEY, to, myself->vpn_ip);
320
321   if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
322     {
323       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
324       return -1;
325     }
326   fw->status.waitingforkey = 1;
327 cp
328   return 0;
329 }
330
331 int send_key_answer(conn_list_t *cl, ip_t to)
332 {
333   conn_list_t *fw;
334 cp
335
336   fw = lookup_conn(to);
337   
338   if(!fw)
339     {
340       syslog(LOG_ERR, _("Attempting to send ANS_KEY to " IP_ADDR_S ", which does not exist?"),
341              IP_ADDR_V(to));
342       return -1;
343     }
344
345  if(debug_lvl > 1)
346     syslog(LOG_DEBUG, _("Sending ANS_KEY to " IP_ADDR_S " (%s)"),
347            IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
348
349   buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx %d %s\n", ANS_KEY, to, myself->vpn_ip, my_key_expiry, my_public_key_base36);
350
351   if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
352     {
353       syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
354       return -1;
355     }
356 cp
357   return 0;
358 }
359
360 /*
361   notify all my direct connections of a new host
362   that was added to the vpn, with the exception
363   of the source of the announcement.
364 */
365 int notify_others(conn_list_t *new, conn_list_t *source,
366                   int (*function)(conn_list_t*, conn_list_t*))
367 {
368   conn_list_t *p;
369 cp
370   for(p = conn_list; p != NULL; p = p->next)
371     if(p != new && p != source && p->status.meta && p->status.active)
372       function(p, new);
373 cp
374   return 0;
375 }
376
377 /*
378   notify one connection of everything
379   i have connected
380 */
381 int notify_one(conn_list_t *new)
382 {
383   conn_list_t *p;
384 cp
385   for(p = conn_list; p != NULL; p = p->next)
386     if(p != new && p->status.active)
387       send_add_host(new, p);
388 cp
389   return 0;
390 }
391
392 /*
393   The incoming request handlers
394 */
395
396 int basic_info_h(conn_list_t *cl)
397 {
398 cp
399   if(debug_lvl > 1)
400     syslog(LOG_DEBUG, _("Got BASIC_INFO from %s"), cl->hostname);
401
402   if(sscanf(cl->buffer, "%*d %d %lx/%lx:%hx %d", &cl->protocol_version, &cl->vpn_ip, &cl->vpn_mask, &cl->port, &cl->flags) != 5)
403     {
404        syslog(LOG_ERR, _("Got bad BASIC_INFO from %s"),
405               cl->hostname);
406        return -1;
407     }  
408
409   if(cl->protocol_version != PROT_CURRENT)
410     {
411       syslog(LOG_ERR, _("Peer uses incompatible protocol version %d"),
412              cl->protocol_version);
413       return -1;
414     }
415
416   if(cl->status.outgoing)
417     {
418       if(setup_vpn_connection(cl) < 0)
419         return -1;
420       send_basic_info(cl);
421     }
422   else
423     {
424       if(setup_vpn_connection(cl) < 0)
425         return -1;
426       send_passphrase(cl);
427     }
428 cp
429   return 0;
430 }
431
432 int passphrase_h(conn_list_t *cl)
433 {
434 cp
435   cl->pp = xmalloc(sizeof(*(cl->pp)));
436
437   if(sscanf(cl->buffer, "%*d %as", &(cl->pp->phrase)) != 1)
438     {
439       syslog(LOG_ERR, _("Got bad PASSPHRASE from " IP_ADDR_S " (%s)"),
440               IP_ADDR_V(cl->vpn_ip), cl->hostname);
441       return -1;
442     }
443   cl->pp->len = strlen(cl->pp->phrase);
444     
445   if(debug_lvl > 1)
446     syslog(LOG_DEBUG, _("Got PASSPHRASE from " IP_ADDR_S " (%s)"),
447               IP_ADDR_V(cl->vpn_ip), cl->hostname);
448
449   if(cl->status.outgoing)
450     send_passphrase(cl);
451   else
452     send_public_key(cl);
453 cp
454   return 0;
455 }
456
457 int public_key_h(conn_list_t *cl)
458 {
459   char *g_n;
460   conn_list_t *old;
461 cp
462   if(sscanf(cl->buffer, "%*d %as", &g_n) != 1)
463     {
464        syslog(LOG_ERR, _("Got bad PUBLIC_KEY from " IP_ADDR_S " (%s)"),
465               IP_ADDR_V(cl->vpn_ip), cl->hostname);
466        return -1;
467     }  
468
469   if(debug_lvl > 1)
470     syslog(LOG_DEBUG, _("Got PUBLIC_KEY from " IP_ADDR_S " (%s)"),
471               IP_ADDR_V(cl->vpn_ip), cl->hostname);
472
473   if(verify_passphrase(cl, g_n))
474     {
475       /* intruder! */
476       syslog(LOG_ERR, _("Intruder: passphrase does not match!"));
477       return -1;
478     }
479
480   if(cl->status.outgoing)
481     send_public_key(cl);
482   else
483     {
484       send_ack(cl);
485
486       /* Okay, before we active the connection, we check if there is another entry
487          in the connection list with the same vpn_ip. If so, it presumably is an
488          old connection that has timed out but we don't know it yet. Because our
489          conn_list entry is not active, lookup_conn will skip ourself. */
490
491       while(old=lookup_conn(cl->vpn_ip)) 
492         terminate_connection(old);
493
494       cl->status.active = 1;
495       notify_others(cl, NULL, send_add_host);
496       notify_one(cl);
497     }
498 cp
499   return 0;
500 }
501
502 int ack_h(conn_list_t *cl)
503 {
504 cp
505   if(debug_lvl > 1)
506     syslog(LOG_DEBUG, _("Got ACK from " IP_ADDR_S " (%s)"),
507               IP_ADDR_V(cl->vpn_ip), cl->hostname);
508   
509   cl->status.active = 1;
510   syslog(LOG_NOTICE, _("Connection with " IP_ADDR_S " (%s) activated"),
511               IP_ADDR_V(cl->vpn_ip), cl->hostname);
512 cp
513   return 0;
514 }
515
516 int termreq_h(conn_list_t *cl)
517 {
518 cp
519   if(!cl->status.active)
520     {
521       syslog(LOG_ERR, _("Got unauthorized TERMREQ from " IP_ADDR_S " (%s)"),
522               IP_ADDR_V(cl->vpn_ip), cl->hostname);
523       return -1;
524     }
525     
526   if(debug_lvl > 1)
527    syslog(LOG_DEBUG, _("Got TERMREQ from " IP_ADDR_S " (%s)"),
528              IP_ADDR_V(cl->vpn_ip), cl->hostname);
529   
530   cl->status.termreq = 1;
531
532   if(cl->status.active)
533     notify_others(cl, NULL, send_del_host);
534
535   cl->status.active = 0;
536
537   terminate_connection(cl);
538 cp
539   return 0;
540 }
541
542 int timeout_h(conn_list_t *cl)
543 {
544 cp
545   if(!cl->status.active)
546     {
547       syslog(LOG_ERR, _("Got unauthorized TIMEOUT from " IP_ADDR_S " (%s)"),
548               IP_ADDR_V(cl->vpn_ip), cl->hostname);
549       return -1;
550     }
551
552   if(debug_lvl > 1)
553     syslog(LOG_DEBUG, _("Got TIMEOUT from " IP_ADDR_S " (%s)"),
554               IP_ADDR_V(cl->vpn_ip), cl->hostname);
555
556   cl->status.termreq = 1;
557   terminate_connection(cl);
558 cp
559   return 0;
560 }
561
562 int del_host_h(conn_list_t *cl)
563 {
564   ip_t vpn_ip;
565   conn_list_t *fw;
566 cp
567   if(!cl->status.active)
568     {
569       syslog(LOG_ERR, _("Got unauthorized DEL_HOST from " IP_ADDR_S " (%s)"),
570               IP_ADDR_V(cl->vpn_ip), cl->hostname);
571       return -1;
572     }
573
574   if(sscanf(cl->buffer, "%*d %lx", &vpn_ip) != 1)
575     {
576        syslog(LOG_ERR, _("Got bad DEL_HOST from " IP_ADDR_S " (%s)"),
577               IP_ADDR_V(cl->vpn_ip), cl->hostname);
578        return -1;
579     }  
580
581   if(debug_lvl > 1)
582     syslog(LOG_DEBUG, _("Got DEL_HOST for " IP_ADDR_S " from " IP_ADDR_S " (%s)"),
583            IP_ADDR_V(vpn_ip), IP_ADDR_V(cl->vpn_ip), cl->hostname);
584
585   if(!(fw = lookup_conn(vpn_ip)))
586     {
587       syslog(LOG_ERR, _("Got DEL_HOST for " IP_ADDR_S " from " IP_ADDR_S " (%s) which does not exist?"),
588              IP_ADDR_V(vpn_ip), IP_ADDR_V(cl->vpn_ip), cl->hostname);
589       return 0;
590     }
591
592   notify_others(fw, cl, send_del_host);
593
594   fw->status.termreq = 1;
595   fw->status.active = 0;
596
597   terminate_connection(fw);
598 cp
599   return 0;
600 }
601
602 int ping_h(conn_list_t *cl)
603 {
604 cp
605   if(!cl->status.active)
606     {
607       syslog(LOG_ERR, _("Got unauthorized PING from " IP_ADDR_S " (%s)"),
608               IP_ADDR_V(cl->vpn_ip), cl->hostname);
609       return -1;
610     }
611
612   if(debug_lvl > 1)
613     syslog(LOG_DEBUG, _("Got PING from " IP_ADDR_S " (%s)"),
614               IP_ADDR_V(cl->vpn_ip), cl->hostname);
615
616   cl->status.pinged = 0;
617   cl->status.got_pong = 1;
618
619   send_pong(cl);
620 cp
621   return 0;
622 }
623
624 int pong_h(conn_list_t *cl)
625 {
626 cp
627   if(!cl->status.active)
628     {
629       syslog(LOG_ERR, _("Got unauthorized PONG from " IP_ADDR_S " (%s)"),
630               IP_ADDR_V(cl->vpn_ip), cl->hostname);
631       return -1;
632     }
633
634   if(debug_lvl > 1)
635     syslog(LOG_DEBUG, _("Got PONG from " IP_ADDR_S " (%s)"),
636               IP_ADDR_V(cl->vpn_ip), cl->hostname);
637
638   cl->status.got_pong = 1;
639 cp
640   return 0;
641 }
642
643 int add_host_h(conn_list_t *cl)
644 {
645   ip_t real_ip;
646   ip_t vpn_ip;
647   ip_t vpn_mask;
648   unsigned short port;
649   int flags;
650   conn_list_t *ncn, *fw;
651 cp
652   if(!cl->status.active)
653     {
654       syslog(LOG_ERR, _("Got unauthorized ADD_HOST from " IP_ADDR_S " (%s)"),
655               IP_ADDR_V(cl->vpn_ip), cl->hostname);
656       return -1;
657     }
658     
659   if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx %d", &real_ip, &vpn_ip, &vpn_mask, &port, &flags) != 5)
660     {
661        syslog(LOG_ERR, _("Got bad ADD_HOST from " IP_ADDR_S " (%s)"),
662               IP_ADDR_V(cl->vpn_ip), cl->hostname);
663        return -1;
664     }  
665
666   /*
667     Suggestion of Hans Bayle
668   */
669   if((fw = lookup_conn(vpn_ip)))
670     {
671       if(fw->nexthop == cl)
672         notify_others(fw, cl, send_add_host);
673       else
674         syslog(LOG_DEBUG, _("Invalid ADD_HOST from " IP_ADDR_S " (%s)"),
675             IP_ADDR_V(cl->vpn_ip), cl->hostname);
676       return -1;
677     }
678
679   ncn = new_conn_list();
680   ncn->real_ip = real_ip;
681   ncn->hostname = hostlookup(htonl(real_ip));
682   ncn->vpn_ip = vpn_ip;
683   ncn->vpn_mask = vpn_mask;
684   ncn->port = port;
685   ncn->flags = flags;
686   ncn->nexthop = cl;
687   ncn->next = conn_list;
688   conn_list = ncn;
689   ncn->status.active = 1;
690
691   if(debug_lvl > 1)
692     syslog(LOG_DEBUG, _("Got ADD_HOST for " IP_ADDR_S " (%s) from " IP_ADDR_S " (%s)"),
693            IP_ADDR_V(ncn->vpn_ip), ncn->hostname, IP_ADDR_V(cl->vpn_ip), cl->hostname);
694
695   notify_others(ncn, cl, send_add_host);
696 cp
697   return 0;
698 }
699
700 int req_key_h(conn_list_t *cl)
701 {
702   ip_t to;
703   ip_t from;
704   conn_list_t *fw;
705 cp
706   if(!cl->status.active)
707     {
708       syslog(LOG_ERR, _("Got unauthorized REQ_KEY from " IP_ADDR_S " (%s)"),
709               IP_ADDR_V(cl->vpn_ip), cl->hostname);
710       return -1;
711     }
712
713   if(sscanf(cl->buffer, "%*d %lx %lx", &to, &from) != 2)
714     {
715        syslog(LOG_ERR, _("Got bad REQ_KEY from " IP_ADDR_S " (%s)"),
716               IP_ADDR_V(cl->vpn_ip), cl->hostname);
717        return -1;
718     }  
719
720   if(debug_lvl > 1)
721     syslog(LOG_DEBUG, _("Got REQ_KEY origin " IP_ADDR_S " destination " IP_ADDR_S " from " IP_ADDR_S " (%s)"),
722            IP_ADDR_V(from), IP_ADDR_V(to), IP_ADDR_V(cl->vpn_ip), cl->hostname);
723
724   if((to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
725     {  /* hey! they want something from ME! :) */
726       send_key_answer(cl, from);
727       return 0;
728     }
729
730   fw = lookup_conn(to);
731   
732   if(!fw)
733     {
734       syslog(LOG_ERR, _("Attempting to forward REQ_KEY to " IP_ADDR_S ", which does not exist?"),
735              IP_ADDR_V(to));
736       return -1;
737     }
738
739   if(debug_lvl > 1)
740     syslog(LOG_DEBUG, _("Forwarding REQ_KEY to " IP_ADDR_S " (%s)"),
741            IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
742   
743   cl->buffer[cl->reqlen-1] = '\n';
744   
745   if(write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen) < 0)
746     {
747       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
748       return -1;
749     }
750 cp
751   return 0;
752 }
753
754 void set_keys(conn_list_t *cl, int expiry, char *key)
755 {
756   char *ek;
757 cp
758   if(!cl->public_key)
759     {
760       cl->public_key = xmalloc(sizeof(*cl->key));
761       cl->public_key->key = NULL;
762     }
763     
764   if(cl->public_key->key)
765     free(cl->public_key->key);
766   cl->public_key->length = strlen(key);
767   cl->public_key->expiry = expiry;
768   cl->public_key->key = xmalloc(cl->public_key->length + 1);
769   strcpy(cl->public_key->key, key);
770
771   ek = make_shared_key(key);
772   
773   if(!cl->key)
774     {
775       cl->key = xmalloc(sizeof(*cl->key));
776       cl->key->key = NULL;
777     }
778
779   if(cl->key->key)
780     free(cl->key->key);
781
782   cl->key->length = strlen(ek);
783   cl->key->expiry = expiry;
784   cl->key->key = xmalloc(cl->key->length + 1);
785   strcpy(cl->key->key, ek);
786 cp
787 }
788
789 int ans_key_h(conn_list_t *cl)
790 {
791   ip_t to;
792   ip_t from;
793   int expiry;
794   char *key;
795   conn_list_t *fw, *gk;
796 cp
797   if(!cl->status.active)
798     {
799       syslog(LOG_ERR, _("Got unauthorized ANS_KEY from " IP_ADDR_S " (%s)"),
800               IP_ADDR_V(cl->vpn_ip), cl->hostname);
801       return -1;
802     }
803
804   if(sscanf(cl->buffer, "%*d %lx %lx %d %as", &to, &from, &expiry, &key) != 4)
805     {
806        syslog(LOG_ERR, _("Got bad ANS_KEY from " IP_ADDR_S " (%s)"),
807               IP_ADDR_V(cl->vpn_ip), cl->hostname);
808        return -1;
809     }  
810
811   if(debug_lvl > 1)
812     syslog(LOG_DEBUG, _("Got ANS_KEY origin " IP_ADDR_S " destination " IP_ADDR_S " from " IP_ADDR_S " (%s)"),
813             IP_ADDR_V(from), IP_ADDR_V(to), IP_ADDR_V(cl->vpn_ip), cl->hostname);
814
815   if(to == myself->vpn_ip)
816     {  /* hey! that key's for ME! :) */
817       gk = lookup_conn(from);
818
819       if(!gk)
820         {
821           syslog(LOG_ERR, _("Receiving ANS_KEY from " IP_ADDR_S ", which does not exist?"),
822                  IP_ADDR_V(from));
823           return -1;
824         }
825
826       set_keys(gk, expiry, key);
827       gk->status.validkey = 1;
828       gk->status.waitingforkey = 0;
829       flush_queues(gk);
830       return 0;
831     }
832
833   fw = lookup_conn(to);
834   
835   if(!fw)
836     {
837       syslog(LOG_ERR, _("Attempting to forward ANS_KEY to " IP_ADDR_S ", which does not exist?"),
838              IP_ADDR_V(to));
839       return -1;
840     }
841
842   if(debug_lvl > 1)
843     syslog(LOG_DEBUG, _("Forwarding ANS_KEY to " IP_ADDR_S " (%s)"),
844            IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
845
846   cl->buffer[cl->reqlen-1] = '\n';
847
848   if((write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen)) < 0)
849     {
850       syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
851       return -1;
852     }
853 cp
854   return 0;
855 }
856
857 int key_changed_h(conn_list_t *cl)
858 {
859   ip_t from;
860   conn_list_t *ik;
861 cp
862   if(!cl->status.active)
863     {
864       syslog(LOG_ERR, _("Got unauthorized KEY_CHANGED from " IP_ADDR_S " (%s)"),
865               IP_ADDR_V(cl->vpn_ip), cl->hostname);
866       return -1;
867     }
868
869   if(sscanf(cl->buffer, "%*d %lx", &from) != 1)
870     {
871        syslog(LOG_ERR, _("Got bad KEY_CHANGED from " IP_ADDR_S " (%s)"),
872               IP_ADDR_V(cl->vpn_ip), cl->hostname);
873        return -1;
874     }  
875
876   if(debug_lvl > 1)
877     syslog(LOG_DEBUG, _("Got KEY_CHANGED origin " IP_ADDR_S " from " IP_ADDR_S " (%s)"),
878             IP_ADDR_V(from), IP_ADDR_V(cl->vpn_ip), cl->hostname);
879
880   ik = lookup_conn(from);
881
882   if(!ik)
883     {
884       syslog(LOG_ERR, _("Got KEY_CHANGED from " IP_ADDR_S ", which does not exist?"),
885              IP_ADDR_V(from));
886       return -1;
887     }
888
889   ik->status.validkey = 0;
890   ik->status.waitingforkey = 0;
891
892   notify_others(cl, ik, send_key_changed);
893 cp
894   return 0;
895 }
896
897 int (*request_handlers[256])(conn_list_t*) = {
898   0, ack_h, 0, 0, 0, 0, 0, 0, 0, 0,
899   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
900   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
901   termreq_h, timeout_h, del_host_h, 0, 0, 0, 0, 0, 0, 0,
902   ping_h, pong_h, 0, 0, 0, 0, 0, 0, 0, 0,
903   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
904   add_host_h, basic_info_h, passphrase_h, public_key_h, 0, 0, 0, 0, 0, 0,
905   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
906   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
907   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
908   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
909   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
910   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
911   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
912   req_key_h, ans_key_h, key_changed_h, 0, 0, 0, 0, 0, 0, 0,
913   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
914   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
915   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
916   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
917   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0
918 };