core: simplify secrets handling during activation

Instead of a bizare mechanism of signals back to the manager
object that used to be required because of the user/system settings
split, let each place that needs secrets request those secrets
itself.  This flattens the secrets request process a ton and
the code flow significantly.

Previously the get secrets flow was something like this:

nm_act_request_get_secrets ()
    nm_secrets_provider_interface_get_secrets ()
        emits manager-get-secrets signal
            provider_get_secerts ()
                system_get_secrets ()
                    system_get_secrets_idle_cb ()
                        nm_sysconfig_connection_get_secrets ()
                            system_get_secrets_reply_cb ()
                                nm_secrets_provider_interface_get_secrets_result ()
                                    signal failure or success

now instead we do something like this:

nm_agent_manager_get_secrets ()
    nm_agent_manager_get_secrets ()
        request_start_secrets ()
            nm_sysconfig_connection_get_secrets ()
                return failure or success to callback
This commit is contained in:
Dan Williams 2010-12-13 13:11:51 -06:00
parent 58088129f7
commit 62a2c34e27
21 changed files with 1036 additions and 1371 deletions

View file

@ -116,8 +116,6 @@ NetworkManager_SOURCES = \
nm-ip4-config.h \
nm-ip6-config.c \
nm-ip6-config.h \
nm-secrets-provider-interface.c \
nm-secrets-provider-interface.h \
nm-active-connection.h \
nm-active-connection.c \
main.c \

View file

@ -177,12 +177,10 @@ ask_for_pin (NMModemGsm *self, gboolean always_ask)
if (!always_ask)
tries = priv->pin_tries++;
g_signal_emit_by_name (self, NM_MODEM_NEED_AUTH,
NM_SETTING_GSM_SETTING_NAME,
(tries || always_ask) ? TRUE : FALSE,
SECRETS_CALLER_MOBILE_BROADBAND,
NM_SETTING_GSM_PIN,
NULL);
nm_modem_get_secrets (NM_MODEM (self),
NM_SETTING_GSM_SETTING_NAME,
(tries || always_ask) ? TRUE : FALSE,
NM_SETTING_GSM_PIN);
}
static void

View file

@ -62,7 +62,9 @@ typedef struct {
char *device;
char *iface;
NMActRequest *act_request;
guint32 secrets_tries;
guint32 secrets_id;
DBusGProxyCall *call;
@ -78,7 +80,8 @@ enum {
PPP_FAILED,
PREPARE_RESULT,
IP4_CONFIG_RESULT,
NEED_AUTH,
AUTH_REQUESTED,
AUTH_RESULT,
LAST_SIGNAL
};
@ -475,67 +478,58 @@ nm_modem_stage4_get_ip4_config (NMModem *self,
return ret;
}
gboolean
nm_modem_connection_secrets_updated (NMModem *self,
NMActRequest *req,
NMConnection *connection,
GSList *updated_settings,
RequestSecretsCaller caller)
static void
cancel_get_secrets (NMModem *self)
{
NMModemPrivate *priv;
gboolean found = FALSE;
const char *setting_name;
GSList *iter;
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (NM_IS_MODEM (self), FALSE);
g_return_val_if_fail (req != NULL, FALSE);
g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
priv = NM_MODEM_GET_PRIVATE (self);
if (caller == SECRETS_CALLER_PPP) {
const char *user = NULL;
const char *pass = NULL;
g_return_val_if_fail (priv->ppp_manager != NULL, FALSE);
if (!NM_MODEM_GET_CLASS (self)->get_user_pass (self, connection, &user, &pass)) {
/* Shouldn't ever happen */
nm_ppp_manager_update_secrets (priv->ppp_manager,
priv->iface,
NULL,
NULL,
"missing GSM/CDMA setting; no secrets could be found.");
} else {
nm_ppp_manager_update_secrets (priv->ppp_manager,
priv->iface,
user ? user : "",
pass ? pass : "",
NULL);
}
return TRUE;
if (priv->secrets_id) {
nm_act_request_cancel_secrets (priv->act_request, priv->secrets_id);
priv->secrets_id = 0;
}
}
g_return_val_if_fail (caller == SECRETS_CALLER_MOBILE_BROADBAND, FALSE);
static void
modem_secrets_cb (NMActRequest *req,
guint32 call_id,
NMConnection *connection,
GError *error,
gpointer user_data)
{
NMModem *self = NM_MODEM (user_data);
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
g_assert (NM_MODEM_GET_CLASS (self)->get_setting_name);
setting_name = NM_MODEM_GET_CLASS (self)->get_setting_name (self);
g_return_if_fail (call_id == priv->secrets_id);
for (iter = updated_settings; iter; iter = g_slist_next (iter)) {
const char *candidate_setting_name = (const char *) iter->data;
priv->secrets_id = 0;
if (!strcmp (candidate_setting_name, setting_name))
found = TRUE;
else {
nm_log_warn (LOGD_MB, "ignoring updated secrets for setting '%s'.",
candidate_setting_name);
}
}
if (error)
nm_log_warn (LOGD_MB, "%s", error->message);
return found;
g_signal_emit (self, signals[AUTH_RESULT], 0, error);
}
gboolean
nm_modem_get_secrets (NMModem *self,
const char *setting_name,
gboolean request_new,
const char *hint)
{
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
cancel_get_secrets (self);
priv->secrets_id = nm_act_request_get_secrets (priv->act_request,
NULL,
setting_name,
request_new,
hint,
modem_secrets_cb,
self);
if (priv->secrets_id)
g_signal_emit (self, signals[AUTH_REQUESTED], 0);
return !!(priv->secrets_id);
}
static NMActStageReturn
@ -559,29 +553,30 @@ nm_modem_act_stage1_prepare (NMModem *self,
GPtrArray *hints = NULL;
const char *setting_name = NULL;
if (priv->act_request)
g_object_unref (priv->act_request);
priv->act_request = g_object_ref (req);
ret = NM_MODEM_GET_CLASS (self)->act_stage1_prepare (self,
req,
&hints,
&setting_name,
reason);
if ((ret == NM_ACT_STAGE_RETURN_POSTPONE) && setting_name) {
const char *hint1 = NULL, *hint2 = NULL;
/* Need some secrets */
if (hints) {
if (hints->len > 0)
hint1 = g_ptr_array_index (hints, 0);
if (hints->len > 1)
hint2 = g_ptr_array_index (hints, 1);
priv->secrets_id = nm_act_request_get_secrets (req,
NULL,
setting_name,
priv->secrets_tries++ ? TRUE : FALSE,
hints ? g_ptr_array_index (hints, 0) : NULL,
modem_secrets_cb,
self);
if (priv->secrets_id)
g_signal_emit (self, signals[AUTH_REQUESTED], 0);
else {
*reason = NM_DEVICE_STATE_REASON_NO_SECRETS;
ret = NM_ACT_STAGE_RETURN_FAILURE;
}
g_signal_emit (self, signals[NEED_AUTH], 0,
setting_name,
priv->secrets_tries++ ? TRUE : FALSE,
SECRETS_CALLER_MOBILE_BROADBAND,
hint1,
hint2);
if (hints)
g_ptr_array_free (hints, TRUE);
}
@ -639,6 +634,12 @@ real_deactivate_quickly (NMModem *self, NMDevice *device)
priv->secrets_tries = 0;
if (priv->act_request) {
cancel_get_secrets (self);
g_object_unref (priv->act_request);
priv->act_request = NULL;
}
if (priv->call) {
dbus_g_proxy_cancel_call (priv->proxy, priv->call);
priv->call = NULL;
@ -697,6 +698,7 @@ nm_modem_device_state_changed (NMModem *self,
NMDeviceStateReason reason)
{
gboolean was_connected = FALSE;
NMModemPrivate *priv;
g_return_if_fail (self != NULL);
g_return_if_fail (NM_IS_MODEM (self));
@ -704,16 +706,26 @@ nm_modem_device_state_changed (NMModem *self,
if (IS_ACTIVATING_STATE (old_state) || (old_state == NM_DEVICE_STATE_ACTIVATED))
was_connected = TRUE;
priv = NM_MODEM_GET_PRIVATE (self);
/* Make sure we don't leave the serial device open */
switch (new_state) {
case NM_DEVICE_STATE_NEED_AUTH:
if (NM_MODEM_GET_PRIVATE (self)->ppp_manager)
if (priv->ppp_manager)
break;
/* else fall through */
case NM_DEVICE_STATE_UNMANAGED:
case NM_DEVICE_STATE_UNAVAILABLE:
case NM_DEVICE_STATE_FAILED:
case NM_DEVICE_STATE_DISCONNECTED:
if (new_state != NM_DEVICE_STATE_NEED_AUTH) {
if (priv->act_request) {
cancel_get_secrets (self);
g_object_unref (priv->act_request);
priv->act_request = NULL;
}
}
if (was_connected) {
dbus_g_proxy_begin_call (nm_modem_get_proxy (self, MM_DBUS_INTERFACE_MODEM),
"Disconnect",
@ -1016,6 +1028,9 @@ finalize (GObject *object)
{
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object);
if (priv->act_request)
g_object_unref (priv->act_request);
if (priv->proxy)
g_object_unref (priv->proxy);
@ -1128,15 +1143,23 @@ nm_modem_class_init (NMModemClass *klass)
_nm_marshal_VOID__BOOLEAN_UINT,
G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_UINT);
signals[NEED_AUTH] =
g_signal_new (NM_MODEM_NEED_AUTH,
signals[AUTH_REQUESTED] =
g_signal_new (NM_MODEM_AUTH_REQUESTED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMModemClass, need_auth),
G_STRUCT_OFFSET (NMModemClass, auth_requested),
NULL, NULL,
_nm_marshal_VOID__STRING_BOOLEAN_UINT_STRING_STRING,
G_TYPE_NONE, 5,
G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
signals[AUTH_RESULT] =
g_signal_new (NM_MODEM_AUTH_RESULT,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMModemClass, auth_result),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
}
const DBusGObjectInfo *

View file

@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2009 Red Hat, Inc.
* Copyright (C) 2009 - 2010 Red Hat, Inc.
* Copyright (C) 2009 Novell, Inc.
*/
@ -46,7 +46,8 @@ G_BEGIN_DECLS
#define NM_MODEM_PPP_FAILED "ppp-failed"
#define NM_MODEM_PREPARE_RESULT "prepare-result"
#define NM_MODEM_IP4_CONFIG_RESULT "ip4-config-result"
#define NM_MODEM_NEED_AUTH "need-auth"
#define NM_MODEM_AUTH_REQUESTED "auth-requested"
#define NM_MODEM_AUTH_RESULT "auth-result"
typedef struct {
GObject parent;
@ -85,12 +86,8 @@ typedef struct {
void (*prepare_result) (NMModem *self, gboolean success, NMDeviceStateReason reason);
void (*ip4_config_result) (NMModem *self, const char *iface, NMIP4Config *config, GError *error);
void (*need_auth) (NMModem *self,
const char *setting_name,
gboolean retry,
RequestSecretsCaller caller,
const char *hint1,
const char *hint2);
void (*auth_requested) (NMModem *self);
void (*auth_result) (NMModem *self, GError *error);
} NMModemClass;
GType nm_modem_get_type (void);
@ -129,6 +126,11 @@ NMActStageReturn nm_modem_stage4_get_ip4_config (NMModem *modem,
NMIP4Config **config,
NMDeviceStateReason *reason);
gboolean nm_modem_get_secrets (NMModem *modem,
const char *setting_name,
gboolean request_new,
const char *hint);
void nm_modem_deactivate_quickly (NMModem *modem, NMDevice *device);
void nm_modem_device_state_changed (NMModem *modem,
@ -140,12 +142,6 @@ gboolean nm_modem_hw_is_up (NMModem *modem, NMDevice *device);
gboolean nm_modem_hw_bring_up (NMModem *modem, NMDevice *device, gboolean *no_firmware);
gboolean nm_modem_connection_secrets_updated (NMModem *modem,
NMActRequest *req,
NMConnection *connection,
GSList *updated_settings,
RequestSecretsCaller caller);
const DBusGObjectInfo *nm_modem_get_serial_dbus_info (void);
gboolean nm_modem_get_mm_enabled (NMModem *self);

View file

@ -37,22 +37,16 @@
#include "nm-dbus-glib-types.h"
static void secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class);
G_DEFINE_TYPE (NMActRequest, nm_act_request, G_TYPE_OBJECT)
G_DEFINE_TYPE_EXTENDED (NMActRequest, nm_act_request, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (NM_TYPE_SECRETS_PROVIDER_INTERFACE,
secrets_provider_interface_init))
#define NM_ACT_REQUEST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ACT_REQUEST, NMActRequestPrivate))
#define NM_ACT_REQUEST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_ACT_REQUEST, \
NMActRequestPrivate))
enum {
CONNECTION_SECRETS_UPDATED,
CONNECTION_SECRETS_FAILED,
PROPERTIES_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
typedef struct {
@ -64,7 +58,9 @@ typedef struct {
gboolean disposed;
NMConnection *connection;
guint32 secrets_call_id;
NMAgentManager *agent_mgr;
GSList *secrets_calls;
char *specific_object;
NMDevice *device;
@ -94,292 +90,9 @@ enum {
LAST_PROP
};
/*******************************************************************/
static void
device_state_changed (NMDevice *device,
NMDeviceState new_state,
NMDeviceState old_state,
NMDeviceStateReason reason,
gpointer user_data)
{
NMActRequest *self = NM_ACT_REQUEST (user_data);
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
NMActiveConnectionState new_ac_state;
gboolean new_default = FALSE, new_default6 = FALSE;
/* Set NMActiveConnection state based on the device's state */
switch (new_state) {
case NM_DEVICE_STATE_PREPARE:
case NM_DEVICE_STATE_CONFIG:
case NM_DEVICE_STATE_NEED_AUTH:
case NM_DEVICE_STATE_IP_CONFIG:
new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATING;
break;
case NM_DEVICE_STATE_ACTIVATED:
new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATED;
new_default = priv->is_default;
new_default6 = priv->is_default6;
break;
default:
new_ac_state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
break;
}
if (new_ac_state != priv->state) {
priv->state = new_ac_state;
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE);
}
if (new_default != priv->is_default) {
priv->is_default = new_default;
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT);
}
if (new_default6 != priv->is_default6) {
priv->is_default6 = new_default6;
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT6);
}
}
NMActRequest *
nm_act_request_new (NMConnection *connection,
const char *specific_object,
gboolean user_requested,
gboolean assumed,
gpointer *device)
{
GObject *object;
NMActRequestPrivate *priv;
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
g_return_val_if_fail (NM_DEVICE (device), NULL);
object = g_object_new (NM_TYPE_ACT_REQUEST, NULL);
if (!object)
return NULL;
priv = NM_ACT_REQUEST_GET_PRIVATE (object);
priv->connection = g_object_ref (connection);
if (specific_object)
priv->specific_object = g_strdup (specific_object);
priv->device = NM_DEVICE (device);
g_signal_connect (device, "state-changed",
G_CALLBACK (device_state_changed),
NM_ACT_REQUEST (object));
priv->user_requested = user_requested;
priv->assumed = assumed;
return NM_ACT_REQUEST (object);
}
static void
nm_act_request_init (NMActRequest *req)
{
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req);
NMDBusManager *dbus_mgr;
priv->ac_path = nm_active_connection_get_next_object_path ();
priv->state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
dbus_mgr = nm_dbus_manager_get ();
dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr),
priv->ac_path,
G_OBJECT (req));
g_object_unref (dbus_mgr);
}
static void
dispose (GObject *object)
{
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
if (priv->disposed) {
G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object);
return;
}
priv->disposed = TRUE;
g_assert (priv->connection);
g_signal_handlers_disconnect_by_func (G_OBJECT (priv->device),
G_CALLBACK (device_state_changed),
NM_ACT_REQUEST (object));
/* Clear any share rules */
nm_act_request_set_shared (NM_ACT_REQUEST (object), FALSE);
g_object_unref (priv->connection);
G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object);
}
static void
clear_share_rules (NMActRequest *req)
{
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req);
GSList *iter;
for (iter = priv->share_rules; iter; iter = g_slist_next (iter)) {
ShareRule *rule = (ShareRule *) iter->data;
g_free (rule->table);
g_free (rule->rule);
g_free (rule);
}
g_slist_free (priv->share_rules);
priv->share_rules = NULL;
}
static void
finalize (GObject *object)
{
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
g_free (priv->specific_object);
g_free (priv->ac_path);
clear_share_rules (NM_ACT_REQUEST (object));
G_OBJECT_CLASS (nm_act_request_parent_class)->finalize (object);
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
GPtrArray *devices;
switch (prop_id) {
case PROP_CONNECTION:
g_value_set_boxed (value, nm_connection_get_path (priv->connection));
break;
case PROP_SPECIFIC_OBJECT:
if (priv->specific_object)
g_value_set_boxed (value, priv->specific_object);
else
g_value_set_boxed (value, "/");
break;
case PROP_DEVICES:
devices = g_ptr_array_sized_new (1);
g_ptr_array_add (devices, g_strdup (nm_device_get_path (priv->device)));
g_value_take_boxed (value, devices);
break;
case PROP_STATE:
g_value_set_uint (value, priv->state);
break;
case PROP_DEFAULT:
g_value_set_boolean (value, priv->is_default);
break;
case PROP_DEFAULT6:
g_value_set_boolean (value, priv->is_default6);
break;
case PROP_VPN:
g_value_set_boolean (value, FALSE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_act_request_class_init (NMActRequestClass *req_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (req_class);
g_type_class_add_private (req_class, sizeof (NMActRequestPrivate));
/* virtual methods */
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize;
/* properties */
g_object_class_install_property
(object_class, PROP_CONNECTION,
g_param_spec_boxed (NM_ACTIVE_CONNECTION_CONNECTION,
"Connection",
"Connection",
DBUS_TYPE_G_OBJECT_PATH,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_SPECIFIC_OBJECT,
g_param_spec_boxed (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT,
"Specific object",
"Specific object",
DBUS_TYPE_G_OBJECT_PATH,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_DEVICES,
g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES,
"Devices",
"Devices",
DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_STATE,
g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE,
"State",
"State",
NM_ACTIVE_CONNECTION_STATE_UNKNOWN,
NM_ACTIVE_CONNECTION_STATE_ACTIVATED,
NM_ACTIVE_CONNECTION_STATE_UNKNOWN,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_DEFAULT,
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT,
"Default",
"Is the default IPv4 active connection",
FALSE,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_DEFAULT6,
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6,
"Default6",
"Is the default IPv6 active connection",
FALSE,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_VPN,
g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN,
"VPN",
"Is a VPN connection",
FALSE,
G_PARAM_READABLE));
/* Signals */
signals[CONNECTION_SECRETS_UPDATED] =
g_signal_new ("connection-secrets-updated",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMActRequestClass, secrets_updated),
NULL, NULL,
_nm_marshal_VOID__OBJECT_POINTER_UINT,
G_TYPE_NONE, 3,
G_TYPE_OBJECT, G_TYPE_POINTER, G_TYPE_UINT);
signals[CONNECTION_SECRETS_FAILED] =
g_signal_new ("connection-secrets-failed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMActRequestClass, secrets_failed),
NULL, NULL,
_nm_marshal_VOID__OBJECT_STRING_UINT,
G_TYPE_NONE, 3,
G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_UINT);
signals[PROPERTIES_CHANGED] =
nm_properties_changed_signal_new (object_class,
G_STRUCT_OFFSET (NMActRequestClass, properties_changed));
nm_active_connection_install_type_info (object_class);
}
#if 0
static gboolean
secrets_update_setting (NMSecretsProviderInterface *interface,
const char *setting_name,
@ -434,55 +147,83 @@ secrets_update_setting (NMSecretsProviderInterface *interface,
return TRUE;
}
#endif
static void
secrets_result (NMSecretsProviderInterface *interface,
const char *setting_name,
RequestSecretsCaller caller,
const GSList *updated,
GError *error)
get_secrets_cb (NMAgentManager *manager,
guint32 call_id,
NMConnection *connection,
GError *error,
gpointer user_data,
gpointer user_data2,
gpointer user_data3)
{
NMActRequest *self = NM_ACT_REQUEST (interface);
NMActRequest *self = NM_ACT_REQUEST (user_data);
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
NMActRequestSecretsFunc callback = user_data2;
g_return_if_fail (priv->connection != NULL);
priv->secrets_calls = g_slist_remove (priv->secrets_calls, GUINT_TO_POINTER (call_id));
if (error) {
g_signal_emit (self, signals[CONNECTION_SECRETS_FAILED], 0,
priv->connection, setting_name, caller);
} else {
g_signal_emit (self, signals[CONNECTION_SECRETS_UPDATED], 0,
priv->connection, updated, caller);
callback (self, call_id, connection, error, user_data3);
}
guint32
nm_act_request_get_secrets (NMActRequest *self,
NMConnection *connection,
const char *setting_name,
gboolean request_new,
const char *hint,
NMActRequestSecretsFunc callback,
gpointer callback_data)
{
NMActRequestPrivate *priv;
guint32 call_id;
g_return_val_if_fail (self, 0);
g_return_val_if_fail (NM_IS_ACT_REQUEST (self), 0);
priv = NM_ACT_REQUEST_GET_PRIVATE (self);
/* If given a connection (ie, called from an NMVpnConnection) then
* use that, otherwise use the private connection.
*
* FIXME: this is icky, and should go away when NMVPNConnection finally
* uses NMActRequest for activation tracking instead of impersonating one
* itself.
*/
call_id = nm_agent_manager_get_secrets (priv->agent_mgr,
connection ? connection : priv->connection,
setting_name,
request_new,
hint,
get_secrets_cb,
self,
callback,
callback_data);
if (call_id > 0)
priv->secrets_calls = g_slist_append (priv->secrets_calls, GUINT_TO_POINTER (call_id));
return call_id;
}
void
nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id)
{
NMActRequestPrivate *priv;
g_return_if_fail (self);
g_return_if_fail (NM_IS_ACT_REQUEST (self));
g_return_if_fail (call_id > 0);
priv = NM_ACT_REQUEST_GET_PRIVATE (self);
if (g_slist_find (priv->secrets_calls, GUINT_TO_POINTER (call_id))) {
priv->secrets_calls = g_slist_remove (priv->secrets_calls, GUINT_TO_POINTER (call_id));
nm_agent_manager_cancel_secrets (priv->agent_mgr, call_id);
}
}
static void
secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class)
{
/* interface implementation */
sp_interface_class->update_setting = secrets_update_setting;
sp_interface_class->result = secrets_result;
}
gboolean
nm_act_request_get_secrets (NMActRequest *self,
const char *setting_name,
gboolean request_new,
RequestSecretsCaller caller,
const char *hint1,
const char *hint2)
{
g_return_val_if_fail (self, FALSE);
g_return_val_if_fail (NM_IS_ACT_REQUEST (self), FALSE);
return nm_secrets_provider_interface_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (self),
nm_act_request_get_connection (self),
setting_name,
request_new,
caller,
hint1,
hint2);
}
/*******************************************************************/
NMConnection *
nm_act_request_get_connection (NMActRequest *req)
@ -578,6 +319,42 @@ nm_act_request_get_default6 (NMActRequest *req)
return NM_ACT_REQUEST_GET_PRIVATE (req)->is_default6;
}
GObject *
nm_act_request_get_device (NMActRequest *req)
{
g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
return G_OBJECT (NM_ACT_REQUEST_GET_PRIVATE (req)->device);
}
gboolean
nm_act_request_get_assumed (NMActRequest *req)
{
g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
return NM_ACT_REQUEST_GET_PRIVATE (req)->assumed;
}
/********************************************************************/
static void
clear_share_rules (NMActRequest *req)
{
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req);
GSList *iter;
for (iter = priv->share_rules; iter; iter = g_slist_next (iter)) {
ShareRule *rule = (ShareRule *) iter->data;
g_free (rule->table);
g_free (rule->rule);
g_free (rule);
}
g_slist_free (priv->share_rules);
priv->share_rules = NULL;
}
static void
share_child_setup (gpointer user_data G_GNUC_UNUSED)
{
@ -664,26 +441,273 @@ nm_act_request_add_share_rule (NMActRequest *req,
g_return_if_fail (NM_IS_ACT_REQUEST (req));
g_return_if_fail (table != NULL);
g_return_if_fail (table_rule != NULL);
rule = g_malloc0 (sizeof (ShareRule));
rule->table = g_strdup (table);
rule->rule = g_strdup (table_rule);
priv->share_rules = g_slist_append (priv->share_rules, rule);
}
GObject *
nm_act_request_get_device (NMActRequest *req)
{
g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
/********************************************************************/
return G_OBJECT (NM_ACT_REQUEST_GET_PRIVATE (req)->device);
static void
device_state_changed (NMDevice *device,
NMDeviceState new_state,
NMDeviceState old_state,
NMDeviceStateReason reason,
gpointer user_data)
{
NMActRequest *self = NM_ACT_REQUEST (user_data);
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
NMActiveConnectionState new_ac_state;
gboolean new_default = FALSE, new_default6 = FALSE;
/* Set NMActiveConnection state based on the device's state */
switch (new_state) {
case NM_DEVICE_STATE_PREPARE:
case NM_DEVICE_STATE_CONFIG:
case NM_DEVICE_STATE_NEED_AUTH:
case NM_DEVICE_STATE_IP_CONFIG:
new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATING;
break;
case NM_DEVICE_STATE_ACTIVATED:
new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATED;
new_default = priv->is_default;
new_default6 = priv->is_default6;
break;
default:
new_ac_state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
break;
}
if (new_ac_state != priv->state) {
priv->state = new_ac_state;
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE);
}
if (new_default != priv->is_default) {
priv->is_default = new_default;
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT);
}
if (new_default6 != priv->is_default6) {
priv->is_default6 = new_default6;
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT6);
}
}
gboolean
nm_act_request_get_assumed (NMActRequest *req)
{
g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
/********************************************************************/
return NM_ACT_REQUEST_GET_PRIVATE (req)->assumed;
NMActRequest *
nm_act_request_new (NMConnection *connection,
const char *specific_object,
NMAgentManager *agent_mgr,
gboolean user_requested,
gboolean assumed,
gpointer *device)
{
GObject *object;
NMActRequestPrivate *priv;
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
g_return_val_if_fail (NM_IS_AGENT_MANAGER (agent_mgr), NULL);
g_return_val_if_fail (NM_DEVICE (device), NULL);
object = g_object_new (NM_TYPE_ACT_REQUEST, NULL);
if (!object)
return NULL;
priv = NM_ACT_REQUEST_GET_PRIVATE (object);
priv->connection = g_object_ref (connection);
if (specific_object)
priv->specific_object = g_strdup (specific_object);
priv->agent_mgr = g_object_ref (agent_mgr);
priv->device = NM_DEVICE (device);
g_signal_connect (device, "state-changed",
G_CALLBACK (device_state_changed),
NM_ACT_REQUEST (object));
priv->user_requested = user_requested;
priv->assumed = assumed;
return NM_ACT_REQUEST (object);
}
static void
nm_act_request_init (NMActRequest *req)
{
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req);
NMDBusManager *dbus_mgr;
priv->ac_path = nm_active_connection_get_next_object_path ();
priv->state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
dbus_mgr = nm_dbus_manager_get ();
dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr),
priv->ac_path,
G_OBJECT (req));
g_object_unref (dbus_mgr);
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
GPtrArray *devices;
switch (prop_id) {
case PROP_CONNECTION:
g_value_set_boxed (value, nm_connection_get_path (priv->connection));
break;
case PROP_SPECIFIC_OBJECT:
if (priv->specific_object)
g_value_set_boxed (value, priv->specific_object);
else
g_value_set_boxed (value, "/");
break;
case PROP_DEVICES:
devices = g_ptr_array_sized_new (1);
g_ptr_array_add (devices, g_strdup (nm_device_get_path (priv->device)));
g_value_take_boxed (value, devices);
break;
case PROP_STATE:
g_value_set_uint (value, priv->state);
break;
case PROP_DEFAULT:
g_value_set_boolean (value, priv->is_default);
break;
case PROP_DEFAULT6:
g_value_set_boolean (value, priv->is_default6);
break;
case PROP_VPN:
g_value_set_boolean (value, FALSE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
dispose (GObject *object)
{
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
GSList *iter;
if (priv->disposed) {
G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object);
return;
}
priv->disposed = TRUE;
g_assert (priv->connection);
g_signal_handlers_disconnect_by_func (G_OBJECT (priv->device),
G_CALLBACK (device_state_changed),
NM_ACT_REQUEST (object));
/* Clear any share rules */
nm_act_request_set_shared (NM_ACT_REQUEST (object), FALSE);
g_object_unref (priv->connection);
for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) {
nm_agent_manager_cancel_secrets (priv->agent_mgr,
GPOINTER_TO_UINT (iter->data));
}
g_slist_free (priv->secrets_calls);
g_object_unref (priv->agent_mgr);
G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object);
}
static void
finalize (GObject *object)
{
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
g_free (priv->specific_object);
g_free (priv->ac_path);
clear_share_rules (NM_ACT_REQUEST (object));
G_OBJECT_CLASS (nm_act_request_parent_class)->finalize (object);
}
static void
nm_act_request_class_init (NMActRequestClass *req_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (req_class);
g_type_class_add_private (req_class, sizeof (NMActRequestPrivate));
/* virtual methods */
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize;
/* properties */
g_object_class_install_property
(object_class, PROP_CONNECTION,
g_param_spec_boxed (NM_ACTIVE_CONNECTION_CONNECTION,
"Connection",
"Connection",
DBUS_TYPE_G_OBJECT_PATH,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_SPECIFIC_OBJECT,
g_param_spec_boxed (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT,
"Specific object",
"Specific object",
DBUS_TYPE_G_OBJECT_PATH,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_DEVICES,
g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES,
"Devices",
"Devices",
DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_STATE,
g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE,
"State",
"State",
NM_ACTIVE_CONNECTION_STATE_UNKNOWN,
NM_ACTIVE_CONNECTION_STATE_ACTIVATED,
NM_ACTIVE_CONNECTION_STATE_UNKNOWN,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_DEFAULT,
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT,
"Default",
"Is the default IPv4 active connection",
FALSE,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_DEFAULT6,
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6,
"Default6",
"Is the default IPv6 active connection",
FALSE,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_VPN,
g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN,
"VPN",
"Is a VPN connection",
FALSE,
G_PARAM_READABLE));
/* Signals */
signals[PROPERTIES_CHANGED] =
nm_properties_changed_signal_new (object_class,
G_STRUCT_OFFSET (NMActRequestClass, properties_changed));
nm_active_connection_install_type_info (object_class);
}

View file

@ -25,7 +25,7 @@
#include <glib-object.h>
#include "nm-connection.h"
#include "nm-active-connection.h"
#include "nm-secrets-provider-interface.h"
#include "nm-agent-manager.h"
#define NM_TYPE_ACT_REQUEST (nm_act_request_get_type ())
#define NM_ACT_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACT_REQUEST, NMActRequest))
@ -42,15 +42,6 @@ typedef struct {
GObjectClass parent;
/* Signals */
void (*secrets_updated) (NMActRequest *req,
NMConnection *connection,
GSList *updated_settings,
RequestSecretsCaller caller);
void (*secrets_failed) (NMActRequest *req,
NMConnection *connection,
const char *setting,
RequestSecretsCaller caller);
void (*properties_changed) (NMActRequest *req, GHashTable *properties);
} NMActRequestClass;
@ -58,6 +49,7 @@ GType nm_act_request_get_type (void);
NMActRequest *nm_act_request_new (NMConnection *connection,
const char *specific_object,
NMAgentManager *agent_mgr,
gboolean user_requested,
gboolean assumed,
gpointer *device); /* An NMDevice */
@ -92,12 +84,23 @@ GObject * nm_act_request_get_device (NMActRequest *req);
gboolean nm_act_request_get_assumed (NMActRequest *req);
gboolean nm_act_request_get_secrets (NMActRequest *req,
const char *setting_name,
gboolean request_new,
RequestSecretsCaller caller,
const char *hint1,
const char *hint2);
/* Secrets handling */
typedef void (*NMActRequestSecretsFunc) (NMActRequest *req,
guint32 call_id,
NMConnection *connection,
GError *error,
gpointer user_data);
guint32 nm_act_request_get_secrets (NMActRequest *req,
NMConnection *connection, /* NULL == use activation request's connection */
const char *setting_name,
gboolean request_new,
const char *hint,
NMActRequestSecretsFunc callback,
gpointer callback_data);
void nm_act_request_cancel_secrets (NMActRequest *req, guint32 call_id);
#endif /* NM_ACTIVATION_REQUEST_H */

View file

@ -31,6 +31,7 @@
#include "nm-agent-manager.h"
#include "nm-secret-agent.h"
#include "nm-manager-auth.h"
#include "nm-sysconfig-connection.h"
G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT)
@ -48,6 +49,8 @@ typedef struct {
* sessions can use the same identifier.
*/
GHashTable *agents;
GHashTable *requests;
} NMAgentManagerPrivate;
@ -296,6 +299,222 @@ done:
/*************************************************************/
typedef struct _Request Request;
typedef void (*RequestNextFunc) (Request *req, gpointer user_data);
typedef void (*RequestCompleteFunc) (Request *req,
GHashTable *secrets,
GError *error,
gpointer user_data);
struct _Request {
guint32 reqid;
NMConnection *connection;
char *setting_name;
gboolean request_new;
char *hint;
guint32 idle_id;
NMAgentSecretsResultFunc callback;
gpointer callback_data;
gpointer other_data2;
gpointer other_data3;
RequestNextFunc next_callback;
RequestCompleteFunc complete_callback;
gpointer req_callback_data;
};
static Request *
request_new (NMConnection *connection,
const char *setting_name,
gboolean get_new,
const char *hint,
NMAgentSecretsResultFunc callback,
gpointer callback_data,
gpointer other_data2,
gpointer other_data3)
{
Request *req;
static guint32 next_id = 1;
req = g_malloc0 (sizeof (Request));
req->reqid = next_id++;
req->connection = g_object_ref (connection);
req->setting_name = g_strdup (setting_name);
req->request_new = get_new;
req->hint = g_strdup (hint);
req->callback = callback;
req->callback_data = callback_data;
req->other_data2 = other_data2;
req->other_data3 = other_data3;
return req;
}
static void
request_free (Request *req)
{
if (req->idle_id)
g_source_remove (req->idle_id);
g_object_unref (req->connection);
g_free (req->setting_name);
g_free (req->hint);
memset (req, 0, sizeof (Request));
g_free (req);
}
static void
request_set_callbacks (Request *req,
RequestNextFunc next_func,
RequestCompleteFunc complete_func,
gpointer user_data)
{
req->next_callback = next_func;
req->complete_callback = complete_func;
req->req_callback_data = user_data;
}
static gboolean
request_start_secrets (gpointer user_data)
{
Request *req = user_data;
GHashTable *secrets;
GError *error = NULL;
req->idle_id = 0;
secrets = nm_sysconfig_connection_get_secrets (NM_SYSCONFIG_CONNECTION (req->connection),
req->setting_name,
req->hint,
req->request_new,
&error);
if (secrets) {
/* The connection already had secrets, no need to get any */
req->complete_callback (req, secrets, NULL, req->req_callback_data);
g_hash_table_destroy (secrets);
} else if (error)
req->complete_callback (req, NULL, error, req->req_callback_data);
else {
/* Couldn't get secrets from system settings, so now we ask the
* agents for secrets. Let the Agent Manager handle which agents
* we'll ask and in which order.
*/
req->next_callback (req, req->req_callback_data);
}
g_clear_error (&error);
return FALSE;
}
/*************************************************************/
static void
mgr_req_next_cb (Request *req, gpointer user_data)
{
#if 0
NMAgentManager *self = NM_AGENT_MANAGER (user_data);
NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
/* Look for the next agent to call for secrets based on whether that
* agent's user is in the connection's ACL.
*/
#endif
}
static void
mgr_req_complete_cb (Request *req,
GHashTable *secrets,
GError *error,
gpointer user_data)
{
NMAgentManager *self = NM_AGENT_MANAGER (user_data);
NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
GError *local = NULL;
if (error)
local = g_error_copy (error);
else {
/* Save the secrets into the connection */
nm_connection_update_secrets (req->connection,
req->setting_name,
secrets,
&local);
}
if (local) {
nm_log_warn (LOGD_SETTINGS,
"Failed to %s connection secrets: (%d) %s",
error ? "get" : "update",
local->code,
local->message ? local->message : "(none)");
}
/* Call the activation requests' secrets callback */
req->callback (self,
req->reqid,
req->connection,
local,
req->callback_data,
req->other_data2,
req->other_data3);
g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid));
g_clear_error (&local);
}
guint32
nm_agent_manager_get_secrets (NMAgentManager *self,
NMConnection *connection,
const char *setting_name,
gboolean get_new,
const char *hint,
NMAgentSecretsResultFunc callback,
gpointer callback_data,
gpointer other_data2,
gpointer other_data3)
{
NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
Request *req;
g_return_val_if_fail (self != NULL, 0);
g_return_val_if_fail (connection != NULL, 0);
g_return_val_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection), 0);
g_return_val_if_fail (callback != NULL, 0);
req = request_new (connection,
setting_name,
get_new,
hint,
callback,
callback_data,
other_data2,
other_data3);
request_set_callbacks (req, mgr_req_next_cb, mgr_req_complete_cb, self);
g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req);
req->idle_id = g_idle_add (request_start_secrets, req);
return req->reqid;
}
void
nm_agent_manager_cancel_secrets (NMAgentManager *self,
guint32 request_id)
{
g_return_if_fail (self != NULL);
g_return_if_fail (request_id > 0);
g_hash_table_remove (NM_AGENT_MANAGER_GET_PRIVATE (self)->requests,
GUINT_TO_POINTER (request_id));
}
/*************************************************************/
static void
name_owner_changed_cb (NMDBusManager *dbus_mgr,
const char *name,
@ -312,7 +531,7 @@ name_owner_changed_cb (NMDBusManager *dbus_mgr,
/*************************************************************/
NMAgentManager *
nm_agent_manager_new (NMDBusManager *dbus_mgr, NMSessionMonitor *session_monitor)
nm_agent_manager_new (NMDBusManager *dbus_mgr)
{
NMAgentManager *self;
NMAgentManagerPrivate *priv;
@ -324,7 +543,7 @@ nm_agent_manager_new (NMDBusManager *dbus_mgr, NMSessionMonitor *session_monitor
if (self) {
priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
priv->session_monitor = g_object_ref (session_monitor);
priv->session_monitor = nm_session_monitor_get ();
priv->dbus_mgr = g_object_ref (dbus_mgr);
connection = nm_dbus_manager_get_connection (dbus_mgr);
dbus_g_connection_register_g_object (connection, NM_DBUS_PATH_AGENT_MANAGER, G_OBJECT (self));
@ -341,6 +560,13 @@ nm_agent_manager_new (NMDBusManager *dbus_mgr, NMSessionMonitor *session_monitor
static void
nm_agent_manager_init (NMAgentManager *self)
{
NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
priv->agents = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
priv->requests = g_hash_table_new_full (g_direct_hash,
g_direct_equal,
NULL,
(GDestroyNotify) request_free);
}
static void
@ -356,6 +582,7 @@ dispose (GObject *object)
g_object_unref (priv->dbus_mgr);
g_hash_table_destroy (priv->agents);
g_hash_table_destroy (priv->requests);
G_OBJECT_CLASS (nm_agent_manager_parent_class)->dispose (object);
}

View file

@ -24,6 +24,8 @@
#include <glib.h>
#include <glib-object.h>
#include <nm-connection.h>
#include "nm-dbus-manager.h"
#include "nm-session-monitor.h"
@ -44,7 +46,27 @@ typedef struct {
GType nm_agent_manager_get_type (void);
NMAgentManager *nm_agent_manager_new (NMDBusManager *dbus_mgr,
NMSessionMonitor *session_monitor);
NMAgentManager *nm_agent_manager_new (NMDBusManager *dbus_mgr);
typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager,
guint32 call_id,
NMConnection *connection,
GError *error,
gpointer user_data,
gpointer user_data2,
gpointer user_data3);
guint32 nm_agent_manager_get_secrets (NMAgentManager *manager,
NMConnection *connection,
const char *setting_name,
gboolean get_new,
const char *hint,
NMAgentSecretsResultFunc callback,
gpointer callback_data,
gpointer other_data2,
gpointer other_data3);
void nm_agent_manager_cancel_secrets (NMAgentManager *manager,
guint32 request_id);
#endif /* NM_AGENT_MANAGER_H */

View file

@ -46,6 +46,8 @@ G_DEFINE_TYPE (NMDeviceBt, nm_device_bt, NM_TYPE_DEVICE)
#define NM_DEVICE_BT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BT, NMDeviceBtPrivate))
static gboolean modem_stage1 (NMDeviceBt *self, NMModem *modem, NMDeviceStateReason *reason);
typedef struct {
char *bdaddr;
char *name;
@ -291,22 +293,30 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
}
static void
modem_need_auth (NMModem *modem,
const char *setting_name,
gboolean retry,
RequestSecretsCaller caller,
const char *hint1,
const char *hint2,
gpointer user_data)
modem_auth_requested (NMModem *modem, gpointer user_data)
{
NMDeviceBt *self = NM_DEVICE_BT (user_data);
NMActRequest *req;
nm_device_state_changed (NM_DEVICE (user_data),
NM_DEVICE_STATE_NEED_AUTH,
NM_DEVICE_STATE_REASON_NONE);
}
req = nm_device_get_act_request (NM_DEVICE (self));
g_assert (req);
static void
modem_auth_result (NMModem *modem, GError *error, gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device);
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
nm_act_request_get_secrets (req, setting_name, retry, caller, hint1, hint2);
if (error) {
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_NO_SECRETS);
} else {
/* Otherwise, on success for GSM/CDMA secrets we need to schedule modem stage1 again */
g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH);
if (!modem_stage1 (NM_DEVICE_BT (device), priv->modem, &reason))
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
}
}
static void
@ -412,41 +422,6 @@ modem_stage1 (NMDeviceBt *self, NMModem *modem, NMDeviceStateReason *reason)
return FALSE;
}
static void
real_connection_secrets_updated (NMDevice *device,
NMConnection *connection,
GSList *updated_settings,
RequestSecretsCaller caller)
{
NMDeviceBt *self = NM_DEVICE_BT (device);
NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self);
NMActRequest *req;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
g_return_if_fail (IS_ACTIVATING_STATE (nm_device_get_state (device)));
req = nm_device_get_act_request (device);
g_assert (req);
if (!nm_modem_connection_secrets_updated (priv->modem,
req,
connection,
updated_settings,
caller)) {
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS);
return;
}
/* PPP handles stuff itself... */
if (caller == SECRETS_CALLER_PPP)
return;
/* Otherwise, on success for GSM/CDMA secrets we need to schedule modem stage1 again */
g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH);
if (!modem_stage1 (self, priv->modem, &reason))
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, reason);
}
/*****************************************************************************/
gboolean
@ -511,7 +486,8 @@ nm_device_bt_modem_added (NMDeviceBt *self,
g_signal_connect (modem, NM_MODEM_PPP_FAILED, G_CALLBACK (ppp_failed), self);
g_signal_connect (modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK (modem_prepare_result), self);
g_signal_connect (modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK (modem_ip4_config_result), self);
g_signal_connect (modem, NM_MODEM_NEED_AUTH, G_CALLBACK (modem_need_auth), self);
g_signal_connect (modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK (modem_auth_requested), self);
g_signal_connect (modem, NM_MODEM_AUTH_RESULT, G_CALLBACK (modem_auth_result), self);
/* Kick off the modem connection */
if (!modem_stage1 (self, modem, &reason))
@ -1019,7 +995,6 @@ nm_device_bt_class_init (NMDeviceBtClass *klass)
device_class->get_best_auto_connection = real_get_best_auto_connection;
device_class->get_generic_capabilities = real_get_generic_capabilities;
device_class->connection_secrets_updated = real_connection_secrets_updated;
device_class->deactivate_quickly = real_deactivate_quickly;
device_class->act_stage2_config = real_act_stage2_config;
device_class->act_stage3_ip4_config_start = real_act_stage3_ip4_config_start;

View file

@ -883,67 +883,6 @@ real_get_best_auto_connection (NMDevice *dev,
return NULL;
}
static void
real_connection_secrets_updated (NMDevice *dev,
NMConnection *connection,
GSList *updated_settings,
RequestSecretsCaller caller)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (dev);
NMActRequest *req;
gboolean valid = FALSE;
GSList *iter;
g_return_if_fail (IS_ACTIVATING_STATE (nm_device_get_state (dev)));
/* PPPoE? */
if (caller == SECRETS_CALLER_PPP) {
NMSettingPPPOE *s_pppoe;
g_assert (priv->ppp_manager);
s_pppoe = (NMSettingPPPOE *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE);
if (!s_pppoe) {
nm_ppp_manager_update_secrets (priv->ppp_manager,
nm_device_get_iface (dev),
NULL,
NULL,
"missing PPPoE setting; no secrets could be found.");
} else {
const char *pppoe_username = nm_setting_pppoe_get_username (s_pppoe);
const char *pppoe_password = nm_setting_pppoe_get_password (s_pppoe);
nm_ppp_manager_update_secrets (priv->ppp_manager,
nm_device_get_iface (dev),
pppoe_username ? pppoe_username : "",
pppoe_password ? pppoe_password : "",
NULL);
}
return;
}
/* Only caller could be ourselves for 802.1x */
g_return_if_fail (caller == SECRETS_CALLER_ETHERNET);
g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH);
for (iter = updated_settings; iter; iter = g_slist_next (iter)) {
const char *setting_name = (const char *) iter->data;
if (!strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME)) {
valid = TRUE;
} else {
nm_log_warn (LOGD_DEVICE, "Ignoring updated secrets for setting '%s'.",
setting_name);
}
}
req = nm_device_get_act_request (dev);
g_assert (req);
g_return_if_fail (nm_act_request_get_connection (req) == connection);
nm_device_activate_schedule_stage1_device_prepare (dev);
}
/* FIXME: Move it to nm-device.c and then get rid of all foo_device_get_setting() all around.
It's here now to keep the patch short. */
static NMSetting *
@ -1019,6 +958,28 @@ supplicant_interface_release (NMDeviceEthernet *self)
}
}
static void
wired_secrets_cb (NMActRequest *req,
guint32 call_id,
NMConnection *connection,
GError *error,
gpointer user_data)
{
NMDevice *dev = NM_DEVICE (user_data);
g_return_if_fail (req == nm_device_get_act_request (dev));
g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH);
g_return_if_fail (nm_act_request_get_connection (req) == connection);
if (error) {
nm_log_warn (LOGD_ETHER, "%s", error->message);
nm_device_state_changed (dev,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_NO_SECRETS);
} else
nm_device_activate_schedule_stage1_device_prepare (dev);
}
static gboolean
link_timeout_cb (gpointer user_data)
{
@ -1060,11 +1021,12 @@ link_timeout_cb (gpointer user_data)
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
nm_act_request_get_secrets (req,
NULL,
setting_name,
TRUE,
SECRETS_CALLER_ETHERNET,
NULL,
NULL);
wired_secrets_cb,
self);
return FALSE;
@ -1249,11 +1211,12 @@ handle_auth_or_fail (NMDeviceEthernet *self,
*/
get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE);
nm_act_request_get_secrets (req,
NULL,
setting_name,
get_new,
SECRETS_CALLER_ETHERNET,
NULL,
NULL);
wired_secrets_cb,
self);
g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
} else {
@ -1969,7 +1932,6 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
parent_class->update_initial_hw_address = real_update_initial_hw_address;
parent_class->get_best_auto_connection = real_get_best_auto_connection;
parent_class->is_available = real_is_available;
parent_class->connection_secrets_updated = real_connection_secrets_updated;
parent_class->check_connection_compatible = real_check_connection_compatible;
parent_class->act_stage1_prepare = real_act_stage1_prepare;

View file

@ -107,22 +107,27 @@ modem_prepare_result (NMModem *modem,
}
static void
modem_need_auth (NMModem *modem,
const char *setting_name,
gboolean retry,
RequestSecretsCaller caller,
const char *hint1,
const char *hint2,
gpointer user_data)
modem_auth_requested (NMModem *modem, gpointer user_data)
{
NMDeviceModem *self = NM_DEVICE_MODEM (user_data);
NMActRequest *req;
nm_device_state_changed (NM_DEVICE (user_data),
NM_DEVICE_STATE_NEED_AUTH,
NM_DEVICE_STATE_REASON_NONE);
}
req = nm_device_get_act_request (NM_DEVICE (self));
g_assert (req);
static void
modem_auth_result (NMModem *modem, GError *error, gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
nm_act_request_get_secrets (req, setting_name, retry, caller, hint1, hint2);
if (error) {
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_NO_SECRETS);
} else {
/* Otherwise, on success for modem secrets we need to schedule stage1 again */
g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH);
nm_device_activate_schedule_stage1_device_prepare (device);
}
}
static void
@ -205,38 +210,6 @@ real_get_best_auto_connection (NMDevice *device,
return nm_modem_get_best_auto_connection (priv->modem, connections, specific_object);
}
static void
real_connection_secrets_updated (NMDevice *device,
NMConnection *connection,
GSList *updated_settings,
RequestSecretsCaller caller)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
NMActRequest *req;
g_return_if_fail (IS_ACTIVATING_STATE (nm_device_get_state (device)));
req = nm_device_get_act_request (device);
g_assert (req);
if (!nm_modem_connection_secrets_updated (priv->modem,
req,
connection,
updated_settings,
caller)) {
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS);
return;
}
/* PPP handles stuff itself... */
if (caller == SECRETS_CALLER_PPP)
return;
/* Otherwise, on success for modem secrets we need to schedule stage1 again */
g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH);
nm_device_activate_schedule_stage1_device_prepare (device);
}
static gboolean
real_check_connection_compatible (NMDevice *device,
NMConnection *connection,
@ -365,7 +338,8 @@ set_modem (NMDeviceModem *self, NMModem *modem)
g_signal_connect (modem, NM_MODEM_PPP_FAILED, G_CALLBACK (ppp_failed), self);
g_signal_connect (modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK (modem_prepare_result), self);
g_signal_connect (modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK (modem_ip4_config_result), self);
g_signal_connect (modem, NM_MODEM_NEED_AUTH, G_CALLBACK (modem_need_auth), self);
g_signal_connect (modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK (modem_auth_requested), self);
g_signal_connect (modem, NM_MODEM_AUTH_RESULT, G_CALLBACK (modem_auth_result), self);
g_signal_connect (modem, "notify::" NM_MODEM_ENABLED, G_CALLBACK (modem_enabled_cb), self);
}
@ -426,7 +400,6 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass)
device_class->get_generic_capabilities = real_get_generic_capabilities;
device_class->get_best_auto_connection = real_get_best_auto_connection;
device_class->connection_secrets_updated = real_connection_secrets_updated;
device_class->check_connection_compatible = real_check_connection_compatible;
device_class->hw_is_up = real_hw_is_up;
device_class->hw_bring_up = real_hw_bring_up;

View file

@ -2245,6 +2245,27 @@ cleanup_association_attempt (NMDeviceWifi *self, gboolean disconnect)
nm_supplicant_interface_disconnect (priv->supplicant.iface);
}
static void
wifi_secrets_cb (NMActRequest *req,
guint32 call_id,
NMConnection *connection,
GError *error,
gpointer user_data)
{
NMDevice *dev = NM_DEVICE (user_data);
g_return_if_fail (req == nm_device_get_act_request (dev));
g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH);
g_return_if_fail (nm_act_request_get_connection (req) == connection);
if (error) {
nm_log_warn (LOGD_WIFI, "%s", error->message);
nm_device_state_changed (dev,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_NO_SECRETS);
} else
nm_device_activate_schedule_stage1_device_prepare (dev);
}
static void
remove_link_timeout (NMDeviceWifi *self)
@ -2340,11 +2361,12 @@ link_timeout_cb (gpointer user_data)
cleanup_association_attempt (self, TRUE);
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
nm_act_request_get_secrets (req,
NULL,
setting_name,
TRUE,
SECRETS_CALLER_WIFI,
NULL,
NULL);
wifi_secrets_cb,
self);
return FALSE;
}
@ -2586,11 +2608,12 @@ handle_auth_or_fail (NMDeviceWifi *self,
*/
get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE);
nm_act_request_get_secrets (req,
NULL,
setting_name,
get_new,
SECRETS_CALLER_WIFI,
NULL,
NULL);
wifi_secrets_cb,
self);
g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
} else {
@ -2966,42 +2989,6 @@ done:
return NM_ACT_STAGE_RETURN_SUCCESS;
}
static void
real_connection_secrets_updated (NMDevice *dev,
NMConnection *connection,
GSList *updated_settings,
RequestSecretsCaller caller)
{
NMActRequest *req;
gboolean valid = FALSE;
GSList *iter;
g_return_if_fail (caller == SECRETS_CALLER_WIFI);
if (nm_device_get_state (dev) != NM_DEVICE_STATE_NEED_AUTH)
return;
for (iter = updated_settings; iter; iter = g_slist_next (iter)) {
const char *setting_name = (const char *) iter->data;
if ( !strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME)
|| !strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME)) {
valid = TRUE;
} else {
nm_log_warn (LOGD_DEVICE, "Ignoring updated secrets for setting '%s'.",
setting_name);
}
}
req = nm_device_get_act_request (dev);
g_assert (req);
g_return_if_fail (nm_act_request_get_connection (req) == connection);
nm_device_activate_schedule_stage1_device_prepare (dev);
}
static NMActStageReturn
real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
{
@ -3712,7 +3699,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
parent_class->update_initial_hw_address = real_update_initial_hw_address;
parent_class->get_best_auto_connection = real_get_best_auto_connection;
parent_class->is_available = real_is_available;
parent_class->connection_secrets_updated = real_connection_secrets_updated;
parent_class->check_connection_compatible = real_check_connection_compatible;
parent_class->act_stage1_prepare = real_act_stage1_prepare;

View file

@ -2849,31 +2849,6 @@ check_connection_compatible (NMDeviceInterface *dev_iface,
return TRUE;
}
static void
connection_secrets_updated_cb (NMActRequest *req,
NMConnection *connection,
GSList *updated_settings,
RequestSecretsCaller caller,
gpointer user_data)
{
NMDevice *self = NM_DEVICE (user_data);
if (NM_DEVICE_GET_CLASS (self)->connection_secrets_updated)
NM_DEVICE_GET_CLASS (self)->connection_secrets_updated (self, connection, updated_settings, caller);
}
static void
connection_secrets_failed_cb (NMActRequest *req,
NMConnection *connection,
const char *setting_name,
RequestSecretsCaller caller,
gpointer user_data)
{
NMDevice *self = NM_DEVICE (user_data);
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS);
}
static gboolean
device_activation_precheck (NMDevice *self, NMConnection *connection, GError **error)
{
@ -2916,14 +2891,6 @@ nm_device_activate (NMDeviceInterface *device,
}
priv->act_request = g_object_ref (req);
priv->secrets_updated_id = g_signal_connect (req,
"connection-secrets-updated",
G_CALLBACK (connection_secrets_updated_cb),
device);
priv->secrets_failed_id = g_signal_connect (req,
"connection-secrets-failed",
G_CALLBACK (connection_secrets_failed_cb),
device);
if (!nm_act_request_get_assumed (req)) {
/* HACK: update the state a bit early to avoid a race between the

View file

@ -84,11 +84,6 @@ typedef struct {
GSList *connections,
char **specific_object);
void (* connection_secrets_updated) (NMDevice *self,
NMConnection *connection,
GSList *updated_settings,
RequestSecretsCaller caller);
gboolean (* check_connection_compatible) (NMDevice *self,
NMConnection *connection,
GError **error);

View file

@ -54,8 +54,8 @@
#include "nm-bluez-common.h"
#include "nm-settings.h"
#include "nm-sysconfig-connection.h"
#include "nm-secrets-provider-interface.h"
#include "nm-manager-auth.h"
#include "nm-agent-manager.h"
#define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd"
#define NM_AUTOIP_DBUS_IFACE "org.freedesktop.nm_avahi_autoipd"
@ -202,8 +202,7 @@ typedef struct {
NMSettings *settings;
char *hostname;
GSList *secrets_calls;
NMAgentManager *agent_mgr;
RadioState radio_states[RFKILL_TYPE_MAX];
gboolean sleeping;
@ -1718,194 +1717,6 @@ nm_manager_get_act_request_by_path (NMManager *manager,
return NULL;
}
typedef struct GetSecretsInfo {
NMManager *manager;
NMSecretsProviderInterface *provider;
char *setting_name;
RequestSecretsCaller caller;
gboolean request_new;
/* User connection bits */
DBusGProxy *proxy;
DBusGProxyCall *call;
/* System connection bits */
guint32 idle_id;
char *hint1;
char *hint2;
char *connection_path;
} GetSecretsInfo;
static void
free_get_secrets_info (gpointer data)
{
GetSecretsInfo *info = data;
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (info->manager);
g_object_weak_unref (G_OBJECT (info->provider), (GWeakNotify) free_get_secrets_info, info);
priv->secrets_calls = g_slist_remove (priv->secrets_calls, info);
if (info->proxy) {
if (info->call)
dbus_g_proxy_cancel_call (info->proxy, info->call);
g_object_unref (info->proxy);
}
if (info->idle_id)
g_source_remove (info->idle_id);
g_free (info->hint1);
g_free (info->hint2);
g_free (info->setting_name);
g_free (info->connection_path);
memset (info, 0, sizeof (GetSecretsInfo));
g_free (info);
}
static void
provider_cancel_secrets (NMSecretsProviderInterface *provider, gpointer user_data)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (user_data);
GSList *iter;
for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) {
GetSecretsInfo *candidate = iter->data;
if (candidate->provider == provider) {
free_get_secrets_info (candidate);
break;
}
}
}
static void
system_get_secrets_reply_cb (NMSysconfigConnection *connection,
GHashTable *secrets,
GError *error,
gpointer user_data)
{
GetSecretsInfo *info = user_data;
GObject *provider;
provider = g_object_ref (info->provider);
nm_secrets_provider_interface_get_secrets_result (info->provider,
info->setting_name,
info->caller,
error ? NULL : secrets,
error);
free_get_secrets_info (info);
g_object_unref (provider);
}
static gboolean
system_get_secrets_idle_cb (gpointer user_data)
{
GetSecretsInfo *info = user_data;
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (info->manager);
NMSysconfigConnection *connection;
GError *error = NULL;
const char *hints[3] = { NULL, NULL, NULL };
info->idle_id = 0;
connection = nm_settings_get_connection_by_path (priv->settings, info->connection_path);
if (!connection) {
error = g_error_new_literal (NM_MANAGER_ERROR,
NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
"unknown connection (not exported by system settings)");
nm_secrets_provider_interface_get_secrets_result (info->provider,
info->setting_name,
info->caller,
NULL,
error);
g_error_free (error);
free_get_secrets_info (info);
return FALSE;
}
hints[0] = info->hint1;
hints[1] = info->hint2;
nm_sysconfig_connection_get_secrets (connection,
info->setting_name,
hints,
info->request_new,
system_get_secrets_reply_cb,
info);
return FALSE;
}
static GetSecretsInfo *
system_get_secrets (NMManager *self,
NMSecretsProviderInterface *provider,
NMConnection *connection,
const char *setting_name,
gboolean request_new,
RequestSecretsCaller caller_id,
const char *hint1,
const char *hint2)
{
GetSecretsInfo *info;
info = g_malloc0 (sizeof (GetSecretsInfo));
info->manager = self;
info->provider = provider;
info->caller = caller_id;
info->setting_name = g_strdup (setting_name);
info->hint1 = hint1 ? g_strdup (hint1) : NULL;
info->hint2 = hint2 ? g_strdup (hint2) : NULL;
info->connection_path = g_strdup (nm_connection_get_path (connection));
info->request_new = request_new;
g_object_weak_ref (G_OBJECT (provider), (GWeakNotify) free_get_secrets_info, info);
info->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
system_get_secrets_idle_cb,
info,
NULL);
return info;
}
static gboolean
provider_get_secrets (NMSecretsProviderInterface *provider,
NMConnection *connection,
const char *setting_name,
gboolean request_new,
RequestSecretsCaller caller_id,
const char *hint1,
const char *hint2,
gpointer user_data)
{
NMManager *self = NM_MANAGER (user_data);
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
GetSecretsInfo *info = NULL;
GSList *iter;
g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (setting_name != NULL, FALSE);
/* Tear down any pending secrets requests for this secrets provider */
for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) {
GetSecretsInfo *candidate = iter->data;
if (provider == candidate->provider) {
free_get_secrets_info (candidate);
break;
}
}
/* Build up the new secrets request */
info = system_get_secrets (self, provider, connection, setting_name,
request_new, caller_id, hint1, hint2);
if (info)
priv->secrets_calls = g_slist_append (priv->secrets_calls, info);
return !!info;
}
static const char *
internal_activate_device (NMManager *manager,
NMDevice *device,
@ -1936,9 +1747,12 @@ internal_activate_device (NMManager *manager,
NM_DEVICE_STATE_REASON_NONE);
}
req = nm_act_request_new (connection, specific_object, user_requested, assumed, (gpointer) device);
g_signal_connect (req, "manager-get-secrets", G_CALLBACK (provider_get_secrets), manager);
g_signal_connect (req, "manager-cancel-secrets", G_CALLBACK (provider_cancel_secrets), manager);
req = nm_act_request_new (connection,
specific_object,
NM_MANAGER_GET_PRIVATE (manager)->agent_mgr,
user_requested,
assumed,
(gpointer) device);
success = nm_device_interface_activate (dev_iface, req, error);
g_object_unref (req);
@ -1970,15 +1784,15 @@ nm_manager_activate_connection (NMManager *manager,
g_assert (s_con);
if (!strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_VPN_SETTING_NAME)) {
NMActRequest *req = NULL;
NMActRequest *parent_req = NULL;
NMVPNManager *vpn_manager;
/* VPN connection */
if (specific_object) {
/* Find the specifc connection the client requested we use */
req = nm_manager_get_act_request_by_path (manager, specific_object, &device);
if (!req) {
parent_req = nm_manager_get_act_request_by_path (manager, specific_object, &device);
if (!parent_req) {
g_set_error (error,
NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
"%s", "Base connection for VPN connection not active.");
@ -1995,13 +1809,13 @@ nm_manager_activate_connection (NMManager *manager,
candidate_req = nm_device_get_act_request (candidate);
if (candidate_req && nm_act_request_get_default (candidate_req)) {
device = candidate;
req = candidate_req;
parent_req = candidate_req;
break;
}
}
}
if (!device || !req) {
if (!device || !parent_req) {
g_set_error (error,
NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
"%s", "Could not find source connection, or the source connection had no active device.");
@ -2011,16 +1825,11 @@ nm_manager_activate_connection (NMManager *manager,
vpn_manager = nm_vpn_manager_get ();
vpn_connection = nm_vpn_manager_activate_connection (vpn_manager,
connection,
req,
parent_req,
device,
error);
if (vpn_connection) {
g_signal_connect (vpn_connection, "manager-get-secrets",
G_CALLBACK (provider_get_secrets), manager);
g_signal_connect (vpn_connection, "manager-cancel-secrets",
G_CALLBACK (provider_cancel_secrets), manager);
if (vpn_connection)
path = nm_vpn_connection_get_active_connection_path (vpn_connection);
}
g_object_unref (vpn_manager);
} else {
NMDeviceState state;
@ -3072,6 +2881,8 @@ nm_manager_get (NMSettings *settings,
priv->settings = g_object_ref (settings);
priv->agent_mgr = nm_agent_manager_new (priv->dbus_mgr);
priv->config_file = g_strdup (config_file);
priv->state_file = g_strdup (state_file);
@ -3142,9 +2953,6 @@ dispose (GObject *object)
g_slist_free (priv->auth_chains);
g_object_unref (priv->authority);
while (g_slist_length (priv->secrets_calls))
free_get_secrets_info ((GetSecretsInfo *) priv->secrets_calls->data);
while (g_slist_length (priv->devices)) {
priv->devices = remove_one_device (manager,
priv->devices,
@ -3157,6 +2965,8 @@ dispose (GObject *object)
g_object_unref (priv->settings);
g_object_unref (priv->agent_mgr);
if (priv->vpn_manager_id) {
g_source_remove (priv->vpn_manager_id);
priv->vpn_manager_id = 0;

View file

@ -1,224 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager -- Network link manager
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2009 Red Hat, Inc.
*/
#include <string.h>
#include "nm-marshal.h"
#include "nm-secrets-provider-interface.h"
#include <nm-setting-8021x.h>
#include <nm-setting-wireless-security.h>
#include "nm-logging.h"
static void
nm_secrets_provider_interface_init (gpointer g_iface)
{
GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
static gboolean initialized = FALSE;
if (initialized)
return;
initialized = TRUE;
/* Signals */
g_signal_new ("manager-get-secrets",
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (NMSecretsProviderInterface, manager_get_secrets),
NULL, NULL,
_nm_marshal_BOOLEAN__POINTER_STRING_BOOLEAN_UINT_STRING_STRING,
G_TYPE_BOOLEAN, 6,
G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
g_signal_new ("manager-cancel-secrets",
iface_type,
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSecretsProviderInterface, manager_cancel_secrets),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
GType
nm_secrets_provider_interface_get_type (void)
{
static GType interface_type = 0;
if (!interface_type) {
const GTypeInfo interface_info = {
sizeof (NMSecretsProviderInterface), /* class_size */
nm_secrets_provider_interface_init, /* base_init */
NULL, /* base_finalize */
NULL,
NULL, /* class_finalize */
NULL, /* class_data */
0,
0, /* n_preallocs */
NULL
};
interface_type = g_type_register_static (G_TYPE_INTERFACE,
"NMSecretsProviderInterface",
&interface_info, 0);
g_type_interface_add_prerequisite (interface_type, G_TYPE_OBJECT);
}
return interface_type;
}
gboolean
nm_secrets_provider_interface_get_secrets (NMSecretsProviderInterface *self,
NMConnection *connection,
const char *setting_name,
gboolean request_new,
RequestSecretsCaller caller,
const char *hint1,
const char *hint2)
{
guint success = FALSE;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (NM_IS_SECRETS_PROVIDER_INTERFACE (self), FALSE);
g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
g_return_val_if_fail (setting_name != NULL, FALSE);
nm_secrets_provider_interface_cancel_get_secrets (self);
g_signal_emit_by_name (self, "manager-get-secrets",
connection, setting_name, request_new, caller, hint1, hint2,
&success);
if (!success) {
nm_log_warn (LOGD_CORE, "failed to get connection secrets.");
return FALSE;
}
return TRUE;
}
void
nm_secrets_provider_interface_cancel_get_secrets (NMSecretsProviderInterface *self)
{
g_return_if_fail (self != NULL);
g_return_if_fail (NM_IS_SECRETS_PROVIDER_INTERFACE (self));
g_signal_emit_by_name (self, "manager-cancel-secrets");
}
static void
add_one_key_to_list (gpointer key, gpointer data, gpointer user_data)
{
GSList **list = (GSList **) user_data;
*list = g_slist_append (*list, key);
}
static gint
settings_order_func (gconstpointer a, gconstpointer b)
{
/* Just ensure the 802.1x setting gets processed _before_ the
* wireless-security one.
*/
if ( !strcmp (a, NM_SETTING_802_1X_SETTING_NAME)
&& !strcmp (b, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME))
return -1;
if ( !strcmp (a, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME)
&& !strcmp (b, NM_SETTING_802_1X_SETTING_NAME))
return 1;
return 0;
}
void
nm_secrets_provider_interface_get_secrets_result (NMSecretsProviderInterface *self,
const char *setting_name,
RequestSecretsCaller caller,
GHashTable *settings,
GError *error)
{
GSList *keys = NULL, *iter;
GSList *updated = NULL;
GError *tmp_error = NULL;
g_return_if_fail (self != NULL);
g_return_if_fail (NM_IS_SECRETS_PROVIDER_INTERFACE (self));
if (error) {
NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self,
setting_name,
caller,
NULL,
error);
return;
}
if (g_hash_table_size (settings) == 0) {
g_set_error (&tmp_error, 0, 0, "%s", "no secrets were received!");
NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self,
setting_name,
caller,
NULL,
tmp_error);
g_clear_error (&tmp_error);
return;
}
g_hash_table_foreach (settings, add_one_key_to_list, &keys);
keys = g_slist_sort (keys, settings_order_func);
for (iter = keys; iter; iter = g_slist_next (iter)) {
GHashTable *hash;
const char *name = (const char *) iter->data;
hash = g_hash_table_lookup (settings, name);
if (!hash) {
nm_log_warn (LOGD_CORE, "couldn't get setting secrets for '%s'", name);
continue;
}
if (NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->update_setting (self, name, hash))
updated = g_slist_append (updated, (gpointer) setting_name);
}
g_slist_free (keys);
if (g_slist_length (updated)) {
NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self,
setting_name,
caller,
updated,
NULL);
} else {
g_set_error (&tmp_error, 0, 0, "%s", "no secrets updated because no valid "
"settings were received!");
NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self,
setting_name,
caller,
NULL,
tmp_error);
g_clear_error (&tmp_error);
}
g_slist_free (updated);
}

View file

@ -1,90 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager -- Network link manager
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2009 Red Hat, Inc.
*/
#ifndef NM_SECRETS_PROVIDER_INTERFACE_H
#define NM_SECRETS_PROVIDER_INTERFACE_H
#include <glib-object.h>
#include <nm-connection.h>
typedef enum {
SECRETS_CALLER_NONE = 0,
SECRETS_CALLER_ETHERNET,
SECRETS_CALLER_WIFI,
SECRETS_CALLER_MOBILE_BROADBAND,
SECRETS_CALLER_PPP,
SECRETS_CALLER_VPN
} RequestSecretsCaller;
#define NM_TYPE_SECRETS_PROVIDER_INTERFACE (nm_secrets_provider_interface_get_type ())
#define NM_SECRETS_PROVIDER_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRETS_PROVIDER_INTERFACE, NMSecretsProviderInterface))
#define NM_IS_SECRETS_PROVIDER_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SECRETS_PROVIDER_INTERFACE))
#define NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SECRETS_PROVIDER_INTERFACE, NMSecretsProviderInterface))
typedef struct _NMSecretsProviderInterface NMSecretsProviderInterface;
struct _NMSecretsProviderInterface {
GTypeInterface g_iface;
/* Methods */
void (*result) (NMSecretsProviderInterface *self,
const char *setting_name,
RequestSecretsCaller caller,
const GSList *updated,
GError *error);
gboolean (*update_setting) (NMSecretsProviderInterface *self,
const char *setting_name,
GHashTable *new);
/* Signals */
void (*manager_get_secrets) (NMSecretsProviderInterface *self,
NMConnection *connection,
const char *setting_name,
gboolean request_new,
RequestSecretsCaller caller,
const char *hint1,
const char *hint2);
void (*manager_cancel_secrets) (NMSecretsProviderInterface *self);
};
GType nm_secrets_provider_interface_get_type (void);
/* For callers */
gboolean nm_secrets_provider_interface_get_secrets (NMSecretsProviderInterface *self,
NMConnection *connection,
const char *setting_name,
gboolean request_new,
RequestSecretsCaller caller,
const char *hint1,
const char *hint2);
void nm_secrets_provider_interface_cancel_get_secrets (NMSecretsProviderInterface *self);
/* For NMManager */
void nm_secrets_provider_interface_get_secrets_result (NMSecretsProviderInterface *self,
const char *setting_name,
RequestSecretsCaller caller,
GHashTable *settings,
GError *error);
#endif /* NM_SECRETS_PROVIDER_INTERFACE_H */

View file

@ -78,6 +78,7 @@ typedef struct {
NMActRequest *act_req;
DBusGMethodInvocation *pending_secrets_context;
guint32 secrets_id;
guint32 ppp_watch_id;
guint32 ppp_timeout_handler;
@ -334,19 +335,29 @@ remove_timeout_handler (NMPPPManager *manager)
}
static void
impl_ppp_manager_need_secrets (NMPPPManager *manager,
DBusGMethodInvocation *context)
cancel_get_secrets (NMPPPManager *self)
{
NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager);
NMConnection *connection;
NMSettingConnection *s_con;
const char *connection_type;
const char *setting_name;
guint32 tries;
GPtrArray *hints = NULL;
const char *hint1 = NULL, *hint2 = NULL;
NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self);
connection = nm_act_request_get_connection (priv->act_req);
if (priv->secrets_id) {
nm_act_request_cancel_secrets (priv->act_req, priv->secrets_id);
priv->secrets_id = 0;
}
}
static gboolean
extract_details_from_connection (NMConnection *connection,
const char **username,
const char **password,
GError **error)
{
NMSettingConnection *s_con;
NMSetting *setting;
const char *connection_type;
g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (username != NULL, FALSE);
g_return_val_if_fail (password != NULL, FALSE);
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
g_assert (s_con);
@ -354,67 +365,114 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager,
connection_type = nm_setting_connection_get_connection_type (s_con);
g_assert (connection_type);
setting = nm_connection_get_setting_by_name (connection, connection_type);
if (!setting) {
g_set_error_literal (error, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR_UNKOWN,
"Missing type-specific setting; no secrets could be found.");
return FALSE;
}
/* FIXME: push this down to the settings and keep PPP manager generic */
if (NM_IS_SETTING_PPPOE (setting)) {
*username = nm_setting_pppoe_get_username (NM_SETTING_PPPOE (setting));
*password = nm_setting_pppoe_get_password (NM_SETTING_PPPOE (setting));
} else if (NM_IS_SETTING_GSM (setting)) {
*username = nm_setting_gsm_get_username (NM_SETTING_GSM (setting));
*password = nm_setting_gsm_get_password (NM_SETTING_GSM (setting));
} else if (NM_IS_SETTING_CDMA (setting)) {
*username = nm_setting_cdma_get_username (NM_SETTING_CDMA (setting));
*password = nm_setting_cdma_get_password (NM_SETTING_CDMA (setting));
}
return TRUE;
}
static void
ppp_secrets_cb (NMActRequest *req,
guint32 call_id,
NMConnection *connection,
GError *error,
gpointer user_data)
{
NMPPPManager *self = NM_PPP_MANAGER (user_data);
NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self);
const char *username = NULL;
const char *password = NULL;
GError *local = NULL;
g_return_if_fail (priv->pending_secrets_context != NULL);
g_return_if_fail (req == priv->act_req);
g_return_if_fail (call_id == priv->secrets_id);
if (error) {
nm_log_warn (LOGD_PPP, "%s", error->message);
dbus_g_method_return_error (priv->pending_secrets_context, error);
goto out;
}
if (!extract_details_from_connection (connection, &username, &password, &local)) {
nm_log_warn (LOGD_PPP, "%s", local->message);
dbus_g_method_return_error (priv->pending_secrets_context, local);
g_clear_error (&local);
goto out;
}
/* This is sort of a hack but...
* pppd plugin only ever needs username and password. Passing the full
* connection there would mean some bloat: the plugin would need to link
* against libnm-util just to parse this. So instead, let's just send what
* it needs.
*/
dbus_g_method_return (priv->pending_secrets_context, username, password);
out:
priv->pending_secrets_context = NULL;
priv->secrets_id = 0;
}
static void
impl_ppp_manager_need_secrets (NMPPPManager *manager,
DBusGMethodInvocation *context)
{
NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager);
NMConnection *connection;
const char *setting_name;
const char *username = NULL;
const char *password = NULL;
guint32 tries;
GPtrArray *hints = NULL;
GError *error = NULL;
connection = nm_act_request_get_connection (priv->act_req);
nm_connection_clear_secrets (connection);
setting_name = nm_connection_need_secrets (connection, &hints);
if (!setting_name) {
NMSetting *setting;
setting = nm_connection_get_setting_by_name (connection, connection_type);
if (setting) {
const char *username = NULL;
const char *password = NULL;
/* FIXME: push this down to the settings and keep PPP manager generic */
if (NM_IS_SETTING_PPPOE (setting)) {
username = nm_setting_pppoe_get_username (NM_SETTING_PPPOE (setting));
password = nm_setting_pppoe_get_password (NM_SETTING_PPPOE (setting));
} else if (NM_IS_SETTING_GSM (setting)) {
username = nm_setting_gsm_get_username (NM_SETTING_GSM (setting));
password = nm_setting_gsm_get_password (NM_SETTING_GSM (setting));
} else if (NM_IS_SETTING_CDMA (setting)) {
username = nm_setting_cdma_get_username (NM_SETTING_CDMA (setting));
password = nm_setting_cdma_get_password (NM_SETTING_CDMA (setting));
}
/* If secrets are not required, send the existing username and password
* back to the PPP plugin immediately.
*/
/* Use existing secrets from the connection */
if (extract_details_from_connection (connection, &username, &password, &error)) {
/* Send existing secrets to the PPP plugin */
priv->pending_secrets_context = context;
nm_ppp_manager_update_secrets (manager,
priv->parent_iface,
username ? username : "",
password ? password : "",
NULL);
ppp_secrets_cb (priv->act_req, priv->secrets_id, connection, NULL, manager);
} else {
GError *err = NULL;
g_set_error (&err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR_UNKOWN,
"Missing type-specific setting; no secrets could be found.");
nm_log_warn (LOGD_PPP, "%s", err->message);
dbus_g_method_return_error (context, err);
nm_log_warn (LOGD_PPP, "%s", error->message);
dbus_g_method_return_error (priv->pending_secrets_context, error);
g_clear_error (&error);
}
return;
}
/* Extract hints */
if (hints) {
if (hints->len > 0)
hint1 = g_ptr_array_index (hints, 0);
if (hints->len > 1)
hint2 = g_ptr_array_index (hints, 1);
}
tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES));
/* Only ask for completely new secrets after retrying them once; some PPP
* servers (T-Mobile USA) appear to ask a few times when they actually don't
* even care what you pass back.
*/
nm_act_request_get_secrets (priv->act_req,
setting_name,
tries > 1 ? TRUE : FALSE,
SECRETS_CALLER_PPP,
hint1,
hint2);
priv->secrets_id = nm_act_request_get_secrets (priv->act_req,
NULL,
setting_name,
tries > 1 ? TRUE : FALSE,
hints ? g_ptr_array_index (hints, 0) : NULL,
ppp_secrets_cb,
manager);
g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, GUINT_TO_POINTER (++tries));
priv->pending_secrets_context = context;
@ -955,46 +1013,6 @@ nm_ppp_manager_start (NMPPPManager *manager,
return priv->pid > 0;
}
void
nm_ppp_manager_update_secrets (NMPPPManager *manager,
const char *device,
const char *username,
const char *password,
const char *error_message)
{
NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager);
g_return_if_fail (NM_IS_PPP_MANAGER (manager));
g_return_if_fail (device != NULL);
g_return_if_fail (priv->pending_secrets_context != NULL);
if (error_message) {
g_return_if_fail (username == NULL);
g_return_if_fail (password == NULL);
} else {
g_return_if_fail (username != NULL);
g_return_if_fail (password != NULL);
}
if (error_message) {
GError *err = NULL;
g_set_error (&err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR_UNKOWN, "%s", error_message);
nm_log_warn (LOGD_PPP, "%s", error_message);
dbus_g_method_return_error (priv->pending_secrets_context, err);
g_error_free (err);
} else {
/* This is sort of a hack but...
pppd plugin only ever needs username and password.
Passing the full connection there would mean some bloat:
the plugin would need to link against libnm-util just to parse this.
So instead, let's just send what it needs */
dbus_g_method_return (priv->pending_secrets_context, username, password);
}
priv->pending_secrets_context = NULL;
}
static gboolean
ensure_killed (gpointer data)
{
@ -1020,6 +1038,8 @@ nm_ppp_manager_stop (NMPPPManager *manager)
priv = NM_PPP_MANAGER_GET_PRIVATE (manager);
cancel_get_secrets (manager);
if (priv->monitor_id) {
g_source_remove (priv->monitor_id);
priv->monitor_id = 0;

View file

@ -16,7 +16,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2008 Novell, Inc.
* Copyright (C) 2008 Red Hat, Inc.
* Copyright (C) 2008 - 2010 Red Hat, Inc.
*/
#ifndef NM_PPP_MANAGER_H
@ -63,12 +63,6 @@ gboolean nm_ppp_manager_start (NMPPPManager *manager,
guint32 timeout_secs,
GError **err);
void nm_ppp_manager_update_secrets (NMPPPManager *manager,
const char *device,
const char *username,
const char *password,
const char *error_message);
void nm_ppp_manager_stop (NMPPPManager *manager);

View file

@ -50,11 +50,7 @@
#include "nm-vpn-connection-glue.h"
static void secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class);
G_DEFINE_TYPE_EXTENDED (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (NM_TYPE_SECRETS_PROVIDER_INTERFACE,
secrets_provider_interface_init))
G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT)
typedef struct {
gboolean disposed;
@ -63,6 +59,7 @@ typedef struct {
NMActRequest *act_request;
char *ac_path;
guint32 secrets_id;
NMDevice *parent_dev;
gulong device_monitor;
@ -784,6 +781,7 @@ nm_vpn_connection_disconnect (NMVPNConnection *connection,
/******************************************************************************/
#if 0
static gboolean
secrets_update_setting (NMSecretsProviderInterface *interface,
const char *setting_name,
@ -807,19 +805,33 @@ secrets_update_setting (NMSecretsProviderInterface *interface,
}
return TRUE;
}
#endif
static void
secrets_result (NMSecretsProviderInterface *interface,
const char *setting_name,
RequestSecretsCaller caller,
const GSList *updated,
GError *error)
cancel_get_secrets (NMVPNConnection *self)
{
NMVPNConnection *self = NM_VPN_CONNECTION (interface);
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
g_return_if_fail (priv->connection != NULL);
g_return_if_fail (caller == SECRETS_CALLER_VPN);
if (priv->secrets_id) {
nm_act_request_cancel_secrets (priv->act_request, priv->secrets_id);
priv->secrets_id = 0;
}
}
static void
vpn_secrets_cb (NMActRequest *req,
guint32 call_id,
NMConnection *connection,
GError *error,
gpointer user_data)
{
NMVPNConnection *self = NM_VPN_CONNECTION (user_data);
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
g_return_if_fail (req == priv->act_request);
g_return_if_fail (call_id == priv->secrets_id);
priv->secrets_id = 0;
if (error)
nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS);
@ -827,14 +839,6 @@ secrets_result (NMSecretsProviderInterface *interface,
really_activate (self);
}
static void
secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class)
{
/* interface implementation */
sp_interface_class->update_setting = secrets_update_setting;
sp_interface_class->result = secrets_result;
}
static void
connection_need_secrets_cb (DBusGProxy *proxy,
char *setting_name,
@ -858,14 +862,14 @@ connection_need_secrets_cb (DBusGProxy *proxy,
return;
}
/* Get the secrets the VPN plugin wants */
if (!nm_secrets_provider_interface_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (self),
priv->connection,
setting_name,
FALSE,
SECRETS_CALLER_VPN,
NULL,
NULL))
priv->secrets_id = nm_act_request_get_secrets (priv->act_request,
priv->connection,
setting_name,
FALSE,
NULL,
vpn_secrets_cb,
self);
if (!priv->secrets_id)
nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS);
}
@ -944,17 +948,17 @@ vpn_cleanup (NMVPNConnection *connection)
}
static void
connection_state_changed (NMVPNConnection *connection,
connection_state_changed (NMVPNConnection *self,
NMVPNConnectionState state,
NMVPNConnectionStateReason reason)
{
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
nm_secrets_provider_interface_cancel_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (priv->act_request));
cancel_get_secrets (self);
switch (state) {
case NM_VPN_CONNECTION_STATE_NEED_AUTH:
call_need_secrets (connection);
call_need_secrets (self);
break;
case NM_VPN_CONNECTION_STATE_DISCONNECTED:
case NM_VPN_CONNECTION_STATE_FAILED:
@ -970,7 +974,7 @@ connection_state_changed (NMVPNConnection *connection,
g_object_unref (priv->proxy);
priv->proxy = NULL;
}
vpn_cleanup (connection);
vpn_cleanup (self);
break;
default:
break;
@ -1025,6 +1029,9 @@ dispose (GObject *object)
if (priv->proxy)
g_object_unref (priv->proxy);
if (priv->secrets_id)
nm_act_request_cancel_secrets (priv->act_request, priv->secrets_id);
g_object_unref (priv->act_request);
g_object_unref (priv->connection);

View file

@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2005 - 2008 Red Hat, Inc.
* Copyright (C) 2005 - 2010 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@ -27,7 +27,6 @@
#include "NetworkManagerVPN.h"
#include "nm-device.h"
#include "nm-activation-request.h"
#include "nm-secrets-provider-interface.h"
#define NM_TYPE_VPN_CONNECTION (nm_vpn_connection_get_type ())
#define NM_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnection))