2 protocol.c -- handle the meta-protocol
3 Copyright (C) 1999-2001 Ivo Timmermans <itimmermans@bigfoot.com>,
4 2000,2001 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.108 2001/10/08 15:37:14 guus Exp $
25 #include <sys/types.h>
30 #include <sys/socket.h>
41 #include <netinet/in.h>
43 #include <openssl/sha.h>
44 #include <openssl/rand.h>
45 #include <openssl/evp.h>
47 #ifndef HAVE_RAND_PSEUDO_BYTES
48 #define RAND_pseudo_bytes RAND_bytes
56 #include "connection.h"
62 int check_id(char *id)
66 for (i = 0; i < strlen(id); i++)
67 if(!isalnum(id[i]) && id[i] != '_')
73 /* Generic request routines - takes care of logging and error
76 int send_request(connection_t *cl, const char *format, ...)
79 char buffer[MAXBUFSIZE];
83 /* Use vsnprintf instead of vasprintf: faster, no memory
84 fragmentation, cleanup is automatic, and there is a limit on the
85 input buffer anyway */
87 va_start(args, format);
88 len = vsnprintf(buffer, MAXBUFSIZE, format, args);
89 request = va_arg(args, int);
92 if(len < 0 || len > MAXBUFSIZE-1)
94 syslog(LOG_ERR, _("Output buffer overflow while sending %s to %s (%s)"), request_name[request], cl->name, cl->hostname);
98 if(debug_lvl >= DEBUG_PROTOCOL)
100 if(debug_lvl >= DEBUG_META)
101 syslog(LOG_DEBUG, _("Sending %s to %s (%s): %s"), request_name[request], cl->name, cl->hostname, buffer);
103 syslog(LOG_DEBUG, _("Sending %s to %s (%s)"), request_name[request], cl->name, cl->hostname);
106 buffer[len++] = '\n';
108 return send_meta(cl, buffer, len);
111 int receive_request(connection_t *cl)
115 if(sscanf(cl->buffer, "%d", &request) == 1)
117 if((request < 0) || (request >= LAST) || (request_handlers[request] == NULL))
119 if(debug_lvl >= DEBUG_META)
120 syslog(LOG_DEBUG, _("Unknown request from %s (%s): %s"),
121 cl->name, cl->hostname, cl->buffer);
123 syslog(LOG_ERR, _("Unknown request from %s (%s)"),
124 cl->name, cl->hostname);
130 if(debug_lvl >= DEBUG_PROTOCOL)
132 if(debug_lvl >= DEBUG_META)
133 syslog(LOG_DEBUG, _("Got %s from %s (%s): %s"),
134 request_name[request], cl->name, cl->hostname, cl->buffer);
136 syslog(LOG_DEBUG, _("Got %s from %s (%s)"),
137 request_name[request], cl->name, cl->hostname);
141 if((cl->allow_request != ALL) && (cl->allow_request != request))
143 syslog(LOG_ERR, _("Unauthorized request from %s (%s)"), cl->name, cl->hostname);
147 if(request_handlers[request](cl))
148 /* Something went wrong. Probably scriptkiddies. Terminate. */
150 syslog(LOG_ERR, _("Error while processing %s from %s (%s)"),
151 request_name[request], cl->name, cl->hostname);
157 syslog(LOG_ERR, _("Bogus data received from %s (%s)"),
158 cl->name, cl->hostname);
165 /* The authentication protocol is described in detail in doc/SECURITY2,
166 the rest will be described in doc/PROTOCOL. */
168 int send_id(connection_t *cl)
171 return send_request(cl, "%d %s %d %lx %hd", ID, myself->name, myself->protocol_version, myself->options, myself->port);
174 int id_h(connection_t *cl)
176 char name[MAX_STRING_SIZE];
178 if(sscanf(cl->buffer, "%*d "MAX_STRING" %d %lx %hd", name, &cl->protocol_version, &cl->options, &cl->port) != 4)
180 syslog(LOG_ERR, _("Got bad ID from %s"), cl->hostname);
184 /* Check if version matches */
186 if(cl->protocol_version != myself->protocol_version)
188 syslog(LOG_ERR, _("Peer %s (%s) uses incompatible version %d"),
189 cl->name, cl->hostname, cl->protocol_version);
193 /* Check if identity is a valid name */
197 syslog(LOG_ERR, _("Peer %s uses invalid identity name"), cl->hostname);
201 /* Copy string to cl */
206 cl->name = xstrdup(name);
208 /* Load information about peer */
210 if(read_host_config(cl))
212 syslog(LOG_ERR, _("Peer %s had unknown identity (%s)"), cl->hostname, cl->name);
216 /* Read in the public key, so that we can send a metakey */
218 if(read_rsa_public_key(cl))
221 cl->allow_request = METAKEY;
223 return send_metakey(cl);
226 int ack_h(connection_t *cl)
229 connection_t *old, *p;
231 avl_node_t *node, *node2;
233 /* Okay, before we active the connection, we check if there is another entry
234 in the connection list with the same name. If so, it presumably is an
235 old connection that has timed out but we don't know it yet.
238 if((old = lookup_id(cl->name)))
240 if(debug_lvl >= DEBUG_CONNECTIONS)
241 syslog(LOG_NOTICE, _("Removing old connection for %s at %s in favour of new connection at %s"),
242 old->name, old->hostname, cl->hostname);
243 if(old->status.outgoing)
245 cl->status.outgoing = 1;
246 old->status.outgoing = 0;
249 terminate_connection(old, 0);
252 /* Also check if no other tinc daemon uses the same IP and port for UDP traffic */
254 old = avl_search(active_tree, cl);
257 syslog(LOG_ERR, _("%s is listening on %s:%hd, which is already in use by %s!"),
258 cl->name, cl->hostname, cl->port, old->name);
262 /* Activate this connection */
264 cl->allow_request = ALL;
266 cl->prevhop = myself;
267 cl->cipher_pkttype = EVP_bf_cbc();
268 cl->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
272 if(debug_lvl >= DEBUG_CONNECTIONS)
273 syslog(LOG_NOTICE, _("Connection with %s (%s) activated"), cl->name, cl->hostname);
275 if(cl->status.outgoing)
276 seconds_till_retry = 5; /* Reset retry timeout */
278 /* Check some options */
280 if((cfg = get_config_val(cl->config, config_indirectdata)))
282 if(cfg->data.val == stupid_true)
283 cl->options |= OPTION_INDIRECT;
286 if((cfg = get_config_val(cl->config, config_tcponly)))
288 if(cfg->data.val == stupid_true)
289 cl->options |= OPTION_TCPONLY;
292 if((myself->options | cl->options) & OPTION_INDIRECT)
297 /* Send him our subnets */
299 for(node = myself->subnet_tree->head; node; node = node->next)
301 subnet = (subnet_t *)node->data;
302 send_add_subnet(cl, subnet);
305 /* And send him all the hosts and their subnets we know... */
307 for(node = active_tree->head; node; node = node->next)
309 p = (connection_t *)node->data;
313 /* Notify others of this connection */
316 send_add_host(p, cl);
318 /* Notify new connection of everything we know */
320 send_add_host(cl, p);
322 for(node2 = p->subnet_tree->head; node2; node2 = node2->next)
324 subnet = (subnet_t *)node2->data;
325 send_add_subnet(cl, subnet);
333 int send_challenge(connection_t *cl)
338 /* CHECKME: what is most reasonable value for len? */
340 len = RSA_size(cl->rsa_key);
342 /* Allocate buffers for the challenge */
344 buffer = xmalloc(len*2+1);
347 free(cl->hischallenge);
349 cl->hischallenge = xmalloc(len);
351 /* Copy random data to the buffer */
353 RAND_bytes(cl->hischallenge, len);
358 bin2hex(cl->hischallenge, buffer, len);
359 buffer[len*2] = '\0';
362 /* Send the challenge */
364 x = send_request(cl, "%d %s", CHALLENGE, buffer);
370 int challenge_h(connection_t *cl)
372 char buffer[MAX_STRING_SIZE];
375 if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
377 syslog(LOG_ERR, _("Got bad CHALLENGE from %s (%s)"), cl->name, cl->hostname);
381 len = RSA_size(myself->rsa_key);
383 /* Check if the length of the challenge is all right */
385 if(strlen(buffer) != len*2)
387 syslog(LOG_ERR, _("Intruder: wrong challenge length from %s (%s)"), cl->name, cl->hostname);
391 /* Allocate buffers for the challenge */
394 cl->mychallenge = xmalloc(len);
396 /* Convert the challenge from hexadecimal back to binary */
398 hex2bin(buffer,cl->mychallenge,len);
400 cl->allow_request = CHAL_REPLY;
402 /* Rest is done by send_chal_reply() */
404 return send_chal_reply(cl);
407 int send_chal_reply(connection_t *cl)
409 char hash[SHA_DIGEST_LENGTH*2+1];
413 syslog(LOG_ERR, _("Trying to send CHAL_REPLY to %s (%s) without a valid CHALLENGE"), cl->name, cl->hostname);
417 /* Calculate the hash from the challenge we received */
419 SHA1(cl->mychallenge, RSA_size(myself->rsa_key), hash);
421 /* Convert the hash to a hexadecimal formatted string */
423 bin2hex(hash,hash,SHA_DIGEST_LENGTH);
424 hash[SHA_DIGEST_LENGTH*2] = '\0';
429 return send_request(cl, "%d %s", CHAL_REPLY, hash);
432 int chal_reply_h(connection_t *cl)
434 char hishash[MAX_STRING_SIZE];
435 char myhash[SHA_DIGEST_LENGTH];
437 if(sscanf(cl->buffer, "%*d "MAX_STRING, hishash) != 1)
439 syslog(LOG_ERR, _("Got bad CHAL_REPLY from %s (%s)"), cl->name, cl->hostname);
443 /* Check if the length of the hash is all right */
445 if(strlen(hishash) != SHA_DIGEST_LENGTH*2)
447 syslog(LOG_ERR, _("Intruder: wrong challenge reply length from %s (%s)"), cl->name, cl->hostname);
451 /* Convert the hash to binary format */
453 hex2bin(hishash, hishash, SHA_DIGEST_LENGTH);
455 /* Calculate the hash from the challenge we sent */
457 SHA1(cl->hischallenge, RSA_size(cl->rsa_key), myhash);
459 /* Verify the incoming hash with the calculated hash */
461 if(memcmp(hishash, myhash, SHA_DIGEST_LENGTH))
463 syslog(LOG_ERR, _("Intruder: wrong challenge reply from %s (%s)"), cl->name, cl->hostname);
464 if(debug_lvl >= DEBUG_SCARY_THINGS)
466 bin2hex(myhash, hishash, SHA_DIGEST_LENGTH);
467 hishash[SHA_DIGEST_LENGTH*2] = '\0';
468 syslog(LOG_DEBUG, _("Expected challenge reply: %s"), hishash);
473 /* Identity has now been positively verified.
474 ack_h() handles the rest from now on.
480 int send_metakey(connection_t *cl)
485 len = RSA_size(cl->rsa_key);
487 /* Allocate buffers for the meta key */
489 buffer = xmalloc(len*2+1);
491 if(!cl->cipher_outkey)
492 cl->cipher_outkey = xmalloc(len);
494 if(!cl->cipher_outctx)
495 cl->cipher_outctx = xmalloc(sizeof(*cl->cipher_outctx));
497 /* Copy random data to the buffer */
499 RAND_bytes(cl->cipher_outkey, len);
501 /* The message we send must be smaller than the modulus of the RSA key.
502 By definition, for a key of k bits, the following formula holds:
504 2^(k-1) <= modulus < 2^(k)
506 Where ^ means "to the power of", not "xor".
507 This means that to be sure, we must choose our message < 2^(k-1).
508 This can be done by setting the most significant bit to zero.
511 cl->cipher_outkey[0] &= 0x7F;
513 if(debug_lvl >= DEBUG_SCARY_THINGS)
515 bin2hex(cl->cipher_outkey, buffer, len);
516 buffer[len*2] = '\0';
517 syslog(LOG_DEBUG, _("Generated random meta key (unencrypted): %s"), buffer);
520 /* Encrypt the random data
522 We do not use one of the PKCS padding schemes here.
523 This is allowed, because we encrypt a totally random string
524 with a length equal to that of the modulus of the RSA key.
527 if(RSA_public_encrypt(len, cl->cipher_outkey, buffer, cl->rsa_key, RSA_NO_PADDING) != len)
529 syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
534 /* Convert the encrypted random data to a hexadecimal formatted string */
536 bin2hex(buffer, buffer, len);
537 buffer[len*2] = '\0';
539 /* Send the meta key */
541 x = send_request(cl, "%d %s", METAKEY, buffer);
544 /* Further outgoing requests are encrypted with the key we just generated */
546 EVP_EncryptInit(cl->cipher_outctx, EVP_bf_cfb(),
547 cl->cipher_outkey + len - EVP_bf_cfb()->key_len,
548 cl->cipher_outkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
550 cl->status.encryptout = 1;
555 int metakey_h(connection_t *cl)
557 char buffer[MAX_STRING_SIZE];
560 if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
562 syslog(LOG_ERR, _("Got bad METAKEY from %s (%s)"), cl->name, cl->hostname);
566 len = RSA_size(myself->rsa_key);
568 /* Check if the length of the meta key is all right */
570 if(strlen(buffer) != len*2)
572 syslog(LOG_ERR, _("Intruder: wrong meta key length from %s (%s)"), cl->name, cl->hostname);
576 /* Allocate buffers for the meta key */
578 if(!cl->cipher_inkey)
579 cl->cipher_inkey = xmalloc(len);
581 if(!cl->cipher_inctx)
582 cl->cipher_inctx = xmalloc(sizeof(*cl->cipher_inctx));
584 /* Convert the challenge from hexadecimal back to binary */
586 hex2bin(buffer,buffer,len);
588 /* Decrypt the meta key */
590 if(RSA_private_decrypt(len, buffer, cl->cipher_inkey, myself->rsa_key, RSA_NO_PADDING) != len) /* See challenge() */
592 syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
596 if(debug_lvl >= DEBUG_SCARY_THINGS)
598 bin2hex(cl->cipher_inkey, buffer, len);
599 buffer[len*2] = '\0';
600 syslog(LOG_DEBUG, _("Received random meta key (unencrypted): %s"), buffer);
603 /* All incoming requests will now be encrypted. */
605 EVP_DecryptInit(cl->cipher_inctx, EVP_bf_cfb(),
606 cl->cipher_inkey + len - EVP_bf_cfb()->key_len,
607 cl->cipher_inkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
609 cl->status.decryptin = 1;
611 cl->allow_request = CHALLENGE;
613 return send_challenge(cl);
616 /* Address and subnet information exchange */
618 int send_add_subnet(connection_t *cl, subnet_t *subnet)
624 owner = subnet->owner->name;
626 x = send_request(cl, "%d %s %s", ADD_SUBNET,
627 owner, netstr = net2str(subnet));
633 int add_subnet_h(connection_t *cl)
635 char subnetstr[MAX_STRING_SIZE];
636 char name[MAX_STRING_SIZE];
637 connection_t *owner, *p;
641 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
643 syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s)"), cl->name, cl->hostname);
647 /* Check if owner name is a valid */
651 syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
655 /* Check if subnet string is valid */
657 if(!(subnet = str2net(subnetstr)))
659 syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
663 /* Check if somebody tries to add a subnet of ourself */
665 if(!strcmp(name, myself->name))
667 syslog(LOG_ERR, _("Warning: got ADD_SUBNET from %s (%s) for ourself, restarting"),
668 cl->name, cl->hostname);
673 /* Check if the owner of the new subnet is in the connection list */
675 if(!(owner = lookup_id(name)))
677 syslog(LOG_ERR, _("Got ADD_SUBNET for %s from %s (%s) which is not in our connection list"),
678 name, cl->name, cl->hostname);
682 /* If everything is correct, add the subnet to the list of the owner */
684 subnet_add(owner, subnet);
688 for(node = connection_tree->head; node; node = node->next)
690 p = (connection_t *)node->data;
691 if(p->status.active && p!= cl)
692 send_add_subnet(p, subnet);
698 int send_del_subnet(connection_t *cl, subnet_t *subnet)
704 owner = subnet->owner->name;
706 x = send_request(cl, "%d %s %s", DEL_SUBNET, owner, netstr = net2str(subnet));
712 int del_subnet_h(connection_t *cl)
714 char subnetstr[MAX_STRING_SIZE];
715 char name[MAX_STRING_SIZE];
716 connection_t *owner, *p;
720 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 3)
722 syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s)"), cl->name, cl->hostname);
726 /* Check if owner name is a valid */
730 syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
734 /* Check if subnet string is valid */
736 if(!(subnet = str2net(subnetstr)))
738 syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
744 /* Check if somebody tries to add a subnet of ourself */
746 if(!strcmp(name, myself->name))
748 syslog(LOG_ERR, _("Warning: got DEL_SUBNET from %s (%s) for ourself, restarting"),
749 cl->name, cl->hostname);
754 /* Check if the owner of the new subnet is in the connection list */
756 if(!(owner = lookup_id(name)))
758 syslog(LOG_ERR, _("Got DEL_SUBNET for %s from %s (%s) which is not in our connection list"),
759 name, cl->name, cl->hostname);
763 /* If everything is correct, delete the subnet from the list of the owner */
769 for(node = connection_tree->head; node; node = node->next)
771 p = (connection_t *)node->data;
772 if(p->status.active && p!= cl)
773 send_del_subnet(p, subnet);
779 /* New and closed connections notification */
781 int send_add_host(connection_t *cl, connection_t *other)
784 return send_request(cl, "%d %s %lx:%d %lx %s", ADD_HOST,
785 other->name, other->address, other->port, other->options, other->prevhop->name);
788 int add_host_h(connection_t *cl)
790 connection_t *old, *new, *p;
791 char name[MAX_STRING_SIZE], prevhop[MAX_STRING_SIZE];
794 new = new_connection();
796 if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%hd %lx "MAX_STRING, name, &new->address, &new->port, &new->options, prevhop) != 5)
798 syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"), cl->name, cl->hostname);
802 /* Check if identity is a valid name */
806 syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
807 free_connection(new);
811 if(check_id(prevhop))
813 syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid prevhop name"), cl->name, cl->hostname);
814 free_connection(new);
818 /* Check if somebody tries to add ourself */
820 if(!strcmp(name, myself->name))
822 syslog(LOG_ERR, _("Got ADD_HOST from %s (%s) for ourself!"), cl->name, cl->hostname);
823 free_connection(new);
827 /* Fill in more of the new connection structure */
829 new->hostname = hostlookup(htonl(new->address));
831 new->prevhop = lookup_id(prevhop);
835 syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): unknown prevhop"), cl->name, cl->hostname);
836 free_connection(new);
840 /* Check if the new host already exists in the connnection list */
842 if((old = lookup_id(name)))
844 if((new->address == old->address) && (new->port == old->port) && (cl->nexthop == old->nexthop))
846 if(debug_lvl >= DEBUG_CONNECTIONS)
847 syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
848 old->name, old->hostname, cl->name, cl->hostname);
849 free_connection(new);
854 if(debug_lvl >= DEBUG_CONNECTIONS)
855 syslog(LOG_NOTICE, _("Removing old entry for %s (%s) from %s in favour of new connection from %s"),
856 old->name, old->hostname, old->nexthop->name, cl->nexthop->name);
858 terminate_connection(old, 0);
862 /* Hook it up into the active tree */
864 new->name = xstrdup(name);
867 /* Tell the rest about the new host */
869 for(node = connection_tree->head; node; node = node->next)
871 p = (connection_t *)node->data;
872 if(p->status.active && p!=cl)
873 send_add_host(p, new);
876 /* Fill in rest of connection structure */
879 new->cipher_pkttype = EVP_bf_cbc();
880 new->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
882 if(new->options & OPTION_INDIRECT || new->prevhop->via != new->prevhop)
883 new->via = new->prevhop->via;
890 int send_del_host(connection_t *cl, connection_t *other)
893 return send_request(cl, "%d %s %lx:%d %lx %s", DEL_HOST,
894 other->name, other->address, other->port, other->options, other->prevhop->name);
897 int del_host_h(connection_t *cl)
899 char name[MAX_STRING_SIZE], prevhop[MAX_STRING_SIZE];
903 connection_t *old, *p;
906 if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%hd %lx "MAX_STRING, name, &address, &port, &options, prevhop) != 5)
908 syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
909 cl->name, cl->hostname);
913 /* Check if identity is a valid name */
917 syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
921 if(check_id(prevhop))
923 syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s): invalid prevhop name"), cl->name, cl->hostname);
927 /* Check if somebody tries to delete ourself */
929 if(!strcmp(name, myself->name))
931 syslog(LOG_ERR, _("Got DEL_HOST from %s (%s) for ourself!"),
932 cl->name, cl->hostname);
936 /* Check if the deleted host already exists in the connnection list */
938 if(!(old = lookup_id(name)))
940 syslog(LOG_ERR, _("Got DEL_HOST from %s (%s) for %s which is not in our connection list"),
941 cl->name, cl->hostname, name);
945 /* Check if the rest matches */
947 if(address!=old->address || port!=old->port || options!=old->options || cl!=old->nexthop || strcmp(prevhop, old->prevhop->name))
949 syslog(LOG_WARNING, _("Got DEL_HOST from %s (%s) for %s which doesn't match"), cl->name, cl->hostname, old->name);
953 /* Ok, since EVERYTHING seems to check out all right, delete it */
955 terminate_connection(old, 0);
957 /* Tell the rest about the deleted host */
959 for(node = connection_tree->head; node; node = node->next)
961 p = (connection_t *)node->data;
962 if(p->status.active && p!=cl)
963 send_del_host(p, old);
969 /* Status and error notification routines */
971 int send_status(connection_t *cl, int statusno, char *statusstring)
975 statusstring = status_text[statusno];
977 return send_request(cl, "%d %d %s", STATUS, statusno, statusstring);
980 int status_h(connection_t *cl)
983 char statusstring[MAX_STRING_SIZE];
985 if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &statusno, statusstring) != 2)
987 syslog(LOG_ERR, _("Got bad STATUS from %s (%s)"),
988 cl->name, cl->hostname);
992 if(debug_lvl >= DEBUG_STATUS)
994 syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"),
995 cl->name, cl->hostname, status_text[statusno], statusstring);
1002 int send_error(connection_t *cl, int err, char *errstring)
1006 errstring = strerror(err);
1007 return send_request(cl, "%d %d %s", ERROR, err, errstring);
1010 int error_h(connection_t *cl)
1013 char errorstring[MAX_STRING_SIZE];
1015 if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &err, errorstring) != 2)
1017 syslog(LOG_ERR, _("Got bad ERROR from %s (%s)"),
1018 cl->name, cl->hostname);
1022 if(debug_lvl >= DEBUG_ERROR)
1024 syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"),
1025 cl->name, cl->hostname, strerror(err), errorstring);
1028 terminate_connection(cl, cl->status.meta);
1033 int send_termreq(connection_t *cl)
1036 return send_request(cl, "%d", TERMREQ);
1039 int termreq_h(connection_t *cl)
1042 terminate_connection(cl, cl->status.meta);
1047 int send_ping(connection_t *cl)
1049 char salt[SALTLEN*2+1];
1051 cl->status.pinged = 1;
1052 cl->last_ping_time = time(NULL);
1053 RAND_pseudo_bytes(salt, SALTLEN);
1054 bin2hex(salt, salt, SALTLEN);
1055 salt[SALTLEN*2] = '\0';
1057 return send_request(cl, "%d %s", PING, salt);
1060 int ping_h(connection_t *cl)
1063 return send_pong(cl);
1066 int send_pong(connection_t *cl)
1068 char salt[SALTLEN*2+1];
1070 RAND_pseudo_bytes(salt, SALTLEN);
1071 bin2hex(salt, salt, SALTLEN);
1072 salt[SALTLEN*2] = '\0';
1074 return send_request(cl, "%d %s", PONG, salt);
1077 int pong_h(connection_t *cl)
1080 cl->status.pinged = 0;
1087 int send_key_changed(connection_t *from, connection_t *cl)
1092 /* Only send this message if some other daemon requested our key previously.
1093 This reduces unnecessary key_changed broadcasts.
1096 if(from==myself && !mykeyused)
1099 for(node = connection_tree->head; node; node = node->next)
1101 p = (connection_t *)node->data;
1102 if(p != cl && p->status.active)
1103 send_request(p, "%d %s", KEY_CHANGED, from->name);
1109 int key_changed_h(connection_t *cl)
1111 char from_id[MAX_STRING_SIZE];
1114 if(sscanf(cl->buffer, "%*d "MAX_STRING, from_id) != 1)
1116 syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
1117 cl->name, cl->hostname);
1121 if(!(from = lookup_id(from_id)))
1123 syslog(LOG_ERR, _("Got KEY_CHANGED from %s (%s) origin %s which does not exist in our connection list"),
1124 cl->name, cl->hostname, from_id);
1128 from->status.validkey = 0;
1129 from->status.waitingforkey = 0;
1131 send_key_changed(from, cl);
1136 int send_req_key(connection_t *from, connection_t *to)
1139 return send_request(to->nexthop, "%d %s %s", REQ_KEY,
1140 from->name, to->name);
1143 int req_key_h(connection_t *cl)
1145 char from_id[MAX_STRING_SIZE];
1146 char to_id[MAX_STRING_SIZE];
1147 connection_t *from, *to;
1150 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, from_id, to_id) != 2)
1152 syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
1153 cl->name, cl->hostname);
1157 if(!(from = lookup_id(from_id)))
1159 syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) origin %s which does not exist in our connection list"),
1160 cl->name, cl->hostname, from_id);
1164 /* Check if this key request is for us */
1166 if(!strcmp(to_id, myself->name)) /* Yes, send our own key back */
1168 bin2hex(myself->cipher_pktkey, pktkey, myself->cipher_pktkeylength);
1169 pktkey[myself->cipher_pktkeylength*2] = '\0';
1170 send_ans_key(myself, from, pktkey);
1175 if(!(to = lookup_id(to_id)))
1177 syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) destination %s which does not exist in our connection list"),
1178 cl->name, cl->hostname, to_id);
1182 if(to->status.validkey) /* Proxy keys */
1184 bin2hex(to->cipher_pktkey, pktkey, to->cipher_pktkeylength);
1185 pktkey[to->cipher_pktkeylength*2] = '\0';
1186 send_ans_key(to, from, pktkey);
1189 send_req_key(from, to);
1196 int send_ans_key(connection_t *from, connection_t *to, char *pktkey)
1199 return send_request(to->nexthop, "%d %s %s %s", ANS_KEY,
1200 from->name, to->name, pktkey);
1203 int ans_key_h(connection_t *cl)
1205 char from_id[MAX_STRING_SIZE];
1206 char to_id[MAX_STRING_SIZE];
1207 char pktkey[MAX_STRING_SIZE];
1209 connection_t *from, *to;
1211 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING, from_id, to_id, pktkey) != 3)
1213 syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
1214 cl->name, cl->hostname);
1218 if(!(from = lookup_id(from_id)))
1220 syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) origin %s which does not exist in our connection list"),
1221 cl->name, cl->hostname, from_id);
1225 /* Check correctness of packet key */
1227 keylength = strlen(pktkey);
1229 if(keylength != from->cipher_pktkeylength*2)
1231 syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s) origin %s: invalid key length"),
1232 cl->name, cl->hostname, from->name);
1236 /* Forward it if necessary */
1238 if(strcmp(to_id, myself->name))
1240 if(!(to = lookup_id(to_id)))
1242 syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) destination %s which does not exist in our connection list"),
1243 cl->name, cl->hostname, to_id);
1246 send_ans_key(from, to, pktkey);
1249 /* Update our copy of the origin's packet key */
1251 if(from->cipher_pktkey)
1252 free(from->cipher_pktkey);
1254 from->cipher_pktkey = xstrdup(pktkey);
1256 hex2bin(from->cipher_pktkey, from->cipher_pktkey, keylength);
1257 from->cipher_pktkey[keylength] = '\0';
1259 from->status.validkey = 1;
1260 from->status.waitingforkey = 0;
1267 int send_tcppacket(connection_t *cl, vpn_packet_t *packet)
1273 x = send_request(cl->nexthop, "%d %hd", PACKET, packet->len);
1278 return send_meta(cl, packet->data, packet->len);
1281 int tcppacket_h(connection_t *cl)
1285 if(sscanf(cl->buffer, "%*d %hd", &len) != 1)
1287 syslog(LOG_ERR, _("Got bad PACKET from %s (%s)"), cl->name, cl->hostname);
1291 /* Set reqlen to len, this will tell receive_meta() that a tcppacket is coming. */
1298 /* Jumptable for the request handlers */
1300 int (*request_handlers[])(connection_t*) = {
1301 id_h, metakey_h, challenge_h, chal_reply_h,
1302 status_h, error_h, termreq_h,
1304 add_host_h, del_host_h,
1305 add_subnet_h, del_subnet_h,
1306 key_changed_h, req_key_h, ans_key_h,
1312 char (*request_name[]) = {
1313 "ID", "METAKEY", "CHALLENGE", "CHAL_REPLY",
1314 "STATUS", "ERROR", "TERMREQ",
1316 "ADD_HOST", "DEL_HOST",
1317 "ADD_SUBNET", "DEL_SUBNET",
1318 "KEY_CHANGED", "REQ_KEY", "ANS_KEY",
1322 /* Status strings */
1324 char (*status_text[]) = {
1330 char (*error_text[]) = {