diff options
author | Benoît Ganne <bganne@cisco.com> | 2021-09-28 11:19:37 +0200 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2021-10-07 15:22:17 +0000 |
commit | c7cceeebb738b0fabd93d2c4fdfd561321a2be1d (patch) | |
tree | 9354d34746b90795bd690cbba7ea637967106de0 /src/plugins/ikev2 | |
parent | b37342c5a7c907e24ab34ab979338cac3b1dfe59 (diff) |
ikev2: do not require optional IDr on IKE AUTH
IDr is optional in IKE AUTH from the initiator. In that case, the
responder is free to use any matching profile and fills the
corresponding IDr in the response.
The initiator is then free to accept or reject it.
Type: improvement
Change-Id: I07a1c64a40ed22bd41767c259406238bbbab5cf4
Signed-off-by: Benoît Ganne <bganne@cisco.com>
Diffstat (limited to 'src/plugins/ikev2')
-rw-r--r-- | src/plugins/ikev2/ikev2.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/src/plugins/ikev2/ikev2.c b/src/plugins/ikev2/ikev2.c index 873ec136dae..c184a466c47 100644 --- a/src/plugins/ikev2/ikev2.c +++ b/src/plugins/ikev2/ikev2.c @@ -1050,7 +1050,7 @@ ikev2_decrypt_sk_payload (ikev2_sa_t * sa, ike_header_t * ike, } static int -ikev2_is_id_equal (ikev2_id_t *i1, ikev2_id_t *i2) +ikev2_is_id_equal (const ikev2_id_t *i1, const ikev2_id_t *i2) { if (i1->type != i2->type) return 0; @@ -1572,6 +1572,25 @@ ikev2_sa_generate_authmsg (ikev2_sa_t * sa, int is_responder) } static int +ikev2_match_profile (const ikev2_profile_t *p, const ikev2_id_t *id_loc, + const ikev2_id_t *id_rem, int is_initiator) +{ + /* on the initiator, IDi is always present and must match + * however on the responder, IDr (which is our local id) is optional */ + if ((is_initiator || id_loc->type != 0) && + !ikev2_is_id_equal (&p->loc_id, id_loc)) + return 0; + + /* on the initiator, we might not have configured a specific remote id + * however on the responder, the remote id should always be configured */ + if ((!is_initiator || p->rem_id.type != 0) && + !ikev2_is_id_equal (&p->rem_id, id_rem)) + return 0; + + return 1; +} + +static int ikev2_ts_cmp (ikev2_ts_t * ts1, ikev2_ts_t * ts2) { if (ts1->ts_type == ts2->ts_type && ts1->protocol_id == ts2->protocol_id && @@ -1609,9 +1628,7 @@ ikev2_sa_match_ts (ikev2_sa_t * sa) id_loc = &sa->r_id; } - /* check id */ - if (!ikev2_is_id_equal (&p->rem_id, id_rem) - || !ikev2_is_id_equal (&p->loc_id, id_loc)) + if (!ikev2_match_profile (p, id_loc, id_rem, sa->is_initiator)) continue; sa->profile_index = p - km->profiles; @@ -1679,9 +1696,7 @@ ikev2_select_profile (ikev2_main_t *km, ikev2_sa_t *sa, pool_foreach (p, km->profiles) { - /* check id */ - if (!ikev2_is_id_equal (&p->rem_id, id_rem) || - !ikev2_is_id_equal (&p->loc_id, id_loc)) + if (!ikev2_match_profile (p, id_loc, id_rem, sa->is_initiator)) continue; if (sa_auth->method == IKEV2_AUTH_METHOD_SHARED_KEY_MIC) @@ -2444,7 +2459,10 @@ ikev2_generate_message (vlib_buffer_t *b, ikev2_sa_t *sa, ike_header_t *ike, else if (sa->state == IKEV2_STATE_SA_INIT) { ikev2_payload_add_id (chain, &sa->i_id, IKEV2_PAYLOAD_IDI); - ikev2_payload_add_id (chain, &sa->r_id, IKEV2_PAYLOAD_IDR); + /* IDr is optional when sending INIT from the initiator */ + ASSERT (sa->r_id.type != 0 || sa->is_initiator); + if (sa->r_id.type != 0) + ikev2_payload_add_id (chain, &sa->r_id, IKEV2_PAYLOAD_IDR); ikev2_payload_add_auth (chain, &sa->i_auth); ikev2_payload_add_sa (chain, sa->childs[0].i_proposals); ikev2_payload_add_ts (chain, sa->childs[0].tsi, IKEV2_PAYLOAD_TSI); |