]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Password management redesigned (untested).
authorOndrej Filip <feela@network.cz>
Sat, 26 Jun 2004 20:11:14 +0000 (20:11 +0000)
committerOndrej Filip <feela@network.cz>
Sat, 26 Jun 2004 20:11:14 +0000 (20:11 +0000)
nest/config.Y
nest/password.c
nest/password.h
proto/rip/auth.c
proto/rip/config.Y
proto/rip/rip.c
proto/rip/rip.h

index 4f9b46b6483bcee57cb9398a17661600dcdcf693..7a83a60aa8f62338bdb4ee8014bfe8dc20ef93e5 100644 (file)
@@ -11,18 +11,21 @@ CF_HDR
 #include "nest/rt-dev.h"
 #include "nest/password.h"
 #include "nest/cmds.h"
+#include "lib/lists.h"
 
 CF_DEFINES
 
 static struct proto_config *this_proto;
 static struct iface_patt *this_ipatt;
+static list *this_p_list;
+static struct password_item *this_p_item;
 
 CF_DECLS
 
 CF_KEYWORDS(ROUTER, ID, PROTOCOL, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
 CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
 CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
-CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREIMPORT)
+CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREIMPORT, GENERATE)
 
 CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
        RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE)
@@ -33,7 +36,7 @@ CF_ENUM(T_ENUM_RTD, RTD_, ROUTER, DEVICE, BLACKHOLE, UNREACHABLE, PROHIBIT)
 %type <i32> idval
 %type <f> imexport
 %type <r> rtable
-%type <p> password_list password_begin
+%type <p> password_list password_begin password_begin_list
 %type <s> optsym
 %type <ra> r_args
 %type <i> echo_mask echo_size debug_mask debug_list debug_flag import_or_proto
@@ -193,36 +196,71 @@ debug_flag:
 
 /* Password lists */
 
-password_begin: 
+password_items: 
+    /* empty */
+  | password_item ';' password_items
+;
+
+password_item:
+    password_item_begin '{' password_item_params '}'
+  | password_item_begin
+;
+
+password_item_begin:
    PASSWORD TEXT {
-     last_password_item = cfg_alloc(sizeof (struct password_item));
-     last_password_item->password = $2;
-     last_password_item->from = 0;
-     last_password_item->to = TIME_INFINITY;
-     last_password_item->id = 0;
-     last_password_item->next = NULL;
-     $$=last_password_item;
+     static int id = 0;
+     this_p_item = cfg_alloc(sizeof (struct password_item));
+     this_p_item->password = $2;
+     this_p_item->genfrom = 0;
+     this_p_item->gento = TIME_INFINITY;
+     this_p_item->accfrom = 0;
+     this_p_item->accto = TIME_INFINITY;
+     this_p_item->id = id++;
+     add_tail(this_p_list, &this_p_item->n);
    }
- ;
+;
 
-password_items:
+password_item_params:
    /* empty */ { } 
- | FROM datetime password_items { last_password_item->from = $2; }
- | TO datetime password_items { last_password_item->to = $2; }
- | PASSIVE datetime password_items { last_password_item->passive = $2; }
- | ID expr password_items { last_password_item->id = $2; }
+ | GENERATE FROM datetime ';' password_item_params { this_p_item->genfrom = $3; }
+ | GENERATE TO datetime ';' password_item_params { this_p_item->gento = $3; }
+ | ACCEPT FROM datetime ';' password_item_params { this_p_item->accfrom = $3; }
+ | ACCEPT TO datetime ';' password_item_params { this_p_item->accto = $3; }
+ | ID expr ';' password_item_params { this_p_item->id = $2; }
  ;
 
-password_list: 
-   /* empty */ { $$ = NULL; } 
- | password_begin password_items ';' password_list {
-     $1->next = $4;
+password_list:
+   password_begin_list '{' password_items '}' {
      $$ = $1;
    }
- ;
+ | password_begin
+;
+
+password_begin_list:
+  PASSWORDS {
+     this_p_list = cfg_alloc(sizeof(list));
+     init_list(this_p_list);
+     $$ = this_p_list;
+  }
+;
+
+password_begin:
+  PASSWORD TEXT {
+     this_p_list = cfg_alloc(sizeof(list));
+     init_list(this_p_list);
+     this_p_item = cfg_alloc(sizeof (struct password_item));
+     this_p_item->password = $2;
+     this_p_item->genfrom = 0;
+     this_p_item->gento = TIME_INFINITY;
+     this_p_item->accfrom = 0;
+     this_p_item->accto = TIME_INFINITY;
+     this_p_item->id = 0;
+     add_tail(this_p_list, &this_p_item->n);
+     $$ = this_p_list;
+  }
+;
 
 /* Core commands */
-
 CF_CLI_HELP(SHOW, ..., [[Show status information]])
 
 CF_CLI(SHOW STATUS,,, [[Show router status]])
index 594569ccc5fcbda29fae4c04939d7a248c0cd920..6309602369ecdfd24aebe121470b1567dca6f027 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *     BIRD -- Password handling
  *
- *     Copyright 1999 Pavel Machek <pavel@ucw.cz>
+ *     (c) 1999 Pavel Machek <pavel@ucw.cz>
+ *     (c) 2004 Ondrej Filip <feela@network.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
 
 struct password_item *last_password_item = NULL;
 
-static int
-password_goodness(struct password_item *i)
-{
-  if (i->from > now)
-    return 0;
-  if (i->to < now)
-    return 0;
-  if (i->passive < now)
-    return 1;
-  return 2;
-}
-
 struct password_item *
-get_best_password(struct password_item *head, int flags UNUSED)
+password_find(list *l)
 {
-  int good = -1;
-  struct password_item *best = NULL;
+  struct password_item *pi;
 
-  while (head) {
-    int cur = password_goodness(head);
-    if (cur > good) {
-      good = cur;
-      best = head;
-    }
-    head=head->next;
+  WALK_LIST(pi, *l)
+  {
+    if ((pi->genfrom > now) && (pi->gento < now))
+      return pi;
   }
-  return best;
+  return NULL;
 }
 
-void
-password_strncpy(char *to, char *from, int len)
+void password_cpy(char *dst, char *src, int size)
 {
-  int i;
-  for (i=0; i<len; i++) {
-    *to++ = *from;
-    if (*from)
-      from++;
-  }
+  bzero(dst, size);
+  memcpy(dst, src, strlen(src) < size ? strlen(src) : size);
 }
 
-int
-password_same(struct password_item *old, struct password_item *new)
-{
-  for(;;)
-    {
-      if (old == new)
-       return 1;
-      if (!old || !new)
-       return 0;
-      if (old->from    != new->from    ||
-         old->to      != new->to      ||
-         old->passive != new->passive ||
-         old->id      != new->id      ||
-         strcmp(old->password, new->password))
-       return 0;
-      old = old->next;
-      new = new->next;
-    }
-}
index 481eeb61b807ebf49cbb0bee44f142af85582001..0c453836eadf9520612a54bbeba1dfc4a1d76db1 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *     BIRD -- Password handling
  *
- *     Copyright 1999 Pavel Machek <pavel@ucw.cz>
+ *     (c) 1999 Pavel Machek <pavel@ucw.cz>
+ *     (c) 2004 Ondrej Filip <feela@network.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
 #define PASSWORD_H
 #include "lib/timer.h"
 
+#define MD5_AUTH_SIZE 16
+
 struct password_item {
-  struct password_item *next;
+  node n;
   char *password;
   int id;
-  bird_clock_t from, passive, to;
+  bird_clock_t accfrom, accto, genfrom, gento;
 };
 
 extern struct password_item *last_password_item;
 
-struct password_item *get_best_password(struct password_item *head, int flags);
-extern int password_same(struct password_item *, struct password_item *);
-extern void password_strncpy(char *to, char *from, int len);
-
+struct password_item *password_find(list *);
+void password_cpy(char *dst, char *src, int size);
 
 #endif
index 3d4b91c82af0faae8794991fa1bf40cd885e9ce3..bc0cc4b11ebf8e359f230172dc4a3c6a24bb0bd2 100644 (file)
@@ -2,6 +2,7 @@
  *     Rest in pieces - RIP protocol
  *
  *     Copyright (c) 1999 Pavel Machek <pavel@ucw.cz>
+ *     Copyright (c) 2004 Ondrej Filip <feela@network.cz>
  *
  *     Bug fixes by Eric Leblond <eleblond@init-sys.com>, April 2003
  * 
@@ -38,7 +39,7 @@ rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, stru
   switch (ntohs(block->authtype)) {    /* Authentication type */
   case AT_PLAINTEXT: 
     {
-      struct password_item *passwd = get_best_password( P_CF->passwords, 0 );
+      struct password_item *passwd = password_find(P_CF->passwords);
       DBG( "Plaintext passwd" );
       if (!passwd) {
        log( L_AUTH "No passwords set and password authentication came" );
@@ -50,12 +51,18 @@ rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, stru
        return 1;
       }
     }
-    return 0;
+    break;
   case AT_MD5:
     DBG( "md5 password" );
     {
-      struct password_item *head;
+      struct password_item *pass = NULL, *ptmp;
       struct rip_md5_tail *tail;
+      struct MD5Context ctxt;
+      char md5sum_packet[16];
+      char md5sum_computed[16];
+      struct neighbor *neigh = neigh_find(p, &whotoldme, 0);
+      list *l = P_CF->passwords;
+
       if (ntohs(block->packetlen) != PACKETLEN(num) - sizeof(struct rip_md5_tail) ) {
        log( L_ERR "Packet length in MD5 does not match computed value" );
        return 1;
@@ -67,44 +74,34 @@ rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, stru
        return 1;
       }
 
-      head = P_CF->passwords;
-      while (head) {
-       DBG( "time, " );
-       if ((head->from > now) || (head->to < now))
-         goto skip;
-       if (block->seq) {
-         struct neighbor *neigh = neigh_find(p, &whotoldme, 0);
-         if (!neigh) {
-           log( L_AUTH "Non-neighbour MD5 checksummed packet?" );
-         } else {
-           if (neigh->aux > block->seq) {
-             log( L_AUTH "MD5 protected packet with lower numbers" );
-             return 0;
-           }
-           neigh->aux = block->seq;
-         }
-       }
-       DBG( "check, " );
-       if (head->id == block->keyid) {
-         struct MD5Context ctxt;
-         char md5sum_packet[16];
-         char md5sum_computed[16];
-
-         memset(md5sum_packet,0,16);
-         memcpy(md5sum_packet, tail->md5, 16);
-         password_strncpy(tail->md5, head->password, 16);
-
-         MD5Init(&ctxt);
-         MD5Update(&ctxt, (char *) packet, ntohs(block->packetlen) +  sizeof(struct rip_block_auth) );
-         MD5Final(md5sum_computed, &ctxt);
-         if (memcmp(md5sum_packet, md5sum_computed, 16))
-           return 1;
-         return 0;
-       }
-      skip:
-       head = head->next;
+      WALK_LIST(ptmp, *l)
+      {
+        if (block->keyid != pass->id) continue;
+        if ((pass->genfrom > now) || (pass->gento < now)) continue;
+        pass = ptmp;
+        break;
+      }
+
+      if(!pass) return 1;
+
+      if (!neigh) {
+        log( L_AUTH "Non-neighbour MD5 checksummed packet?" );
+      } else {
+       if (neigh->aux > block->seq) {
+         log( L_AUTH "MD5 protected packet with lower numbers" );
+         return 1;
+        }
+       neigh->aux = block->seq;
       }
-      return 1;
+
+      memcpy(md5sum_packet, tail->md5, 16);
+      password_cpy(tail->md5, pass->password, 16);
+
+      MD5Init(&ctxt);
+      MD5Update(&ctxt, (char *) packet, ntohs(block->packetlen) +  sizeof(struct rip_block_auth) );
+      MD5Final(md5sum_computed, &ctxt);
+      if (memcmp(md5sum_packet, md5sum_computed, 16))
+        return 1;
     }
   }
     
@@ -118,7 +115,7 @@ rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, stru
 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 );
+  struct password_item *passwd = password_find( P_CF->passwords);
 
   if (!P_CF->authtype)
     return PACKETLEN(num);
@@ -134,7 +131,7 @@ rip_outgoing_authentication( struct proto *p, struct rip_block_auth *block, stru
   block->mustbeFFFF = 0xffff;
   switch (P_CF->authtype) {
   case AT_PLAINTEXT:
-    password_strncpy( (char *) (&block->packetlen), passwd->password, 16);
+    password_cpy( (char *) (&block->packetlen), passwd->password, 16);
     return PACKETLEN(num);
   case AT_MD5:
     {
@@ -159,8 +156,7 @@ rip_outgoing_authentication( struct proto *p, struct rip_block_auth *block, stru
       tail->mustbeFFFF = 0xffff;
       tail->mustbe0001 = 0x0100;
 
-      memset(tail->md5,0,16);
-      password_strncpy( tail->md5, passwd->password, 16 );
+      password_cpy(tail->md5, passwd->password, 16);
       MD5Init(&ctxt);
       MD5Update(&ctxt, (char *) packet, PACKETLEN(num) + sizeof(struct  rip_md5_tail));
       MD5Final(tail->md5, &ctxt);
index 00d68f7860ba69e03e36da90f1e6bf334cee8570..4a352c66c79e42164d68b074441cdd9fc0d32082 100644 (file)
@@ -51,7 +51,7 @@ rip_cfg:
  | rip_cfg GARBAGE TIME expr ';' { RIP_CFG->garbage_time = $4; }
  | rip_cfg TIMEOUT TIME expr ';' { RIP_CFG->timeout_time = $4; }
  | rip_cfg AUTHENTICATION rip_auth ';' {RIP_CFG->authtype = $3; }
- | rip_cfg PASSWORDS '{' password_list '}' {RIP_CFG->passwords = $4; }
+ | rip_cfg password_list ';' {RIP_CFG->passwords = $2; }
  | rip_cfg HONOR ALWAYS ';'    { RIP_CFG->honor = HO_ALWAYS; }
  | rip_cfg HONOR NEIGHBOR ';'    { RIP_CFG->honor = HO_NEIGHBOR; }
  | rip_cfg HONOR NEVER ';'    { RIP_CFG->honor = HO_NEVER; }
index 8c7b37c6e76996c7236a40182448e195663a7f67..05525e9538d5e111d055e47054b1c4e9f6ed872c 100644 (file)
@@ -981,9 +981,6 @@ rip_reconfigure(struct proto *p, struct proto_config *c)
 
   if (!iface_patts_equal(&P_CF->iface_list, &new->iface_list, (void *) rip_pat_compare))
     return 0;
-  if (!password_same(P_CF->passwords, 
-                    new->passwords))
-    return 0;
   return !memcmp(((byte *) P_CF) + generic,
                  ((byte *) new) + generic,
                  sizeof(struct rip_proto_config) - generic);
index e01a4bdb90e467b71a7cb9a01e0ed25f776595ba..5a6e36d8f29c698488e50cb43a95ed23395c10dd 100644 (file)
@@ -121,7 +121,7 @@ struct rip_patt {
 struct rip_proto_config {
   struct proto_config c;
   list iface_list;     /* Patterns configured -- keep it first; see rip_reconfigure why */
-  struct password_item *passwords;     /* Passwords, keep second */
+  list *passwords;     /* Passwords, keep second */
 
   int infinity;                /* User configurable data; must be comparable with memcmp */
   int port;