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.100 2001/07/19 12:29:40 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);
252 /* Now we can add the name to the id tree */
256 /* Also check if no other tinc daemon uses the same IP and port for UDP traffic */
258 old = avl_search(active_tree, cl);
261 syslog(LOG_ERR, _("%s is listening on %s:%hd, which is already in use by %s!"),
262 cl->name, cl->hostname, cl->port, old->name);
266 /* Activate this connection */
268 cl->allow_request = ALL;
269 cl->status.active = 1;
271 cl->cipher_pkttype = EVP_bf_cbc();
272 cl->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
276 if(debug_lvl >= DEBUG_CONNECTIONS)
277 syslog(LOG_NOTICE, _("Connection with %s (%s) activated"), cl->name, cl->hostname);
279 if(cl->status.outgoing)
280 seconds_till_retry = 5; /* Reset retry timeout */
282 /* Check some options */
284 if((cfg = get_config_val(cl->config, config_indirectdata)))
286 if(cfg->data.val == stupid_true)
287 cl->options |= OPTION_INDIRECT;
290 if((cfg = get_config_val(cl->config, config_tcponly)))
292 if(cfg->data.val == stupid_true)
293 cl->options |= OPTION_TCPONLY;
296 /* Send him our subnets */
298 for(node = myself->subnet_tree->head; node; node = node->next)
300 subnet = (subnet_t *)node->data;
301 send_add_subnet(cl, subnet);
304 /* And send him all the hosts and their subnets we know... */
306 for(node = active_tree->head; node; node = node->next)
308 p = (connection_t *)node->data;
310 if(p != cl && p->status.active)
312 /* Notify others of this connection */
315 send_add_host(p, cl);
317 /* Notify new connection of everything we know */
319 send_add_host(cl, p);
321 for(node2 = p->subnet_tree->head; node2; node2 = node2->next)
323 subnet = (subnet_t *)node2->data;
324 send_add_subnet(cl, subnet);
332 int send_challenge(connection_t *cl)
337 /* CHECKME: what is most reasonable value for len? */
339 len = RSA_size(cl->rsa_key);
341 /* Allocate buffers for the challenge */
343 buffer = xmalloc(len*2+1);
346 free(cl->hischallenge);
348 cl->hischallenge = xmalloc(len);
350 /* Copy random data to the buffer */
352 RAND_bytes(cl->hischallenge, len);
357 bin2hex(cl->hischallenge, buffer, len);
358 buffer[len*2] = '\0';
361 /* Send the challenge */
363 x = send_request(cl, "%d %s", CHALLENGE, buffer);
369 int challenge_h(connection_t *cl)
371 char buffer[MAX_STRING_SIZE];
374 if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
376 syslog(LOG_ERR, _("Got bad CHALLENGE from %s (%s)"), cl->name, cl->hostname);
380 len = RSA_size(myself->rsa_key);
382 /* Check if the length of the challenge is all right */
384 if(strlen(buffer) != len*2)
386 syslog(LOG_ERR, _("Intruder: wrong challenge length from %s (%s)"), cl->name, cl->hostname);
390 /* Allocate buffers for the challenge */
393 cl->mychallenge = xmalloc(len);
395 /* Convert the challenge from hexadecimal back to binary */
397 hex2bin(buffer,cl->mychallenge,len);
399 cl->allow_request = CHAL_REPLY;
401 /* Rest is done by send_chal_reply() */
403 return send_chal_reply(cl);
406 int send_chal_reply(connection_t *cl)
408 char hash[SHA_DIGEST_LENGTH*2+1];
412 syslog(LOG_ERR, _("Trying to send CHAL_REPLY to %s (%s) without a valid CHALLENGE"), cl->name, cl->hostname);
416 /* Calculate the hash from the challenge we received */
418 SHA1(cl->mychallenge, RSA_size(myself->rsa_key), hash);
420 /* Convert the hash to a hexadecimal formatted string */
422 bin2hex(hash,hash,SHA_DIGEST_LENGTH);
423 hash[SHA_DIGEST_LENGTH*2] = '\0';
428 return send_request(cl, "%d %s", CHAL_REPLY, hash);
431 int chal_reply_h(connection_t *cl)
433 char hishash[MAX_STRING_SIZE];
434 char myhash[SHA_DIGEST_LENGTH];
436 if(sscanf(cl->buffer, "%*d "MAX_STRING, hishash) != 1)
438 syslog(LOG_ERR, _("Got bad CHAL_REPLY from %s (%s)"), cl->name, cl->hostname);
442 /* Check if the length of the hash is all right */
444 if(strlen(hishash) != SHA_DIGEST_LENGTH*2)
446 syslog(LOG_ERR, _("Intruder: wrong challenge reply length from %s (%s)"), cl->name, cl->hostname);
450 /* Convert the hash to binary format */
452 hex2bin(hishash, hishash, SHA_DIGEST_LENGTH);
454 /* Calculate the hash from the challenge we sent */
456 SHA1(cl->hischallenge, RSA_size(cl->rsa_key), myhash);
458 /* Verify the incoming hash with the calculated hash */
460 if(memcmp(hishash, myhash, SHA_DIGEST_LENGTH))
462 syslog(LOG_ERR, _("Intruder: wrong challenge reply from %s (%s)"), cl->name, cl->hostname);
463 if(debug_lvl >= DEBUG_SCARY_THINGS)
465 bin2hex(myhash, hishash, SHA_DIGEST_LENGTH);
466 hishash[SHA_DIGEST_LENGTH*2] = '\0';
467 syslog(LOG_DEBUG, _("Expected challenge reply: %s"), hishash);
472 /* Identity has now been positively verified.
473 ack_h() handles the rest from now on.
479 int send_metakey(connection_t *cl)
484 len = RSA_size(cl->rsa_key);
486 /* Allocate buffers for the meta key */
488 buffer = xmalloc(len*2+1);
490 if(!cl->cipher_outkey)
491 cl->cipher_outkey = xmalloc(len);
493 if(!cl->cipher_outctx)
494 cl->cipher_outctx = xmalloc(sizeof(*cl->cipher_outctx));
496 /* Copy random data to the buffer */
498 RAND_bytes(cl->cipher_outkey, len);
500 /* The message we send must be smaller than the modulus of the RSA key.
501 By definition, for a key of k bits, the following formula holds:
503 2^(k-1) <= modulus < 2^(k)
505 Where ^ means "to the power of", not "xor".
506 This means that to be sure, we must choose our message < 2^(k-1).
507 This can be done by setting the most significant bit to zero.
510 cl->cipher_outkey[0] &= 0x7F;
512 if(debug_lvl >= DEBUG_SCARY_THINGS)
514 bin2hex(cl->cipher_outkey, buffer, len);
515 buffer[len*2] = '\0';
516 syslog(LOG_DEBUG, _("Generated random meta key (unencrypted): %s"), buffer);
519 /* Encrypt the random data
521 We do not use one of the PKCS padding schemes here.
522 This is allowed, because we encrypt a totally random string
523 with a length equal to that of the modulus of the RSA key.
526 if(RSA_public_encrypt(len, cl->cipher_outkey, buffer, cl->rsa_key, RSA_NO_PADDING) != len)
528 syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
533 /* Convert the encrypted random data to a hexadecimal formatted string */
535 bin2hex(buffer, buffer, len);
536 buffer[len*2] = '\0';
538 /* Send the meta key */
540 x = send_request(cl, "%d %s", METAKEY, buffer);
543 /* Further outgoing requests are encrypted with the key we just generated */
545 EVP_EncryptInit(cl->cipher_outctx, EVP_bf_cfb(),
546 cl->cipher_outkey + len - EVP_bf_cfb()->key_len,
547 cl->cipher_outkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
549 cl->status.encryptout = 1;
554 int metakey_h(connection_t *cl)
556 char buffer[MAX_STRING_SIZE];
559 if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
561 syslog(LOG_ERR, _("Got bad METAKEY from %s (%s)"), cl->name, cl->hostname);
565 len = RSA_size(myself->rsa_key);
567 /* Check if the length of the meta key is all right */
569 if(strlen(buffer) != len*2)
571 syslog(LOG_ERR, _("Intruder: wrong meta key length from %s (%s)"), cl->name, cl->hostname);
575 /* Allocate buffers for the meta key */
577 if(!cl->cipher_inkey)
578 cl->cipher_inkey = xmalloc(len);
580 if(!cl->cipher_inctx)
581 cl->cipher_inctx = xmalloc(sizeof(*cl->cipher_inctx));
583 /* Convert the challenge from hexadecimal back to binary */
585 hex2bin(buffer,buffer,len);
587 /* Decrypt the meta key */
589 if(RSA_private_decrypt(len, buffer, cl->cipher_inkey, myself->rsa_key, RSA_NO_PADDING) != len) /* See challenge() */
591 syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
595 if(debug_lvl >= DEBUG_SCARY_THINGS)
597 bin2hex(cl->cipher_inkey, buffer, len);
598 buffer[len*2] = '\0';
599 syslog(LOG_DEBUG, _("Received random meta key (unencrypted): %s"), buffer);
602 /* All incoming requests will now be encrypted. */
604 EVP_DecryptInit(cl->cipher_inctx, EVP_bf_cfb(),
605 cl->cipher_inkey + len - EVP_bf_cfb()->key_len,
606 cl->cipher_inkey + len - EVP_bf_cfb()->key_len - EVP_bf_cfb()->iv_len);
608 cl->status.decryptin = 1;
610 cl->allow_request = CHALLENGE;
612 return send_challenge(cl);
615 /* Address and subnet information exchange */
617 int send_add_subnet(connection_t *cl, subnet_t *subnet)
623 if((cl->options | myself->options | subnet->owner->options) & OPTION_INDIRECT)
624 owner = myself->name;
626 owner = subnet->owner->name;
628 x = send_request(cl, "%d %s %s", ADD_SUBNET,
629 owner, netstr = net2str(subnet));
635 int add_subnet_h(connection_t *cl)
637 char subnetstr[MAX_STRING_SIZE];
638 char name[MAX_STRING_SIZE];
639 connection_t *owner, *p;
643 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
645 syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s)"), cl->name, cl->hostname);
649 /* Check if owner name is a valid */
653 syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
657 /* Check if subnet string is valid */
659 if(!(subnet = str2net(subnetstr)))
661 syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
665 /* Check if somebody tries to add a subnet of ourself */
667 if(!strcmp(name, myself->name))
669 syslog(LOG_ERR, _("Warning: got ADD_SUBNET from %s (%s) for ourself, restarting"),
670 cl->name, cl->hostname);
675 /* Check if the owner of the new subnet is in the connection list */
677 if(!(owner = lookup_id(name)))
679 syslog(LOG_ERR, _("Got ADD_SUBNET for %s from %s (%s) which is not in our connection list"),
680 name, cl->name, cl->hostname);
684 /* If everything is correct, add the subnet to the list of the owner */
686 subnet_add(owner, subnet);
690 for(node = connection_tree->head; node; node = node->next)
692 p = (connection_t *)node->data;
693 if(p->status.meta && p->status.active && p!= cl)
694 send_add_subnet(p, subnet);
700 int send_del_subnet(connection_t *cl, subnet_t *subnet)
706 if(cl->options & OPTION_INDIRECT)
707 owner = myself->name;
709 owner = subnet->owner->name;
711 x = send_request(cl, "%d %s %s", DEL_SUBNET, owner, netstr = net2str(subnet));
717 int del_subnet_h(connection_t *cl)
719 char subnetstr[MAX_STRING_SIZE];
720 char name[MAX_STRING_SIZE];
721 connection_t *owner, *p;
725 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 3)
727 syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s)"), cl->name, cl->hostname);
731 /* Check if owner name is a valid */
735 syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
739 /* Check if subnet string is valid */
741 if(!(subnet = str2net(subnetstr)))
743 syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
749 /* Check if somebody tries to add a subnet of ourself */
751 if(!strcmp(name, myself->name))
753 syslog(LOG_ERR, _("Warning: got DEL_SUBNET from %s (%s) for ourself, restarting"),
754 cl->name, cl->hostname);
759 /* Check if the owner of the new subnet is in the connection list */
761 if(!(owner = lookup_id(name)))
763 syslog(LOG_ERR, _("Got DEL_SUBNET for %s from %s (%s) which is not in our connection list"),
764 name, cl->name, cl->hostname);
768 /* If everything is correct, delete the subnet from the list of the owner */
774 for(node = connection_tree->head; node; node = node->next)
776 p = (connection_t *)node->data;
777 if(p->status.meta && p->status.active && p!= cl)
778 send_del_subnet(p, subnet);
784 /* New and closed connections notification */
786 int send_add_host(connection_t *cl, connection_t *other)
789 if(!((cl->options | myself->options | other->options) & OPTION_INDIRECT))
790 return send_request(cl, "%d %s %lx:%d %lx", ADD_HOST,
791 other->name, other->address, other->port, other->options);
796 int add_host_h(connection_t *cl)
798 connection_t *old, *new, *p;
799 char name[MAX_STRING_SIZE];
802 new = new_connection();
804 if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%hd %lx", name, &new->address, &new->port, &new->options) != 4)
806 syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"), cl->name, cl->hostname);
810 /* Check if identity is a valid name */
814 syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
815 free_connection(new);
819 /* Check if somebody tries to add ourself */
821 if(!strcmp(name, myself->name))
823 syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"), cl->name, cl->hostname);
825 free_connection(new);
829 /* Fill in more of the new connection structure */
831 new->hostname = hostlookup(htonl(new->address));
833 /* Check if the new host already exists in the connnection list */
835 if((old = lookup_id(name)))
837 if((new->address == old->address) && (new->port == old->port))
839 if(debug_lvl >= DEBUG_CONNECTIONS)
840 syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
841 old->name, old->hostname, cl->name, cl->hostname);
842 free_connection(new);
847 if(debug_lvl >= DEBUG_CONNECTIONS)
848 syslog(LOG_NOTICE, _("Removing old entry for %s (%s) in favour of new connection"),
849 old->name, old->hostname);
851 terminate_connection(old);
855 /* Hook it up into the active tree */
857 new->name = xstrdup(name);
861 /* Tell the rest about the new host */
863 for(node = connection_tree->head; node; node = node->next)
865 p = (connection_t *)node->data;
866 if(p->status.meta && p->status.active && p!=cl)
867 send_add_host(p, new);
870 /* Fill in rest of connection structure */
873 new->status.active = 1;
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 if(!((cl->options | myself->options) & OPTION_INDIRECT))
884 return send_request(cl, "%d %s %lx:%d %lx", DEL_HOST,
885 other->name, other->address, other->port, other->options);
890 int del_host_h(connection_t *cl)
892 char name[MAX_STRING_SIZE];
896 connection_t *old, *p;
899 if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%hd %lx", name, &address, &port, &options) != 4)
901 syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
902 cl->name, cl->hostname);
906 /* Check if identity is a valid name */
910 syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
914 /* Check if somebody tries to delete ourself */
916 if(!strcmp(name, myself->name))
918 syslog(LOG_ERR, _("Warning: got DEL_HOST from %s (%s) for ourself, restarting"),
919 cl->name, cl->hostname);
924 /* Check if the new host already exists in the connnection list */
926 if(!(old = lookup_id(name)))
928 syslog(LOG_ERR, _("Got DEL_HOST from %s (%s) for %s which is not in our connection list"),
929 cl->name, cl->hostname, name);
933 /* Check if the rest matches */
935 if(address!=old->address || port!=old->port || options!=old->options || cl!=old->nexthop)
937 syslog(LOG_WARNING, _("Got DEL_HOST from %s (%s) for %s which doesn't match"), cl->name, cl->hostname, old->name);
941 /* Ok, since EVERYTHING seems to check out all right, delete it */
943 old->status.active = 0;
944 terminate_connection(old);
946 /* Tell the rest about the new host */
948 for(node = connection_tree->head; node; node = node->next)
950 p = (connection_t *)node->data;
951 if(p->status.meta && p->status.active && p!=cl)
952 send_del_host(p, old);
958 /* Status and error notification routines */
960 int send_status(connection_t *cl, int statusno, char *statusstring)
964 statusstring = status_text[statusno];
966 return send_request(cl, "%d %d %s", STATUS, statusno, statusstring);
969 int status_h(connection_t *cl)
972 char statusstring[MAX_STRING_SIZE];
974 if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &statusno, statusstring) != 2)
976 syslog(LOG_ERR, _("Got bad STATUS from %s (%s)"),
977 cl->name, cl->hostname);
981 if(debug_lvl >= DEBUG_STATUS)
983 syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"),
984 cl->name, cl->hostname, status_text[statusno], statusstring);
991 int send_error(connection_t *cl, int err, char *errstring)
995 errstring = strerror(err);
996 return send_request(cl, "%d %d %s", ERROR, err, errstring);
999 int error_h(connection_t *cl)
1002 char errorstring[MAX_STRING_SIZE];
1004 if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &err, errorstring) != 2)
1006 syslog(LOG_ERR, _("Got bad ERROR from %s (%s)"),
1007 cl->name, cl->hostname);
1011 if(debug_lvl >= DEBUG_ERROR)
1013 syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"),
1014 cl->name, cl->hostname, strerror(err), errorstring);
1017 terminate_connection(cl);
1022 int send_termreq(connection_t *cl)
1025 return send_request(cl, "%d", TERMREQ);
1028 int termreq_h(connection_t *cl)
1031 terminate_connection(cl);
1036 int send_ping(connection_t *cl)
1038 char salt[SALTLEN*2+1];
1040 cl->status.pinged = 1;
1041 cl->last_ping_time = time(NULL);
1042 RAND_pseudo_bytes(salt, SALTLEN);
1043 bin2hex(salt, salt, SALTLEN);
1044 salt[SALTLEN*2] = '\0';
1046 return send_request(cl, "%d %s", PING, salt);
1049 int ping_h(connection_t *cl)
1052 return send_pong(cl);
1055 int send_pong(connection_t *cl)
1057 char salt[SALTLEN*2+1];
1059 RAND_pseudo_bytes(salt, SALTLEN);
1060 bin2hex(salt, salt, SALTLEN);
1061 salt[SALTLEN*2] = '\0';
1063 return send_request(cl, "%d %s", PONG, salt);
1066 int pong_h(connection_t *cl)
1069 cl->status.pinged = 0;
1076 int send_key_changed(connection_t *from, connection_t *cl)
1081 /* Only send this message if some other daemon requested our key previously.
1082 This reduces unnecessary key_changed broadcasts.
1085 if(from==myself && !mykeyused)
1088 for(node = connection_tree->head; node; node = node->next)
1090 p = (connection_t *)node->data;
1091 if(p != cl && p->status.meta && p->status.active)
1092 if(!(p->options & OPTION_INDIRECT) || from == myself)
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 if(!(from->options | cl->options | myself->options) & OPTION_INDIRECT)
1122 send_key_changed(from, cl);
1127 int send_req_key(connection_t *from, connection_t *to)
1130 return send_request(to->nexthop, "%d %s %s", REQ_KEY,
1131 from->name, to->name);
1134 int req_key_h(connection_t *cl)
1136 char from_id[MAX_STRING_SIZE];
1137 char to_id[MAX_STRING_SIZE];
1138 connection_t *from, *to;
1141 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, from_id, to_id) != 2)
1143 syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
1144 cl->name, cl->hostname);
1148 if(!(from = lookup_id(from_id)))
1150 syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) origin %s which does not exist in our connection list"),
1151 cl->name, cl->hostname, from_id);
1155 /* Check if this key request is for us */
1157 if(!strcmp(to_id, myself->name)) /* Yes, send our own key back */
1159 bin2hex(myself->cipher_pktkey, pktkey, myself->cipher_pktkeylength);
1160 pktkey[myself->cipher_pktkeylength*2] = '\0';
1161 send_ans_key(myself, from, pktkey);
1166 if(!(to = lookup_id(to_id)))
1168 syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) destination %s which does not exist in our connection list"),
1169 cl->name, cl->hostname, to_id);
1173 if(to->status.validkey) /* Proxy keys */
1175 bin2hex(to->cipher_pktkey, pktkey, to->cipher_pktkeylength);
1176 pktkey[to->cipher_pktkeylength*2] = '\0';
1177 send_ans_key(to, from, pktkey);
1180 send_req_key(from, to);
1187 int send_ans_key(connection_t *from, connection_t *to, char *pktkey)
1190 return send_request(to->nexthop, "%d %s %s %s", ANS_KEY,
1191 from->name, to->name, pktkey);
1194 int ans_key_h(connection_t *cl)
1196 char from_id[MAX_STRING_SIZE];
1197 char to_id[MAX_STRING_SIZE];
1198 char pktkey[MAX_STRING_SIZE];
1200 connection_t *from, *to;
1202 if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING, from_id, to_id, pktkey) != 3)
1204 syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
1205 cl->name, cl->hostname);
1209 if(!(from = lookup_id(from_id)))
1211 syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) origin %s which does not exist in our connection list"),
1212 cl->name, cl->hostname, from_id);
1216 /* Check correctness of packet key */
1218 keylength = strlen(pktkey);
1220 if(keylength != from->cipher_pktkeylength*2)
1222 syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s) origin %s: invalid key length"),
1223 cl->name, cl->hostname, from->name);
1227 /* Forward it if necessary */
1229 if(strcmp(to_id, myself->name))
1231 if(!(to = lookup_id(to_id)))
1233 syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) destination %s which does not exist in our connection list"),
1234 cl->name, cl->hostname, to_id);
1237 send_ans_key(from, to, pktkey);
1240 /* Update our copy of the origin's packet key */
1242 if(from->cipher_pktkey)
1243 free(from->cipher_pktkey);
1245 from->cipher_pktkey = xstrdup(pktkey);
1247 hex2bin(from->cipher_pktkey, from->cipher_pktkey, keylength);
1248 from->cipher_pktkey[keylength] = '\0';
1250 from->status.validkey = 1;
1251 from->status.waitingforkey = 0;
1258 int send_tcppacket(connection_t *cl, vpn_packet_t *packet)
1264 x = send_request(cl->nexthop, "%d %hd", PACKET, packet->len);
1269 return send_meta(cl, packet->data, packet->len);
1272 int tcppacket_h(connection_t *cl)
1276 if(sscanf(cl->buffer, "%*d %hd", &len) != 1)
1278 syslog(LOG_ERR, _("Got bad PACKET from %s (%s)"), cl->name, cl->hostname);
1282 /* Set reqlen to len, this will tell receive_meta() that a tcppacket is coming. */
1289 /* Jumptable for the request handlers */
1291 int (*request_handlers[])(connection_t*) = {
1292 id_h, metakey_h, challenge_h, chal_reply_h,
1293 status_h, error_h, termreq_h,
1295 add_host_h, del_host_h,
1296 add_subnet_h, del_subnet_h,
1297 key_changed_h, req_key_h, ans_key_h,
1303 char (*request_name[]) = {
1304 "ID", "METAKEY", "CHALLENGE", "CHAL_REPLY",
1305 "STATUS", "ERROR", "TERMREQ",
1307 "ADD_HOST", "DEL_HOST",
1308 "ADD_SUBNET", "DEL_SUBNET",
1309 "KEY_CHANGED", "REQ_KEY", "ANS_KEY",
1313 /* Status strings */
1315 char (*status_text[]) = {
1321 char (*error_text[]) = {