static struct password_item *this_p_item;
static int password_id;
-static list *
+static inline void
+reset_passwords(void)
+{
+ this_p_list = NULL;
+}
+
+static inline list *
get_passwords(void)
{
list *rv = this_p_list;
static struct nbma_node *this_nbma;
static struct area_net_config *this_pref;
+static void
+finish_iface_config(struct ospf_iface_patt *ip)
+{
+ ip->passwords = get_passwords();
+
+ if ((ip->autype == OSPF_AUTH_CRYPT) && (ip->helloint < 5))
+ log(L_WARN "Hello or poll interval less that 5 makes cryptographic authenication prone to replay attacks");
+
+ if ((ip->autype == OSPF_AUTH_NONE) && (ip->passwords != NULL))
+ log(L_WARN "Password option without authentication option does not make sense");
+}
+
CF_DECLS
CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG)
;
ospf_vlink:
- ospf_vlink_start '{' ospf_vlink_opts '}' { OSPF_PATT->passwords = get_passwords(); }
+ ospf_vlink_start '{' ospf_vlink_opts '}' { finish_iface_config(OSPF_PATT); }
| ospf_vlink_start
;
OSPF_PATT->type = OSPF_IT_VLINK;
init_list(&OSPF_PATT->nbma_list);
OSPF_PATT->autype = OSPF_AUTH_NONE;
+ reset_passwords();
}
;
OSPF_PATT->stub = 0;
init_list(&OSPF_PATT->nbma_list);
OSPF_PATT->autype = OSPF_AUTH_NONE;
+ reset_passwords();
}
;
;
ospf_iface:
- ospf_iface_start iface_patt ospf_iface_opt_list { OSPF_PATT->passwords = get_passwords(); }
+ ospf_iface_start iface_patt ospf_iface_opt_list { finish_iface_config(OSPF_PATT); }
;
ospf_iface_list:
u16 autype;
u16 helloint; /* number of seconds between hello sending */
list *passwords;
- u32 csn; /* Crypt seq num. that will be sent net */
+ u32 csn; /* Last used crypt seq number */
+ bird_clock_t csn_use; /* Last time when packet with that CSN was sent */
ip_addr drip; /* Designated router */
u32 drid;
ip_addr bdrip; /* Backup DR */
pkt->checksum = 0;
+ /* Perhaps use random value to prevent replay attacks after
+ reboot when system does not have independent RTC? */
if (!ifa->csn)
- ifa->csn = (u32) time(NULL);
+ {
+ ifa->csn = (u32) now;
+ ifa->csn_use = now;
+ }
+
+ /* We must have sufficient delay between sending a packet and increasing
+ CSN to prevent reordering of packets (in a network) with different CSNs */
+ if ((now - ifa->csn_use) > 1)
+ ifa->csn++;
+
+ ifa->csn_use = now;
pkt->u.md5.keyid = passwd->id;
pkt->u.md5.len = OSPF_AUTH_CRYPT_SIZE;
pkt->u.md5.zero = 0;
- pkt->u.md5.csn = htonl(ifa->csn++);
+ pkt->u.md5.csn = htonl(ifa->csn);
tail = ((void *)pkt) + ntohs(pkt->length);
MD5Init(&ctxt);
MD5Update(&ctxt, (char *) pkt, ntohs(pkt->length));
if (n)
{
- if(ntohs(pkt->u.md5.csn) < n->csn)
- {
- OSPF_TRACE(D_PACKETS, "OSPF_auth: lower sequence number");
- return 0;
- }
- n->csn = ntohs(pkt->u.md5.csn);
+ u32 rcv_csn = ntohl(pkt->u.md5.csn);
+ if(rcv_csn < n->csn)
+ {
+ OSPF_TRACE(D_PACKETS, "OSPF_auth: lower sequence number (rcv %d, old %d)", rcv_csn, n->csn);
+ return 0;
+ }
+
+ n->csn = rcv_csn;
}
MD5Init(&ctxt);