core: merge branch 'th/cancel-get-secrets-bgo776168'

https://bugzilla.gnome.org/show_bug.cgi?id=776168
This commit is contained in:
Thomas Haller 2016-12-20 15:54:43 +01:00
commit c75c77d757
6 changed files with 162 additions and 43 deletions

View file

@ -108,6 +108,8 @@ typedef struct _NMDeviceEthernetPrivate {
char * s390_nettype;
GHashTable * s390_options;
NMActRequestGetSecretsCallId wired_secrets_id;
/* PPPoE */
NMPPPManager *ppp_manager;
NMIP4Config *pending_ip4_config;
@ -133,6 +135,10 @@ G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE)
/*****************************************************************************/
static void wired_secrets_cancel (NMDeviceEthernet *self);
/*****************************************************************************/
static char *
get_link_basename (const char *parent_path, const char *name, GError **error)
{
@ -285,6 +291,9 @@ device_state_changed (NMDevice *device,
NMDeviceState old_state,
NMDeviceStateReason reason)
{
if (new_state > NM_DEVICE_STATE_ACTIVATED)
wired_secrets_cancel (NM_DEVICE_ETHERNET (device));
if ( new_state == NM_DEVICE_STATE_ACTIVATED
|| new_state == NM_DEVICE_STATE_FAILED
|| new_state == NM_DEVICE_STATE_DISCONNECTED)
@ -459,22 +468,66 @@ wired_secrets_cb (NMActRequest *req,
GError *error,
gpointer user_data)
{
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data);
NMDevice *dev = NM_DEVICE (self);
NMDeviceEthernet *self = user_data;
NMDevice *device = user_data;
NMDeviceEthernetPrivate *priv;
if (req != nm_device_get_act_request (dev))
g_return_if_fail (NM_IS_DEVICE_ETHERNET (self));
g_return_if_fail (NM_IS_ACT_REQUEST (req));
priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
g_return_if_fail (priv->wired_secrets_id == call_id);
priv->wired_secrets_id = NULL;
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH);
g_return_if_fail (req == nm_device_get_act_request (device));
g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH);
g_return_if_fail (nm_act_request_get_settings_connection (req) == connection);
if (error) {
_LOGW (LOGD_ETHER, "%s", error->message);
nm_device_state_changed (dev,
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_NO_SECRETS);
} else
nm_device_activate_schedule_stage1_device_prepare (dev);
nm_device_activate_schedule_stage1_device_prepare (device);
}
static void
wired_secrets_cancel (NMDeviceEthernet *self)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
if (priv->wired_secrets_id)
nm_act_request_cancel_secrets (NULL, priv->wired_secrets_id);
nm_assert (!priv->wired_secrets_id);
}
static void
wired_secrets_get_secrets (NMDeviceEthernet *self,
const char *setting_name,
NMSecretAgentGetSecretsFlags flags)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
NMActRequest *req;
wired_secrets_cancel (self);
req = nm_device_get_act_request (NM_DEVICE (self));
g_return_if_fail (NM_IS_ACT_REQUEST (req));
priv->wired_secrets_id = nm_act_request_get_secrets (req,
TRUE,
setting_name,
flags,
NULL,
wired_secrets_cb,
self);
g_return_if_fail (priv->wired_secrets_id);
}
static gboolean
@ -517,12 +570,7 @@ link_timeout_cb (gpointer user_data)
supplicant_interface_release (self);
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
nm_act_request_get_secrets (req,
setting_name,
NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW,
NULL,
wired_secrets_cb,
self);
wired_secrets_get_secrets (self, setting_name, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW);
return FALSE;
@ -698,12 +746,9 @@ handle_auth_or_fail (NMDeviceEthernet *self,
setting_name = nm_connection_need_secrets (applied_connection, NULL);
if (setting_name) {
NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION;
if (new_secrets)
flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
nm_act_request_get_secrets (req, setting_name, flags, NULL, wired_secrets_cb, self);
wired_secrets_get_secrets (self, setting_name,
NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION
| (new_secrets ? NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW : 0));
g_object_set_data (G_OBJECT (applied_connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
} else
_LOGI (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets.");
@ -1656,6 +1701,8 @@ dispose (GObject *object)
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object);
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
wired_secrets_cancel (self);
supplicant_interface_release (self);
nm_clear_g_source (&priv->pppoe_wait_id);
@ -1706,7 +1753,7 @@ get_property (GObject *object, guint prop_id,
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
const GValue *value, GParamSpec *pspec)
{
switch (prop_id) {
default:

View file

@ -108,6 +108,8 @@ typedef struct {
NM80211Mode mode;
NMActRequestGetSecretsCallId wifi_secrets_id;
guint periodic_source_id;
guint link_timeout_id;
guint32 failed_iface_count;
@ -1738,12 +1740,23 @@ wifi_secrets_cb (NMActRequest *req,
GError *error,
gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
NMDeviceWifi *self = NM_DEVICE_WIFI (device);
NMDevice *device = user_data;
NMDeviceWifi *self = user_data;
NMDeviceWifiPrivate *priv;
if (req != nm_device_get_act_request (device))
g_return_if_fail (NM_IS_DEVICE_WIFI (self));
g_return_if_fail (NM_IS_ACT_REQUEST (req));
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
g_return_if_fail (priv->wifi_secrets_id == call_id);
priv->wifi_secrets_id = NULL;
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
g_return_if_fail (req == nm_device_get_act_request (device));
g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH);
g_return_if_fail (nm_act_request_get_settings_connection (req) == connection);
@ -1756,6 +1769,39 @@ wifi_secrets_cb (NMActRequest *req,
nm_device_activate_schedule_stage1_device_prepare (device);
}
static void
wifi_secrets_cancel (NMDeviceWifi *self)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
if (priv->wifi_secrets_id)
nm_act_request_cancel_secrets (NULL, priv->wifi_secrets_id);
nm_assert (!priv->wifi_secrets_id);
}
static void
wifi_secrets_get_secrets (NMDeviceWifi *self,
const char *setting_name,
NMSecretAgentGetSecretsFlags flags)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
NMActRequest *req;
wifi_secrets_cancel (self);
req = nm_device_get_act_request (NM_DEVICE (self));
g_return_if_fail (NM_IS_ACT_REQUEST (req));
priv->wifi_secrets_id = nm_act_request_get_secrets (req,
TRUE,
setting_name,
flags,
NULL,
wifi_secrets_cb,
self);
g_return_if_fail (priv->wifi_secrets_id);
}
/*
* link_timeout_cb
*
@ -1900,13 +1946,10 @@ handle_8021x_or_psk_auth_fail (NMDeviceWifi *self,
cleanup_association_attempt (self, TRUE);
nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
nm_act_request_get_secrets (req,
setting_name,
NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION
| NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW,
NULL,
wifi_secrets_cb,
self);
wifi_secrets_get_secrets (self,
setting_name,
NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION
| NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW);
handled = TRUE;
}
@ -2171,7 +2214,7 @@ handle_auth_or_fail (NMDeviceWifi *self,
if (!req) {
req = nm_device_get_act_request (NM_DEVICE (self));
g_assert (req);
g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE);
}
applied_connection = nm_act_request_get_applied_connection (req);
@ -2185,12 +2228,9 @@ handle_auth_or_fail (NMDeviceWifi *self,
nm_act_request_clear_secrets (req);
setting_name = nm_connection_need_secrets (applied_connection, NULL);
if (setting_name) {
NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION;
if (new_secrets)
flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
nm_act_request_get_secrets (req, setting_name, flags, NULL, wifi_secrets_cb, self);
wifi_secrets_get_secrets (self, setting_name,
NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION
| (new_secrets ? NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW : 0));
g_object_set_data (G_OBJECT (applied_connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
ret = NM_ACT_STAGE_RETURN_POSTPONE;
} else
@ -2878,6 +2918,9 @@ device_state_changed (NMDevice *device,
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
gboolean clear_aps = FALSE;
if (new_state > NM_DEVICE_STATE_ACTIVATED)
wifi_secrets_cancel (self);
if (new_state <= NM_DEVICE_STATE_UNAVAILABLE) {
/* Clean up the supplicant interface because in these states the
* device cannot be used.
@ -3028,6 +3071,8 @@ dispose (GObject *object)
nm_clear_g_source (&priv->periodic_source_id);
wifi_secrets_cancel (self);
cleanup_association_attempt (self, TRUE);
supplicant_interface_release (self);
cleanup_supplicant_failures (self);
@ -3150,7 +3195,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
klass->scanning_allowed = scanning_allowed;
/* Properties */
obj_properties[PROP_MODE] =
g_param_spec_uint (NM_DEVICE_WIFI_MODE, "", "",
NM_802_11_MODE_UNKNOWN,
@ -3192,7 +3236,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
/* Signals */
signals[ACCESS_POINT_ADDED] =
g_signal_new (NM_DEVICE_WIFI_ACCESS_POINT_ADDED,
G_OBJECT_CLASS_TYPE (object_class),

View file

@ -820,6 +820,7 @@ nm_modem_get_secrets (NMModem *self,
if (request_new)
flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
priv->secrets_id = nm_act_request_get_secrets (priv->act_request,
FALSE,
setting_name,
flags,
hint,
@ -870,6 +871,7 @@ nm_modem_act_stage1_prepare (NMModem *self,
flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
priv->secrets_id = nm_act_request_get_secrets (req,
FALSE,
setting_name,
flags,
hints ? g_ptr_array_index (hints, 0) : NULL,

View file

@ -94,17 +94,19 @@ struct _NMActRequestGetSecretsCallId {
NMActRequestSecretsFunc callback;
gpointer callback_data;
NMSettingsConnectionCallId call_id;
bool has_ref;
};
typedef struct _NMActRequestGetSecretsCallId GetSecretsInfo;
static GetSecretsInfo *
_get_secrets_info_new (NMActRequest *self, NMActRequestSecretsFunc callback, gpointer callback_data)
_get_secrets_info_new (NMActRequest *self, gboolean ref_self, NMActRequestSecretsFunc callback, gpointer callback_data)
{
GetSecretsInfo *info;
info = g_slice_new0 (GetSecretsInfo);
info->self = self;
info->has_ref = ref_self;
info->self = ref_self ? g_object_ref (self) : self;
info->callback = callback;
info->callback_data = callback_data;
@ -114,6 +116,8 @@ _get_secrets_info_new (NMActRequest *self, NMActRequestSecretsFunc callback, gpo
static void
_get_secrets_info_free (GetSecretsInfo *info)
{
if (info->has_ref)
g_object_unref (info->self);
g_slice_free (GetSecretsInfo, info);
}
@ -149,6 +153,8 @@ get_secrets_cb (NMSettingsConnection *connection,
/**
* nm_act_request_get_secrets:
* @self:
* @ref_self: if %TRUE, the pending call take a reference on @self.
* It also allows you to omit the @self argument in nm_act_request_cancel_secrets().
* @setting_name:
* @flags:
* @hint:
@ -167,6 +173,7 @@ get_secrets_cb (NMSettingsConnection *connection,
*/
NMActRequestGetSecretsCallId
nm_act_request_get_secrets (NMActRequest *self,
gboolean ref_self,
const char *setting_name,
NMSecretAgentGetSecretsFlags flags,
const char *hint,
@ -180,14 +187,14 @@ nm_act_request_get_secrets (NMActRequest *self,
NMConnection *applied_connection;
const char *hints[2] = { hint, NULL };
g_return_val_if_fail (NM_IS_ACT_REQUEST (self), 0);
g_return_val_if_fail (NM_IS_ACT_REQUEST (self), NULL);
priv = NM_ACT_REQUEST_GET_PRIVATE (self);
settings_connection = nm_act_request_get_settings_connection (self);
applied_connection = nm_act_request_get_applied_connection (self);
info = _get_secrets_info_new (self, callback, callback_data);
info = _get_secrets_info_new (self, ref_self, callback, callback_data);
priv->secrets_calls = g_slist_append (priv->secrets_calls, info);
@ -229,14 +236,32 @@ _do_cancel_secrets (NMActRequest *self, GetSecretsInfo *info, gboolean is_dispos
_get_secrets_info_free (info);
}
/**
* nm_act_request_cancel_secrets:
* @self: The #NMActRequest. Note that this argument can be %NULL if, and only if
* the call_id was created with @take_ref.
* @call_id:
*
* You are only allowed to cancel the call once, and only before the callback
* is already invoked. Note that cancelling causes the callback to be invoked
* synchronously.
*/
void
nm_act_request_cancel_secrets (NMActRequest *self, NMActRequestGetSecretsCallId call_id)
{
NMActRequestPrivate *priv;
g_return_if_fail (NM_IS_ACT_REQUEST (self));
g_return_if_fail (call_id);
if (self) {
g_return_if_fail (NM_IS_ACT_REQUEST (self));
g_return_if_fail (self == call_id->self);
} else {
g_return_if_fail (call_id->has_ref);
g_return_if_fail (NM_IS_ACT_REQUEST (call_id->self));
self = call_id->self;
}
priv = NM_ACT_REQUEST_GET_PRIVATE (self);
if (!g_slist_find (priv->secrets_calls, call_id))

View file

@ -63,6 +63,7 @@ typedef void (*NMActRequestSecretsFunc) (NMActRequest *req,
gpointer user_data);
NMActRequestGetSecretsCallId nm_act_request_get_secrets (NMActRequest *req,
gboolean take_ref,
const char *setting_name,
NMSecretAgentGetSecretsFlags flags,
const char *hint,

View file

@ -346,6 +346,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager,
flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
priv->secrets_id = nm_act_request_get_secrets (priv->act_req,
FALSE,
priv->secrets_setting_name,
flags,
hints ? g_ptr_array_index (hints, 0) : NULL,