Bugfixes: select right password for password authentication, do not

try to process authentication blocks as datablocks, make it possible
to add data at end of packet. Password authentication should actually work.
This commit is contained in:
Pavel Machek 1999-11-25 14:54:08 +00:00
parent 4aa885a53c
commit d3702d57fd
4 changed files with 53 additions and 37 deletions

View file

@ -33,7 +33,7 @@ protocol rip MyRIP_test {
passwords { password "ahoj" from 0 to 10; passwords { password "ahoj" from 0 to 10;
password "nazdar" from 10; password "nazdar" from 10;
} }
authentication md5; authentication plaintext;
} }
protocol device { protocol device {

View file

@ -4,6 +4,7 @@
* Copyright (c) 1999 Pavel Machek <pavel@ucw.cz> * Copyright (c) 1999 Pavel Machek <pavel@ucw.cz>
* *
* Can be freely distributed and used under the terms of the GNU GPL. * Can be freely distributed and used under the terms of the GNU GPL.
*
*/ */
#define LOCAL_DEBUG #define LOCAL_DEBUG
@ -34,15 +35,19 @@ rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, stru
{ {
DBG( "Incoming authentication: " ); DBG( "Incoming authentication: " );
switch (block->authtype) { /* Authentication type */ switch (block->authtype) { /* Authentication type */
case AT_PLAINTEXT: case AT_PLAINTEXT:
DBG( "Plaintext passwd" ); {
if (!P_CF->passwords) { struct password_item *passwd = get_best_password( P_CF->passwords, 0 );
log( L_AUTH "no passwords set and password authentication came\n" ); DBG( "Plaintext passwd" );
return 1; if (!passwd) {
} log( L_AUTH "no passwords set and password authentication came\n" );
if (strncmp( (char *) (&block->packetlen), P_CF->passwords->password, 16)) { return 1;
log( L_AUTH "Passwd authentication failed!\n" ); }
return 1; if (strncmp( (char *) (&block->packetlen), passwd->password, 16)) {
log( L_AUTH "Passwd authentication failed!\n" );
DBG( "Expected %s, got %s\n", passwd->password, &block->packetlen );
return 1;
}
} }
return 0; return 0;
case AT_MD5: case AT_MD5:
@ -51,12 +56,16 @@ rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, stru
struct password_item *head; struct password_item *head;
struct rip_md5_tail *tail; struct rip_md5_tail *tail;
if (block->packetlen != PACKETLEN(num)) { if (block->packetlen != PACKETLEN(num) + 20) {
log( L_ERR "packetlen in md5 does not match computed value\n" ); log( L_ERR "packetlen in md5 does not match computed value\n" );
return 1; return 1;
} }
tail = (struct rip_md5_tail *) ((char *) packet + (block->packetlen - sizeof(struct rip_block_auth))); tail = (struct rip_md5_tail *) ((char *) packet + (block->packetlen - sizeof(struct rip_block_auth)));
if ((tail->mustbeFFFF != 0xffff) || (tail->mustbe0001 != 0x0001)) {
log( L_ERR "md5 tail signature is not there\n" );
return 1;
}
head = P_CF->passwords; head = P_CF->passwords;
while (head) { while (head) {
@ -91,15 +100,19 @@ rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, stru
return 0; return 0;
} }
void int
rip_outgoing_authentication( struct proto *p, struct rip_block_auth *block, struct rip_packet *packet, int num ) rip_outgoing_authentication( struct proto *p, struct rip_block_auth *block, struct rip_packet *packet, int num )
{ {
struct password_item *passwd = get_best_password( P_CF->passwords, 0 ); struct password_item *passwd = get_best_password( P_CF->passwords, 0 );
if (!P_CF->authtype)
return PACKETLEN(num);
DBG( "Outgoing authentication: " ); DBG( "Outgoing authentication: " );
if (!passwd) { if (!passwd) {
log( L_ERR "no suitable password found for authentication\n" ); log( L_ERR "no suitable password found for authentication\n" );
return; return PACKETLEN(num);
} }
block->authtype = P_CF->authtype; block->authtype = P_CF->authtype;
@ -107,7 +120,7 @@ rip_outgoing_authentication( struct proto *p, struct rip_block_auth *block, stru
switch (P_CF->authtype) { switch (P_CF->authtype) {
case AT_PLAINTEXT: case AT_PLAINTEXT:
password_strncpy( (char *) (&block->packetlen), passwd->password, 16); password_strncpy( (char *) (&block->packetlen), passwd->password, 16);
return; return PACKETLEN(num);
case AT_MD5: case AT_MD5:
{ {
struct rip_md5_tail *tail; struct rip_md5_tail *tail;
@ -121,8 +134,8 @@ rip_outgoing_authentication( struct proto *p, struct rip_block_auth *block, stru
block->authlen = 20; block->authlen = 20;
block->seq = sequence++; block->seq = sequence++;
block->zero0 = 0; block->zero0 = 0;
block->zero1 = 1; block->zero1 = 0;
block->packetlen = PACKETLEN(num); block->packetlen = PACKETLEN(num) + block->authlen;
tail = (struct rip_md5_tail *) ((char *) packet + (block->packetlen - sizeof(struct rip_block_auth))); tail = (struct rip_md5_tail *) ((char *) packet + (block->packetlen - sizeof(struct rip_block_auth)));
tail->mustbeFFFF = 0xffff; tail->mustbeFFFF = 0xffff;
@ -132,7 +145,9 @@ rip_outgoing_authentication( struct proto *p, struct rip_block_auth *block, stru
MD5Init(&ctxt); MD5Init(&ctxt);
MD5Update(&ctxt, (char *) packet, block->packetlen ); MD5Update(&ctxt, (char *) packet, block->packetlen );
MD5Final((char *) (&tail->md5), &ctxt); MD5Final((char *) (&tail->md5), &ctxt);
return; return block->packetlen;
} }
default:
bug( "Uknown authtype in outgoing authentication?\n" );
} }
} }

View file

@ -114,7 +114,7 @@ rip_tx( sock *s )
struct rip_connection *c = rif->busy; struct rip_connection *c = rif->busy;
struct proto *p = c->proto; struct proto *p = c->proto;
struct rip_packet *packet = (void *) s->tbuf; struct rip_packet *packet = (void *) s->tbuf;
int i; int i, packetlen;
DBG( "Sending to %I\n", s->daddr ); DBG( "Sending to %I\n", s->daddr );
do { do {
@ -151,17 +151,17 @@ rip_tx( sock *s )
break_loop: break_loop:
if (P_CF->authtype) packetlen = rip_outgoing_authentication(p, (void *) &packet->block[0], packet, i);
rip_outgoing_authentication(p, (void *) &packet->block[0], packet, i);
DBG( ", sending %d blocks, ", i ); DBG( ", sending %d blocks, ", i );
if (!i) #if 0 /* FIXME: enable this for production! */
if (i == !!P_CF->authtype)
continue; continue;
#endif
if (ipa_nonzero(c->daddr)) if (ipa_nonzero(c->daddr))
i = sk_send_to( s, sizeof( struct rip_packet_heading ) + i*sizeof( struct rip_block ), c->daddr, c->dport ); i = sk_send_to( s, packetlen, c->daddr, c->dport );
else else
i = sk_send( s, sizeof( struct rip_packet_heading ) + i*sizeof( struct rip_block ) ); i = sk_send( s, packetlen );
DBG( "it wants more\n" ); DBG( "it wants more\n" );
@ -294,13 +294,12 @@ process_block( struct proto *p, struct rip_block *block, ip_addr whotoldme )
ip_addr network = block->network; ip_addr network = block->network;
CHK_MAGIC; CHK_MAGIC;
debug( "block: %I tells me: %I/??? available, metric %d... ", whotoldme, network, metric );
if ((!metric) || (metric > P_CF->infinity)) { if ((!metric) || (metric > P_CF->infinity)) {
log( L_WARN "Got metric %d from %I", metric, whotoldme ); log( L_WARN "Got metric %d from %I", metric, whotoldme );
return; return;
} }
debug( "block: %I tells me: %I/??? available, metric %d... ", whotoldme, network, metric );
advertise_entry( p, block, whotoldme ); advertise_entry( p, block, whotoldme );
} }
@ -351,12 +350,14 @@ rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr
for (i=0; i<num; i++) { for (i=0; i<num; i++) {
struct rip_block *block = &packet->block[i]; struct rip_block *block = &packet->block[i];
if (block->family == 0xffff) if (block->family == 0xffff) {
if (!i) { if (i)
if (rip_incoming_authentication(p, (void *) block, packet, num)) BAD( "Authentication header is not the first" );
BAD( "Authentication failed" ); if (rip_incoming_authentication(p, (void *) block, packet, num))
authenticated = 1; BAD( "Authentication failed" );
} authenticated = 1;
continue;
}
if ((!authenticated) && (P_CF->authtype != AT_NONE)) if ((!authenticated) && (P_CF->authtype != AT_NONE))
BAD( "Packet is not authenticated and it should be" ); BAD( "Packet is not authenticated and it should be" );
ipa_ntoh( block->network ); ipa_ntoh( block->network );

View file

@ -42,7 +42,7 @@ struct rip_packet_heading {
}; };
#ifndef IPV6 #ifndef IPV6
struct rip_block { struct rip_block { /* 20 bytes */
u16 family; /* 0xffff on first message means this is authentication */ u16 family; /* 0xffff on first message means this is authentication */
u16 tag; u16 tag;
ip_addr network; ip_addr network;
@ -51,7 +51,7 @@ struct rip_block {
u32 metric; u32 metric;
}; };
#else #else
struct rip_block { struct rip_block { /* IPv6 version! */
ip_addr network; ip_addr network;
u16 tag; u16 tag;
u8 pxlen; u8 pxlen;
@ -59,7 +59,7 @@ struct rip_block {
}; };
#endif #endif
struct rip_block_auth { struct rip_block_auth { /* 20 bytes */
u16 mustbeFFFF; u16 mustbeFFFF;
u16 authtype; u16 authtype;
u16 packetlen; u16 packetlen;
@ -70,7 +70,7 @@ struct rip_block_auth {
u32 zero1; u32 zero1;
}; };
struct rip_md5_tail { struct rip_md5_tail { /* 20 bytes */
u16 mustbeFFFF; u16 mustbeFFFF;
u16 mustbe0001; u16 mustbe0001;
char md5[16]; char md5[16];
@ -158,4 +158,4 @@ void rip_init_config(struct rip_proto_config *c);
/* Authentication functions */ /* Authentication functions */
int rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, struct rip_packet *packet, int num ); int rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, struct rip_packet *packet, int num );
void rip_outgoing_authentication( struct proto *p, struct rip_block_auth *block, struct rip_packet *packet, int num ); int rip_outgoing_authentication( struct proto *p, struct rip_block_auth *block, struct rip_packet *packet, int num );