charon-nm: Support reauthentication and redirection

This commit is contained in:
Tobias Brunner
2020-02-14 13:55:42 +01:00
parent 4373a59bf5
commit 3d2f5ae003
+60 -47
View File
@@ -248,77 +248,88 @@ static void signal_failure(NMVpnServicePlugin *plugin, NMVpnPluginFailure failur
nm_vpn_service_plugin_failure(plugin, failure); nm_vpn_service_plugin_failure(plugin, failure);
} }
/** METHOD(listener_t, ike_state_change, bool,
* Implementation of listener_t.ike_state_change NMStrongswanPluginPrivate *this, ike_sa_t *ike_sa, ike_sa_state_t state)
*/
static bool ike_state_change(listener_t *listener, ike_sa_t *ike_sa,
ike_sa_state_t state)
{ {
NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener; if (this->ike_sa == ike_sa && state == IKE_DESTROYING)
if (private->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 FALSE;
} }
return TRUE; return TRUE;
} }
/** METHOD(listener_t, child_state_change, bool,
* Implementation of listener_t.child_state_change NMStrongswanPluginPrivate *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
*/ child_sa_state_t state)
static bool child_state_change(listener_t *listener, ike_sa_t *ike_sa,
child_sa_t *child_sa, child_sa_state_t state)
{ {
NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener; if (this->ike_sa == ike_sa && state == CHILD_DESTROYING)
if (private->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 FALSE;
} }
return TRUE; return TRUE;
} }
/** METHOD(listener_t, ike_rekey, bool,
* Implementation of listener_t.child_updown NMStrongswanPluginPrivate *this, ike_sa_t *old, ike_sa_t *new)
*/
static bool child_updown(listener_t *listener, ike_sa_t *ike_sa,
child_sa_t *child_sa, bool up)
{ {
NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener; if (this->ike_sa == old)
{ /* follow a rekeyed IKE_SA */
this->ike_sa = new;
}
return TRUE;
}
if (private->ike_sa == ike_sa) 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;
}
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) if (up)
{ /* disable initiate-failure-detection hooks */ { /* disable initiate-failure-detection hooks */
private->listener.ike_state_change = NULL; this->listener.ike_state_change = NULL;
private->listener.child_state_change = NULL; this->listener.child_state_change = NULL;
signal_ip_config(private->plugin, ike_sa, child_sa); signal_ip_config(this->plugin, ike_sa, child_sa);
} }
else 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 FALSE;
} }
} }
return TRUE; 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 * 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 * Register listener, enable initiate-failure-detection hooks
*/ */
priv->ike_sa = ike_sa; priv->ike_sa = ike_sa;
priv->listener.ike_state_change = ike_state_change; priv->listener.ike_state_change = _ike_state_change;
priv->listener.child_state_change = child_state_change; priv->listener.child_state_change = _child_state_change;
charon->bus->add_listener(charon->bus, &priv->listener); 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 = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin);
priv->plugin = NM_VPN_SERVICE_PLUGIN(plugin); priv->plugin = NM_VPN_SERVICE_PLUGIN(plugin);
memset(&priv->listener, 0, sizeof(listener_t)); memset(&priv->listener, 0, sizeof(listener_t));
priv->listener.child_updown = child_updown; priv->listener.child_updown = _child_updown;
priv->listener.ike_rekey = ike_rekey; 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; priv->name = NULL;
} }