]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Bugfixes: select right password for password authentication, do not
authorPavel Machek <pavel@ucw.cz>
Thu, 25 Nov 1999 14:54:08 +0000 (14:54 +0000)
committerPavel Machek <pavel@ucw.cz>
Thu, 25 Nov 1999 14:54:08 +0000 (14:54 +0000)
try to process authentication blocks as datablocks, make it possible
to add data at end of packet. Password authentication should actually work.

bird.conf
proto/rip/auth.c
proto/rip/rip.c
proto/rip/rip.h

index f024c1649663256096c8069e5c9861ef132aec12..b2ac49bf268800a1a5ed754c9c95f1bd3503049a 100644 (file)
--- a/bird.conf
+++ b/bird.conf
@@ -33,7 +33,7 @@ protocol rip MyRIP_test {
        passwords { password "ahoj" from 0 to 10;
                password "nazdar" from 10;
        }
-       authentication md5;
+       authentication plaintext;
 }
 
 protocol device {
index 7d09f2736279883f49ecac3cbd92286b111a156e..ccdcd56fb0eecb8a94fb3bd0e726d93b798adf33 100644 (file)
@@ -4,6 +4,7 @@
  *     Copyright (c) 1999 Pavel Machek <pavel@ucw.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
+ *
  */
 
 #define LOCAL_DEBUG
@@ -34,15 +35,19 @@ rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, stru
 {
   DBG( "Incoming authentication: " );
   switch (block->authtype) {   /* Authentication type */
-  case AT_PLAINTEXT:
-    DBG( "Plaintext passwd" );
-    if (!P_CF->passwords) {
-      log( L_AUTH "no passwords set and password authentication came\n" );
-      return 1;
-    }
-    if (strncmp( (char *) (&block->packetlen), P_CF->passwords->password, 16)) {
-      log( L_AUTH "Passwd authentication failed!\n" );
-      return 1;
+  case AT_PLAINTEXT: 
+    {
+      struct password_item *passwd = get_best_password( P_CF->passwords, 0 );
+      DBG( "Plaintext passwd" );
+      if (!passwd) {
+       log( L_AUTH "no passwords set and password authentication came\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;
   case AT_MD5:
@@ -51,12 +56,16 @@ rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, stru
       struct password_item *head;
       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" );
        return 1;
       }
 
       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;
       while (head) {
@@ -91,15 +100,19 @@ rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, stru
   return 0;
 }
 
-void
+int
 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 );
+
+  if (!P_CF->authtype)
+    return PACKETLEN(num);
+
   DBG( "Outgoing authentication: " );
 
   if (!passwd) {
     log( L_ERR "no suitable password found for authentication\n" );
-    return;
+    return PACKETLEN(num);
   }
 
   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) {
   case AT_PLAINTEXT:
     password_strncpy( (char *) (&block->packetlen), passwd->password, 16);
-    return;
+    return PACKETLEN(num);
   case AT_MD5:
     {
       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->seq = sequence++;
       block->zero0 = 0;
-      block->zero1 = 1;
-      block->packetlen = PACKETLEN(num);
+      block->zero1 = 0;
+      block->packetlen = PACKETLEN(num) + block->authlen;
 
       tail = (struct rip_md5_tail *) ((char *) packet + (block->packetlen - sizeof(struct rip_block_auth)));
       tail->mustbeFFFF = 0xffff;
@@ -132,7 +145,9 @@ rip_outgoing_authentication( struct proto *p, struct rip_block_auth *block, stru
       MD5Init(&ctxt);
       MD5Update(&ctxt, (char *) packet, block->packetlen );
       MD5Final((char *) (&tail->md5), &ctxt);
-      return;
+      return block->packetlen;
     }
+  default:
+    bug( "Uknown authtype in outgoing authentication?\n" );
   }
 }
index 1fdb179d3df22d2f0d7dc64152851cf7bf1e829e..16c61cf51953a2019b6296408fdb666651aec39b 100644 (file)
@@ -114,7 +114,7 @@ rip_tx( sock *s )
   struct rip_connection *c = rif->busy;
   struct proto *p = c->proto;
   struct rip_packet *packet = (void *) s->tbuf;
-  int i;
+  int i, packetlen;
 
   DBG( "Sending to %I\n", s->daddr );
   do {
@@ -151,17 +151,17 @@ rip_tx( sock *s )
 
   break_loop:
 
-    if (P_CF->authtype)
-      rip_outgoing_authentication(p, (void *) &packet->block[0], packet, i);
+    packetlen = rip_outgoing_authentication(p, (void *) &packet->block[0], packet, i);
 
     DBG( ", sending %d blocks, ", i );
-    if (!i)
+#if 0  /* FIXME: enable this for production! */
+    if (i == !!P_CF->authtype)
       continue;
-
+#endif
     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
-      i = sk_send( s, sizeof( struct rip_packet_heading ) + i*sizeof( struct rip_block ) );
+      i = sk_send( s, packetlen );
 
     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;
 
   CHK_MAGIC;
+  debug( "block: %I tells me: %I/??? available, metric %d... ", whotoldme, network, metric );
   if ((!metric) || (metric > P_CF->infinity)) {
     log( L_WARN "Got metric %d from %I", metric, whotoldme );
     return;
   }
 
-  debug( "block: %I tells me: %I/??? available, metric %d... ", whotoldme, network, metric );
-
   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++) {
            struct rip_block *block = &packet->block[i];
-           if (block->family == 0xffff)
-             if (!i) {
-               if (rip_incoming_authentication(p, (void *) block, packet, num))
-                 BAD( "Authentication failed" );
-               authenticated = 1;
-             } 
+           if (block->family == 0xffff) {
+             if (i)
+               BAD( "Authentication header is not the first" );
+             if (rip_incoming_authentication(p, (void *) block, packet, num))
+               BAD( "Authentication failed" );
+             authenticated = 1;
+             continue;
+           }
            if ((!authenticated) && (P_CF->authtype != AT_NONE))
              BAD( "Packet is not authenticated and it should be" );
            ipa_ntoh( block->network );
index 2b5a2d299da4c021051960b6d7fa84c37982a106..613d198c9445de0dd16328163c93a420bf566276 100644 (file)
@@ -42,7 +42,7 @@ struct rip_packet_heading {
 };
 
 #ifndef IPV6
-struct rip_block {
+struct rip_block {     /* 20 bytes */
   u16 family;  /* 0xffff on first message means this is authentication */
   u16 tag;
   ip_addr network;
@@ -51,7 +51,7 @@ struct rip_block {
   u32 metric;
 };
 #else
-struct rip_block {
+struct rip_block { /* IPv6 version! */
   ip_addr network;
   u16 tag;
   u8 pxlen;
@@ -59,7 +59,7 @@ struct rip_block {
 };
 #endif
 
-struct rip_block_auth {
+struct rip_block_auth { /* 20 bytes */
   u16 mustbeFFFF;
   u16 authtype;
   u16 packetlen;
@@ -70,7 +70,7 @@ struct rip_block_auth {
   u32 zero1;
 };
 
-struct rip_md5_tail {
+struct rip_md5_tail {  /* 20 bytes */
   u16 mustbeFFFF;
   u16 mustbe0001;
   char md5[16];
@@ -158,4 +158,4 @@ void rip_init_config(struct rip_proto_config *c);
 /* Authentication functions */
 
 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 );