- 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)
{ {
@ -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)
@ -144,7 +154,7 @@ cp
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;
} }
@ -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 */
@ -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);
} }
@ -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)
@ -553,7 +651,7 @@ 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;
} }
@ -562,7 +660,7 @@ cp
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,14 +826,14 @@ 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;
} }
@ -754,7 +852,7 @@ 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;
} }
@ -839,7 +937,7 @@ cp
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