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.103 2001/07/21 15:34:18 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 from %s"),
242 cl->name, old->hostname, cl->hostname);
243 if(old->status.outgoing)
245 cl->status.outgoing = 1;
246 old->status.outgoing = 0;
248 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->cipher_pkttype = EVP_bf_cbc();
267 cl->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
271 if(debug_lvl >= DEBUG_CONNECTIONS)
272 syslog(LOG_NOTICE, _("Connection with %s (%s) activated"), cl->name, cl->hostname);
274 if(cl->status.outgoing)
275 seconds_till_retry = 5; /* Reset retry timeout */
277 /* Check some options */
279 if((cfg = get_config_val(cl->config, config_indirectdata)))
281 if(cfg->data.val == stupid_true)
282 cl->options |= OPTION_INDIRECT;
285 if((cfg = get_config_val(cl->config, config_tcponly)))
287 if(cfg->data.val == stupid_true)
288 cl->options |= OPTION_TCPONLY;
291 /* Send him our subnets */
293 for(node = myself->subnet_tree->head; node; node = node->next)
295 subnet = (subnet_t *)node->data;
296 send_add_subnet(cl, subnet);
299 /* And send him all the hosts and their subnets we know... */
301 for(node = active_tree->head; node; node = node->next)
303 p = (connection_t *)node->data;
307 /* Notify others of this connection */
310 send_add_host(p, cl);
312 /* Notify new connection of everything we know */
314 send_add_host(cl, p);
316 for(node2 = p->subnet_tree->head; node2; node2 = node2->next)
318 subnet = (subnet_t *)node2->data;
319 send_add_subnet(cl, subnet);
327 int send_challenge(connection_t *cl)
332 /* CHECKME: what is most reasonable value for len? */
334 len = RSA_size(cl->rsa_key);
336 /* Allocate buffers for the challenge */
338 buffer = xmalloc(len*2+1);
341 free(cl->hischallenge);
343 cl->hischallenge = xmalloc(len);
345 /* Copy random data to the buffer */
347 RAND_bytes(cl->hischallenge, len);
352 bin2hex(cl->hischallenge, buffer, len);
353 buffer[len*2] = '\0';
356 /* Send the challenge */
358 x = send_request(cl, "%d %s", CHALLENGE, buffer);
364 int challenge_h(connection_t *cl)
366 char buffer[MAX_STRING_SIZE];
369 if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
371 syslog(LOG_ERR, _("Got bad CHALLENGE from %s (%s)"), cl->name, cl->hostname);
375 len = RSA_size(myself->rsa_key);
377 /* Check if the length of the challenge is all right */
379 if(strlen(buffer) != len*2)
381 syslog(LOG_ERR, _("Intruder: wrong challenge length from %s (%s)"), cl->name, cl->hostname);
385 /* Allocate buffers for the challenge */
388 cl->mychallenge = xmalloc(len);
390 /* Convert the challenge from hexadecimal back to binary */
392 hex2bin(buffer,cl->mychallenge,len);
394 cl->allow_request = CHAL_REPLY;
396 /* Rest is done by send_chal_reply() */
398 return send_chal_reply(cl);
401 int send_chal_reply(connection_t *cl)
403 char hash[SHA_DIGEST_LENGTH*2+1];
407 syslog(LOG_ERR, _("Trying to send CHAL_REPLY to %s (%s) without a valid CHALLENGE"), cl->name, cl->hostname);
411 /* Calculate the hash from the challenge we received */
413 SHA1(cl->mychallenge, RSA_size(myself->rsa_key), hash);
415 /* Convert the hash to a hexadecimal formatted string */
417 bin2hex(hash,hash,SHA_DIGEST_LENGTH);
418 hash[SHA_DIGEST_LENGTH*2] = '\0';
423 return send_request(cl, "%d %s", CHAL_REPLY, hash);
426 int chal_reply_h(connection_t *cl)
428 char hishash[MAX_STRING_SIZE];
429 char myhash[SHA_DIGEST_LENGTH];
431 if(sscanf(cl->buffer, "%*d "MAX_STRING, hishash) != 1)
433 syslog(LOG_ERR, _("Got bad CHAL_REPLY from %s (%s)"), cl->name, cl->hostname);
437 /* Check if the length of the hash is all right */
439 if(strlen(hishash) != SHA_DIGEST_LENGTH*2)
441 syslog(LOG_ERR, _("Intruder: wrong challenge reply length from %s (%s)"), cl->name, cl->hostname);
445 /* Convert the hash to binary format */
447 hex2bin(hishash, hishash, SHA_DIGEST_LENGTH);
449 /* Calculate the hash from the challenge we sent */
451 SHA1(cl->hischallenge, RSA_size(cl->rsa_key), myhash);
453 /* Verify the incoming hash with the calculated hash */
455 if(memcmp(hishash, myhash, SHA_DIGEST_LENGTH))
457 syslog(LOG_ERR, _("Intruder: wrong challenge reply from %s (%s)"), cl->name, cl->hostname);
458 if(debug_lvl >= DEBUG_SCARY_THINGS)
460 bin2hex(myhash, hishash, SHA_DIGEST_LENGTH);
461 hishash[SHA_DIGEST_LENGTH*2] = '\0';
462 syslog(LOG_DEBUG, _("Expected challenge reply: %s"), hishash);
467 /* Identity has now been positively verified.
468 ack_h() handles the rest from now on.
474 int send_metakey(connection_t *cl)
479 len = RSA_size(cl->rsa_key);
481 /* Allocate buffers for the meta key */
483 buffer = xmalloc(len*2+1);
485 if(!cl->cipher_outkey)
486 cl->cipher_outkey = xmalloc(len);
488 if(!cl->cipher_outctx)
489 cl->cipher_outctx = xmalloc(sizeof(*cl->cipher_outctx));
491 /* Copy random data to the buffer */
493 RAND_bytes(cl->cipher_outkey, len);
495 /* The message we send must be smaller than the modulus of the RSA key.
496 By definition, for a key of k bits, the following formula holds:
498 2^(k-1) <= modulus < 2^(k)
500 Where ^ means "to the power of", not "xor".
501 This means that to be sure, we must choose our message < 2^(k-1).
502 This can be done by setting the most significant bit to zero.
505 cl->cipher_outkey[0] &= 0x7F;
507 if(debug_lvl >= DEBUG_SCARY_THINGS)
509 bin2hex(cl->cipher_outkey, buffer, len);
510 buffer[len*2] = '\0';
511 syslog(LOG_DEBUG, _("Generated random meta key (unencrypted): %s"), buffer);
514 /* Encrypt the random data
516 We do not use one of the PKCS padding schemes here.
517 This is allowed, because we encrypt a totally random string
518 with a length equal to that of the modulus of the RSA key.
521 if(RSA_public_encrypt(len, cl->cipher_outkey, buffer, cl->rsa_key, RSA_NO_PADDING) != len)
523 syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
528 /* Convert the encrypted random data to a hexadecimal formatted string */
530 bin2hex(buffer, buffer, len);
531 buffer[len*2] = '\0';
533 /* Send the meta key */
535 x = send_request(cl, "%d %s", METAKEY, buffer);
538 /* Further outgoing requests are encrypted with the key we just generated */
540 EVP_EncryptInit(cl->cipher_outctx, EVP_bf_cfb(),
541 cl->cipher_outkey + len - EVP_bf_cfb()->key_len,
542 cl->cipher_outkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
544 cl->status.encryptout = 1;
549 int metakey_h(connection_t *cl)
551 char buffer[MAX_STRING_SIZE];
554 if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
556 syslog(LOG_ERR, _("Got bad METAKEY from %s (%s)"), cl->name, cl->hostname);
560 len = RSA_size(myself->rsa_key);
562 /* Check if the length of the meta key is all right */
564 if(strlen(buffer) != len*2)
566 syslog(LOG_ERR, _("Intruder: wrong meta key length from %s (%s)"), cl->name, cl->hostname);
570 /* Allocate buffers for the meta key */
572 if(!cl->cipher_inkey)
573 cl->cipher_inkey = xmalloc(len);
575 if(!cl->cipher_inctx)
576 cl->cipher_inctx = xmalloc(sizeof(*cl->cipher_inctx));
578 /* Convert the challenge from hexadecimal back to binary */
580 hex2bin(buffer,buffer,len);
582 /* Decrypt the meta key */
584 if(RSA_private_decrypt(len, buffer, cl->cipher_inkey, myself->rsa_key, RSA_NO_PADDING) != len) /* See challenge() */
586 syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
590 if(debug_lvl >= DEBUG_SCARY_THINGS)
592 bin2hex(cl->cipher_inkey, buffer, len);
593 buffer[len*2] = '\0';
594 syslog(LOG_DEBUG, _("Received random meta key (unencrypted): %s"), buffer);
597 /* All incoming requests will now be encrypted. */
599 EVP_DecryptInit(cl->cipher_inctx, EVP_bf_cfb(),
600 cl->cipher_inkey + len - EVP_bf_cfb()->key_len,
601 cl->cipher_inkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
603 cl->status.decryptin = 1;
605 cl->allow_request = CHALLENGE;
607 return send_challenge(cl);
610 /* Address and subnet information exchange */
612 int send_add_subnet(connection_t *cl, subnet_t *subnet)
618 if((cl->options | myself->options | subnet->owner->options) & OPTION_INDIRECT)
619 owner = myself->name;
621 owner = subnet->owner->name;
623 x = send_request(cl, "%d %s %s", ADD_SUBNET,
624 owner, netstr = net2str(subnet));
630 int add_subnet_h(connection_t *cl)
632 char subnetstr[MAX_STRING_SIZE];
633 char name[MAX_STRING_SIZE];
634 connection_t *owner, *p;
638 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
640 syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s)"), cl->name, cl->hostname);
644 /* Check if owner name is a valid */
648 syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
652 /* Check if subnet string is valid */
654 if(!(subnet = str2net(subnetstr)))
656 syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
660 /* Check if somebody tries to add a subnet of ourself */
662 if(!strcmp(name, myself->name))
664 syslog(LOG_ERR, _("Warning: got ADD_SUBNET from %s (%s) for ourself, restarting"),
665 cl->name, cl->hostname);
670 /* Check if the owner of the new subnet is in the connection list */
672 if(!(owner = lookup_id(name)))
674 syslog(LOG_ERR, _("Got ADD_SUBNET for %s from %s (%s) which is not in our connection list"),
675 name, cl->name, cl->hostname);
679 /* If everything is correct, add the subnet to the list of the owner */
681 subnet_add(owner, subnet);
685 for(node = connection_tree->head; node; node = node->next)
687 p = (connection_t *)node->data;
688 if(p->status.active && p!= cl)
689 send_add_subnet(p, subnet);
695 int send_del_subnet(connection_t *cl, subnet_t *subnet)
701 if(cl->options & OPTION_INDIRECT)
702 owner = myself->name;
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 if(!((cl->options | myself->options | other->options) & OPTION_INDIRECT))
785 return send_request(cl, "%d %s %lx:%d %lx", ADD_HOST,
786 other->name, other->address, other->port, other->options);
791 int add_host_h(connection_t *cl)
793 connection_t *old, *new, *p;
794 char name[MAX_STRING_SIZE];
797 new = new_connection();
799 if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%hd %lx", name, &new->address, &new->port, &new->options) != 4)
801 syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"), cl->name, cl->hostname);
805 /* Check if identity is a valid name */
809 syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
810 free_connection(new);
814 /* Check if somebody tries to add ourself */
816 if(!strcmp(name, myself->name))
818 syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"), cl->name, cl->hostname);
820 free_connection(new);
824 /* Fill in more of the new connection structure */
826 new->hostname = hostlookup(htonl(new->address));
828 /* Check if the new host already exists in the connnection list */
830 if((old = lookup_id(name)))
832 if((new->address == old->address) && (new->port == old->port) && (cl == old->nexthop))
834 if(debug_lvl >= DEBUG_CONNECTIONS)
835 syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
836 old->name, old->hostname, cl->name, cl->hostname);
837 free_connection(new);
842 if(debug_lvl >= DEBUG_CONNECTIONS)
843 syslog(LOG_NOTICE, _("Removing old entry for %s (%s) in favour of new connection"),
844 old->name, old->hostname);
846 terminate_connection(old, 0);
850 /* Hook it up into the active tree */
852 new->name = xstrdup(name);
855 /* Tell the rest about the new host */
857 for(node = connection_tree->head; node; node = node->next)
859 p = (connection_t *)node->data;
860 if(p->status.active && p!=cl)
861 send_add_host(p, new);
864 /* Fill in rest of connection structure */
867 new->cipher_pkttype = EVP_bf_cbc();
868 new->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
873 int send_del_host(connection_t *cl, connection_t *other)
876 if(!((cl->options | myself->options) & OPTION_INDIRECT))
877 return send_request(cl, "%d %s %lx:%d %lx", DEL_HOST,
878 other->name, other->address, other->port, other->options);
883 int del_host_h(connection_t *cl)
885 char name[MAX_STRING_SIZE];
889 connection_t *old, *p;
892 if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%hd %lx", name, &address, &port, &options) != 4)
894 syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
895 cl->name, cl->hostname);
899 /* Check if identity is a valid name */
903 syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
907 /* Check if somebody tries to delete ourself */
909 if(!strcmp(name, myself->name))
911 syslog(LOG_ERR, _("Warning: got DEL_HOST from %s (%s) for ourself, restarting"),
912 cl->name, cl->hostname);
917 /* Check if the deleted host already exists in the connnection list */
919 if(!(old = lookup_id(name)))
921 syslog(LOG_ERR, _("Got DEL_HOST from %s (%s) for %s which is not in our connection list"),
922 cl->name, cl->hostname, name);
926 /* Check if the rest matches */
928 if(address!=old->address || port!=old->port || options!=old->options || cl!=old->nexthop)
930 syslog(LOG_WARNING, _("Got DEL_HOST from %s (%s) for %s which doesn't match"), cl->name, cl->hostname, old->name);
934 /* Ok, since EVERYTHING seems to check out all right, delete it */
936 terminate_connection(old, 0);
938 /* Tell the rest about the deleted host */
940 for(node = connection_tree->head; node; node = node->next)
942 p = (connection_t *)node->data;
943 if(p->status.active && p!=cl)
944 send_del_host(p, old);
950 /* Status and error notification routines */
952 int send_status(connection_t *cl, int statusno, char *statusstring)
956 statusstring = status_text[statusno];
958 return send_request(cl, "%d %d %s", STATUS, statusno, statusstring);
961 int status_h(connection_t *cl)
964 char statusstring[MAX_STRING_SIZE];
966 if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &statusno, statusstring) != 2)
968 syslog(LOG_ERR, _("Got bad STATUS from %s (%s)"),
969 cl->name, cl->hostname);
973 if(debug_lvl >= DEBUG_STATUS)
975 syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"),
976 cl->name, cl->hostname, status_text[statusno], statusstring);
983 int send_error(connection_t *cl, int err, char *errstring)
987 errstring = strerror(err);
988 return send_request(cl, "%d %d %s", ERROR, err, errstring);
991 int error_h(connection_t *cl)
994 char errorstring[MAX_STRING_SIZE];
996 if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &err, errorstring) != 2)
998 syslog(LOG_ERR, _("Got bad ERROR from %s (%s)"),
999 cl->name, cl->hostname);
1003 if(debug_lvl >= DEBUG_ERROR)
1005 syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"),
1006 cl->name, cl->hostname, strerror(err), errorstring);
1009 terminate_connection(cl, 1);
1014 int send_termreq(connection_t *cl)
1017 return send_request(cl, "%d", TERMREQ);
1020 int termreq_h(connection_t *cl)
1023 terminate_connection(cl, 1);
1028 int send_ping(connection_t *cl)
1030 char salt[SALTLEN*2+1];
1032 cl->status.pinged = 1;
1033 cl->last_ping_time = time(NULL);
1034 RAND_pseudo_bytes(salt, SALTLEN);
1035 bin2hex(salt, salt, SALTLEN);
1036 salt[SALTLEN*2] = '\0';
1038 return send_request(cl, "%d %s", PING, salt);
1041 int ping_h(connection_t *cl)
1044 return send_pong(cl);
1047 int send_pong(connection_t *cl)
1049 char salt[SALTLEN*2+1];
1051 RAND_pseudo_bytes(salt, SALTLEN);
1052 bin2hex(salt, salt, SALTLEN);
1053 salt[SALTLEN*2] = '\0';
1055 return send_request(cl, "%d %s", PONG, salt);
1058 int pong_h(connection_t *cl)
1061 cl->status.pinged = 0;
1068 int send_key_changed(connection_t *from, connection_t *cl)
1073 /* Only send this message if some other daemon requested our key previously.
1074 This reduces unnecessary key_changed broadcasts.
1077 if(from==myself && !mykeyused)
1080 for(node = connection_tree->head; node; node = node->next)
1082 p = (connection_t *)node->data;
1083 if(p != cl && p->status.active)
1084 if(!(p->options & OPTION_INDIRECT) || from == myself)
1085 send_request(p, "%d %s", KEY_CHANGED, from->name);
1091 int key_changed_h(connection_t *cl)
1093 char from_id[MAX_STRING_SIZE];
1096 if(sscanf(cl->buffer, "%*d "MAX_STRING, from_id) != 1)
1098 syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
1099 cl->name, cl->hostname);
1103 if(!(from = lookup_id(from_id)))
1105 syslog(LOG_ERR, _("Got KEY_CHANGED from %s (%s) origin %s which does not exist in our connection list"),
1106 cl->name, cl->hostname, from_id);
1110 from->status.validkey = 0;
1111 from->status.waitingforkey = 0;
1113 if(!(from->options | cl->options | myself->options) & OPTION_INDIRECT)
1114 send_key_changed(from, cl);
1119 int send_req_key(connection_t *from, connection_t *to)
1122 return send_request(to->nexthop, "%d %s %s", REQ_KEY,
1123 from->name, to->name);
1126 int req_key_h(connection_t *cl)
1128 char from_id[MAX_STRING_SIZE];
1129 char to_id[MAX_STRING_SIZE];
1130 connection_t *from, *to;
1133 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, from_id, to_id) != 2)
1135 syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
1136 cl->name, cl->hostname);
1140 if(!(from = lookup_id(from_id)))
1142 syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) origin %s which does not exist in our connection list"),
1143 cl->name, cl->hostname, from_id);
1147 /* Check if this key request is for us */
1149 if(!strcmp(to_id, myself->name)) /* Yes, send our own key back */
1151 bin2hex(myself->cipher_pktkey, pktkey, myself->cipher_pktkeylength);
1152 pktkey[myself->cipher_pktkeylength*2] = '\0';
1153 send_ans_key(myself, from, pktkey);
1158 if(!(to = lookup_id(to_id)))
1160 syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) destination %s which does not exist in our connection list"),
1161 cl->name, cl->hostname, to_id);
1165 if(to->status.validkey) /* Proxy keys */
1167 bin2hex(to->cipher_pktkey, pktkey, to->cipher_pktkeylength);
1168 pktkey[to->cipher_pktkeylength*2] = '\0';
1169 send_ans_key(to, from, pktkey);
1172 send_req_key(from, to);
1179 int send_ans_key(connection_t *from, connection_t *to, char *pktkey)
1182 return send_request(to->nexthop, "%d %s %s %s", ANS_KEY,
1183 from->name, to->name, pktkey);
1186 int ans_key_h(connection_t *cl)
1188 char from_id[MAX_STRING_SIZE];
1189 char to_id[MAX_STRING_SIZE];
1190 char pktkey[MAX_STRING_SIZE];
1192 connection_t *from, *to;
1194 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING, from_id, to_id, pktkey) != 3)
1196 syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
1197 cl->name, cl->hostname);
1201 if(!(from = lookup_id(from_id)))
1203 syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) origin %s which does not exist in our connection list"),
1204 cl->name, cl->hostname, from_id);
1208 /* Check correctness of packet key */
1210 keylength = strlen(pktkey);
1212 if(keylength != from->cipher_pktkeylength*2)
1214 syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s) origin %s: invalid key length"),
1215 cl->name, cl->hostname, from->name);
1219 /* Forward it if necessary */
1221 if(strcmp(to_id, myself->name))
1223 if(!(to = lookup_id(to_id)))
1225 syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) destination %s which does not exist in our connection list"),
1226 cl->name, cl->hostname, to_id);
1229 send_ans_key(from, to, pktkey);
1232 /* Update our copy of the origin's packet key */
1234 if(from->cipher_pktkey)
1235 free(from->cipher_pktkey);
1237 from->cipher_pktkey = xstrdup(pktkey);
1239 hex2bin(from->cipher_pktkey, from->cipher_pktkey, keylength);
1240 from->cipher_pktkey[keylength] = '\0';
1242 from->status.validkey = 1;
1243 from->status.waitingforkey = 0;
1250 int send_tcppacket(connection_t *cl, vpn_packet_t *packet)
1256 x = send_request(cl->nexthop, "%d %hd", PACKET, packet->len);
1261 return send_meta(cl, packet->data, packet->len);
1264 int tcppacket_h(connection_t *cl)
1268 if(sscanf(cl->buffer, "%*d %hd", &len) != 1)
1270 syslog(LOG_ERR, _("Got bad PACKET from %s (%s)"), cl->name, cl->hostname);
1274 /* Set reqlen to len, this will tell receive_meta() that a tcppacket is coming. */
1281 /* Jumptable for the request handlers */
1283 int (*request_handlers[])(connection_t*) = {
1284 id_h, metakey_h, challenge_h, chal_reply_h,
1285 status_h, error_h, termreq_h,
1287 add_host_h, del_host_h,
1288 add_subnet_h, del_subnet_h,
1289 key_changed_h, req_key_h, ans_key_h,
1295 char (*request_name[]) = {
1296 "ID", "METAKEY", "CHALLENGE", "CHAL_REPLY",
1297 "STATUS", "ERROR", "TERMREQ",
1299 "ADD_HOST", "DEL_HOST",
1300 "ADD_SUBNET", "DEL_SUBNET",
1301 "KEY_CHANGED", "REQ_KEY", "ANS_KEY",
1305 /* Status strings */
1307 char (*status_text[]) = {
1313 char (*error_text[]) = {