- Updated authentication scheme.

- Removed all trailing spaces from all lines.
- Added things to add_ and del_subnet_h.
This commit is contained in:
Guus Sliepen 2000-09-17 21:42:05 +00:00
parent 84f210edd9
commit 5d0b3516d5

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol.c,v 1.28.4.32 2000/09/15 12:58:40 zarq Exp $ $Id: protocol.c,v 1.28.4.33 2000/09/17 21:42:05 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -53,9 +53,9 @@ int check_id(char *id)
for (i = 0; i < strlen(id); i++) for (i = 0; i < strlen(id); i++)
{ {
if(!isalpha(id[i]) && id[i] != '_') if(!isalpha(id[i]) && id[i] != '_')
{ {
return 0; return 0;
} }
} }
return 1; return 1;
@ -66,26 +66,29 @@ int check_id(char *id)
int send_request(conn_list_t *cl, const char *format, int request, /*args*/ ...) int send_request(conn_list_t *cl, const char *format, int request, /*args*/ ...)
{ {
va_list args; va_list args;
char *buffer = NULL; char buffer[MAXBUFSIZE+1];
int len; int len;
cp cp
if(debug_lvl >= DEBUG_PROTOCOL) /* Use vsnprintf instead of vasprintf: faster, no memory fragmentation, cleanup is automatic,
syslog(LOG_DEBUG, _("Sending %s to %s (%s)"), request_name[request], cl->name, cl->hostname); and there is a limit on the input buffer anyway */
va_start(args, request); va_start(args, request);
len = vasprintf(&buffer, format, args); len = vsnprintf(buffer, MAXBUFSIZE+1, format, args);
va_end(args); va_end(args);
if(len < 0 || !buffer) if(len < 0 || len > MAXBUFSIZE)
{ {
syslog(LOG_ERR, _("Error during vasprintf(): %m")); syslog(LOG_ERR, _("Output buffer overflow while sending %s to %s (%s)"), request_name[request], cl->name, cl->hostname);
return -1; return -1;
} }
if(debug_lvl >= DEBUG_META) if(debug_lvl >= DEBUG_META)
syslog(LOG_DEBUG, _("Sending meta data to %s (%s): %s"), syslog(LOG_DEBUG, _("Sending %s to %s (%s): %s"), request_name[request],
cl->name, cl->hostname, buffer); cl->name, cl->hostname, buffer);
else if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_DEBUG, _("Sending %s to %s (%s)"), request_name[request], cl->name, cl->hostname);
if(cl->status.encryptin) if(cl->status.encryptin)
{ {
@ -97,7 +100,7 @@ cp
syslog(LOG_ERR, _("Sending meta data failed: %m")); syslog(LOG_ERR, _("Sending meta data failed: %m"));
return -1; return -1;
} }
cp cp
} }
/* Connection protocol: /* Connection protocol:
@ -105,27 +108,34 @@ cp
Client Server Client Server
send_id(u) send_id(u)
send_challenge(R) send_challenge(R)
send_chal_reply(BH) send_chal_reply(H)
send_id(B) send_id(u)
send_challenge(BR) send_challenge(R)
send_chal_reply(BH) send_chal_reply(H)
send_ack(B) ---------------------------------------
send_ack(B) Any negotations about the meta protocol
encryption go here(u).
---------------------------------------
send_ack(u)
send_ack(u)
---------------------------------------
Other requests(E)...
(u) Unencrypted, (u) Unencrypted,
(R) RSA, (R) RSA,
(H) SHA1, (H) SHA1,
(B) Blowfish. (E) Encrypted with symmetric cipher.
Part of the challenge is directly used to set the blowfish key and the initial vector. Part of the challenge is directly used to set the symmetric cipher key and the initial vector.
(Twee vliegen in één klap!) Since a man-in-the-middle cannot decrypt the RSA challenges, this means that he cannot get or
*/ forge the key for the symmetric cipher.
*/
int send_id(conn_list_t *cl) int send_id(conn_list_t *cl)
{ {
cp cp
return send_request(cl, "%d %s %d %s", ID, return send_request(cl, "%d %s %d %s", ID,
myself->name, myself->protocol_version, opt2str(myself->options)); myself->name, myself->protocol_version, opt2str(myself->options));
} }
int id_h(conn_list_t *cl) int id_h(conn_list_t *cl)
@ -138,34 +148,34 @@ cp
syslog(LOG_ERR, _("Got bad ID from %s"), cl->hostname); syslog(LOG_ERR, _("Got bad ID from %s"), cl->hostname);
return -1; return -1;
} }
/* Check if version matches */ /* Check if version matches */
if(cl->protocol_version != myself->protocol_version) if(cl->protocol_version != myself->protocol_version)
{ {
syslog(LOG_ERR, _("Peer %s (%s) uses incompatible version %d"), syslog(LOG_ERR, _("Peer %s (%s) uses incompatible version %d"),
cl->name, cl->hostname, cl->protocol_version); cl->name, cl->hostname, cl->protocol_version);
return -1; return -1;
} }
/* Check if option string is valid */ /* Check if option string is valid */
if((cl->options = str2opt(options)) == -1) if((cl->options = str2opt(options)) == -1)
{ {
syslog(LOG_ERR, _("Peer %s uses invalid option string"), cl->hostname); syslog(LOG_ERR, _("Peer %s uses invalid option string"), cl->hostname);
return -1; return -1;
} }
/* Check if identity is a valid name */ /* Check if identity is a valid name */
if(!check_id(cl->name)) if(!check_id(cl->name))
{ {
syslog(LOG_ERR, _("Peer %s uses invalid identity name"), cl->hostname); syslog(LOG_ERR, _("Peer %s uses invalid identity name"), cl->hostname);
return -1; return -1;
} }
/* Load information about peer */ /* Load information about peer */
if(!read_id(cl)) if(!read_id(cl))
{ {
syslog(LOG_ERR, _("Peer %s had unknown identity (%s)"), cl->hostname, cl->name); syslog(LOG_ERR, _("Peer %s had unknown identity (%s)"), cl->hostname, cl->name);
@ -206,20 +216,20 @@ int send_challenge(conn_list_t *cl)
cp cp
if(cl->chal_answer) if(cl->chal_answer)
free(cl->chal_answer); free(cl->chal_answer);
/* Allocate buffers for the challenge and the hash */ /* Allocate buffers for the challenge and the hash */
cl->chal_answer = xmalloc(SHA_DIGEST_LENGTH); cl->chal_answer = xmalloc(SHA_DIGEST_LENGTH);
keylength = BN_num_bytes(cl->rsakey->length); keylength = BN_num_bytes(cl->rsakey->length);
buffer = xmalloc(keylength*2); buffer = xmalloc(keylength*2);
/* Copy random data and the public key to the buffer */ /* Copy random data and the public key to the buffer */
RAND_bytes(buffer, keylength); RAND_bytes(buffer, keylength);
BN_bn2bin(cl->rsakey->length, buffer+keylength); BN_bn2bin(cl->rsakey->length, buffer+keylength);
/* If we don't have a blowfish key set yet, use the random data from the challenge to do so. */ /* If we don't have a blowfish key set yet, use the random data from the challenge to do so. */
if(!cl->status.encryptin) if(!cl->status.encryptin)
{ {
set_metakey(cl, buffer, keylength); set_metakey(cl, buffer, keylength);
@ -235,7 +245,7 @@ cp
buffer[keylength*2] = '\0'; buffer[keylength*2] = '\0';
/* Send the challenge */ /* Send the challenge */
cl->allow_request = CHAL_REPLY; cl->allow_request = CHAL_REPLY;
x = send_request(cl, "%d %s", CHALLENGE, buffer); x = send_request(cl, "%d %s", CHALLENGE, buffer);
free(buffer); free(buffer);
@ -248,7 +258,7 @@ int challenge_h(conn_list_t *cl)
{ {
char *challenge; char *challenge;
int x; int x;
cp cp
if(sscanf(cl->buffer, "%*d %as", &cl->name, &challenge) != 1) if(sscanf(cl->buffer, "%*d %as", &cl->name, &challenge) != 1)
{ {
@ -257,7 +267,7 @@ cp
} }
/* Rest is done by send_chal_reply() */ /* Rest is done by send_chal_reply() */
x = send_chal_reply(cl, challenge); x = send_chal_reply(cl, challenge);
free(challenge); free(challenge);
cp cp
@ -270,7 +280,7 @@ int send_chal_reply(conn_list_t *cl, char *challenge)
int keylength; int keylength;
char *hash; char *hash;
int x; int x;
cp cp
keylength = BN_num_bytes(myself->rsakey->length); keylength = BN_num_bytes(myself->rsakey->length);
@ -283,21 +293,21 @@ cp
} }
/* Allocate buffers for the challenge and the hash */ /* Allocate buffers for the challenge and the hash */
buffer = xmalloc(keylength*2); buffer = xmalloc(keylength*2);
hash = xmalloc(SHA_DIGEST_LENGTH*2+1); hash = xmalloc(SHA_DIGEST_LENGTH*2+1);
/* Copy the incoming random data and our public key to the buffer */ /* Copy the incoming random data and our public key to the buffer */
hex2bin(challenge, buffer, keylength); hex2bin(challenge, buffer, keylength);
BN_bn2bin(myself->rsakey->length, buffer+keylength); BN_bn2bin(myself->rsakey->length, buffer+keylength);
/* Calculate the hash from that */ /* Calculate the hash from that */
SHA1(buffer, keylength*2, hash); SHA1(buffer, keylength*2, hash);
/* If we don't have a blowfish key set yet, use the random data from the challenge to do so. */ /* If we don't have a blowfish key set yet, use the random data from the challenge to do so. */
if(!cl->status.encrypted) if(!cl->status.encrypted)
{ {
set_metakey(cl, buffer, keylength); set_metakey(cl, buffer, keylength);
@ -322,7 +332,7 @@ cp
free(hash); free(hash);
cp cp
return x; return x;
} }
int chal_reply_h(conn_list_t *cl) int chal_reply_h(conn_list_t *cl)
{ {
@ -335,19 +345,19 @@ cp
} }
/* Check if the length of the hash is all right */ /* Check if the length of the hash is all right */
if(strlen(hash) != SHA_DIGEST_LENGTH*2) if(strlen(hash) != SHA_DIGEST_LENGTH*2)
{ {
syslog(LOG_ERR, _("Intruder: wrong challenge reply length from %s (%s)"), cl->name, cl->hostname); syslog(LOG_ERR, _("Intruder: wrong challenge reply length from %s (%s)"), cl->name, cl->hostname);
return -1; return -1;
} }
/* Convert the hash to binary format */ /* Convert the hash to binary format */
hex2bin(hash, hash, SHA_DIGEST_LENGTH); hex2bin(hash, hash, SHA_DIGEST_LENGTH);
/* Verify the incoming hash with the calculated hash */ /* Verify the incoming hash with the calculated hash */
if(!memcmp(hash, cl->chal_answer, SHA_DIGEST_LENGTH)) if(!memcmp(hash, cl->chal_answer, SHA_DIGEST_LENGTH))
{ {
syslog(LOG_ERR, _("Intruder: wrong challenge reply from %s (%s)"), cl->name, cl->hostname); syslog(LOG_ERR, _("Intruder: wrong challenge reply from %s (%s)"), cl->name, cl->hostname);
@ -358,7 +368,7 @@ cp
If we are accepting this new connection, then send our identity, If we are accepting this new connection, then send our identity,
if we are making this connecting, acknowledge. if we are making this connecting, acknowledge.
*/ */
free(hash); free(hash);
free(cl->chal_answer); free(cl->chal_answer);
@ -384,14 +394,14 @@ cp
int ack_h(conn_list_t *cl) int ack_h(conn_list_t *cl)
{ {
conn_list_t *old; conn_list_t *old;
cp cp
/* Okay, before we active the connection, we check if there is another entry /* Okay, before we active the connection, we check if there is another entry
in the connection list with the same vpn_ip. If so, it presumably is an in the connection list with the same vpn_ip. If so, it presumably is an
old connection that has timed out but we don't know it yet. old connection that has timed out but we don't know it yet.
*/ */
while((old = lookup_id(cl->name))) while((old = lookup_id(cl->name)))
{ {
if(debug_lvl > DEBUG_CONNECTIONS) if(debug_lvl > DEBUG_CONNECTIONS)
syslog(LOG_NOTICE, _("Removing old entry for %s at %s in favour of new connection from %s"), syslog(LOG_NOTICE, _("Removing old entry for %s at %s in favour of new connection from %s"),
@ -427,14 +437,58 @@ cp
int send_add_subnet(conn_list_t *cl, conn_list_t *other, subnet_t *subnet) int send_add_subnet(conn_list_t *cl, conn_list_t *other, subnet_t *subnet)
{ {
cp cp
/* return send_request(cl, "%d %s %d %s", ADD_SUBNET,
other->name, subnet->type, net2str(subnet)); */
return send_request(cl, "%d %s %s", ADD_SUBNET, return send_request(cl, "%d %s %s", ADD_SUBNET,
other->name, net2str(subnet)); other->name, net2str(subnet));
} }
int add_subnet_h(conn_list_t *cl) int add_subnet_h(conn_list_t *cl)
{ {
char *subnetstr;
char *name;
conn_list_t *owner;
subnet_t *subnet, *old;
cp
if(sscanf(cl->buffer, "%*d %as %as", &name, &subnetstr) != 3)
{
syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s)"), cl->name, cl->hostname);
return -1;
}
/* Check if owner name is a valid */
if(!check_id(name))
{
syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
return -1;
}
/* Check if subnet string is valid */
if((subnet = str2net(subnetstr)) == -1)
{
syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
return -1;
}
/* Check if somebody tries to add a subnet of ourself */
if(!strcmp(name, myself->name))
{
syslog(LOG_ERR, _("Warning: got ADD_SUBNET from %s (%s) for ourself, restarting"),
cl->name, cl->hostname);
sighup = 1;
return 0;
}
/* Check if the owner of the new subnet is in the connection list */
if(!(owner = lookup_id(name))
{
syslog(LOG_NOTICE, _("Got ADD_SUBNET for %s from %s (%s) which is not in our connection list"),
name, cl->name, cl->hostname);
}
} }
int send_del_subnet(conn_list_t *cl, conn_list_t *other, subnet_t *subnet) int send_del_subnet(conn_list_t *cl, conn_list_t *other, subnet_t *subnet)
@ -445,6 +499,50 @@ cp
int del_subnet_h(conn_list_t *cl) int del_subnet_h(conn_list_t *cl)
{ {
char *subnetstr;
char *name;
conn_list_t *owner;
subnet_t *subnet, *old;
cp
if(sscanf(cl->buffer, "%*d %as %as", &name, &subnetstr) != 3)
{
syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s)"), cl->name, cl->hostname);
return -1;
}
/* Check if owner name is a valid */
if(!check_id(name))
{
syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
return -1;
}
/* Check if subnet string is valid */
if((subnet = str2net(subnetstr)) == -1)
{
syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
return -1;
}
/* Check if somebody tries to delete a subnet of ourself */
if(!strcmp(name, myself->name))
{
syslog(LOG_ERR, _("Warning: got DEL_SUBNET from %s (%s) for ourself, restarting"),
cl->name, cl->hostname);
sighup = 1;
return 0;
}
/* Check if the owner of the new subnet is in the connection list */
if(!(owner = lookup_id(name))
{
syslog(LOG_NOTICE, _("Got DEL_SUBNET for %s from %s (%s) which is not in our connection list"),
name, cl->name, cl->hostname);
}
} }
/* New and closed connections notification */ /* New and closed connections notification */
@ -466,10 +564,10 @@ cp
{ {
syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"), cl->name, cl->hostname); syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"), cl->name, cl->hostname);
return -1; return -1;
} }
/* Check if option string is valid */ /* Check if option string is valid */
if((new->options = str2opt(options)) == -1) if((new->options = str2opt(options)) == -1)
{ {
syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid option string"), cl->name, cl->hostname); syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid option string"), cl->name, cl->hostname);
@ -477,15 +575,15 @@ cp
} }
/* Check if identity is a valid name */ /* Check if identity is a valid name */
if(!check_id(new->name)) if(!check_id(new->name))
{ {
syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname); syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
return -1; return -1;
} }
/* Check if somebody tries to add ourself */ /* Check if somebody tries to add ourself */
if(!strcmp(new->name, myself->name)) if(!strcmp(new->name, myself->name))
{ {
syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"), cl->name, cl->hostname); syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"), cl->name, cl->hostname);
@ -496,7 +594,7 @@ cp
/* Fill in more of the new conn_list structure */ /* Fill in more of the new conn_list structure */
new->hostname = hostlookup(htonl(new->real_ip)); new->hostname = hostlookup(htonl(new->real_ip));
/* Check if the new host already exists in the connnection list */ /* Check if the new host already exists in the connnection list */
if((old = lookup_id(new->name))) if((old = lookup_id(new->name)))
@ -505,14 +603,14 @@ cp
{ {
if(debug_lvl > DEBUG_CONNECTIONS) if(debug_lvl > DEBUG_CONNECTIONS)
syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"), syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
old->name, old->hostname, new->name, new->hostname); old->name, old->hostname, new->name, new->hostname);
return 0; return 0;
} }
else else
{ {
if(debug_lvl > DEBUG_CONNECTIONS) if(debug_lvl > DEBUG_CONNECTIONS)
syslog(LOG_NOTICE, _("Removing old entry for %s (%s)"), syslog(LOG_NOTICE, _("Removing old entry for %s (%s)"),
old->name, old->hostname); old->name, old->hostname);
old->status.active = 0; old->status.active = 0;
terminate_connection(old); terminate_connection(old);
} }
@ -522,15 +620,15 @@ cp
new->nexthop = cl; new->nexthop = cl;
new->status.active = 1; new->status.active = 1;
/* Hook it up into the conn_list */ /* Hook it up into the conn_list */
conn_list_add(conn_list, new); conn_list_add(conn_list, new);
/* Tell the rest about the new host */ /* Tell the rest about the new host */
notify_others(new, cl, send_add_host); notify_others(new, cl, send_add_host);
cp cp
return 0; return 0;
} }
@ -539,7 +637,7 @@ int send_del_host(conn_list_t *cl, conn_list_t *other)
{ {
cp cp
return send_request(cl, "%d %s %lx:%d", DEL_HOST, return send_request(cl, "%d %s %lx:%d", DEL_HOST,
other->name, other->real_ip, other->port); other->name, other->real_ip, other->port);
} }
int del_host_h(conn_list_t *cl) int del_host_h(conn_list_t *cl)
@ -548,21 +646,21 @@ int del_host_h(conn_list_t *cl)
ip_t address; ip_t address;
port_t port; port_t port;
conn_list_t *old; conn_list_t *old;
cp cp
if(sscanf(cl->buffer, "%*d %as %lx:%d", &id, &address, &port) != 3) if(sscanf(cl->buffer, "%*d %as %lx:%d", &id, &address, &port) != 3)
{ {
syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"), syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
cl->name, cl->hostname); cl->name, cl->hostname);
return -1; return -1;
} }
/* Check if somebody tries to delete ourself */ /* Check if somebody tries to delete ourself */
if(!strcmp(id, myself->name)) if(!strcmp(id, myself->name))
{ {
syslog(LOG_ERR, _("Warning: got DEL_HOST from %s (%s) for ourself, restarting"), syslog(LOG_ERR, _("Warning: got DEL_HOST from %s (%s) for ourself, restarting"),
cl->name, cl->hostname); cl->name, cl->hostname);
sighup = 1; sighup = 1;
return 0; return 0;
} }
@ -587,7 +685,7 @@ cp
if(debug_lvl > DEBUG_CONNECTIONS) if(debug_lvl > DEBUG_CONNECTIONS)
{ {
syslog(LOG_NOTICE, _("Got DEL_HOST for %s from %s (%s) which is not in our connection list"), syslog(LOG_NOTICE, _("Got DEL_HOST for %s from %s (%s) which is not in our connection list"),
id, cl->name, cl->hostname); id, cl->name, cl->hostname);
} }
cp cp
return 0; return 0;
@ -612,14 +710,14 @@ cp
if(sscanf(cl->buffer, "%*d %d %as", &statusno, &statusstring) != 2) if(sscanf(cl->buffer, "%*d %d %as", &statusno, &statusstring) != 2)
{ {
syslog(LOG_ERR, _("Got bad STATUS from %s (%s)"), syslog(LOG_ERR, _("Got bad STATUS from %s (%s)"),
cl->name, cl->hostname); cl->name, cl->hostname);
return -1; return -1;
} }
if(debug_lvl > DEBUG_STATUS) if(debug_lvl > DEBUG_STATUS)
{ {
syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"), syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"),
cl->name, cl->hostname, status_text[statusno], statusstring); cl->name, cl->hostname, status_text[statusno], statusstring);
} }
cp cp
@ -643,14 +741,14 @@ cp
if(sscanf(cl->buffer, "%*d %d %as", &errno, &errorstring) != 2) if(sscanf(cl->buffer, "%*d %d %as", &errno, &errorstring) != 2)
{ {
syslog(LOG_ERR, _("Got bad error from %s (%s)"), syslog(LOG_ERR, _("Got bad error from %s (%s)"),
cl->name, cl->hostname); cl->name, cl->hostname);
return -1; return -1;
} }
if(debug_lvl > DEBUG_error) if(debug_lvl > DEBUG_error)
{ {
syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"), syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"),
cl->name, cl->hostname, strerror(errno), errorstring); cl->name, cl->hostname, strerror(errno), errorstring);
} }
free(errorstring); free(errorstring);
@ -714,7 +812,7 @@ cp
{ {
if(p!=cl && p->status.meta && p->status.active) if(p!=cl && p->status.meta && p->status.active)
send_request(p, "%d %s", KEY_CHANGED, send_request(p, "%d %s", KEY_CHANGED,
from->name); from->name);
} }
cp cp
return 0; return 0;
@ -728,33 +826,33 @@ cp
if(sscanf(cl->buffer, "%*d %as", &from_id) != 1) if(sscanf(cl->buffer, "%*d %as", &from_id) != 1)
{ {
syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"), syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
cl->name, cl->hostname); cl->name, cl->hostname);
return -1; return -1;
} }
if(!(from = lookup_id(from_id))) if(!(from = lookup_id(from_id)))
{ {
syslog(LOG_ERR, _("Got KEY_CHANGED from %s (%s) origin %s which does not exist in our connection list"), syslog(LOG_ERR, _("Got KEY_CHANGED from %s (%s) origin %s which does not exist in our connection list"),
cl->name, cl->hostname, from_id); cl->name, cl->hostname, from_id);
free(from_id); free(from_id);
return -1; return -1;
} }
free(from_id); free(from_id);
from->status.validkey = 0; from->status.validkey = 0;
from->status.waitingforkey = 0; from->status.waitingforkey = 0;
send_key_changed(from, cl); send_key_changed(from, cl);
cp cp
return 0; return 0;
} }
int send_req_key(conn_list_t *from, conn_list_t *to) int send_req_key(conn_list_t *from, conn_list_t *to)
{ {
cp cp
return send_request(to->nexthop, "%d %s %s", REQ_KEY, return send_request(to->nexthop, "%d %s %s", REQ_KEY,
from->name, to->name); from->name, to->name);
} }
int req_key_h(conn_list_t *cl) int req_key_h(conn_list_t *cl)
@ -765,14 +863,14 @@ cp
if(sscanf(cl->buffer, "%*d %as %as", &from_id, &to_id) != 2) if(sscanf(cl->buffer, "%*d %as %as", &from_id, &to_id) != 2)
{ {
syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"), syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
cl->name, cl->hostname); cl->name, cl->hostname);
return -1; return -1;
} }
if(!(from = lookup_id(from_id))) if(!(from = lookup_id(from_id)))
{ {
syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) origin %s which does not exist in our connection list"), syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) origin %s which does not exist in our connection list"),
cl->name, cl->hostname, from_id); cl->name, cl->hostname, from_id);
free(from_id); free(to_id); free(from_id); free(to_id);
return -1; return -1;
} }
@ -788,7 +886,7 @@ cp
if(!(to = lookup_id(to_id))) if(!(to = lookup_id(to_id)))
{ {
syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) destination %s which does not exist in our connection list"), syslog(LOG_ERR, _("Got REQ_KEY from %s (%s) destination %s which does not exist in our connection list"),
cl->name, cl->hostname, to_id); cl->name, cl->hostname, to_id);
free(from_id); free(to_id); free(from_id); free(to_id);
return -1; return -1;
} }
@ -804,7 +902,7 @@ int send_ans_key(conn_list_t *from, conn_list_t *to, char *datakey)
{ {
cp cp
return send_request(to->nexthop, "%d %s %s %s", ANS_KEY, return send_request(to->nexthop, "%d %s %s %s", ANS_KEY,
from->name, to->name, datakey); from->name, to->name, datakey);
} }
int ans_key_h(conn_list_t *cl) int ans_key_h(conn_list_t *cl)
@ -816,14 +914,14 @@ cp
if(sscanf(cl->buffer, "%*d %as %as %as", &from_id, &to_id, &datakey) != 3) if(sscanf(cl->buffer, "%*d %as %as %as", &from_id, &to_id, &datakey) != 3)
{ {
syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"), syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
cl->name, cl->hostname); cl->name, cl->hostname);
return -1; return -1;
} }
if(!(from = lookup_id(from_id))) if(!(from = lookup_id(from_id)))
{ {
syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) origin %s which does not exist in our connection list"), syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) origin %s which does not exist in our connection list"),
cl->name, cl->hostname, from_id); cl->name, cl->hostname, from_id);
free(from_id); free(to_id); free(datakey); free(from_id); free(to_id); free(datakey);
return -1; return -1;
} }
@ -833,13 +931,13 @@ cp
if(!strcmp(to_id, myself->name)) if(!strcmp(to_id, myself->name))
{ {
/* It is for us, convert it to binary and set the key with it. */ /* It is for us, convert it to binary and set the key with it. */
keylength = strlen(datakey); keylength = strlen(datakey);
if((keylength%2) || (keylength <= 0)) if((keylength%2) || (keylength <= 0))
{ {
syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s) origin %s: invalid key"), syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s) origin %s: invalid key"),
cl->name, cl->hostname, from->name); cl->name, cl->hostname, from->name);
free(from_id); free(to_id); free(datakey); free(from_id); free(to_id); free(datakey);
return -1; return -1;
} }
@ -852,7 +950,7 @@ cp
if(!(to = lookup_id(to_id))) if(!(to = lookup_id(to_id)))
{ {
syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) destination %s which does not exist in our connection list"), syslog(LOG_ERR, _("Got ANS_KEY from %s (%s) destination %s which does not exist in our connection list"),
cl->name, cl->hostname, to_id); cl->name, cl->hostname, to_id);
free(from_id); free(to_id); free(datakey); free(from_id); free(to_id); free(datakey);
return -1; return -1;
} }
@ -873,7 +971,7 @@ cp
*/ */
int notify_others(conn_list_t *new, conn_list_t *source, int notify_others(conn_list_t *new, conn_list_t *source,
int (*function)(conn_list_t*, conn_list_t*)) int (*function)(conn_list_t*, conn_list_t*))
{ {
conn_list_t *p; conn_list_t *p;
cp cp