along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id: protocol.c,v 1.28.4.57 2000/11/04 20:44:28 guus Exp $
+ $Id: protocol.c,v 1.28.4.65 2000/11/22 20:25:27 guus Exp $
*/
#include "config.h"
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
+#include <stdarg.h>
#include <utils.h>
#include <xalloc.h>
#include <netinet/in.h>
-#include <openssl/sha.h>
-#include <openssl/rand.h>
-#include <openssl/evp.h>
+#ifdef HAVE_OPENSSL_SHA_H
+# include <openssl/sha.h>
+#else
+# include <sha.h>
+#endif
+
+#ifdef HAVE_OPENSSL_RAND_H
+# include <openssl/rand.h>
+#else
+# include <rand.h>
+#endif
+
+#ifdef HAVE_OPENSSL_EVP_H
+# include <openssl/evp.h>
+#else
+# include <evp.h>
+#endif
+
#include "conf.h"
#include "net.h"
#include "netutl.h"
#include "protocol.h"
#include "meta.h"
-#include "connlist.h"
+#include "connection.h"
#include "system.h"
/* Generic request routines - takes care of logging and error detection as well */
-int send_request(conn_list_t *cl, const char *format, ...)
+int send_request(connection_t *cl, const char *format, ...)
{
va_list args;
char buffer[MAXBUFSIZE];
return send_meta(cl, buffer, len);
}
-int receive_request(conn_list_t *cl)
+int receive_request(connection_t *cl)
{
int request;
cp
forge the key for the symmetric cipher.
*/
-int send_id(conn_list_t *cl)
+int send_id(connection_t *cl)
{
cp
cl->allow_request = CHALLENGE;
return send_request(cl, "%d %s %d %lx %hd", ID, myself->name, myself->protocol_version, myself->options, myself->port);
}
-int id_h(conn_list_t *cl)
+int id_h(connection_t *cl)
{
- conn_list_t *old;
+ connection_t *old;
config_t const *cfg;
+ char name[MAX_STRING_SIZE];
cp
- if(sscanf(cl->buffer, "%*d %as %d %lx %hd", &cl->name, &cl->protocol_version, &cl->options, &cl->port) != 4)
+ if(sscanf(cl->buffer, "%*d "MAX_STRING" %d %lx %hd", name, &cl->protocol_version, &cl->options, &cl->port) != 4)
{
syslog(LOG_ERR, _("Got bad ID from %s"), cl->hostname);
return -1;
/* Check if identity is a valid name */
- if(check_id(cl->name))
+ if(check_id(name))
{
syslog(LOG_ERR, _("Peer %s uses invalid identity name"), cl->hostname);
return -1;
}
+
+ /* Copy string to cl */
+
+ cl->name = xstrdup(name);
/* Load information about peer */
-cp
+
if(read_host_config(cl))
{
syslog(LOG_ERR, _("Peer %s had unknown identity (%s)"), cl->hostname, cl->name);
connection list. If so, we are probably making a loop, which
is not desirable.
*/
-cp
+
if(cl->status.outgoing)
{
if((old = lookup_id(cl->name)))
return 0;
}
}
-cp
- if((cfg = get_config_val(cl->config, publickey)))
+
+ /* Now we can add the name to the id tree */
+
+ id_add(cl);
+
+ /* Read in the public key, so that we can send a challenge */
+
+ if((cfg = get_config_val(cl->config, config_publickey)))
{
cl->rsa_key = RSA_new();
BN_hex2bn(&cl->rsa_key->n, cfg->data.ptr);
return send_challenge(cl);
}
-int send_challenge(conn_list_t *cl)
+int send_challenge(connection_t *cl)
{
char *buffer;
int len, x;
return x;
}
-int challenge_h(conn_list_t *cl)
+int challenge_h(connection_t *cl)
{
- char *buffer;
+ char buffer[MAX_STRING_SIZE];
int len;
cp
- if(sscanf(cl->buffer, "%*d %as", &buffer) != 1)
+ if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
{
syslog(LOG_ERR, _("Got bad CHALLENGE from %s (%s)"), cl->name, cl->hostname);
return -1;
if(strlen(buffer) != len*2)
{
syslog(LOG_ERR, _("Intruder: wrong challenge length from %s (%s)"), cl->name, cl->hostname);
- free(buffer);
return -1;
}
if(RSA_private_decrypt(len, buffer, cl->mychallenge, myself->rsa_key, RSA_NO_PADDING) != len) /* See challenge() */
{
syslog(LOG_ERR, _("Error during encryption of challenge for %s (%s)"), cl->name, cl->hostname);
- free(buffer);
return -1;
}
syslog(LOG_DEBUG, _("Received random challenge (unencrypted): %s"), buffer);
}
- free(buffer);
-
/* Rest is done by send_chal_reply() */
cp
return send_chal_reply(cl);
}
-int send_chal_reply(conn_list_t *cl)
+int send_chal_reply(connection_t *cl)
{
char hash[SHA_DIGEST_LENGTH*2+1];
cp
return send_request(cl, "%d %s", CHAL_REPLY, hash);
}
-int chal_reply_h(conn_list_t *cl)
+int chal_reply_h(connection_t *cl)
{
- char *hishash;
+ char hishash[MAX_STRING_SIZE];
char myhash[SHA_DIGEST_LENGTH];
cp
- if(sscanf(cl->buffer, "%*d %as", &hishash) != 1)
+ if(sscanf(cl->buffer, "%*d "MAX_STRING, hishash) != 1)
{
syslog(LOG_ERR, _("Got bad CHAL_REPLY from %s (%s)"), cl->name, cl->hostname);
- free(hishash);
return -1;
}
if(strlen(hishash) != SHA_DIGEST_LENGTH*2)
{
syslog(LOG_ERR, _("Intruder: wrong challenge reply length from %s (%s)"), cl->name, cl->hostname);
- free(hishash);
return -1;
}
hishash[SHA_DIGEST_LENGTH*2] = '\0';
syslog(LOG_DEBUG, _("Expected challenge reply: %s"), hishash);
}
- free(hishash);
return -1;
}
- free(hishash);
-
/* Identity has now been positively verified.
If we are accepting this new connection, then send our identity,
if we are making this connecting, acknowledge.
return send_id(cl);
}
-int send_metakey(conn_list_t *cl)
+int send_metakey(connection_t *cl)
{
char *buffer;
int len, x;
return x;
}
-int metakey_h(conn_list_t *cl)
+int metakey_h(connection_t *cl)
{
- char *buffer;
+ char buffer[MAX_STRING_SIZE];
int len;
cp
- if(sscanf(cl->buffer, "%*d %as", &buffer) != 1)
+ if(sscanf(cl->buffer, "%*d "MAX_STRING, buffer) != 1)
{
syslog(LOG_ERR, _("Got bad METAKEY from %s (%s)"), cl->name, cl->hostname);
return -1;
if(strlen(buffer) != len*2)
{
syslog(LOG_ERR, _("Intruder: wrong meta key length from %s (%s)"), cl->name, cl->hostname);
- free(buffer);
return -1;
}
if(RSA_private_decrypt(len, buffer, cl->cipher_inkey, myself->rsa_key, RSA_NO_PADDING) != len) /* See challenge() */
{
syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), cl->name, cl->hostname);
- free(buffer);
return -1;
}
syslog(LOG_DEBUG, _("Received random meta key (unencrypted): %s"), buffer);
}
- free(buffer);
-
EVP_DecryptInit(cl->cipher_inctx, EVP_bf_cfb(), cl->cipher_inkey, cl->cipher_inkey + EVP_bf_cfb()->key_len);
cp
return send_metakey(cl);
}
-int send_ack(conn_list_t *cl)
+int send_ack(connection_t *cl)
{
int x;
cp
if(cl->status.outgoing)
cl->allow_request = ACK;
+ setup_vpn_connection(cl);
+
x = send_request(cl, "%d", ACK);
cl->status.encryptout = 1;
cp
return x;
}
-int ack_h(conn_list_t *cl)
+int ack_h(connection_t *cl)
{
- conn_list_t *old, *p;
- subnet_t *s;
+ connection_t *old, *p;
+ subnet_t *subnet;
+ rbl_t *rbl, *rbl2;
cp
/* Okay, before we active the connection, we check if there is another entry
in the connection list with the same name. If so, it presumably is an
/* Send him our subnets */
- for(s = myself->subnets; s; s = s->next)
- send_add_subnet(cl, s);
-
+ RBL_FOREACH(myself->subnet_tree, rbl)
+ {
+ subnet = (subnet_t *)rbl->data;
+ send_add_subnet(cl, subnet);
+ }
/* And send him all the hosts and their subnets we know... */
- for(p = conn_list; p; p = p->next)
- if(p != cl && p->status.active)
- {
- /* Notify others of this connection */
-
- if(p->status.meta)
- send_add_host(p, cl);
+ RBL_FOREACH(connection_tree, rbl)
+ {
+ p = (connection_t *)rbl->data;
+
+ if(p != cl && p->status.active)
+ {
+ /* Notify others of this connection */
- /* Notify new connection of everything we know */
+ if(p->status.meta)
+ send_add_host(p, cl);
- send_add_host(cl, p);
-
- for(s = p->subnets; s; s = s->next)
- send_add_subnet(cl, s);
- }
+ /* Notify new connection of everything we know */
+
+ send_add_host(cl, p);
+
+ RBL_FOREACH(p->subnet_tree, rbl2)
+ {
+ subnet = (subnet_t *)rbl2->data;
+ send_add_subnet(cl, subnet);
+ }
+ }
+ }
cp
return 0;
}
/* Address and subnet information exchange */
-int send_add_subnet(conn_list_t *cl, subnet_t *subnet)
+int send_add_subnet(connection_t *cl, subnet_t *subnet)
{
int x;
char *netstr;
return x;
}
-int add_subnet_h(conn_list_t *cl)
+int add_subnet_h(connection_t *cl)
{
- char *subnetstr;
- char *name;
- conn_list_t *owner, *p;
+ char subnetstr[MAX_STRING_SIZE];
+ char name[MAX_STRING_SIZE];
+ connection_t *owner, *p;
subnet_t *subnet;
+ rbl_t *rbl;
cp
- if(sscanf(cl->buffer, "%*d %as %as", &name, &subnetstr) != 2)
+ if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
{
syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s)"), cl->name, cl->hostname);
- free(name); free(subnetstr);
return -1;
}
if(check_id(name))
{
syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
- free(name); free(subnetstr);
return -1;
}
if(!(subnet = str2net(subnetstr)))
{
syslog(LOG_ERR, _("Got bad ADD_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
- free(name); free(subnetstr);
return -1;
}
- free(subnetstr);
-
/* 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);
- free(name);
sighup = 1;
return 0;
}
{
syslog(LOG_ERR, _("Got ADD_SUBNET for %s from %s (%s) which is not in our connection list"),
name, cl->name, cl->hostname);
- free(name);
return -1;
}
/* Tell the rest */
- for(p = conn_list; p; p = p->next)
- if(p->status.meta && p->status.active && p!= cl)
- send_add_subnet(p, subnet);
+ RBL_FOREACH(connection_tree, rbl)
+ {
+ p = (connection_t *)rbl->data;
+ if(p->status.meta && p->status.active && p!= cl)
+ send_add_subnet(p, subnet);
+ }
cp
return 0;
}
-int send_del_subnet(conn_list_t *cl, subnet_t *subnet)
+int send_del_subnet(connection_t *cl, subnet_t *subnet)
{
int x;
char *netstr;
return x;
}
-int del_subnet_h(conn_list_t *cl)
+int del_subnet_h(connection_t *cl)
{
- char *subnetstr;
- char *name;
- conn_list_t *owner, *p;
+ char subnetstr[MAX_STRING_SIZE];
+ char name[MAX_STRING_SIZE];
+ connection_t *owner, *p;
subnet_t *subnet;
+ rbl_t *rbl;
cp
- if(sscanf(cl->buffer, "%*d %as %as", &name, &subnetstr) != 3)
+ if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, name, subnetstr) != 3)
{
syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s)"), cl->name, cl->hostname);
- free(name); free(subnetstr);
return -1;
}
if(check_id(name))
{
syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid identity name"), cl->name, cl->hostname);
- free(name); free(subnetstr);
return -1;
}
if(!(subnet = str2net(subnetstr)))
{
syslog(LOG_ERR, _("Got bad DEL_SUBNET from %s (%s): invalid subnet string"), cl->name, cl->hostname);
- free(name); free(subnetstr);
return -1;
}
{
syslog(LOG_ERR, _("Warning: got DEL_SUBNET from %s (%s) for ourself, restarting"),
cl->name, cl->hostname);
- free(name);
sighup = 1;
return 0;
}
{
syslog(LOG_ERR, _("Got DEL_SUBNET for %s from %s (%s) which is not in our connection list"),
name, cl->name, cl->hostname);
- free(name);
return -1;
}
/* Tell the rest */
- for(p = conn_list; p; p = p->next)
- if(p->status.meta && p->status.active && p!= cl)
- send_del_subnet(p, subnet);
+ RBL_FOREACH(connection_tree, rbl)
+ {
+ p = (connection_t *)rbl->data;
+ if(p->status.meta && p->status.active && p!= cl)
+ send_del_subnet(p, subnet);
+ }
cp
return 0;
}
/* New and closed connections notification */
-int send_add_host(conn_list_t *cl, conn_list_t *other)
+int send_add_host(connection_t *cl, connection_t *other)
{
cp
return send_request(cl, "%d %s %lx:%d %lx", ADD_HOST,
other->name, other->address, other->port, other->options);
}
-int add_host_h(conn_list_t *cl)
+int add_host_h(connection_t *cl)
{
- conn_list_t *old, *new;
- conn_list_t *p;
-
+ connection_t *old, *new, *p;
+ char name[MAX_STRING_SIZE];
+ rbl_t *rbl;
cp
- new = new_conn_list();
+ new = new_connection();
- if(sscanf(cl->buffer, "%*d %as %lx:%d %lx", &new->name, &new->address, &new->port, &new->options) != 4)
+ if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%d %lx", name, &new->address, &new->port, &new->options) != 4)
{
syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s)"), cl->name, cl->hostname);
return -1;
/* Check if identity is a valid name */
- if(check_id(new->name))
+ if(check_id(name))
{
syslog(LOG_ERR, _("Got bad ADD_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
- free_conn_list(new);
+ free_connection(new);
return -1;
}
{
syslog(LOG_ERR, _("Warning: got ADD_HOST from %s (%s) for ourself, restarting"), cl->name, cl->hostname);
sighup = 1;
- free_conn_list(new);
+ free_connection(new);
return 0;
}
- /* Fill in more of the new conn_list structure */
+ /* Fill in more of the new connection structure */
new->hostname = hostlookup(htonl(new->address));
/* Check if the new host already exists in the connnection list */
- if((old = lookup_id(new->name)))
+ if((old = lookup_id(name)))
{
if((new->address == old->address) && (new->port == old->port))
{
if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
- old->name, old->hostname, new->name, new->hostname);
- free_conn_list(new);
+ old->name, old->hostname, name, new->hostname);
+ free_connection(new);
return 0;
}
else
}
}
- /* Hook it up into the conn_list */
+ /* Hook it up into the connection */
- conn_list_add(new);
+ new->name = xstrdup(name);
+ connection_add(new);
+ id_add(new);
/* Tell the rest about the new host */
- for(p = conn_list; p; p = p->next)
- if(p->status.meta && p->status.active && p!=cl)
- send_add_host(p, new);
+ RBL_FOREACH(connection_tree, rbl)
+ {
+ p = (connection_t *)rbl->data;
+ if(p->status.meta && p->status.active && p!=cl)
+ send_add_host(p, new);
+ }
- /* Fill in rest of conn_list structure */
+ /* Fill in rest of connection structure */
new->nexthop = cl;
new->status.active = 1;
new->cipher_pkttype = EVP_bf_cfb();
new->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len;
+ /* Okay this is a bit ugly... it would be better to setup UDP sockets dynamically, or
+ * perhaps just one UDP socket... but then again, this has benefits too...
+ */
+
+ setup_vpn_connection(new);
cp
return 0;
}
-int send_del_host(conn_list_t *cl, conn_list_t *other)
+int send_del_host(connection_t *cl, connection_t *other)
{
cp
return send_request(cl, "%d %s %lx:%d %lx", DEL_HOST,
other->name, other->address, other->port, other->options);
}
-int del_host_h(conn_list_t *cl)
+int del_host_h(connection_t *cl)
{
- char *name;
+ char name[MAX_STRING_SIZE];
ip_t address;
port_t port;
long int options;
- conn_list_t *old, *p;
+ connection_t *old, *p;
+ rbl_t *rbl;
cp
- if(sscanf(cl->buffer, "%*d %as %lx:%d %lx", &name, &address, &port, &options) != 4)
+ if(sscanf(cl->buffer, "%*d "MAX_STRING" %lx:%d %lx", name, &address, &port, &options) != 4)
{
syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s)"),
cl->name, cl->hostname);
if(check_id(name))
{
syslog(LOG_ERR, _("Got bad DEL_HOST from %s (%s): invalid identity name"), cl->name, cl->hostname);
- free(name);
return -1;
}
{
syslog(LOG_ERR, _("Warning: got DEL_HOST from %s (%s) for ourself, restarting"),
cl->name, cl->hostname);
- free(name);
sighup = 1;
return 0;
}
{
syslog(LOG_ERR, _("Got DEL_HOST from %s (%s) for %s which is not in our connection list"),
name, cl->name, cl->hostname);
- free(name);
return -1;
}
/* Tell the rest about the new host */
- for(p = conn_list; p; p = p->next)
- if(p->status.meta && p->status.active && p!=cl)
- send_del_host(p, old);
+ RBL_FOREACH(connection_tree, rbl)
+ {
+ p = (connection_t *)rbl->data;
+ if(p->status.meta && p->status.active && p!=cl)
+ send_del_host(p, old);
+ }
cp
return 0;
}
/* Status and error notification routines */
-int send_status(conn_list_t *cl, int statusno, char *statusstring)
+int send_status(connection_t *cl, int statusno, char *statusstring)
{
cp
if(!statusstring)
return send_request(cl, "%d %d %s", STATUS, statusno, statusstring);
}
-int status_h(conn_list_t *cl)
+int status_h(connection_t *cl)
{
int statusno;
- char *statusstring;
+ char statusstring[MAX_STRING_SIZE];
cp
- if(sscanf(cl->buffer, "%*d %d %as", &statusno, &statusstring) != 2)
+ if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &statusno, statusstring) != 2)
{
syslog(LOG_ERR, _("Got bad STATUS from %s (%s)"),
cl->name, cl->hostname);
}
cp
- free(statusstring);
return 0;
}
-int send_error(conn_list_t *cl, int errno, char *errstring)
+int send_error(connection_t *cl, int errno, char *errstring)
{
cp
if(!errstring)
return send_request(cl, "%d %d %s", ERROR, errno, errstring);
}
-int error_h(conn_list_t *cl)
+int error_h(connection_t *cl)
{
int errno;
- char *errorstring;
+ char errorstring[MAX_STRING_SIZE];
cp
- if(sscanf(cl->buffer, "%*d %d %as", &errno, &errorstring) != 2)
+ if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &errno, errorstring) != 2)
{
syslog(LOG_ERR, _("Got bad ERROR from %s (%s)"),
cl->name, cl->hostname);
cl->name, cl->hostname, strerror(errno), errorstring);
}
- free(errorstring);
terminate_connection(cl);
cp
return 0;
}
-int send_termreq(conn_list_t *cl)
+int send_termreq(connection_t *cl)
{
cp
return send_request(cl, "%d", TERMREQ);
}
-int termreq_h(conn_list_t *cl)
+int termreq_h(connection_t *cl)
{
cp
terminate_connection(cl);
/* Keepalive routines - FIXME: needs a closer look */
-int send_ping(conn_list_t *cl)
+int send_ping(connection_t *cl)
{
cp
cl->status.pinged = 1;
return send_request(cl, "%d", PING);
}
-int ping_h(conn_list_t *cl)
+int ping_h(connection_t *cl)
{
cp
return send_pong(cl);
}
-int send_pong(conn_list_t *cl)
+int send_pong(connection_t *cl)
{
cp
return send_request(cl, "%d", PONG);
}
-int pong_h(conn_list_t *cl)
+int pong_h(connection_t *cl)
{
cp
cl->status.pinged = 0;
/* Key exchange */
-int send_key_changed(conn_list_t *from, conn_list_t *cl)
+int send_key_changed(connection_t *from, connection_t *cl)
{
- conn_list_t *p;
+ connection_t *p;
+ rbl_t *rbl;
cp
- for(p = conn_list; p != NULL; p = p->next)
+ RBL_FOREACH(connection_tree, rbl)
{
- if(p!=cl && p->status.meta && p->status.active)
- send_request(p, "%d %s", KEY_CHANGED,
- from->name);
+ p = (connection_t *)rbl->data;
+ if(p != cl && p->status.meta && p->status.active)
+ send_request(p, "%d %s", KEY_CHANGED, from->name);
}
cp
return 0;
}
-int key_changed_h(conn_list_t *cl)
+int key_changed_h(connection_t *cl)
{
- char *from_id;
- conn_list_t *from;
+ char from_id[MAX_STRING_SIZE];
+ connection_t *from;
cp
- if(sscanf(cl->buffer, "%*d %as", &from_id) != 1)
+ if(sscanf(cl->buffer, "%*d "MAX_STRING, from_id) != 1)
{
syslog(LOG_ERR, _("Got bad KEY_CHANGED from %s (%s)"),
cl->name, cl->hostname);
{
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);
- free(from_id);
return -1;
}
- free(from_id);
-
from->status.validkey = 0;
from->status.waitingforkey = 0;
return 0;
}
-int send_req_key(conn_list_t *from, conn_list_t *to)
+int send_req_key(connection_t *from, connection_t *to)
{
cp
return send_request(to->nexthop, "%d %s %s", REQ_KEY,
from->name, to->name);
}
-int req_key_h(conn_list_t *cl)
+int req_key_h(connection_t *cl)
{
- char *from_id, *to_id;
- conn_list_t *from, *to;
+ char from_id[MAX_STRING_SIZE];
+ char to_id[MAX_STRING_SIZE];
+ connection_t *from, *to;
char pktkey[129];
cp
- if(sscanf(cl->buffer, "%*d %as %as", &from_id, &to_id) != 2)
+ if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING, from_id, to_id) != 2)
{
syslog(LOG_ERR, _("Got bad REQ_KEY from %s (%s)"),
cl->name, cl->hostname);
{
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);
- free(from_id); free(to_id);
return -1;
}
{
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);
- free(from_id); free(to_id);
return -1;
}
send_req_key(from, to);
}
- free(from_id); free(to_id);
cp
return 0;
}
-int send_ans_key(conn_list_t *from, conn_list_t *to, char *pktkey)
+int send_ans_key(connection_t *from, connection_t *to, char *pktkey)
{
cp
return send_request(to->nexthop, "%d %s %s %s", ANS_KEY,
from->name, to->name, pktkey);
}
-int ans_key_h(conn_list_t *cl)
+int ans_key_h(connection_t *cl)
{
- char *from_id, *to_id, *pktkey;
+ char from_id[MAX_STRING_SIZE];
+ char to_id[MAX_STRING_SIZE];
+ char pktkey[MAX_STRING_SIZE];
int keylength;
- conn_list_t *from, *to;
+ connection_t *from, *to;
cp
- if(sscanf(cl->buffer, "%*d %as %as %as", &from_id, &to_id, &pktkey) != 3)
+ if(sscanf(cl->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING, from_id, to_id, pktkey) != 3)
{
syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s)"),
cl->name, cl->hostname);
{
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);
- free(from_id); free(to_id); free(pktkey);
return -1;
}
{
syslog(LOG_ERR, _("Got bad ANS_KEY from %s (%s) origin %s: invalid key length"),
cl->name, cl->hostname, from->name);
- free(from_id); free(to_id); free(pktkey);
return -1;
}
{
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);
- free(from_id); free(to_id);
return -1;
}
send_ans_key(from, to, pktkey);
if(from->cipher_pktkey)
free(from->cipher_pktkey);
+ from->cipher_pktkey = xstrdup(pktkey);
keylength /= 2;
- hex2bin(pktkey, pktkey, keylength);
- pktkey[keylength] = '\0';
- from->cipher_pktkey = pktkey;
+ hex2bin(from->cipher_pktkey, from->cipher_pktkey, keylength);
+ from->cipher_pktkey[keylength] = '\0';
from->status.validkey = 1;
from->status.waitingforkey = 0;
-
- free(from_id); free(to_id);
cp
return 0;
}
/* Jumptable for the request handlers */
-int (*request_handlers[])(conn_list_t*) = {
+int (*request_handlers[])(connection_t*) = {
id_h, challenge_h, chal_reply_h, metakey_h, ack_h,
status_h, error_h, termreq_h,
ping_h, pong_h,