diff --git a/doc/bird.sgml b/doc/bird.sgml index 9a12a710..6622c1ad 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1072,16 +1072,14 @@ protocol ospf <name> { rx buffer [normal|large|<num>]; type [broadcast|nonbroadcast|pointopoint]; strict nonbroadcast <switch>; - authentication [none|simple]; + authentication [none|simple|cryptographics]; password "<text>"; - passwords { - password "<text>" { - id <num>; - generate from "<date>"; - generate to "<date>"; - accept from "<date>"; - accept to "<date>"; - }; + password "<text>" { + id <num>; + generate from "<date>"; + generate to "<date>"; + accept from "<date>"; + accept to "<date>"; }; neighbors { <ip>; @@ -1210,7 +1208,7 @@ protocol ospf <name> { very weak. authentication cryptographic - 16-byte long md5 digest is appended to every packet. For the digest + 16-byte long MD5 digest is appended to every packet. For the digest generation 16-byte long passwords are used. Those passwords are not sent via network, so this mechanismus is quite secure. Packets can still be read by an attacker. @@ -1220,7 +1218,9 @@ protocol ospf <name> { id num ID of the password, (0-255). If it's not used, BIRD will choose - some automatically. + ID based on an order of the password item in the interface. For + example, second password item in one interface will have default + ID 2. generate from date The start time of the usage of the password for packet signing. @@ -1439,7 +1439,7 @@ RIP on networks where maximal distance is higher than 15 hosts. You can read mor URL="http://www.ietf.org/html.charters/rip-charter.html" name="http://www.ietf.org/html.charters/rip-charter.html">. Both IPv4 (RFC 1723) and IPv6 (RFC 2080) versions of RIP are supported by BIRD, historical RIPv1 (RFC 1058)is -not currently supported. RIPv4 md5 authentication (RFC 2082) is supported. +not currently supported. RIPv4 MD5 authentication (RFC 2082) is supported.

RIP is a very simple protocol, and it has a lot of shortcomings. Slow convergence, big network load and inability to handle larger networks @@ -1454,7 +1454,7 @@ because there are no good implementations of OSPFv3. passwords { } section. Default: none. diff --git a/nest/config.Y b/nest/config.Y index 91c3363b..48940ffd 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -20,6 +20,16 @@ static struct proto_config *this_proto; static struct iface_patt *this_ipatt; static list *this_p_list; static struct password_item *this_p_item; +static int password_id; + +static list * +get_passwords(void) +{ + list *rv = this_p_list; + this_p_list = NULL; + return rv; +} + CF_DECLS @@ -37,7 +47,6 @@ CF_ENUM(T_ENUM_RTD, RTD_, ROUTER, DEVICE, BLACKHOLE, UNREACHABLE, PROHIBIT) %type idval %type imexport %type rtable -%type

password_list password_begin password_begin_list %type optsym %type r_args %type echo_mask echo_size debug_mask debug_list debug_flag import_or_proto @@ -197,6 +206,11 @@ debug_flag: /* Password lists */ +password_list: + PASSWORDS '{' password_items '}' + | password_item +; + password_items: /* empty */ | password_item ';' password_items @@ -209,14 +223,18 @@ password_item: password_item_begin: PASSWORD TEXT { - static int id = 1; + if (!this_p_list) { + this_p_list = cfg_alloc(sizeof(list)); + init_list(this_p_list); + password_id = 1; + } 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++; + this_p_item->id = password_id++; add_tail(this_p_list, &this_p_item->n); } ; @@ -230,36 +248,6 @@ password_item_params: | ID expr ';' password_item_params { this_p_item->id = $2; if ($2 <= 0) cf_error("Password ID has to be greated than zero."); } ; -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); - $$ = (void *) 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 = 1; - add_tail(this_p_list, &this_p_item->n); - $$ = (void *) this_p_list; - } -; /* Core commands */ CF_CLI_HELP(SHOW, ..., [[Show status information]]) diff --git a/nest/password.c b/nest/password.c index 80c4c7b4..179939e2 100644 --- a/nest/password.c +++ b/nest/password.c @@ -14,19 +14,26 @@ struct password_item *last_password_item = NULL; struct password_item * -password_find(list *l) +password_find(list *l, int first_fit) { struct password_item *pi; + struct password_item *pf = NULL; if (l) { WALK_LIST(pi, *l) { if ((pi->genfrom < now_real) && (pi->gento > now_real)) - return pi; + { + if (first_fit) + return pi; + + if (!pf || pf->genfrom < pi->genfrom) + pf = pi; + } } } - return NULL; + return pf; } void password_cpy(char *dst, char *src, int size) diff --git a/nest/password.h b/nest/password.h index 0c453836..726af733 100644 --- a/nest/password.h +++ b/nest/password.h @@ -22,7 +22,7 @@ struct password_item { extern struct password_item *last_password_item; -struct password_item *password_find(list *); +struct password_item *password_find(list *l, int first_fit); void password_cpy(char *dst, char *src, int size); #endif diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y index dfcab4e6..0956d9e3 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -32,7 +32,7 @@ CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL) CF_GRAMMAR -CF_ADDTO(proto, ospf_proto '}') +CF_ADDTO(proto, ospf_proto '}' { OSPF_PATT->passwords = get_passwords(); } ) ospf_proto_start: proto_start OSPF { this_proto = proto_config_new(&proto_ospf, sizeof(struct ospf_config)); @@ -102,7 +102,7 @@ ospf_vlink_item: | AUTHENTICATION NONE { OSPF_PATT->autype = OSPF_AUTH_NONE ; } | AUTHENTICATION SIMPLE { OSPF_PATT->autype = OSPF_AUTH_SIMPLE ; } | AUTHENTICATION CRYPTOGRAPHIC { OSPF_PATT->autype = OSPF_AUTH_CRYPT ; } - | password_list {OSPF_PATT->passwords = (list *) $1; } + | password_list ; ospf_vlink_start: VIRTUAL LINK idval @@ -146,7 +146,7 @@ ospf_iface_item: | RX BUFFER LARGE { OSPF_PATT->rxbuf = OSPF_RXBUF_LARGE ; } | RX BUFFER NORMAL { OSPF_PATT->rxbuf = OSPF_RXBUF_NORMAL ; } | RX BUFFER expr { OSPF_PATT->rxbuf = $3 ; if ($3 < OSPF_RXBUF_MINSIZE) cf_error("Buffer size is too small") ; } - | password_list {OSPF_PATT->passwords = (list *) $1; } + | password_list ; pref_list: diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c index 4e8dcaf0..ee352827 100644 --- a/proto/ospf/packet.c +++ b/proto/ospf/packet.c @@ -41,7 +41,7 @@ ospf_pkt_maxsize(struct ospf_iface *ifa) void ospf_pkt_finalize(struct ospf_iface *ifa, struct ospf_packet *pkt) { - struct password_item *passwd = password_find (ifa->passwords); + struct password_item *passwd = NULL; void *tail; struct MD5Context ctxt; char password[OSPF_AUTH_CRYPT_SIZE]; @@ -52,6 +52,7 @@ ospf_pkt_finalize(struct ospf_iface *ifa, struct ospf_packet *pkt) { case OSPF_AUTH_SIMPLE: bzero(&pkt->u, sizeof(union ospf_auth)); + passwd = password_find(ifa->passwords, 1); if (!passwd) { log( L_ERR "No suitable password found for authentication" ); @@ -65,6 +66,7 @@ ospf_pkt_finalize(struct ospf_iface *ifa, struct ospf_packet *pkt) sizeof(struct ospf_packet), NULL); break; case OSPF_AUTH_CRYPT: + passwd = password_find(ifa->passwords, 0); if (!passwd) { log( L_ERR "No suitable password found for authentication" ); @@ -123,7 +125,7 @@ ospf_pkt_checkauth(struct ospf_neighbor *n, struct ospf_iface *ifa, struct ospf_ return 1; break; case OSPF_AUTH_SIMPLE: - pass = password_find (ifa->passwords); + pass = password_find(ifa->passwords, 1); if(!pass) { OSPF_TRACE(D_PACKETS, "OSPF_auth: no password found"); diff --git a/proto/rip/auth.c b/proto/rip/auth.c index 1f7050f0..b7b0611e 100644 --- a/proto/rip/auth.c +++ b/proto/rip/auth.c @@ -39,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 = password_find(P_CF->passwords); + struct password_item *passwd = password_find(P_CF->passwords, 1); DBG( "Plaintext passwd" ); if (!passwd) { log( L_AUTH "No passwords set and password authentication came" ); @@ -115,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 = password_find( P_CF->passwords); + struct password_item *passwd = password_find(P_CF->passwords, 1); if (!P_CF->authtype) return PACKETLEN(num); diff --git a/proto/rip/config.Y b/proto/rip/config.Y index bd303e97..f1ae43cb 100644 --- a/proto/rip/config.Y +++ b/proto/rip/config.Y @@ -34,7 +34,7 @@ CF_KEYWORDS(RIP, INFINITY, METRIC, PORT, PERIOD, GARBAGE, TIMEOUT, PASSWORDS, CF_GRAMMAR -CF_ADDTO(proto, rip_cfg '}') +CF_ADDTO(proto, rip_cfg '}' { RIP_CFG->passwords = get_passwords(); } ) rip_cfg_start: proto_start RIP { this_proto = proto_config_new(&proto_rip, sizeof(struct rip_proto_config)); @@ -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 password_list ';' {RIP_CFG->passwords = (list *)$2; } + | rip_cfg password_list ';' | 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; }