Commit 4727d1db authored by Ondrej Zajicek (work)'s avatar Ondrej Zajicek (work)
Browse files

OSPF: Support of authentication trailer for OSPFv3

Implement RFC 7166, crypthographic authentication for OSPFv3
analogous to authentication used for OSPFv2.
parent f3a8cf05
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ ospf_iface_finish(void)

  ip->passwords = get_passwords();

  if ((ip->autype == OSPF_AUTH_CRYPT) && (ip->helloint < 5))
  if (ospf_cfg_is_v2() && (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))
@@ -54,6 +54,9 @@ ospf_iface_finish(void)
      /* Set default OSPF crypto algorithms */
      if (!pass->alg && (ip->autype == OSPF_AUTH_CRYPT))
	pass->alg = ospf_cfg_is_v2() ? ALG_MD5 : ALG_HMAC_SHA256;

      if (ospf_cfg_is_v3() && ip->autype && (pass->alg < ALG_HMAC))
	cf_error("Keyed hash algorithms are not allowed, use HMAC algorithms");
    }
  }
}
@@ -181,7 +184,7 @@ static inline void
ospf_check_auth(void)
{
  if (ospf_cfg_is_v3())
    cf_error("Authentication not supported in OSPFv3");
    cf_error("Plaintext authentication not supported in OSPFv3");
}


@@ -346,8 +349,8 @@ ospf_vlink_item:
 | DEAD COUNT expr { OSPF_PATT->deadc = $3 ; if ($3<=1) cf_error("Dead count must be greater than one"); }
 | AUTHENTICATION NONE { OSPF_PATT->autype = OSPF_AUTH_NONE;  }
 | AUTHENTICATION SIMPLE { OSPF_PATT->autype = OSPF_AUTH_SIMPLE; ospf_check_auth(); }
 | AUTHENTICATION CRYPTOGRAPHIC { OSPF_PATT->autype = OSPF_AUTH_CRYPT; ospf_check_auth(); }
 | password_list { ospf_check_auth(); }
 | AUTHENTICATION CRYPTOGRAPHIC { OSPF_PATT->autype = OSPF_AUTH_CRYPT; }
 | password_list
 ;

ospf_vlink_start: VIRTUAL LINK idval
@@ -396,7 +399,7 @@ ospf_iface_item:
 | NEIGHBORS '{' nbma_list '}'
 | AUTHENTICATION NONE { OSPF_PATT->autype = OSPF_AUTH_NONE; }
 | AUTHENTICATION SIMPLE { OSPF_PATT->autype = OSPF_AUTH_SIMPLE; ospf_check_auth(); }
 | AUTHENTICATION CRYPTOGRAPHIC { OSPF_PATT->autype = OSPF_AUTH_CRYPT; ospf_check_auth(); }
 | AUTHENTICATION CRYPTOGRAPHIC { OSPF_PATT->autype = OSPF_AUTH_CRYPT; }
 | RX BUFFER NORMAL { OSPF_PATT->rx_buffer = 0; }
 | RX BUFFER LARGE { OSPF_PATT->rx_buffer = OSPF_MAX_PKT_SIZE; }
 | RX BUFFER expr { OSPF_PATT->rx_buffer = $3; if (($3 < OSPF_MIN_PKT_SIZE) || ($3 > OSPF_MAX_PKT_SIZE)) cf_error("Buffer size must be in range 256-65535"); }
@@ -406,7 +409,7 @@ ospf_iface_item:
 | TTL SECURITY bool { OSPF_PATT->ttl_security = $3; }
 | TTL SECURITY TX ONLY { OSPF_PATT->ttl_security = 2; }
 | BFD bool { OSPF_PATT->bfd = $2; cf_check_bfd($2); }
 | password_list { ospf_check_auth(); }
 | password_list
 ;

pref_list:
+9 −3
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
struct ospf_dbdes2_packet
{
  struct ospf_packet hdr;
  union ospf_auth auth;
  union ospf_auth2 auth;

  u16 iface_mtu;
  u8 options;
@@ -38,6 +38,13 @@ struct ospf_dbdes3_packet
};


uint
ospf_dbdes3_options(struct ospf_packet *pkt)
{
  struct ospf_dbdes3_packet *ps = (void *) pkt;
  return ntohl(ps->options);
}

static inline uint
ospf_dbdes_hdrlen(struct ospf_proto *p)
{
@@ -45,7 +52,6 @@ ospf_dbdes_hdrlen(struct ospf_proto *p)
    sizeof(struct ospf_dbdes2_packet) : sizeof(struct ospf_dbdes3_packet);
}


static void
ospf_dbdes_body(struct ospf_proto *p, struct ospf_packet *pkt,
		struct ospf_lsa_header **body, uint *count)
@@ -129,7 +135,7 @@ ospf_prepare_dbdes(struct ospf_proto *p, struct ospf_neighbor *n)
  else /* OSPFv3 */
  {
    struct ospf_dbdes3_packet *ps = (void *) pkt;
    ps->options = htonl(ifa->oa->options);
    ps->options = htonl(ifa->oa->options | (ifa->autype == OSPF_AUTH_CRYPT ? OPT_AT : 0));
    ps->iface_mtu = htons(iface_mtu);
    ps->padding = 0;
    ps->imms = 0;	/* Will be set later */
+10 −3
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
struct ospf_hello2_packet
{
  struct ospf_packet hdr;
  union ospf_auth auth;
  union ospf_auth2 auth;

  u32 netmask;
  u16 helloint;
@@ -42,6 +42,13 @@ struct ospf_hello3_packet
};


uint
ospf_hello3_options(struct ospf_packet *pkt)
{
  struct ospf_hello3_packet *ps = (void *) pkt;
  return ntohl(ps->options) & 0x00FFFFFF;
}

void
ospf_send_hello(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn)
{
@@ -86,9 +93,10 @@ ospf_send_hello(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn)
  else
  {
    struct ospf_hello3_packet *ps = (void *) pkt;
    u32 options = ifa->oa->options | (ifa->autype == OSPF_AUTH_CRYPT ? OPT_AT : 0);

    ps->iface_id = htonl(ifa->iface_id);
    ps->options = ntohl(ifa->oa->options | (ifa->priority << 24));
    ps->options = ntohl(options | (ifa->priority << 24));
    ps->helloint = ntohs(ifa->helloint);
    ps->deadint = htons(ifa->deadint);
    ps->dr = htonl(ifa->drid);
@@ -334,7 +342,6 @@ ospf_receive_hello(struct ospf_packet *pkt, struct ospf_iface *ifa,
  n->priority = rcv_priority;
  n->iface_id = rcv_iface_id;


  /* Update inactivity timer */
  ospf_neigh_sm(n, INM_HELLOREC);

+12 −1
Original line number Diff line number Diff line
@@ -61,7 +61,10 @@ ifa_tx_hdrlen(struct ospf_iface *ifa)

  /* Relevant just for OSPFv2 */
  if (ifa->autype == OSPF_AUTH_CRYPT)
  {
    hlen += ospf_is_v2(p) ? 0 : sizeof(struct ospf_auth3);
    hlen += max_mac_length(ifa->passwords);
  }

  return hlen;
}
@@ -137,7 +140,7 @@ ospf_sk_open(struct ospf_iface *ifa)
    goto err;

  /* 12 is an offset of the checksum in an OSPFv3 packet */
  if (ospf_is_v3(p))
  if (ospf_is_v3(p) && !ifa->autype)
    if (sk_set_ipv6_checksum(sk, 12) < 0)
      goto err;

@@ -828,6 +831,14 @@ ospf_iface_reconfigure(struct ospf_iface *ifa, struct ospf_iface_patt *new)
  {
    OSPF_TRACE(D_EVENTS, "Changing authentication type of %s", ifname);
    ifa->autype = new->autype;

    /* For OSPFv3, we need to update checksum calculation by OS */
    if (ospf_is_v3(p) && ifa->sk)
      if (sk_set_ipv6_checksum(ifa->sk, ifa->autype ? -1 : 12) < 0)
      {
	sk_log_error(ifa->sk, p->p.name);
	return 0;
      }
  }

  /* Update passwords */
+0 −2
Original line number Diff line number Diff line
@@ -84,8 +84,6 @@ ospf_neighbor_new(struct ospf_iface *ifa)
  n->pool = pool;
  n->ifa = ifa;
  add_tail(&ifa->neigh_list, NODE n);
  n->adj = 0;
  n->csn = 0;
  n->state = NEIGHBOR_DOWN;

  init_lists(p, n);
Loading