From: Tobias Brunner Date: Tue, 29 Jun 2021 13:54:15 +0000 (+0200) Subject: ikev2: Only request reauth during IKE_AUTH if active reauth is not possible X-Git-Tag: 5.9.4dr2~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=23e46ea5ab5dea2980a5aa471788ffdd9bcb6e29;p=thirdparty%2Fstrongswan.git ikev2: Only request reauth during IKE_AUTH if active reauth is not possible If we can initiate the reauthentication ourselves, there is no reason to explicitly request the peer to do so (at basically the same time). --- diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 2ce5987773..ba59b052b5 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -1937,6 +1937,23 @@ METHOD(ike_sa_t, rekey, status_t, return this->task_manager->initiate(this->task_manager); } +/* + * Described in header + */ +bool ike_sa_can_reauthenticate(ike_sa_t *public) +{ + private_ike_sa_t *this = (private_ike_sa_t*)public; + + return array_count(this->other_vips) == 0 && + !has_condition(this, COND_XAUTH_AUTHENTICATED) && + !has_condition(this, COND_EAP_AUTHENTICATED) +#ifdef ME + /* as mediation server we too cannot reauth the IKE_SA */ + && !this->is_mediation_server +#endif /* ME */ + ; +} + METHOD(ike_sa_t, reauth, status_t, private_ike_sa_t *this) { @@ -1954,37 +1971,20 @@ METHOD(ike_sa_t, reauth, status_t, /* we can't reauthenticate as responder when we use EAP or virtual IPs. * If the peer does not support RFC4478, there is no way to keep the * IKE_SA up. */ - if (!has_condition(this, COND_ORIGINAL_INITIATOR)) + if (!has_condition(this, COND_ORIGINAL_INITIATOR) && + !ike_sa_can_reauthenticate(&this->public)) { - DBG1(DBG_IKE, "initiator did not reauthenticate as requested"); - if (array_count(this->other_vips) != 0 || - has_condition(this, COND_XAUTH_AUTHENTICATED) || - has_condition(this, COND_EAP_AUTHENTICATED) -#ifdef ME - /* as mediation server we too cannot reauth the IKE_SA */ - || this->is_mediation_server -#endif /* ME */ - ) - { - time_t del, now; + time_t del, now; - del = this->stats[STAT_DELETE]; - now = time_monotonic(NULL); - DBG1(DBG_IKE, "IKE_SA %s[%d] will timeout in %V", - get_name(this), this->unique_id, &now, &del); - return FAILED; - } - else - { - DBG0(DBG_IKE, "reauthenticating IKE_SA %s[%d] actively", - get_name(this), this->unique_id); - } - } - else - { - DBG0(DBG_IKE, "reauthenticating IKE_SA %s[%d]", - get_name(this), this->unique_id); + del = this->stats[STAT_DELETE]; + now = time_monotonic(NULL); + DBG1(DBG_IKE, "initiator did not reauthenticate as requested, IKE_SA " + "%s[%d] will timeout in %V", get_name(this), this->unique_id, + &now, &del); + return FAILED; } + DBG0(DBG_IKE, "reauthenticating IKE_SA %s[%d]", + get_name(this), this->unique_id); set_condition(this, COND_REAUTHENTICATING, TRUE); this->task_manager->queue_ike_reauth(this->task_manager); return this->task_manager->initiate(this->task_manager); diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index 3b8a0cd521..ada8e89b60 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -1243,4 +1243,12 @@ struct ike_sa_t { ike_sa_t *ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator, ike_version_t version); +/** + * Check if the given IKE_SA can be reauthenticated actively or if config + * parameters or the authentication method prevent it. + * + * @return TRUE if active reauthentication is possible + */ +bool ike_sa_can_reauthenticate(ike_sa_t *this); + #endif /** IKE_SA_H_ @}*/ diff --git a/src/libcharon/sa/ikev2/tasks/ike_auth_lifetime.c b/src/libcharon/sa/ikev2/tasks/ike_auth_lifetime.c index 495a353c57..6beaafe85c 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_auth_lifetime.c +++ b/src/libcharon/sa/ikev2/tasks/ike_auth_lifetime.c @@ -103,7 +103,10 @@ METHOD(task_t, build_r, status_t, if (message->get_exchange_type(message) == IKE_AUTH && this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED) { - add_auth_lifetime(this, message); + if (!ike_sa_can_reauthenticate(this->ike_sa)) + { + add_auth_lifetime(this, message); + } return SUCCESS; } return NEED_MORE; diff --git a/testing/tests/ikev2/reauth-early/description.txt b/testing/tests/ikev2/reauth-early/description.txt index 84ef91b0f0..791cd331a3 100644 --- a/testing/tests/ikev2/reauth-early/description.txt +++ b/testing/tests/ikev2/reauth-early/description.txt @@ -1,7 +1,8 @@ This scenario tests repeated authentication according to RFC 4478. The initiator carol sets a large reauth_time=60m but the responder moon defining a much shorter reauth_time=30s proposes this -value via an AUTH_LIFETIME notification to the initiator. Thus the +value via an AUTH_LIFETIME notification to the initiator as it can't initiate +the reauthentication itself due to the EAP authentication. Thus the IKE reauthentication takes places after less than 30s. A ping from carol to client alice hiding in the subnet behind moon tests if the CHILD_SA has been recreated under the new IKE_SA. diff --git a/testing/tests/ikev2/reauth-early/hosts/carol/etc/strongswan.conf b/testing/tests/ikev2/reauth-early/hosts/carol/etc/strongswan.conf index 7625e5066e..5cc6eb3f81 100644 --- a/testing/tests/ikev2/reauth-early/hosts/carol/etc/strongswan.conf +++ b/testing/tests/ikev2/reauth-early/hosts/carol/etc/strongswan.conf @@ -1,5 +1,5 @@ # /etc/strongswan.conf - strongSwan configuration file charon { - load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac vici kernel-netlink socket-default updown + load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac vici kernel-netlink socket-default updown md5 eap-tls } diff --git a/testing/tests/ikev2/reauth-early/hosts/carol/etc/swanctl/swanctl.conf b/testing/tests/ikev2/reauth-early/hosts/carol/etc/swanctl/swanctl.conf index 2b2c985124..3bb84d4394 100755 --- a/testing/tests/ikev2/reauth-early/hosts/carol/etc/swanctl/swanctl.conf +++ b/testing/tests/ikev2/reauth-early/hosts/carol/etc/swanctl/swanctl.conf @@ -9,12 +9,12 @@ connections { over_time = 10s local { - auth = pubkey + auth = eap-tls certs = carolCert.pem id = carol@strongswan.org } remote { - auth = pubkey + auth = eap-tls id = moon.strongswan.org } children { diff --git a/testing/tests/ikev2/reauth-early/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/reauth-early/hosts/moon/etc/strongswan.conf index 7625e5066e..5cc6eb3f81 100644 --- a/testing/tests/ikev2/reauth-early/hosts/moon/etc/strongswan.conf +++ b/testing/tests/ikev2/reauth-early/hosts/moon/etc/strongswan.conf @@ -1,5 +1,5 @@ # /etc/strongswan.conf - strongSwan configuration file charon { - load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac vici kernel-netlink socket-default updown + load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac vici kernel-netlink socket-default updown md5 eap-tls } diff --git a/testing/tests/ikev2/reauth-early/hosts/moon/etc/swanctl/swanctl.conf b/testing/tests/ikev2/reauth-early/hosts/moon/etc/swanctl/swanctl.conf index cd49a4b995..5aec9e9c91 100755 --- a/testing/tests/ikev2/reauth-early/hosts/moon/etc/swanctl/swanctl.conf +++ b/testing/tests/ikev2/reauth-early/hosts/moon/etc/swanctl/swanctl.conf @@ -9,12 +9,12 @@ connections { rand_time = 0 local { - auth = pubkey + auth = eap-tls certs = moonCert.pem id = moon.strongswan.org } remote { - auth = pubkey + auth = eap-tls } children { net { diff --git a/testing/tests/ikev2/reauth-late/description.txt b/testing/tests/ikev2/reauth-late/description.txt index 6d5ddc22ee..9a5e8184b8 100644 --- a/testing/tests/ikev2/reauth-late/description.txt +++ b/testing/tests/ikev2/reauth-late/description.txt @@ -1,7 +1,8 @@ This scenario tests repeated authentication according to RFC 4478. The initiator carol sets a short reauth_time=20s but the responder moon defining a much larger reauth_time=60m proposes this -value via an AUTH_LIFETIME notification to the initiator. The initiator +value via an AUTH_LIFETIME notification to the initiator as it can't initiate +the reauthentication itself due to the virtual IP address. The initiator ignores this notification and schedules the IKE reauthentication at its configured time. A ping from carol to client alice hiding in the subnet behind moon tests if the CHILD_SA has been diff --git a/testing/tests/ikev2/reauth-late/evaltest.dat b/testing/tests/ikev2/reauth-late/evaltest.dat index f6b7ea1303..e2b4a9f658 100644 --- a/testing/tests/ikev2/reauth-late/evaltest.dat +++ b/testing/tests/ikev2/reauth-late/evaltest.dat @@ -1,5 +1,5 @@ -moon:: swanctl --list-sas --ike-id 2 --raw 2> /dev/null::rw.*version=2 state=ESTABLISHED local-host=PH_IP_MOON local-port=4500 local-id=moon.strongswan.org remote-host=PH_IP_CAROL remote-port=4500 remote-id=carol@strongswan.org.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=CURVE_25519.*child-sas.*net.*reqid=1 state=INSTALLED mode=TUNNEL.*ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[10.1.0.0/16] remote-ts=\[192.168.0.100/32]::YES -carol::swanctl --list-sas --ike-id 2 --raw 2> /dev/null::home.*version=2 state=ESTABLISHED local-host=PH_IP_CAROL local-port=4500 local-id=carol@strongswan.org remote-host=PH_IP_MOON remote-port=4500 remote-id=moon.strongswan.org initiator=yes.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=CURVE_25519.*child-sas.*home.*state=INSTALLED mode=TUNNEL.*ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[192.168.0.100/32] remote-ts=\[10.1.0.0/16]::YES +moon:: swanctl --list-sas --ike-id 2 --raw 2> /dev/null::rw.*version=2 state=ESTABLISHED local-host=PH_IP_MOON local-port=4500 local-id=moon.strongswan.org remote-host=PH_IP_CAROL remote-port=4500 remote-id=carol@strongswan.org.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=CURVE_25519.*child-sas.*net.*reqid=1 state=INSTALLED mode=TUNNEL.*ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[10.1.0.0/16] remote-ts=\[10.3.0.1/32]::YES +carol::swanctl --list-sas --ike-id 2 --raw 2> /dev/null::home.*version=2 state=ESTABLISHED local-host=PH_IP_CAROL local-port=4500 local-id=carol@strongswan.org remote-host=PH_IP_MOON remote-port=4500 remote-id=moon.strongswan.org initiator=yes.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=CURVE_25519.*child-sas.*home.*state=INSTALLED mode=TUNNEL.*ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[10.3.0.1/32] remote-ts=\[10.1.0.0/16]::YES carol::cat /var/log/daemon.log::scheduling reauthentication in 20s::YES carol::cat /var/log/daemon.log::received AUTH_LIFETIME of 3600s, reauthentication already scheduled in 20s::YES carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_.eq=1::YES diff --git a/testing/tests/ikev2/reauth-late/hosts/carol/etc/swanctl/swanctl.conf b/testing/tests/ikev2/reauth-late/hosts/carol/etc/swanctl/swanctl.conf index 646468dc35..5bd7e4c438 100755 --- a/testing/tests/ikev2/reauth-late/hosts/carol/etc/swanctl/swanctl.conf +++ b/testing/tests/ikev2/reauth-late/hosts/carol/etc/swanctl/swanctl.conf @@ -4,6 +4,8 @@ connections { local_addrs = PH_IP_CAROL remote_addrs = PH_IP_MOON + vips = 0.0.0.0 + # short lifetimes for testing purposes reauth_time = 20s over_time = 10s diff --git a/testing/tests/ikev2/reauth-late/hosts/moon/etc/swanctl/swanctl.conf b/testing/tests/ikev2/reauth-late/hosts/moon/etc/swanctl/swanctl.conf index 0041568d25..65004fa20c 100755 --- a/testing/tests/ikev2/reauth-late/hosts/moon/etc/swanctl/swanctl.conf +++ b/testing/tests/ikev2/reauth-late/hosts/moon/etc/swanctl/swanctl.conf @@ -3,6 +3,8 @@ connections { rw { local_addrs = PH_IP_MOON + pools = rw + # short lifetimes for testing purposes reauth_time = 60m over_time = 10s @@ -28,3 +30,9 @@ connections { proposals = aes128-sha256-x25519 } } + +pools { + rw { + addrs = 10.3.0.0/24 + } +}