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>
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.
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.
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.
20 $Id: protocol.c,v 1.28.4.9 2000/06/26 20:30:21 guus Exp $
25 #include <sys/types.h>
30 #include <sys/socket.h>
45 char buffer[MAXBUFSIZE+1];
48 /* Outgoing request routines */
50 int send_ack(conn_list_t *cl)
54 syslog(LOG_DEBUG, _("Sending ACK to " IP_ADDR_S " (%s)"),
55 IP_ADDR_V(cl->vpn_ip), cl->hostname);
57 buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", ACK);
59 if((write(cl->meta_socket, buffer, buflen)) < 0)
61 syslog(LOG_ERR, _("Send failed: %d:%d: %m"), __FILE__, __LINE__);
66 syslog(LOG_NOTICE, _("Connection with " IP_ADDR_S " (%s) activated"),
67 IP_ADDR_V(cl->vpn_ip), cl->hostname);
72 int send_termreq(conn_list_t *cl)
76 syslog(LOG_DEBUG, _("Sending TERMREQ to " IP_ADDR_S " (%s)"),
77 IP_ADDR_V(cl->vpn_ip), cl->hostname);
79 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", TERMREQ, myself->vpn_ip);
81 if(write(cl->meta_socket, buffer, buflen) < 0)
84 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
91 int send_timeout(conn_list_t *cl)
95 syslog(LOG_DEBUG, _("Sending TIMEOUT to " IP_ADDR_S " (%s)"),
96 IP_ADDR_V(cl->vpn_ip), cl->hostname);
98 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", PINGTIMEOUT, myself->vpn_ip);
100 if((write(cl->meta_socket, buffer, buflen)) < 0)
102 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
109 int send_del_host(conn_list_t *cl, conn_list_t *new_host)
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);
116 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", DEL_HOST, new_host->vpn_ip);
118 if((write(cl->meta_socket, buffer, buflen)) < 0)
120 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
127 int send_ping(conn_list_t *cl)
131 syslog(LOG_DEBUG, _("Sending PING to " IP_ADDR_S " (%s)"),
132 IP_ADDR_V(cl->vpn_ip), cl->hostname);
134 buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PING);
136 if((write(cl->meta_socket, buffer, buflen)) < 0)
138 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
145 int send_pong(conn_list_t *cl)
149 syslog(LOG_DEBUG, _("Sending PONG to " IP_ADDR_S " (%s)"),
150 IP_ADDR_V(cl->vpn_ip), cl->hostname);
152 buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PONG);
154 if((write(cl->meta_socket, buffer, buflen)) < 0)
156 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
163 int send_add_host(conn_list_t *cl, conn_list_t *new_host)
169 real_ip = new_host->real_ip;
170 hostname = new_host->hostname;
171 flags = new_host->flags;
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
179 if(flags & EXPORTINDIRECTDATA)
181 flags &= ~EXPORTINDIRECTDATA;
182 flags |= INDIRECTDATA;
183 real_ip = myself->vpn_ip;
184 hostname = myself->hostname;
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);
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);
193 if((write(cl->meta_socket, buffer, buflen)) < 0)
195 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
202 int send_key_changed(conn_list_t *cl, conn_list_t *src)
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);
209 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", KEY_CHANGED, src->vpn_ip);
211 if((write(cl->meta_socket, buffer, buflen)) < 0)
213 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
220 void send_key_changed_all(void)
224 for(p = conn_list; p != NULL; p = p->next)
225 if(p->status.meta && p->status.active)
226 send_key_changed(p, myself);
230 int send_basic_info(conn_list_t *cl)
234 syslog(LOG_DEBUG, _("Sending BASIC_INFO to %s"),
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);
239 if((write(cl->meta_socket, buffer, buflen)) < 0)
241 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
248 int send_passphrase(conn_list_t *cl)
252 encrypt_passphrase(&tmp);
255 syslog(LOG_DEBUG, _("Sending PASSPHRASE to " IP_ADDR_S " (%s)"),
256 IP_ADDR_V(cl->vpn_ip), cl->hostname);
258 buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PASSPHRASE, tmp.phrase);
260 if((write(cl->meta_socket, buffer, buflen)) < 0)
262 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
269 int send_public_key(conn_list_t *cl)
273 syslog(LOG_DEBUG, _("Sending PUBLIC_KEY to " IP_ADDR_S " (%s)"),
274 IP_ADDR_V(cl->vpn_ip), cl->hostname);
276 buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PUBLIC_KEY, my_public_key_base36);
278 if((write(cl->meta_socket, buffer, buflen)) < 0)
280 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
287 /* WDN doet deze functie? (GS)
288 int send_calculate(conn_list_t *cl, char *k)
291 buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", CALCULATE, k);
293 if((write(cl->meta_socket, buffer, buflen)) < 0)
295 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
303 int send_key_request(ip_t to)
307 fw = lookup_conn(to);
310 syslog(LOG_ERR, _("Attempting to send REQ_KEY to " IP_ADDR_S ", which does not exist?"),
316 syslog(LOG_DEBUG, _("Sending REQ_KEY to " IP_ADDR_S " (%s)"),
317 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
319 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx\n", REQ_KEY, to, myself->vpn_ip);
321 if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
323 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
326 fw->status.waitingforkey = 1;
331 int send_key_answer(conn_list_t *cl, ip_t to)
336 fw = lookup_conn(to);
340 syslog(LOG_ERR, _("Attempting to send ANS_KEY to " IP_ADDR_S ", which does not exist?"),
346 syslog(LOG_DEBUG, _("Sending ANS_KEY to " IP_ADDR_S " (%s)"),
347 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
349 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx %d %s\n", ANS_KEY, to, myself->vpn_ip, my_key_expiry, my_public_key_base36);
351 if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
353 syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
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.
365 int notify_others(conn_list_t *new, conn_list_t *source,
366 int (*function)(conn_list_t*, conn_list_t*))
370 for(p = conn_list; p != NULL; p = p->next)
371 if(p != new && p != source && p->status.meta && p->status.active)
378 notify one connection of everything
381 int notify_one(conn_list_t *new)
385 for(p = conn_list; p != NULL; p = p->next)
386 if(p != new && p->status.active)
387 send_add_host(new, p);
393 The incoming request handlers
396 int basic_info_h(conn_list_t *cl)
400 syslog(LOG_DEBUG, _("Got BASIC_INFO from %s"), cl->hostname);
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)
404 syslog(LOG_ERR, _("Got bad BASIC_INFO from %s"),
409 if(cl->protocol_version != PROT_CURRENT)
411 syslog(LOG_ERR, _("Peer uses incompatible protocol version %d"),
412 cl->protocol_version);
416 if(cl->status.outgoing)
418 if(setup_vpn_connection(cl) < 0)
424 if(setup_vpn_connection(cl) < 0)
432 int passphrase_h(conn_list_t *cl)
435 cl->pp = xmalloc(sizeof(*(cl->pp)));
437 if(sscanf(cl->buffer, "%*d %as", &(cl->pp->phrase)) != 1)
439 syslog(LOG_ERR, _("Got bad PASSPHRASE from " IP_ADDR_S " (%s)"),
440 IP_ADDR_V(cl->vpn_ip), cl->hostname);
443 cl->pp->len = strlen(cl->pp->phrase);
446 syslog(LOG_DEBUG, _("Got PASSPHRASE from " IP_ADDR_S " (%s)"),
447 IP_ADDR_V(cl->vpn_ip), cl->hostname);
449 if(cl->status.outgoing)
457 int public_key_h(conn_list_t *cl)
462 if(sscanf(cl->buffer, "%*d %as", &g_n) != 1)
464 syslog(LOG_ERR, _("Got bad PUBLIC_KEY from " IP_ADDR_S " (%s)"),
465 IP_ADDR_V(cl->vpn_ip), cl->hostname);
470 syslog(LOG_DEBUG, _("Got PUBLIC_KEY from " IP_ADDR_S " (%s)"),
471 IP_ADDR_V(cl->vpn_ip), cl->hostname);
473 if(verify_passphrase(cl, g_n))
476 syslog(LOG_ERR, _("Intruder: passphrase does not match!"));
480 if(cl->status.outgoing)
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. */
491 while(old=lookup_conn(cl->vpn_ip))
492 terminate_connection(old);
494 cl->status.active = 1;
495 notify_others(cl, NULL, send_add_host);
502 int ack_h(conn_list_t *cl)
506 syslog(LOG_DEBUG, _("Got ACK from " IP_ADDR_S " (%s)"),
507 IP_ADDR_V(cl->vpn_ip), cl->hostname);
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);
516 int termreq_h(conn_list_t *cl)
519 if(!cl->status.active)
521 syslog(LOG_ERR, _("Got unauthorized TERMREQ from " IP_ADDR_S " (%s)"),
522 IP_ADDR_V(cl->vpn_ip), cl->hostname);
527 syslog(LOG_DEBUG, _("Got TERMREQ from " IP_ADDR_S " (%s)"),
528 IP_ADDR_V(cl->vpn_ip), cl->hostname);
530 cl->status.termreq = 1;
532 if(cl->status.active)
533 notify_others(cl, NULL, send_del_host);
535 cl->status.active = 0;
537 terminate_connection(cl);
542 int timeout_h(conn_list_t *cl)
545 if(!cl->status.active)
547 syslog(LOG_ERR, _("Got unauthorized TIMEOUT from " IP_ADDR_S " (%s)"),
548 IP_ADDR_V(cl->vpn_ip), cl->hostname);
553 syslog(LOG_DEBUG, _("Got TIMEOUT from " IP_ADDR_S " (%s)"),
554 IP_ADDR_V(cl->vpn_ip), cl->hostname);
556 cl->status.termreq = 1;
557 terminate_connection(cl);
562 int del_host_h(conn_list_t *cl)
567 if(!cl->status.active)
569 syslog(LOG_ERR, _("Got unauthorized DEL_HOST from " IP_ADDR_S " (%s)"),
570 IP_ADDR_V(cl->vpn_ip), cl->hostname);
574 if(sscanf(cl->buffer, "%*d %lx", &vpn_ip) != 1)
576 syslog(LOG_ERR, _("Got bad DEL_HOST from " IP_ADDR_S " (%s)"),
577 IP_ADDR_V(cl->vpn_ip), cl->hostname);
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);
585 if(!(fw = lookup_conn(vpn_ip)))
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);
592 notify_others(fw, cl, send_del_host);
594 fw->status.termreq = 1;
595 fw->status.active = 0;
597 terminate_connection(fw);
602 int ping_h(conn_list_t *cl)
605 if(!cl->status.active)
607 syslog(LOG_ERR, _("Got unauthorized PING from " IP_ADDR_S " (%s)"),
608 IP_ADDR_V(cl->vpn_ip), cl->hostname);
613 syslog(LOG_DEBUG, _("Got PING from " IP_ADDR_S " (%s)"),
614 IP_ADDR_V(cl->vpn_ip), cl->hostname);
616 cl->status.pinged = 0;
617 cl->status.got_pong = 1;
624 int pong_h(conn_list_t *cl)
627 if(!cl->status.active)
629 syslog(LOG_ERR, _("Got unauthorized PONG from " IP_ADDR_S " (%s)"),
630 IP_ADDR_V(cl->vpn_ip), cl->hostname);
635 syslog(LOG_DEBUG, _("Got PONG from " IP_ADDR_S " (%s)"),
636 IP_ADDR_V(cl->vpn_ip), cl->hostname);
638 cl->status.got_pong = 1;
643 int add_host_h(conn_list_t *cl)
650 conn_list_t *ncn, *fw;
652 if(!cl->status.active)
654 syslog(LOG_ERR, _("Got unauthorized ADD_HOST from " IP_ADDR_S " (%s)"),
655 IP_ADDR_V(cl->vpn_ip), cl->hostname);
659 if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx %d", &real_ip, &vpn_ip, &vpn_mask, &port, &flags) != 5)
661 syslog(LOG_ERR, _("Got bad ADD_HOST from " IP_ADDR_S " (%s)"),
662 IP_ADDR_V(cl->vpn_ip), cl->hostname);
667 Suggestion of Hans Bayle
669 if((fw = lookup_conn(vpn_ip)))
671 if(fw->nexthop == cl)
672 notify_others(fw, cl, send_add_host);
674 syslog(LOG_DEBUG, _("Invalid ADD_HOST from " IP_ADDR_S " (%s)"),
675 IP_ADDR_V(cl->vpn_ip), cl->hostname);
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;
687 ncn->next = conn_list;
689 ncn->status.active = 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);
695 notify_others(ncn, cl, send_add_host);
700 int req_key_h(conn_list_t *cl)
706 if(!cl->status.active)
708 syslog(LOG_ERR, _("Got unauthorized REQ_KEY from " IP_ADDR_S " (%s)"),
709 IP_ADDR_V(cl->vpn_ip), cl->hostname);
713 if(sscanf(cl->buffer, "%*d %lx %lx", &to, &from) != 2)
715 syslog(LOG_ERR, _("Got bad REQ_KEY from " IP_ADDR_S " (%s)"),
716 IP_ADDR_V(cl->vpn_ip), cl->hostname);
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);
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);
730 fw = lookup_conn(to);
734 syslog(LOG_ERR, _("Attempting to forward REQ_KEY to " IP_ADDR_S ", which does not exist?"),
740 syslog(LOG_DEBUG, _("Forwarding REQ_KEY to " IP_ADDR_S " (%s)"),
741 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
743 cl->buffer[cl->reqlen-1] = '\n';
745 if(write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen) < 0)
747 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
754 void set_keys(conn_list_t *cl, int expiry, char *key)
760 cl->public_key = xmalloc(sizeof(*cl->key));
761 cl->public_key->key = NULL;
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);
771 ek = make_shared_key(key);
775 cl->key = xmalloc(sizeof(*cl->key));
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);
789 int ans_key_h(conn_list_t *cl)
795 conn_list_t *fw, *gk;
797 if(!cl->status.active)
799 syslog(LOG_ERR, _("Got unauthorized ANS_KEY from " IP_ADDR_S " (%s)"),
800 IP_ADDR_V(cl->vpn_ip), cl->hostname);
804 if(sscanf(cl->buffer, "%*d %lx %lx %d %as", &to, &from, &expiry, &key) != 4)
806 syslog(LOG_ERR, _("Got bad ANS_KEY from " IP_ADDR_S " (%s)"),
807 IP_ADDR_V(cl->vpn_ip), cl->hostname);
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);
815 if(to == myself->vpn_ip)
816 { /* hey! that key's for ME! :) */
817 gk = lookup_conn(from);
821 syslog(LOG_ERR, _("Receiving ANS_KEY from " IP_ADDR_S ", which does not exist?"),
826 set_keys(gk, expiry, key);
827 gk->status.validkey = 1;
828 gk->status.waitingforkey = 0;
833 fw = lookup_conn(to);
837 syslog(LOG_ERR, _("Attempting to forward ANS_KEY to " IP_ADDR_S ", which does not exist?"),
843 syslog(LOG_DEBUG, _("Forwarding ANS_KEY to " IP_ADDR_S " (%s)"),
844 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
846 cl->buffer[cl->reqlen-1] = '\n';
848 if((write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen)) < 0)
850 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
857 int key_changed_h(conn_list_t *cl)
862 if(!cl->status.active)
864 syslog(LOG_ERR, _("Got unauthorized KEY_CHANGED from " IP_ADDR_S " (%s)"),
865 IP_ADDR_V(cl->vpn_ip), cl->hostname);
869 if(sscanf(cl->buffer, "%*d %lx", &from) != 1)
871 syslog(LOG_ERR, _("Got bad KEY_CHANGED from " IP_ADDR_S " (%s)"),
872 IP_ADDR_V(cl->vpn_ip), cl->hostname);
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);
880 ik = lookup_conn(from);
884 syslog(LOG_ERR, _("Got KEY_CHANGED from " IP_ADDR_S ", which does not exist?"),
889 ik->status.validkey = 0;
890 ik->status.waitingforkey = 0;
892 notify_others(cl, ik, send_key_changed);
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