From: Tobias Brunner Date: Thu, 6 Feb 2020 16:36:46 +0000 (+0100) Subject: charon-nm: Support reauthentication and redirection X-Git-Tag: 5.8.3dr1~11^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3d2f5ae0035246d0882a63a2b8d4535ee8ca89fe;p=thirdparty%2Fstrongswan.git charon-nm: Support reauthentication and redirection --- diff --git a/src/charon-nm/nm/nm_service.c b/src/charon-nm/nm/nm_service.c index b096ad0ef5..2f8206d85a 100644 --- a/src/charon-nm/nm/nm_service.c +++ b/src/charon-nm/nm/nm_service.c @@ -248,77 +248,88 @@ static void signal_failure(NMVpnServicePlugin *plugin, NMVpnPluginFailure failur nm_vpn_service_plugin_failure(plugin, failure); } -/** - * Implementation of listener_t.ike_state_change - */ -static bool ike_state_change(listener_t *listener, ike_sa_t *ike_sa, - ike_sa_state_t state) +METHOD(listener_t, ike_state_change, bool, + NMStrongswanPluginPrivate *this, ike_sa_t *ike_sa, ike_sa_state_t state) { - NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener; - - if (private->ike_sa == ike_sa && state == IKE_DESTROYING) + if (this->ike_sa == ike_sa && state == IKE_DESTROYING) { - signal_failure(private->plugin, NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED); + signal_failure(this->plugin, NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED); return FALSE; } return TRUE; } -/** - * Implementation of listener_t.child_state_change - */ -static bool child_state_change(listener_t *listener, ike_sa_t *ike_sa, - child_sa_t *child_sa, child_sa_state_t state) +METHOD(listener_t, child_state_change, bool, + NMStrongswanPluginPrivate *this, ike_sa_t *ike_sa, child_sa_t *child_sa, + child_sa_state_t state) { - NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener; - - if (private->ike_sa == ike_sa && state == CHILD_DESTROYING) + if (this->ike_sa == ike_sa && state == CHILD_DESTROYING) { - signal_failure(private->plugin, NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED); + signal_failure(this->plugin, NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED); return FALSE; } return TRUE; } -/** - * Implementation of listener_t.child_updown - */ -static bool child_updown(listener_t *listener, ike_sa_t *ike_sa, - child_sa_t *child_sa, bool up) +METHOD(listener_t, ike_rekey, bool, + NMStrongswanPluginPrivate *this, ike_sa_t *old, ike_sa_t *new) { - NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener; + if (this->ike_sa == old) + { /* follow a rekeyed IKE_SA */ + this->ike_sa = new; + } + return TRUE; +} + +METHOD(listener_t, ike_reestablish_pre, bool, + NMStrongswanPluginPrivate *this, ike_sa_t *old, ike_sa_t *new) +{ + if (this->ike_sa == old) + { /* ignore child state changes during redirects etc. (task migration) */ + this->listener.child_state_change = NULL; + } + return TRUE; +} - if (private->ike_sa == ike_sa) +METHOD(listener_t, ike_reestablish_post, bool, + NMStrongswanPluginPrivate *this, ike_sa_t *old, ike_sa_t *new, + bool initiated) +{ + if (this->ike_sa == old && initiated) + { /* if we get redirected during IKE_AUTH we just migrate to the new SA */ + this->ike_sa = new; + /* re-register hooks to detect initiation failures */ + this->listener.ike_state_change = _ike_state_change; + this->listener.child_state_change = _child_state_change; + } + return TRUE; +} + +METHOD(listener_t, child_updown, bool, + NMStrongswanPluginPrivate *this, ike_sa_t *ike_sa, child_sa_t *child_sa, + bool up) +{ + if (this->ike_sa == ike_sa) { if (up) { /* disable initiate-failure-detection hooks */ - private->listener.ike_state_change = NULL; - private->listener.child_state_change = NULL; - signal_ip_config(private->plugin, ike_sa, child_sa); + this->listener.ike_state_change = NULL; + this->listener.child_state_change = NULL; + signal_ip_config(this->plugin, ike_sa, child_sa); } else { - signal_failure(private->plugin, NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED); + if (ike_sa->has_condition(ike_sa, COND_REAUTHENTICATING)) + { /* we ignore this during reauthentication */ + return TRUE; + } + signal_failure(this->plugin, NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED); return FALSE; } } return TRUE; } -/** - * Implementation of listener_t.ike_rekey - */ -static bool ike_rekey(listener_t *listener, ike_sa_t *old, ike_sa_t *new) -{ - NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener; - - if (private->ike_sa == old) - { /* follow a rekeyed IKE_SA */ - private->ike_sa = new; - } - return TRUE; -} - /** * Find a certificate for which we have a private key on a smartcard */ @@ -827,8 +838,8 @@ static gboolean connect_(NMVpnServicePlugin *plugin, NMConnection *connection, * Register listener, enable initiate-failure-detection hooks */ priv->ike_sa = ike_sa; - priv->listener.ike_state_change = ike_state_change; - priv->listener.child_state_change = child_state_change; + priv->listener.ike_state_change = _ike_state_change; + priv->listener.child_state_change = _child_state_change; charon->bus->add_listener(charon->bus, &priv->listener); /** @@ -968,8 +979,10 @@ static void nm_strongswan_plugin_init(NMStrongswanPlugin *plugin) priv = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin); priv->plugin = NM_VPN_SERVICE_PLUGIN(plugin); memset(&priv->listener, 0, sizeof(listener_t)); - priv->listener.child_updown = child_updown; - priv->listener.ike_rekey = ike_rekey; + priv->listener.child_updown = _child_updown; + priv->listener.ike_rekey = _ike_rekey; + priv->listener.ike_reestablish_pre = _ike_reestablish_pre; + priv->listener.ike_reestablish_post = _ike_reestablish_post; priv->name = NULL; }