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.99 2001/07/15 18:07:31 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)
177 char name[MAX_STRING_SIZE];
179 if(sscanf(cl->buffer, "%*d "MAX_STRING" %d %lx %hd", name, &cl->protocol_version, &cl->options, &cl->port) != 4)
181 syslog(LOG_ERR, _("Got bad ID from %s"), cl->hostname);
185 /* Check if version matches */
187 if(cl->protocol_version != myself->protocol_version)
189 syslog(LOG_ERR, _("Peer %s (%s) uses incompatible version %d"),
190 cl->name, cl->hostname, cl->protocol_version);
194 /* Check if identity is a valid name */
198 syslog(LOG_ERR, _("Peer %s uses invalid identity name"), cl->hostname);
202 /* Copy string to cl */
207 cl->name = xstrdup(name);
209 /* Make sure we don't make an outgoing connection to a host that is already in our connection list */
211 if(cl->status.outgoing)
212 if((old = lookup_id(cl->name)))
214 if(debug_lvl >= DEBUG_CONNECTIONS)
215 syslog(LOG_NOTICE, _("We are already connected to %s."), cl->name);
216 old->status.outgoing = 1;
220 /* Load information about peer */
222 if(read_host_config(cl))
224 syslog(LOG_ERR, _("Peer %s had unknown identity (%s)"), cl->hostname, cl->name);
228 /* Read in the public key, so that we can send a metakey */
230 if(read_rsa_public_key(cl))
233 cl->allow_request = METAKEY;
235 return send_metakey(cl);
238 int ack_h(connection_t *cl)
241 connection_t *old, *p;
243 avl_node_t *node, *node2;
245 /* Okay, before we active the connection, we check if there is another entry
246 in the connection list with the same name. If so, it presumably is an
247 old connection that has timed out but we don't know it yet.
250 if((old = lookup_id(cl->name)))
252 if(debug_lvl >= DEBUG_CONNECTIONS)
253 syslog(LOG_NOTICE, _("Removing old connection for %s at %s in favour of new connection from %s"),
254 cl->name, old->hostname, cl->hostname);
255 if(old->status.outgoing)
257 cl->status.outgoing = 1;
258 old->status.outgoing = 0;
260 terminate_connection(old);
264 /* Now we can add the name to the id tree */
268 /* Also check if no other tinc daemon uses the same IP and port for UDP traffic */
270 old = avl_search(active_tree, cl);
273 syslog(LOG_ERR, _("%s is listening on %s:%hd, which is already in use by %s!"),
274 cl->name, cl->hostname, cl->port, old->name);
278 /* Activate this connection */
280 cl->allow_request = ALL;
281 cl->status.active = 1;
283 cl->cipher_pkttype = EVP_bf_cbc();
284 cl->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
288 if(debug_lvl >= DEBUG_CONNECTIONS)
289 syslog(LOG_NOTICE, _("Connection with %s (%s) activated"), cl->name, cl->hostname);
291 if(cl->status.outgoing)
292 seconds_till_retry = 5; /* Reset retry timeout */
294 /* Check some options */
296 if((cfg = get_config_val(cl->config, config_indirectdata)))
298 if(cfg->data.val == stupid_true)
299 cl->options |= OPTION_INDIRECT;
302 if((cfg = get_config_val(cl->config, config_tcponly)))
304 if(cfg->data.val == stupid_true)
305 cl->options |= OPTION_TCPONLY;
308 /* Send him our subnets */
310 for(node = myself->subnet_tree->head; node; node = node->next)
312 subnet = (subnet_t *)node->data;
313 send_add_subnet(cl, subnet);
316 /* And send him all the hosts and their subnets we know... */
318 for(node = connection_tree->head; node; node = node->next)
320 p = (connection_t *)node->data;
322 if(p != cl && p->status.active)
324 /* Notify others of this connection */
327 send_add_host(p, cl);
329 /* Notify new connection of everything we know */
331 send_add_host(cl, p);
333 for(node2 = p->subnet_tree->head; node2; node2 = node2->next)
335 subnet = (subnet_t *)node2->data;
336 send_add_subnet(cl, subnet);
344 int send_challenge(connection_t *cl)
349 /* CHECKME: what is most reasonable value for len? */
351 len = RSA_size(cl->rsa_key);
353 /* Allocate buffers for the challenge */
355 buffer = xmalloc(len*2+1);
358 free(cl->hischallenge);
360 cl->hischallenge = xmalloc(len);
362 /* Copy random data to the buffer */
364 RAND_bytes(cl->hischallenge, len);
369 bin2hex(cl->hischallenge, buffer, len);
370 buffer[len*2] = '\0';
373 /* Send the challenge */
375 x = send_request(cl, "%d %s", CHALLENGE, buffer);
381 int challenge_h(connection_t *cl)
383 char buffer[MAX_STRING_SIZE];
386 if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
388 syslog(LOG_ERR, _("Got bad CHALLENGE from %s (%s)"), cl->name, cl->hostname);
392 len = RSA_size(myself->rsa_key);
394 /* Check if the length of the challenge is all right */
396 if(strlen(buffer) != len*2)
398 syslog(LOG_ERR, _("Intruder: wrong challenge length from %s (%s)"), cl->name, cl->hostname);
402 /* Allocate buffers for the challenge */
405 cl->mychallenge = xmalloc(len);
407 /* Convert the challenge from hexadecimal back to binary */
409 hex2bin(buffer,cl->mychallenge,len);
411 cl->allow_request = CHAL_REPLY;
413 /* Rest is done by send_chal_reply() */
415 return send_chal_reply(cl);
418 int send_chal_reply(connection_t *cl)
420 char hash[SHA_DIGEST_LENGTH*2+1];
424 syslog(LOG_ERR, _("Trying to send CHAL_REPLY to %s (%s) without a valid CHALLENGE"), cl->name, cl->hostname);
428 /* Calculate the hash from the challenge we received */
430 SHA1(cl->mychallenge, RSA_size(myself->rsa_key), hash);
432 /* Convert the hash to a hexadecimal formatted string */
434 bin2hex(hash,hash,SHA_DIGEST_LENGTH);
435 hash[SHA_DIGEST_LENGTH*2] = '\0';
440 return send_request(cl, "%d %s", CHAL_REPLY, hash);
443 int chal_reply_h(connection_t *cl)
445 char hishash[MAX_STRING_SIZE];
446 char myhash[SHA_DIGEST_LENGTH];
448 if(sscanf(cl->buffer, "%*d "MAX_STRING, hishash) != 1)
450 syslog(LOG_ERR, _("Got bad CHAL_REPLY from %s (%s)"), cl->name, cl->hostname);
454 /* Check if the length of the hash is all right */
456 if(strlen(hishash) != SHA_DIGEST_LENGTH*2)
458 syslog(LOG_ERR, _("Intruder: wrong challenge reply length from %s (%s)"), cl->name, cl->hostname);
462 /* Convert the hash to binary format */
464 hex2bin(hishash, hishash, SHA_DIGEST_LENGTH);
466 /* Calculate the hash from the challenge we sent */
468 SHA1(cl->hischallenge, RSA_size(cl->rsa_key), myhash);
470 /* Verify the incoming hash with the calculated hash */
472 if(memcmp(hishash, myhash, SHA_DIGEST_LENGTH))
474 syslog(LOG_ERR, _("Intruder: wrong challenge reply from %s (%s)"), cl->name, cl->hostname);
475 if(debug_lvl >= DEBUG_SCARY_THINGS)
477 bin2hex(myhash, hishash, SHA_DIGEST_LENGTH);
478 hishash[SHA_DIGEST_LENGTH*2] = '\0';
479 syslog(LOG_DEBUG, _("Expected challenge reply: %s"), hishash);
484 /* Identity has now been positively verified.
485 ack_h() handles the rest from now on.
491 int send_metakey(connection_t *cl)
496 len = RSA_size(cl->rsa_key);
498 /* Allocate buffers for the meta key */
500 buffer = xmalloc(len*2+1);
502 if(!cl->cipher_outkey)
503 cl->cipher_outkey = xmalloc(len);
505 if(!cl->cipher_outctx)
506 cl->cipher_outctx = xmalloc(sizeof(*cl->cipher_outctx));
508 /* Copy random data to the buffer */
510 RAND_bytes(cl->cipher_outkey, len);
512 /* The message we send must be smaller than the modulus of the RSA key.
513 By definition, for a key of k bits, the following formula holds:
515 2^(k-1) <= modulus < 2^(k)
517 Where ^ means "to the power of", not "xor".
518 This means that to be sure, we must choose our message < 2^(k-1).
519 This can be done by setting the most significant bit to zero.
522 cl->cipher_outkey[0] &= 0x7F;
524 if(debug_lvl >= DEBUG_SCARY_THINGS)
526 bin2hex(cl->cipher_outkey, buffer, len);
527 buffer[len*2] = '\0';
528 syslog(LOG_DEBUG, _("Generated random meta key (unencrypted): %s"), buffer);
531 /* Encrypt the random data
533 We do not use one of the PKCS padding schemes here.
534 This is allowed, because we encrypt a totally random string
535 with a length equal to that of the modulus of the RSA key.
538 if(RSA_public_encrypt(len, cl->cipher_outkey, buffer, cl->rsa_key, RSA_NO_PADDING) != len)
540 syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
545 /* Convert the encrypted random data to a hexadecimal formatted string */
547 bin2hex(buffer, buffer, len);
548 buffer[len*2] = '\0';
550 /* Send the meta key */
552 x = send_request(cl, "%d %s", METAKEY, buffer);
555 /* Further outgoing requests are encrypted with the key we just generated */
557 EVP_EncryptInit(cl->cipher_outctx, EVP_bf_cfb(),
558 cl->cipher_outkey + len - EVP_bf_cfb()->key_len,
559 cl->cipher_outkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
561 cl->status.encryptout = 1;
566 int metakey_h(connection_t *cl)
568 char buffer[MAX_STRING_SIZE];
571 if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
573 syslog(LOG_ERR, _("Got bad METAKEY from %s (%s)"), cl->name, cl->hostname);
577 len = RSA_size(myself->rsa_key);
579 /* Check if the length of the meta key is all right */
581 if(strlen(buffer) != len*2)
583 syslog(LOG_ERR, _("Intruder: wrong meta key length from %s (%s)"), cl->name, cl->hostname);
587 /* Allocate buffers for the meta key */
589 if(!cl->cipher_inkey)
590 cl->cipher_inkey = xmalloc(len);
592 if(!cl->cipher_inctx)
593 cl->cipher_inctx = xmalloc(sizeof(*cl->cipher_inctx));
595 /* Convert the challenge from hexadecimal back to binary */
597 hex2bin(buffer,buffer,len);
599 /* Decrypt the meta key */
601 if(RSA_private_decrypt(len, buffer, cl->cipher_inkey, myself->rsa_key, RSA_NO_PADDING) != len) /* See challenge() */
603 syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
607 if(debug_lvl >= DEBUG_SCARY_THINGS)
609 bin2hex(cl->cipher_inkey, buffer, len);
610 buffer[len*2] = '\0';
611 syslog(LOG_DEBUG, _("Received random meta key (unencrypted): %s"), buffer);
614 /* All incoming requests will now be encrypted. */
616 EVP_DecryptInit(cl->cipher_inctx, EVP_bf_cfb(),
617 cl->cipher_inkey + len - EVP_bf_cfb()->key_len,
618 cl->cipher_inkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
620 cl->status.decryptin = 1;
622 cl->allow_request = CHALLENGE;
624 return send_challenge(cl);
627 /* Address and subnet information exchange */
629 int send_add_subnet(connection_t *cl, subnet_t *subnet)
635 if((cl->options | myself->options | subnet->owner->options) & OPTION_INDIRECT)
636 owner = myself->name;
638 owner = subnet->owner->name;
640 x = send_request(cl, "%d %s %s", ADD_SUBNET,
641 owner, netstr = net2str(subnet));
647 int add_subnet_h(connection_t *cl)
649 char subnetstr[MAX_STRING_SIZE];
650 char name[MAX_STRING_SIZE];
651 connection_t *owner, *p;
655 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
657 syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s)"), cl->name, cl->hostname);
661 /* Check if owner name is a valid */
665 syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
669 /* Check if subnet string is valid */
671 if(!(subnet = str2net(subnetstr)))
673 syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
677 /* Check if somebody tries to add a subnet of ourself */
679 if(!strcmp(name, myself->name))
681 syslog(LOG_ERR, _("Warning: got ADD_SUBNET from %s (%s) for ourself, restarting"),
682 cl->name, cl->hostname);
687 /* Check if the owner of the new subnet is in the connection list */
689 if(!(owner = lookup_id(name)))
691 syslog(LOG_ERR, _("Got ADD_SUBNET for %s from %s (%s) which is not in our connection list"),
692 name, cl->name, cl->hostname);
696 /* If everything is correct, add the subnet to the list of the owner */
698 subnet_add(owner, subnet);
702 for(node = connection_tree->head; node; node = node->next)
704 p = (connection_t *)node->data;
705 if(p->status.meta && p->status.active && p!= cl)
706 send_add_subnet(p, subnet);
712 int send_del_subnet(connection_t *cl, subnet_t *subnet)
718 if(cl->options & OPTION_INDIRECT)
719 owner = myself->name;
721 owner = subnet->owner->name;
723 x = send_request(cl, "%d %s %s", DEL_SUBNET, owner, netstr = net2str(subnet));
729 int del_subnet_h(connection_t *cl)
731 char subnetstr[MAX_STRING_SIZE];
732 char name[MAX_STRING_SIZE];
733 connection_t *owner, *p;
737 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 3)
739 syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s)"), cl->name, cl->hostname);
743 /* Check if owner name is a valid */
747 syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
751 /* Check if subnet string is valid */
753 if(!(subnet = str2net(subnetstr)))
755 syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
761 /* Check if somebody tries to add a subnet of ourself */
763 if(!strcmp(name, myself->name))
765 syslog(LOG_ERR, _("Warning: got DEL_SUBNET from %s (%s) for ourself, restarting"),
766 cl->name, cl->hostname);
771 /* Check if the owner of the new subnet is in the connection list */
773 if(!(owner = lookup_id(name)))
775 syslog(LOG_ERR, _("Got DEL_SUBNET for %s from %s (%s) which is not in our connection list"),
776 name, cl->name, cl->hostname);
780 /* If everything is correct, delete the subnet from the list of the owner */
786 for(node = connection_tree->head; node; node = node->next)
788 p = (connection_t *)node->data;
789 if(p->status.meta && p->status.active && p!= cl)
790 send_del_subnet(p, subnet);
796 /* New and closed connections notification */
798 int send_add_host(connection_t *cl, connection_t *other)
801 if(!((cl->options | myself->options | other->options) & OPTION_INDIRECT))
802 return send_request(cl, "%d %s %lx:%d %lx", ADD_HOST,
803 other->name, other->address, other->port, other->options);
808 int add_host_h(connection_t *cl)
810 connection_t *old, *new, *p;
811 char name[MAX_STRING_SIZE];
814 new = new_connection();
816 if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%hd %lx", name, &new->address, &new->port, &new->options) != 4)
818 syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"), cl->name, cl->hostname);
822 /* Check if identity is a valid name */
826 syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
827 free_connection(new);
831 /* Check if somebody tries to add ourself */
833 if(!strcmp(name, myself->name))
835 syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"), cl->name, cl->hostname);
837 free_connection(new);
841 /* Fill in more of the new connection structure */
843 new->hostname = hostlookup(htonl(new->address));
845 /* Check if the new host already exists in the connnection list */
847 if((old = lookup_id(name)))
849 if((new->address == old->address) && (new->port == old->port))
851 if(debug_lvl >= DEBUG_CONNECTIONS)
852 syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
853 old->name, old->hostname, name, new->hostname);
854 free_connection(new);
859 if(debug_lvl >= DEBUG_CONNECTIONS)
860 syslog(LOG_NOTICE, _("Removing old entry for %s (%s) in favour of new connection"),
861 old->name, old->hostname);
863 terminate_connection(old);
867 /* Hook it up into the connection */
869 new->name = xstrdup(name);
873 /* Tell the rest about the new host */
875 for(node = connection_tree->head; node; node = node->next)
877 p = (connection_t *)node->data;
878 if(p->status.meta && p->status.active && p!=cl)
879 send_add_host(p, new);
882 /* Fill in rest of connection structure */
885 new->status.active = 1;
886 new->cipher_pkttype = EVP_bf_cbc();
887 new->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
892 int send_del_host(connection_t *cl, connection_t *other)
895 if(!((cl->options | myself->options) & OPTION_INDIRECT))
896 return send_request(cl, "%d %s %lx:%d %lx", DEL_HOST,
897 other->name, other->address, other->port, other->options);
902 int del_host_h(connection_t *cl)
904 char name[MAX_STRING_SIZE];
908 connection_t *old, *p;
911 if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%hd %lx", name, &address, &port, &options) != 4)
913 syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
914 cl->name, cl->hostname);
918 /* Check if identity is a valid name */
922 syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
926 /* Check if somebody tries to delete ourself */
928 if(!strcmp(name, myself->name))
930 syslog(LOG_ERR, _("Warning: got DEL_HOST from %s (%s) for ourself, restarting"),
931 cl->name, cl->hostname);
936 /* Check if the new 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 name, cl->name, cl->hostname);
945 /* Check if the rest matches */
947 if(address!=old->address || port!=old->port || options!=old->options || cl!=old->nexthop)
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 old->status.active = 0;
956 terminate_connection(old);
958 /* Tell the rest about the new host */
960 for(node = connection_tree->head; node; node = node->next)
962 p = (connection_t *)node->data;
963 if(p->status.meta && p->status.active && p!=cl)
964 send_del_host(p, old);
970 /* Status and error notification routines */
972 int send_status(connection_t *cl, int statusno, char *statusstring)
976 statusstring = status_text[statusno];
978 return send_request(cl, "%d %d %s", STATUS, statusno, statusstring);
981 int status_h(connection_t *cl)
984 char statusstring[MAX_STRING_SIZE];
986 if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &statusno, statusstring) != 2)
988 syslog(LOG_ERR, _("Got bad STATUS from %s (%s)"),
989 cl->name, cl->hostname);
993 if(debug_lvl >= DEBUG_STATUS)
995 syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"),
996 cl->name, cl->hostname, status_text[statusno], statusstring);
1003 int send_error(connection_t *cl, int err, char *errstring)
1007 errstring = strerror(err);
1008 return send_request(cl, "%d %d %s", ERROR, err, errstring);
1011 int error_h(connection_t *cl)
1014 char errorstring[MAX_STRING_SIZE];
1016 if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &err, errorstring) != 2)
1018 syslog(LOG_ERR, _("Got bad ERROR from %s (%s)"),
1019 cl->name, cl->hostname);
1023 if(debug_lvl >= DEBUG_ERROR)
1025 syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"),
1026 cl->name, cl->hostname, strerror(err), errorstring);
1029 terminate_connection(cl);
1034 int send_termreq(connection_t *cl)
1037 return send_request(cl, "%d", TERMREQ);
1040 int termreq_h(connection_t *cl)
1043 terminate_connection(cl);
1048 int send_ping(connection_t *cl)
1050 char salt[SALTLEN*2+1];
1052 cl->status.pinged = 1;
1053 cl->last_ping_time = time(NULL);
1054 RAND_pseudo_bytes(salt, SALTLEN);
1055 bin2hex(salt, salt, SALTLEN);
1056 salt[SALTLEN*2] = '\0';
1058 return send_request(cl, "%d %s", PING, salt);
1061 int ping_h(connection_t *cl)
1064 return send_pong(cl);
1067 int send_pong(connection_t *cl)
1069 char salt[SALTLEN*2+1];
1071 RAND_pseudo_bytes(salt, SALTLEN);
1072 bin2hex(salt, salt, SALTLEN);
1073 salt[SALTLEN*2] = '\0';
1075 return send_request(cl, "%d %s", PONG, salt);
1078 int pong_h(connection_t *cl)
1081 cl->status.pinged = 0;
1088 int send_key_changed(connection_t *from, connection_t *cl)
1093 /* Only send this message if some other daemon requested our key previously.
1094 This reduces unnecessary key_changed broadcasts.
1097 if(from==myself && !mykeyused)
1100 for(node = connection_tree->head; node; node = node->next)
1102 p = (connection_t *)node->data;
1103 if(p != cl && p->status.meta && p->status.active)
1104 if(!(p->options & OPTION_INDIRECT) || from == myself)
1105 send_request(p, "%d %s", KEY_CHANGED, from->name);
1111 int key_changed_h(connection_t *cl)
1113 char from_id[MAX_STRING_SIZE];
1116 if(sscanf(cl->buffer, "%*d "MAX_STRING, from_id) != 1)
1118 syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
1119 cl->name, cl->hostname);
1123 if(!(from = lookup_id(from_id)))
1125 syslog(LOG_ERR, _("Got KEY_CHANGED from %s (%s) origin %s which does not exist in our connection list"),
1126 cl->name, cl->hostname, from_id);
1130 from->status.validkey = 0;
1131 from->status.waitingforkey = 0;
1133 if(!(from->options | cl->options | myself->options) & OPTION_INDIRECT)
1134 send_key_changed(from, cl);
1139 int send_req_key(connection_t *from, connection_t *to)
1142 return send_request(to->nexthop, "%d %s %s", REQ_KEY,
1143 from->name, to->name);
1146 int req_key_h(connection_t *cl)
1148 char from_id[MAX_STRING_SIZE];
1149 char to_id[MAX_STRING_SIZE];
1150 connection_t *from, *to;
1153 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, from_id, to_id) != 2)
1155 syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
1156 cl->name, cl->hostname);
1160 if(!(from = lookup_id(from_id)))
1162 syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) origin %s which does not exist in our connection list"),
1163 cl->name, cl->hostname, from_id);
1167 /* Check if this key request is for us */
1169 if(!strcmp(to_id, myself->name)) /* Yes, send our own key back */
1171 bin2hex(myself->cipher_pktkey, pktkey, myself->cipher_pktkeylength);
1172 pktkey[myself->cipher_pktkeylength*2] = '\0';
1173 send_ans_key(myself, from, pktkey);
1178 if(!(to = lookup_id(to_id)))
1180 syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) destination %s which does not exist in our connection list"),
1181 cl->name, cl->hostname, to_id);
1185 if(to->status.validkey) /* Proxy keys */
1187 bin2hex(to->cipher_pktkey, pktkey, to->cipher_pktkeylength);
1188 pktkey[to->cipher_pktkeylength*2] = '\0';
1189 send_ans_key(to, from, pktkey);
1192 send_req_key(from, to);
1199 int send_ans_key(connection_t *from, connection_t *to, char *pktkey)
1202 return send_request(to->nexthop, "%d %s %s %s", ANS_KEY,
1203 from->name, to->name, pktkey);
1206 int ans_key_h(connection_t *cl)
1208 char from_id[MAX_STRING_SIZE];
1209 char to_id[MAX_STRING_SIZE];
1210 char pktkey[MAX_STRING_SIZE];
1212 connection_t *from, *to;
1214 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING, from_id, to_id, pktkey) != 3)
1216 syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
1217 cl->name, cl->hostname);
1221 if(!(from = lookup_id(from_id)))
1223 syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) origin %s which does not exist in our connection list"),
1224 cl->name, cl->hostname, from_id);
1228 /* Check correctness of packet key */
1230 keylength = strlen(pktkey);
1232 if(keylength != from->cipher_pktkeylength*2)
1234 syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s) origin %s: invalid key length"),
1235 cl->name, cl->hostname, from->name);
1239 /* Forward it if necessary */
1241 if(strcmp(to_id, myself->name))
1243 if(!(to = lookup_id(to_id)))
1245 syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) destination %s which does not exist in our connection list"),
1246 cl->name, cl->hostname, to_id);
1249 send_ans_key(from, to, pktkey);
1252 /* Update our copy of the origin's packet key */
1254 if(from->cipher_pktkey)
1255 free(from->cipher_pktkey);
1257 from->cipher_pktkey = xstrdup(pktkey);
1259 hex2bin(from->cipher_pktkey, from->cipher_pktkey, keylength);
1260 from->cipher_pktkey[keylength] = '\0';
1262 from->status.validkey = 1;
1263 from->status.waitingforkey = 0;
1270 int send_tcppacket(connection_t *cl, vpn_packet_t *packet)
1276 x = send_request(cl->nexthop, "%d %hd", PACKET, packet->len);
1281 return send_meta(cl, packet->data, packet->len);
1284 int tcppacket_h(connection_t *cl)
1288 if(sscanf(cl->buffer, "%*d %hd", &len) != 1)
1290 syslog(LOG_ERR, _("Got bad PACKET from %s (%s)"), cl->name, cl->hostname);
1294 /* Set reqlen to len, this will tell receive_meta() that a tcppacket is coming. */
1301 /* Jumptable for the request handlers */
1303 int (*request_handlers[])(connection_t*) = {
1304 id_h, metakey_h, challenge_h, chal_reply_h,
1305 status_h, error_h, termreq_h,
1307 add_host_h, del_host_h,
1308 add_subnet_h, del_subnet_h,
1309 key_changed_h, req_key_h, ans_key_h,
1315 char (*request_name[]) = {
1316 "ID", "METAKEY", "CHALLENGE", "CHAL_REPLY",
1317 "STATUS", "ERROR", "TERMREQ",
1319 "ADD_HOST", "DEL_HOST",
1320 "ADD_SUBNET", "DEL_SUBNET",
1321 "KEY_CHANGED", "REQ_KEY", "ANS_KEY",
1325 /* Status strings */
1327 char (*status_text[]) = {
1333 char (*error_text[]) = {