summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Filip <feela@network.cz>2004-06-26 20:11:14 +0000
committerOndrej Filip <feela@network.cz>2004-06-26 20:11:14 +0000
commit5236fb03afecd3d7a6ec6e96712c79a31be32132 (patch)
treeafee4d3766107cdc205d7da70a66d09014aa1ef6
parent98ac61766d81d9f20c4a7c7e12859c3b82b24f4c (diff)
Password management redesigned (untested).
-rw-r--r--nest/config.Y82
-rw-r--r--nest/password.c63
-rw-r--r--nest/password.h15
-rw-r--r--proto/rip/auth.c84
-rw-r--r--proto/rip/config.Y2
-rw-r--r--proto/rip/rip.c3
-rw-r--r--proto/rip/rip.h2
7 files changed, 122 insertions, 129 deletions
diff --git a/nest/config.Y b/nest/config.Y
index 4f9b46b6..7a83a60a 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -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]])
diff --git a/nest/password.c b/nest/password.c
index 594569cc..63096023 100644
--- a/nest/password.c
+++ b/nest/password.c
@@ -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.
*/
@@ -12,62 +13,22 @@
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;
- }
-}
diff --git a/nest/password.h b/nest/password.h
index 481eeb61..0c453836 100644
--- a/nest/password.h
+++ b/nest/password.h
@@ -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.
*/
@@ -10,18 +11,18 @@
#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
diff --git a/proto/rip/auth.c b/proto/rip/auth.c
index 3d4b91c8..bc0cc4b1 100644
--- a/proto/rip/auth.c
+++ b/proto/rip/auth.c
@@ -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);
diff --git a/proto/rip/config.Y b/proto/rip/config.Y
index 00d68f78..4a352c66 100644
--- a/proto/rip/config.Y
+++ b/proto/rip/config.Y
@@ -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; }
diff --git a/proto/rip/rip.c b/proto/rip/rip.c
index 8c7b37c6..05525e95 100644
--- a/proto/rip/rip.c
+++ b/proto/rip/rip.c
@@ -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);
diff --git a/proto/rip/rip.h b/proto/rip/rip.h
index e01a4bdb..5a6e36d8 100644
--- a/proto/rip/rip.h
+++ b/proto/rip/rip.h
@@ -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;