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.106 2001/09/24 14:12:00 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;
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->lastbutonehop = 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 /* Send him our subnets */
294 for(node = myself->subnet_tree->head; node; node = node->next)
296 subnet = (subnet_t *)node->data;
297 send_add_subnet(cl, subnet);
300 /* And send him all the hosts and their subnets we know... */
302 for(node = active_tree->head; node; node = node->next)
304 p = (connection_t *)node->data;
308 /* Notify others of this connection */
311 send_add_host(p, cl);
313 /* Notify new connection of everything we know */
315 send_add_host(cl, p);
317 for(node2 = p->subnet_tree->head; node2; node2 = node2->next)
319 subnet = (subnet_t *)node2->data;
320 send_add_subnet(cl, subnet);
328 int send_challenge(connection_t *cl)
333 /* CHECKME: what is most reasonable value for len? */
335 len = RSA_size(cl->rsa_key);
337 /* Allocate buffers for the challenge */
339 buffer = xmalloc(len*2+1);
342 free(cl->hischallenge);
344 cl->hischallenge = xmalloc(len);
346 /* Copy random data to the buffer */
348 RAND_bytes(cl->hischallenge, len);
353 bin2hex(cl->hischallenge, buffer, len);
354 buffer[len*2] = '\0';
357 /* Send the challenge */
359 x = send_request(cl, "%d %s", CHALLENGE, buffer);
365 int challenge_h(connection_t *cl)
367 char buffer[MAX_STRING_SIZE];
370 if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
372 syslog(LOG_ERR, _("Got bad CHALLENGE from %s (%s)"), cl->name, cl->hostname);
376 len = RSA_size(myself->rsa_key);
378 /* Check if the length of the challenge is all right */
380 if(strlen(buffer) != len*2)
382 syslog(LOG_ERR, _("Intruder: wrong challenge length from %s (%s)"), cl->name, cl->hostname);
386 /* Allocate buffers for the challenge */
389 cl->mychallenge = xmalloc(len);
391 /* Convert the challenge from hexadecimal back to binary */
393 hex2bin(buffer,cl->mychallenge,len);
395 cl->allow_request = CHAL_REPLY;
397 /* Rest is done by send_chal_reply() */
399 return send_chal_reply(cl);
402 int send_chal_reply(connection_t *cl)
404 char hash[SHA_DIGEST_LENGTH*2+1];
408 syslog(LOG_ERR, _("Trying to send CHAL_REPLY to %s (%s) without a valid CHALLENGE"), cl->name, cl->hostname);
412 /* Calculate the hash from the challenge we received */
414 SHA1(cl->mychallenge, RSA_size(myself->rsa_key), hash);
416 /* Convert the hash to a hexadecimal formatted string */
418 bin2hex(hash,hash,SHA_DIGEST_LENGTH);
419 hash[SHA_DIGEST_LENGTH*2] = '\0';
424 return send_request(cl, "%d %s", CHAL_REPLY, hash);
427 int chal_reply_h(connection_t *cl)
429 char hishash[MAX_STRING_SIZE];
430 char myhash[SHA_DIGEST_LENGTH];
432 if(sscanf(cl->buffer, "%*d "MAX_STRING, hishash) != 1)
434 syslog(LOG_ERR, _("Got bad CHAL_REPLY from %s (%s)"), cl->name, cl->hostname);
438 /* Check if the length of the hash is all right */
440 if(strlen(hishash) != SHA_DIGEST_LENGTH*2)
442 syslog(LOG_ERR, _("Intruder: wrong challenge reply length from %s (%s)"), cl->name, cl->hostname);
446 /* Convert the hash to binary format */
448 hex2bin(hishash, hishash, SHA_DIGEST_LENGTH);
450 /* Calculate the hash from the challenge we sent */
452 SHA1(cl->hischallenge, RSA_size(cl->rsa_key), myhash);
454 /* Verify the incoming hash with the calculated hash */
456 if(memcmp(hishash, myhash, SHA_DIGEST_LENGTH))
458 syslog(LOG_ERR, _("Intruder: wrong challenge reply from %s (%s)"), cl->name, cl->hostname);
459 if(debug_lvl >= DEBUG_SCARY_THINGS)
461 bin2hex(myhash, hishash, SHA_DIGEST_LENGTH);
462 hishash[SHA_DIGEST_LENGTH*2] = '\0';
463 syslog(LOG_DEBUG, _("Expected challenge reply: %s"), hishash);
468 /* Identity has now been positively verified.
469 ack_h() handles the rest from now on.
475 int send_metakey(connection_t *cl)
480 len = RSA_size(cl->rsa_key);
482 /* Allocate buffers for the meta key */
484 buffer = xmalloc(len*2+1);
486 if(!cl->cipher_outkey)
487 cl->cipher_outkey = xmalloc(len);
489 if(!cl->cipher_outctx)
490 cl->cipher_outctx = xmalloc(sizeof(*cl->cipher_outctx));
492 /* Copy random data to the buffer */
494 RAND_bytes(cl->cipher_outkey, len);
496 /* The message we send must be smaller than the modulus of the RSA key.
497 By definition, for a key of k bits, the following formula holds:
499 2^(k-1) <= modulus < 2^(k)
501 Where ^ means "to the power of", not "xor".
502 This means that to be sure, we must choose our message < 2^(k-1).
503 This can be done by setting the most significant bit to zero.
506 cl->cipher_outkey[0] &= 0x7F;
508 if(debug_lvl >= DEBUG_SCARY_THINGS)
510 bin2hex(cl->cipher_outkey, buffer, len);
511 buffer[len*2] = '\0';
512 syslog(LOG_DEBUG, _("Generated random meta key (unencrypted): %s"), buffer);
515 /* Encrypt the random data
517 We do not use one of the PKCS padding schemes here.
518 This is allowed, because we encrypt a totally random string
519 with a length equal to that of the modulus of the RSA key.
522 if(RSA_public_encrypt(len, cl->cipher_outkey, buffer, cl->rsa_key, RSA_NO_PADDING) != len)
524 syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
529 /* Convert the encrypted random data to a hexadecimal formatted string */
531 bin2hex(buffer, buffer, len);
532 buffer[len*2] = '\0';
534 /* Send the meta key */
536 x = send_request(cl, "%d %s", METAKEY, buffer);
539 /* Further outgoing requests are encrypted with the key we just generated */
541 EVP_EncryptInit(cl->cipher_outctx, EVP_bf_cfb(),
542 cl->cipher_outkey + len - EVP_bf_cfb()->key_len,
543 cl->cipher_outkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
545 cl->status.encryptout = 1;
550 int metakey_h(connection_t *cl)
552 char buffer[MAX_STRING_SIZE];
555 if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
557 syslog(LOG_ERR, _("Got bad METAKEY from %s (%s)"), cl->name, cl->hostname);
561 len = RSA_size(myself->rsa_key);
563 /* Check if the length of the meta key is all right */
565 if(strlen(buffer) != len*2)
567 syslog(LOG_ERR, _("Intruder: wrong meta key length from %s (%s)"), cl->name, cl->hostname);
571 /* Allocate buffers for the meta key */
573 if(!cl->cipher_inkey)
574 cl->cipher_inkey = xmalloc(len);
576 if(!cl->cipher_inctx)
577 cl->cipher_inctx = xmalloc(sizeof(*cl->cipher_inctx));
579 /* Convert the challenge from hexadecimal back to binary */
581 hex2bin(buffer,buffer,len);
583 /* Decrypt the meta key */
585 if(RSA_private_decrypt(len, buffer, cl->cipher_inkey, myself->rsa_key, RSA_NO_PADDING) != len) /* See challenge() */
587 syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
591 if(debug_lvl >= DEBUG_SCARY_THINGS)
593 bin2hex(cl->cipher_inkey, buffer, len);
594 buffer[len*2] = '\0';
595 syslog(LOG_DEBUG, _("Received random meta key (unencrypted): %s"), buffer);
598 /* All incoming requests will now be encrypted. */
600 EVP_DecryptInit(cl->cipher_inctx, EVP_bf_cfb(),
601 cl->cipher_inkey + len - EVP_bf_cfb()->key_len,
602 cl->cipher_inkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
604 cl->status.decryptin = 1;
606 cl->allow_request = CHALLENGE;
608 return send_challenge(cl);
611 /* Address and subnet information exchange */
613 int send_add_subnet(connection_t *cl, subnet_t *subnet)
619 owner = subnet->owner->name;
621 x = send_request(cl, "%d %s %s", ADD_SUBNET,
622 owner, netstr = net2str(subnet));
628 int add_subnet_h(connection_t *cl)
630 char subnetstr[MAX_STRING_SIZE];
631 char name[MAX_STRING_SIZE];
632 connection_t *owner, *p;
636 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
638 syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s)"), cl->name, cl->hostname);
642 /* Check if owner name is a valid */
646 syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
650 /* Check if subnet string is valid */
652 if(!(subnet = str2net(subnetstr)))
654 syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
658 /* Check if somebody tries to add a subnet of ourself */
660 if(!strcmp(name, myself->name))
662 syslog(LOG_ERR, _("Warning: got ADD_SUBNET from %s (%s) for ourself, restarting"),
663 cl->name, cl->hostname);
668 /* Check if the owner of the new subnet is in the connection list */
670 if(!(owner = lookup_id(name)))
672 syslog(LOG_ERR, _("Got ADD_SUBNET for %s from %s (%s) which is not in our connection list"),
673 name, cl->name, cl->hostname);
677 /* If everything is correct, add the subnet to the list of the owner */
679 subnet_add(owner, subnet);
683 for(node = connection_tree->head; node; node = node->next)
685 p = (connection_t *)node->data;
686 if(p->status.active && p!= cl)
687 send_add_subnet(p, subnet);
693 int send_del_subnet(connection_t *cl, subnet_t *subnet)
699 owner = subnet->owner->name;
701 x = send_request(cl, "%d %s %s", DEL_SUBNET, owner, netstr = net2str(subnet));
707 int del_subnet_h(connection_t *cl)
709 char subnetstr[MAX_STRING_SIZE];
710 char name[MAX_STRING_SIZE];
711 connection_t *owner, *p;
715 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 3)
717 syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s)"), cl->name, cl->hostname);
721 /* Check if owner name is a valid */
725 syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
729 /* Check if subnet string is valid */
731 if(!(subnet = str2net(subnetstr)))
733 syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
739 /* Check if somebody tries to add a subnet of ourself */
741 if(!strcmp(name, myself->name))
743 syslog(LOG_ERR, _("Warning: got DEL_SUBNET from %s (%s) for ourself, restarting"),
744 cl->name, cl->hostname);
749 /* Check if the owner of the new subnet is in the connection list */
751 if(!(owner = lookup_id(name)))
753 syslog(LOG_ERR, _("Got DEL_SUBNET for %s from %s (%s) which is not in our connection list"),
754 name, cl->name, cl->hostname);
758 /* If everything is correct, delete the subnet from the list of the owner */
764 for(node = connection_tree->head; node; node = node->next)
766 p = (connection_t *)node->data;
767 if(p->status.active && p!= cl)
768 send_del_subnet(p, subnet);
774 /* New and closed connections notification */
776 int send_add_host(connection_t *cl, connection_t *other)
779 return send_request(cl, "%d %s %lx:%d %lx %s", ADD_HOST,
780 other->name, other->address, other->port, other->options, other->lastbutonehop->name);
783 int add_host_h(connection_t *cl)
785 connection_t *old, *new, *p;
786 char name[MAX_STRING_SIZE], lastbutone[MAX_STRING_SIZE];
789 new = new_connection();
791 if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%hd %lx "MAX_STRING, name, &new->address, &new->port, &new->options, lastbutone) != 5)
793 syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"), cl->name, cl->hostname);
797 /* Check if identity is a valid name */
801 syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
802 free_connection(new);
806 if(check_id(lastbutone))
808 syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid lastbutone name"), cl->name, cl->hostname);
809 free_connection(new);
813 /* Check if somebody tries to add ourself */
815 if(!strcmp(name, myself->name))
817 syslog(LOG_ERR, _("Got ADD_HOST from %s (%s) for ourself!"), cl->name, cl->hostname);
818 free_connection(new);
822 /* Fill in more of the new connection structure */
824 new->hostname = hostlookup(htonl(new->address));
826 new->lastbutonehop = lookup_id(lastbutone);
828 if(!new->lastbutonehop)
830 syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): unknown lastbutone"), cl->name, cl->hostname);
831 free_connection(new);
835 /* Check if the new host already exists in the connnection list */
837 if((old = lookup_id(name)))
839 if((new->address == old->address) && (new->port == old->port) && (cl->nexthop == old->nexthop))
841 if(debug_lvl >= DEBUG_CONNECTIONS)
842 syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
843 old->name, old->hostname, cl->name, cl->hostname);
844 free_connection(new);
849 if(debug_lvl >= DEBUG_CONNECTIONS)
850 syslog(LOG_NOTICE, _("Removing old entry for %s (%s) from %s in favour of new connection from %s"),
851 old->name, old->hostname, old->nexthop->name, cl->nexthop->name);
853 terminate_connection(old, 0);
857 /* Hook it up into the active tree */
859 new->name = xstrdup(name);
862 /* Tell the rest about the new host */
864 for(node = connection_tree->head; node; node = node->next)
866 p = (connection_t *)node->data;
867 if(p->status.active && p!=cl)
868 send_add_host(p, new);
871 /* Fill in rest of connection structure */
874 new->cipher_pkttype = EVP_bf_cbc();
875 new->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
880 int send_del_host(connection_t *cl, connection_t *other)
883 return send_request(cl, "%d %s %lx:%d %lx %s", DEL_HOST,
884 other->name, other->address, other->port, other->options, other->lastbutonehop->name);
887 int del_host_h(connection_t *cl)
889 char name[MAX_STRING_SIZE], lastbutone[MAX_STRING_SIZE];
893 connection_t *old, *p;
896 if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%hd %lx "MAX_STRING, name, &address, &port, &options, lastbutone) != 5)
898 syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
899 cl->name, cl->hostname);
903 /* Check if identity is a valid name */
907 syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
911 if(check_id(lastbutone))
913 syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s): invalid lastbutone name"), cl->name, cl->hostname);
917 /* Check if somebody tries to delete ourself */
919 if(!strcmp(name, myself->name))
921 syslog(LOG_ERR, _("Got DEL_HOST from %s (%s) for ourself!"),
922 cl->name, cl->hostname);
926 /* Check if the deleted host already exists in the connnection list */
928 if(!(old = lookup_id(name)))
930 syslog(LOG_ERR, _("Got DEL_HOST from %s (%s) for %s which is not in our connection list"),
931 cl->name, cl->hostname, name);
935 /* Check if the rest matches */
937 if(address!=old->address || port!=old->port || options!=old->options || cl!=old->nexthop || strcmp(lastbutone, old->lastbutonehop->name))
939 syslog(LOG_WARNING, _("Got DEL_HOST from %s (%s) for %s which doesn't match"), cl->name, cl->hostname, old->name);
943 /* Ok, since EVERYTHING seems to check out all right, delete it */
945 terminate_connection(old, 0);
947 /* Tell the rest about the deleted host */
949 for(node = connection_tree->head; node; node = node->next)
951 p = (connection_t *)node->data;
952 if(p->status.active && p!=cl)
953 send_del_host(p, old);
959 /* Status and error notification routines */
961 int send_status(connection_t *cl, int statusno, char *statusstring)
965 statusstring = status_text[statusno];
967 return send_request(cl, "%d %d %s", STATUS, statusno, statusstring);
970 int status_h(connection_t *cl)
973 char statusstring[MAX_STRING_SIZE];
975 if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &statusno, statusstring) != 2)
977 syslog(LOG_ERR, _("Got bad STATUS from %s (%s)"),
978 cl->name, cl->hostname);
982 if(debug_lvl >= DEBUG_STATUS)
984 syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"),
985 cl->name, cl->hostname, status_text[statusno], statusstring);
992 int send_error(connection_t *cl, int err, char *errstring)
996 errstring = strerror(err);
997 return send_request(cl, "%d %d %s", ERROR, err, errstring);
1000 int error_h(connection_t *cl)
1003 char errorstring[MAX_STRING_SIZE];
1005 if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &err, errorstring) != 2)
1007 syslog(LOG_ERR, _("Got bad ERROR from %s (%s)"),
1008 cl->name, cl->hostname);
1012 if(debug_lvl >= DEBUG_ERROR)
1014 syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"),
1015 cl->name, cl->hostname, strerror(err), errorstring);
1018 terminate_connection(cl, cl->status.meta);
1023 int send_termreq(connection_t *cl)
1026 return send_request(cl, "%d", TERMREQ);
1029 int termreq_h(connection_t *cl)
1032 terminate_connection(cl, cl->status.meta);
1037 int send_ping(connection_t *cl)
1039 char salt[SALTLEN*2+1];
1041 cl->status.pinged = 1;
1042 cl->last_ping_time = time(NULL);
1043 RAND_pseudo_bytes(salt, SALTLEN);
1044 bin2hex(salt, salt, SALTLEN);
1045 salt[SALTLEN*2] = '\0';
1047 return send_request(cl, "%d %s", PING, salt);
1050 int ping_h(connection_t *cl)
1053 return send_pong(cl);
1056 int send_pong(connection_t *cl)
1058 char salt[SALTLEN*2+1];
1060 RAND_pseudo_bytes(salt, SALTLEN);
1061 bin2hex(salt, salt, SALTLEN);
1062 salt[SALTLEN*2] = '\0';
1064 return send_request(cl, "%d %s", PONG, salt);
1067 int pong_h(connection_t *cl)
1070 cl->status.pinged = 0;
1077 int send_key_changed(connection_t *from, connection_t *cl)
1082 /* Only send this message if some other daemon requested our key previously.
1083 This reduces unnecessary key_changed broadcasts.
1086 if(from==myself && !mykeyused)
1089 for(node = connection_tree->head; node; node = node->next)
1091 p = (connection_t *)node->data;
1092 if(p != cl && p->status.active)
1093 send_request(p, "%d %s", KEY_CHANGED, from->name);
1099 int key_changed_h(connection_t *cl)
1101 char from_id[MAX_STRING_SIZE];
1104 if(sscanf(cl->buffer, "%*d "MAX_STRING, from_id) != 1)
1106 syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
1107 cl->name, cl->hostname);
1111 if(!(from = lookup_id(from_id)))
1113 syslog(LOG_ERR, _("Got KEY_CHANGED from %s (%s) origin %s which does not exist in our connection list"),
1114 cl->name, cl->hostname, from_id);
1118 from->status.validkey = 0;
1119 from->status.waitingforkey = 0;
1121 send_key_changed(from, cl);
1126 int send_req_key(connection_t *from, connection_t *to)
1129 return send_request(to->nexthop, "%d %s %s", REQ_KEY,
1130 from->name, to->name);
1133 int req_key_h(connection_t *cl)
1135 char from_id[MAX_STRING_SIZE];
1136 char to_id[MAX_STRING_SIZE];
1137 connection_t *from, *to;
1140 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, from_id, to_id) != 2)
1142 syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
1143 cl->name, cl->hostname);
1147 if(!(from = lookup_id(from_id)))
1149 syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) origin %s which does not exist in our connection list"),
1150 cl->name, cl->hostname, from_id);
1154 /* Check if this key request is for us */
1156 if(!strcmp(to_id, myself->name)) /* Yes, send our own key back */
1158 bin2hex(myself->cipher_pktkey, pktkey, myself->cipher_pktkeylength);
1159 pktkey[myself->cipher_pktkeylength*2] = '\0';
1160 send_ans_key(myself, from, pktkey);
1165 if(!(to = lookup_id(to_id)))
1167 syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) destination %s which does not exist in our connection list"),
1168 cl->name, cl->hostname, to_id);
1172 if(to->status.validkey) /* Proxy keys */
1174 bin2hex(to->cipher_pktkey, pktkey, to->cipher_pktkeylength);
1175 pktkey[to->cipher_pktkeylength*2] = '\0';
1176 send_ans_key(to, from, pktkey);
1179 send_req_key(from, to);
1186 int send_ans_key(connection_t *from, connection_t *to, char *pktkey)
1189 return send_request(to->nexthop, "%d %s %s %s", ANS_KEY,
1190 from->name, to->name, pktkey);
1193 int ans_key_h(connection_t *cl)
1195 char from_id[MAX_STRING_SIZE];
1196 char to_id[MAX_STRING_SIZE];
1197 char pktkey[MAX_STRING_SIZE];
1199 connection_t *from, *to;
1201 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING, from_id, to_id, pktkey) != 3)
1203 syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
1204 cl->name, cl->hostname);
1208 if(!(from = lookup_id(from_id)))
1210 syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) origin %s which does not exist in our connection list"),
1211 cl->name, cl->hostname, from_id);
1215 /* Check correctness of packet key */
1217 keylength = strlen(pktkey);
1219 if(keylength != from->cipher_pktkeylength*2)
1221 syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s) origin %s: invalid key length"),
1222 cl->name, cl->hostname, from->name);
1226 /* Forward it if necessary */
1228 if(strcmp(to_id, myself->name))
1230 if(!(to = lookup_id(to_id)))
1232 syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) destination %s which does not exist in our connection list"),
1233 cl->name, cl->hostname, to_id);
1236 send_ans_key(from, to, pktkey);
1239 /* Update our copy of the origin's packet key */
1241 if(from->cipher_pktkey)
1242 free(from->cipher_pktkey);
1244 from->cipher_pktkey = xstrdup(pktkey);
1246 hex2bin(from->cipher_pktkey, from->cipher_pktkey, keylength);
1247 from->cipher_pktkey[keylength] = '\0';
1249 from->status.validkey = 1;
1250 from->status.waitingforkey = 0;
1257 int send_tcppacket(connection_t *cl, vpn_packet_t *packet)
1263 x = send_request(cl->nexthop, "%d %hd", PACKET, packet->len);
1268 return send_meta(cl, packet->data, packet->len);
1271 int tcppacket_h(connection_t *cl)
1275 if(sscanf(cl->buffer, "%*d %hd", &len) != 1)
1277 syslog(LOG_ERR, _("Got bad PACKET from %s (%s)"), cl->name, cl->hostname);
1281 /* Set reqlen to len, this will tell receive_meta() that a tcppacket is coming. */
1288 /* Jumptable for the request handlers */
1290 int (*request_handlers[])(connection_t*) = {
1291 id_h, metakey_h, challenge_h, chal_reply_h,
1292 status_h, error_h, termreq_h,
1294 add_host_h, del_host_h,
1295 add_subnet_h, del_subnet_h,
1296 key_changed_h, req_key_h, ans_key_h,
1302 char (*request_name[]) = {
1303 "ID", "METAKEY", "CHALLENGE", "CHAL_REPLY",
1304 "STATUS", "ERROR", "TERMREQ",
1306 "ADD_HOST", "DEL_HOST",
1307 "ADD_SUBNET", "DEL_SUBNET",
1308 "KEY_CHANGED", "REQ_KEY", "ANS_KEY",
1312 /* Status strings */
1314 char (*status_text[]) = {
1320 char (*error_text[]) = {