1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301 USA.
18 * Copyright 2010 - 2011 Red Hat, Inc.
21 #include "nm-default.h"
24 #include <dbus/dbus-glib-lowlevel.h>
26 #include "NetworkManager.h"
27 #include "nm-secret-agent.h"
28 #include "nm-glib-enum-types.h"
29 #include "nm-dbus-helpers-private.h"
30 #include "nm-setting-private.h"
32 static void impl_secret_agent_get_secrets (NMSecretAgent *self,
33 GHashTable *connection_hash,
34 const char *connection_path,
35 const char *setting_name,
38 DBusGMethodInvocation *context);
40 static void impl_secret_agent_cancel_get_secrets (NMSecretAgent *self,
41 const char *connection_path,
42 const char *setting_name,
43 DBusGMethodInvocation *context);
45 static void impl_secret_agent_save_secrets (NMSecretAgent *self,
46 GHashTable *connection_hash,
47 const char *connection_path,
48 DBusGMethodInvocation *context);
50 static void impl_secret_agent_delete_secrets (NMSecretAgent *self,
51 GHashTable *connection_hash,
52 const char *connection_path,
53 DBusGMethodInvocation *context);
55 #include "nm-secret-agent-glue.h"
57 G_DEFINE_ABSTRACT_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT)
59 #define NM_SECRET_AGENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SECRET_AGENT, NMSecretAgentPrivate))
61 static gboolean auto_register_cb (gpointer user_data);
65 NMSecretAgentCapabilities capabilities;
68 DBusGProxy *dbus_proxy;
69 DBusGProxy *manager_proxy;
70 DBusGProxyCall *reg_call;
72 /* GetSecretsInfo structs of in-flight GetSecrets requests */
78 gboolean auto_register;
79 gboolean suppress_auto;
80 gboolean auto_register_id;
81 } NMSecretAgentPrivate;
99 static guint signals[LAST_SIGNAL] = { 0 };
102 /********************************************************************/
105 nm_secret_agent_error_quark (void)
107 static GQuark ret = 0;
109 if (G_UNLIKELY (ret == 0))
110 ret = g_quark_from_static_string ("nm-secret-agent-error");
114 /*************************************************************/
117 get_nm_owner (NMSecretAgent *self)
119 NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
120 GError *error = NULL;
123 if (!priv->nm_owner) {
124 if (!dbus_g_proxy_call_with_timeout (priv->dbus_proxy,
125 "GetNameOwner", 2000, &error,
126 G_TYPE_STRING, NM_DBUS_SERVICE,
128 G_TYPE_STRING, &owner,
132 priv->nm_owner = g_strdup (owner);
136 return priv->nm_owner;
140 _internal_unregister (NMSecretAgent *self)
142 NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
144 if (priv->registered) {
145 dbus_g_connection_unregister_g_object (priv->bus, G_OBJECT (self));
146 priv->registered = FALSE;
147 g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_REGISTERED);
154 DBusGMethodInvocation *context;
158 get_secrets_info_finalize (NMSecretAgent *self, GetSecretsInfo *info)
160 NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
162 g_return_if_fail (info != NULL);
164 priv->pending_gets = g_slist_remove (priv->pending_gets, info);
167 g_free (info->setting_name);
168 memset (info, 0, sizeof (*info));
173 name_owner_changed (DBusGProxy *proxy,
175 const char *old_owner,
176 const char *new_owner,
179 NMSecretAgent *self = NM_SECRET_AGENT (user_data);
180 NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
181 gboolean old_owner_good = (old_owner && strlen (old_owner));
182 gboolean new_owner_good = (new_owner && strlen (new_owner));
185 if (strcmp (name, NM_DBUS_SERVICE) == 0) {
186 g_free (priv->nm_owner);
187 priv->nm_owner = g_strdup (new_owner);
189 if (!old_owner_good && new_owner_good) {
191 auto_register_cb (self);
192 } else if (old_owner_good && !new_owner_good) {
193 /* Cancel any pending secrets requests */
194 for (iter = priv->pending_gets; iter; iter = g_slist_next (iter)) {
195 GetSecretsInfo *info = iter->data;
197 NM_SECRET_AGENT_GET_CLASS (self)->cancel_get_secrets (self,
201 g_slist_free (priv->pending_gets);
202 priv->pending_gets = NULL;
205 _internal_unregister (self);
206 } else if (old_owner_good && new_owner_good && strcmp (old_owner, new_owner)) {
207 /* Hmm, NM magically restarted */
208 _internal_unregister (self);
209 auto_register_cb (self);
215 verify_sender (NMSecretAgent *self,
216 DBusGMethodInvocation *context,
219 NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
222 const char *nm_owner;
223 DBusError dbus_error;
224 uid_t sender_uid = G_MAXUINT;
225 gboolean allowed = FALSE;
227 g_return_val_if_fail (context != NULL, FALSE);
229 /* Verify the sender's UID is 0, and that the sender is the same as
230 * NetworkManager's bus name owner.
233 nm_owner = get_nm_owner (self);
235 g_set_error_literal (error,
236 NM_SECRET_AGENT_ERROR,
237 NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED,
238 "NetworkManager bus name owner unknown.");
242 bus = dbus_g_connection_get_connection (priv->bus);
244 g_set_error_literal (error,
245 NM_SECRET_AGENT_ERROR,
246 NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED,
247 "Failed to get DBus connection.");
251 sender = dbus_g_method_get_sender (context);
253 g_set_error_literal (error,
254 NM_SECRET_AGENT_ERROR,
255 NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED,
256 "Failed to get request sender.");
260 /* Check that the sender matches the current NM bus name owner */
261 if (strcmp (sender, nm_owner) != 0) {
262 g_set_error_literal (error,
263 NM_SECRET_AGENT_ERROR,
264 NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED,
265 "Request sender does not match NetworkManager bus name owner.");
269 dbus_error_init (&dbus_error);
270 sender_uid = dbus_bus_get_unix_user (bus, sender, &dbus_error);
271 if (dbus_error_is_set (&dbus_error)) {
273 NM_SECRET_AGENT_ERROR,
274 NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED,
275 "Failed to get request unix user: (%s) %s.",
276 dbus_error.name, dbus_error.message);
277 dbus_error_free (&dbus_error);
281 /* We only accept requests from NM, which always runs as root */
282 if (0 != sender_uid) {
283 g_set_error_literal (error,
284 NM_SECRET_AGENT_ERROR,
285 NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED,
286 "Request sender is not root.");
298 verify_request (NMSecretAgent *self,
299 DBusGMethodInvocation *context,
300 GHashTable *connection_hash,
301 const char *connection_path,
302 NMConnection **out_connection,
305 NMConnection *connection = NULL;
307 g_return_val_if_fail (out_connection, FALSE);
309 if (!verify_sender (self, context, error))
312 /* No connection? If the sender verified, then we allow the request */
313 if (connection_hash == NULL)
316 /* If we have a connection hash, we require a path too */
317 if (connection_path == NULL) {
318 g_set_error_literal (error,
319 NM_SECRET_AGENT_ERROR,
320 NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
321 "Invalid connection: no connection path given.");
325 /* Make sure the given connection is valid */
326 connection = _nm_connection_new_from_hash (connection_hash);
327 nm_connection_set_path (connection, connection_path);
328 *out_connection = connection;
334 get_secrets_cb (NMSecretAgent *self,
335 NMConnection *connection,
340 GetSecretsInfo *info = user_data;
343 dbus_g_method_return_error (info->context, error);
345 dbus_g_method_return (info->context, secrets);
347 /* Remove the request from internal tracking */
348 get_secrets_info_finalize (self, info);
352 impl_secret_agent_get_secrets (NMSecretAgent *self,
353 GHashTable *connection_hash,
354 const char *connection_path,
355 const char *setting_name,
358 DBusGMethodInvocation *context)
360 NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
361 GError *error = NULL;
362 NMConnection *connection = NULL;
363 GetSecretsInfo *info;
365 /* Make sure the request comes from NetworkManager and is valid */
366 if (!verify_request (self, context, connection_hash, connection_path, &connection, &error)) {
367 dbus_g_method_return_error (context, error);
368 g_clear_error (&error);
372 info = g_malloc0 (sizeof (GetSecretsInfo));
373 info->path = g_strdup (connection_path);
374 info->setting_name = g_strdup (setting_name);
375 info->context = context;
376 priv->pending_gets = g_slist_append (priv->pending_gets, info);
378 NM_SECRET_AGENT_GET_CLASS (self)->get_secrets (self,
386 g_object_unref (connection);
389 static GetSecretsInfo *
390 find_get_secrets_info (GSList *list, const char *path, const char *setting_name)
394 for (iter = list; iter; iter = g_slist_next (iter)) {
395 GetSecretsInfo *candidate = iter->data;
397 if ( g_strcmp0 (path, candidate->path) == 0
398 && g_strcmp0 (setting_name, candidate->setting_name) == 0)
405 impl_secret_agent_cancel_get_secrets (NMSecretAgent *self,
406 const char *connection_path,
407 const char *setting_name,
408 DBusGMethodInvocation *context)
410 NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
411 GError *error = NULL;
412 GetSecretsInfo *info;
414 /* Make sure the request comes from NetworkManager and is valid */
415 if (!verify_request (self, context, NULL, NULL, NULL, &error)) {
416 dbus_g_method_return_error (context, error);
417 g_clear_error (&error);
421 info = find_get_secrets_info (priv->pending_gets, connection_path, setting_name);
423 g_set_error_literal (&error,
424 NM_SECRET_AGENT_ERROR,
425 NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
426 "No secrets request in progress for this connection.");
427 dbus_g_method_return_error (context, error);
428 g_clear_error (&error);
432 /* Send the cancel request up to the subclass and finalize it */
433 NM_SECRET_AGENT_GET_CLASS (self)->cancel_get_secrets (self,
436 dbus_g_method_return (context);
440 save_secrets_cb (NMSecretAgent *self,
441 NMConnection *connection,
445 DBusGMethodInvocation *context = user_data;
448 dbus_g_method_return_error (context, error);
450 dbus_g_method_return (context);
454 impl_secret_agent_save_secrets (NMSecretAgent *self,
455 GHashTable *connection_hash,
456 const char *connection_path,
457 DBusGMethodInvocation *context)
459 GError *error = NULL;
460 NMConnection *connection = NULL;
462 /* Make sure the request comes from NetworkManager and is valid */
463 if (!verify_request (self, context, connection_hash, connection_path, &connection, &error)) {
464 dbus_g_method_return_error (context, error);
465 g_clear_error (&error);
469 NM_SECRET_AGENT_GET_CLASS (self)->save_secrets (self,
474 g_object_unref (connection);
478 delete_secrets_cb (NMSecretAgent *self,
479 NMConnection *connection,
483 DBusGMethodInvocation *context = user_data;
486 dbus_g_method_return_error (context, error);
488 dbus_g_method_return (context);
492 impl_secret_agent_delete_secrets (NMSecretAgent *self,
493 GHashTable *connection_hash,
494 const char *connection_path,
495 DBusGMethodInvocation *context)
497 GError *error = NULL;
498 NMConnection *connection = NULL;
500 /* Make sure the request comes from NetworkManager and is valid */
501 if (!verify_request (self, context, connection_hash, connection_path, &connection, &error)) {
502 dbus_g_method_return_error (context, error);
503 g_clear_error (&error);
507 NM_SECRET_AGENT_GET_CLASS (self)->delete_secrets (self,
512 g_object_unref (connection);
515 /**************************************************************/
518 reg_result (NMSecretAgent *self, GError *error)
520 NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
523 /* If registration failed we shouldn't expose ourselves on the bus */
524 _internal_unregister (self);
526 priv->registered = TRUE;
527 g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_REGISTERED);
530 g_signal_emit (self, signals[REGISTRATION_RESULT], 0, error);
534 reg_request_cb (DBusGProxy *proxy,
535 DBusGProxyCall *call,
538 NMSecretAgent *self = NM_SECRET_AGENT (user_data);
539 NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
540 GError *error = NULL;
542 priv->reg_call = NULL;
544 dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID);
545 reg_result (self, error);
546 g_clear_error (&error);
550 reg_with_caps_cb (DBusGProxy *proxy,
551 DBusGProxyCall *call,
554 NMSecretAgent *self = NM_SECRET_AGENT (user_data);
555 NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
557 priv->reg_call = NULL;
559 if (dbus_g_proxy_end_call (proxy, call, NULL, G_TYPE_INVALID)) {
560 reg_result (self, NULL);
564 /* Might be an old NetworkManager that doesn't support capabilities;
565 * fall back to old Register() method instead.
567 priv->reg_call = dbus_g_proxy_begin_call_with_timeout (priv->manager_proxy,
573 G_TYPE_STRING, priv->identifier,
578 * nm_secret_agent_register:
579 * @self: a #NMSecretAgent
581 * Registers the #NMSecretAgent with the NetworkManager secret manager,
582 * indicating to NetworkManager that the agent is able to provide and save
583 * secrets for connections on behalf of its user. Registration is an
584 * asynchronous operation and its success or failure is indicated via the
585 * 'registration-result' signal.
587 * Returns: a new %TRUE if registration was successfully requested (this does
588 * not mean registration itself was successful), %FALSE if registration was not
589 * successfully requested.
592 nm_secret_agent_register (NMSecretAgent *self)
594 NMSecretAgentPrivate *priv;
595 NMSecretAgentClass *class;
597 g_return_val_if_fail (NM_IS_SECRET_AGENT (self), FALSE);
599 priv = NM_SECRET_AGENT_GET_PRIVATE (self);
601 g_return_val_if_fail (priv->registered == FALSE, FALSE);
602 g_return_val_if_fail (priv->reg_call == NULL, FALSE);
603 g_return_val_if_fail (priv->bus != NULL, FALSE);
604 g_return_val_if_fail (priv->manager_proxy != NULL, FALSE);
606 /* Also make sure the subclass can actually respond to secrets requests */
607 class = NM_SECRET_AGENT_GET_CLASS (self);
608 g_return_val_if_fail (class->get_secrets != NULL, FALSE);
609 g_return_val_if_fail (class->save_secrets != NULL, FALSE);
610 g_return_val_if_fail (class->delete_secrets != NULL, FALSE);
615 priv->suppress_auto = FALSE;
617 /* Export our secret agent interface before registering with the manager */
618 dbus_g_connection_register_g_object (priv->bus,
619 NM_DBUS_PATH_SECRET_AGENT,
622 priv->reg_call = dbus_g_proxy_begin_call_with_timeout (priv->manager_proxy,
623 "RegisterWithCapabilities",
628 G_TYPE_STRING, priv->identifier,
629 G_TYPE_UINT, priv->capabilities,
635 * nm_secret_agent_unregister:
636 * @self: a #NMSecretAgent
638 * Unregisters the #NMSecretAgent with the NetworkManager secret manager,
639 * indicating to NetworkManager that the agent is will no longer provide or
640 * store secrets on behalf of this user.
642 * Returns: a new %TRUE if unregistration was successful, %FALSE if it was not.
645 nm_secret_agent_unregister (NMSecretAgent *self)
647 NMSecretAgentPrivate *priv;
649 g_return_val_if_fail (NM_IS_SECRET_AGENT (self), FALSE);
651 priv = NM_SECRET_AGENT_GET_PRIVATE (self);
653 g_return_val_if_fail (priv->registered == TRUE, FALSE);
654 g_return_val_if_fail (priv->bus != NULL, FALSE);
655 g_return_val_if_fail (priv->manager_proxy != NULL, FALSE);
660 dbus_g_proxy_call_no_reply (priv->manager_proxy, "Unregister", G_TYPE_INVALID);
662 _internal_unregister (self);
663 priv->suppress_auto = TRUE;
669 * nm_secret_agent_get_registered:
670 * @self: a #NMSecretAgent
672 * Returns: a %TRUE if the agent is registered, %FALSE if it is not.
675 nm_secret_agent_get_registered (NMSecretAgent *self)
677 g_return_val_if_fail (NM_IS_SECRET_AGENT (self), FALSE);
679 return NM_SECRET_AGENT_GET_PRIVATE (self)->registered;
683 auto_register_cb (gpointer user_data)
685 NMSecretAgent *self = NM_SECRET_AGENT (user_data);
686 NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
688 priv->auto_register_id = 0;
689 if (priv->auto_register && !priv->suppress_auto &&
690 (priv->reg_call == NULL && !priv->registered))
691 nm_secret_agent_register (self);
695 /**************************************************************/
698 * nm_secret_agent_get_secrets:
699 * @self: a #NMSecretAgent
700 * @connection: the #NMConnection for which we're asked secrets
701 * @setting_name: the name of the secret setting
702 * @hints: (array zero-terminated=1): hints to the agent
703 * @flags: flags that modify the behavior of the request
704 * @callback: (scope async): a callback, to be invoked when the operation is done
705 * @user_data: (closure): caller-specific data to be passed to @callback
707 * Asyncronously retrieve secrets belonging to @connection for the
708 * setting @setting_name. @flags indicate specific behavior that the secret
709 * agent should use when performing the request, for example returning only
710 * existing secrets without user interaction, or requesting entirely new
711 * secrets from the user.
713 * Virtual: get_secrets
716 nm_secret_agent_get_secrets (NMSecretAgent *self,
717 NMConnection *connection,
718 const char *setting_name,
720 NMSecretAgentGetSecretsFlags flags,
721 NMSecretAgentGetSecretsFunc callback,
724 g_return_if_fail (NM_IS_SECRET_AGENT (self));
725 g_return_if_fail (NM_IS_CONNECTION (connection));
726 g_return_if_fail (nm_connection_get_path (connection));
727 g_return_if_fail (setting_name != NULL);
728 g_return_if_fail (strlen (setting_name) > 0);
729 g_return_if_fail (callback != NULL);
731 NM_SECRET_AGENT_GET_CLASS (self)->get_secrets (self,
733 nm_connection_get_path (connection),
742 * nm_secret_agent_save_secrets:
743 * @self: a #NMSecretAgent
744 * @connection: a #NMConnection
745 * @callback: (scope async): a callback, to be invoked when the operation is done
746 * @user_data: (closure): caller-specific data to be passed to @callback
748 * Asyncronously ensure that all secrets inside @connection
749 * are stored to disk.
751 * Virtual: save_secrets
754 nm_secret_agent_save_secrets (NMSecretAgent *self,
755 NMConnection *connection,
756 NMSecretAgentSaveSecretsFunc callback,
759 g_return_if_fail (NM_IS_SECRET_AGENT (self));
760 g_return_if_fail (NM_IS_CONNECTION (connection));
761 g_return_if_fail (nm_connection_get_path (connection));
763 NM_SECRET_AGENT_GET_CLASS (self)->save_secrets (self,
765 nm_connection_get_path (connection),
771 * nm_secret_agent_delete_secrets:
772 * @self: a #NMSecretAgent
773 * @connection: a #NMConnection
774 * @callback: (scope async): a callback, to be invoked when the operation is done
775 * @user_data: (closure): caller-specific data to be passed to @callback
777 * Asynchronously ask the agent to delete all saved secrets belonging to
780 * Virtual: delete_secrets
783 nm_secret_agent_delete_secrets (NMSecretAgent *self,
784 NMConnection *connection,
785 NMSecretAgentDeleteSecretsFunc callback,
788 g_return_if_fail (NM_IS_SECRET_AGENT (self));
789 g_return_if_fail (NM_IS_CONNECTION (connection));
790 g_return_if_fail (nm_connection_get_path (connection));
792 NM_SECRET_AGENT_GET_CLASS (self)->delete_secrets (self,
794 nm_connection_get_path (connection),
799 /**************************************************************/
802 validate_identifier (const char *identifier)
804 const char *p = identifier;
807 /* Length between 3 and 255 characters inclusive */
808 id_len = strlen (identifier);
809 if (id_len < 3 || id_len > 255)
812 if ((identifier[0] == '.') || (identifier[id_len - 1] == '.'))
815 /* FIXME: do complete validation here */
817 if (!g_ascii_isalnum (*p) && (*p != '_') && (*p != '-') && (*p != '.'))
819 if ((*p == '.') && (*(p + 1) == '.'))
828 nm_secret_agent_init (NMSecretAgent *self)
830 NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
831 GError *error = NULL;
833 priv->bus = _nm_dbus_new_connection (&error);
835 g_warning ("Couldn't connect to system bus: %s", error->message);
836 g_error_free (error);
840 priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus,
843 DBUS_INTERFACE_DBUS);
844 g_assert (priv->dbus_proxy);
846 dbus_g_object_register_marshaller (g_cclosure_marshal_generic,
848 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
850 dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged",
851 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
853 dbus_g_proxy_connect_signal (priv->dbus_proxy,
855 G_CALLBACK (name_owner_changed),
860 priv->manager_proxy = _nm_dbus_new_proxy_for_connection (priv->bus,
861 NM_DBUS_PATH_AGENT_MANAGER,
862 NM_DBUS_INTERFACE_AGENT_MANAGER);
863 if (!priv->manager_proxy) {
864 g_warning ("Couldn't create NM agent manager proxy.");
869 priv->auto_register_id = g_idle_add (auto_register_cb, self);
873 get_property (GObject *object,
878 NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (object);
881 case PROP_IDENTIFIER:
882 g_value_set_string (value, priv->identifier);
884 case PROP_AUTO_REGISTER:
885 g_value_set_boolean (value, priv->auto_register);
887 case PROP_REGISTERED:
888 g_value_set_boolean (value, priv->registered);
890 case PROP_CAPABILITIES:
891 g_value_set_flags (value, priv->capabilities);
894 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
900 set_property (GObject *object,
905 NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (object);
906 const char *identifier;
909 case PROP_IDENTIFIER:
910 identifier = g_value_get_string (value);
912 g_return_if_fail (validate_identifier (identifier));
914 g_free (priv->identifier);
915 priv->identifier = g_strdup (identifier);
917 case PROP_AUTO_REGISTER:
918 priv->auto_register = g_value_get_boolean (value);
920 case PROP_CAPABILITIES:
921 priv->capabilities = g_value_get_flags (value);
924 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
930 dispose (GObject *object)
932 NMSecretAgent *self = NM_SECRET_AGENT (object);
933 NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
935 if (priv->registered)
936 nm_secret_agent_unregister (self);
938 if (priv->auto_register_id) {
939 g_source_remove (priv->auto_register_id);
940 priv->auto_register_id = 0;
943 g_free (priv->identifier);
944 priv->identifier = NULL;
945 g_free (priv->nm_owner);
946 priv->nm_owner = NULL;
948 while (priv->pending_gets)
949 get_secrets_info_finalize (self, priv->pending_gets->data);
951 g_clear_object (&priv->dbus_proxy);
952 g_clear_object (&priv->manager_proxy);
955 dbus_g_connection_unref (priv->bus);
959 G_OBJECT_CLASS (nm_secret_agent_parent_class)->dispose (object);
963 nm_secret_agent_class_init (NMSecretAgentClass *class)
965 GObjectClass *object_class = G_OBJECT_CLASS (class);
967 g_type_class_add_private (class, sizeof (NMSecretAgentPrivate));
969 /* Virtual methods */
970 object_class->dispose = dispose;
971 object_class->get_property = get_property;
972 object_class->set_property = set_property;
975 * NMSecretAgent:identifier:
977 * Identifies this agent; only one agent in each user session may use the
978 * same identifier. Identifier formatting follows the same rules as
979 * D-Bus bus names with the exception that the ':' character is not
980 * allowed. The valid set of characters is "[A-Z][a-z][0-9]_-." and the
981 * identifier is limited in length to 255 characters with a minimum
982 * of 3 characters. An example valid identifier is 'org.gnome.nm-applet'
985 g_object_class_install_property
986 (object_class, PROP_IDENTIFIER,
987 g_param_spec_string (NM_SECRET_AGENT_IDENTIFIER, "", "",
990 G_PARAM_CONSTRUCT_ONLY |
991 G_PARAM_STATIC_STRINGS));
994 * NMSecretAgent:auto-register:
996 * If TRUE, the agent will attempt to automatically register itself after
997 * it is created (via an idle handler) and to re-register itself if
998 * NetworkManager restarts. If FALSE, the agent does not automatically
999 * register with NetworkManager, and nm_secret_agent_register() must be
1000 * called. If 'auto-register' is TRUE, calling nm_secret_agent_unregister()
1001 * will suppress auto-registration until nm_secret_agent_register() is
1002 * called, which re-enables auto-registration.
1004 g_object_class_install_property
1005 (object_class, PROP_AUTO_REGISTER,
1006 g_param_spec_boolean (NM_SECRET_AGENT_AUTO_REGISTER, "", "",
1010 G_PARAM_STATIC_STRINGS));
1013 * NMSecretAgent:registered:
1015 * %TRUE if the agent is registered with NetworkManager, %FALSE if not.
1017 g_object_class_install_property
1018 (object_class, PROP_REGISTERED,
1019 g_param_spec_boolean (NM_SECRET_AGENT_REGISTERED, "", "",
1022 G_PARAM_STATIC_STRINGS));
1025 * NMSecretAgent:capabilities:
1027 * A bitfield of %NMSecretAgentCapabilities.
1029 g_object_class_install_property
1030 (object_class, PROP_CAPABILITIES,
1031 g_param_spec_flags (NM_SECRET_AGENT_CAPABILITIES, "", "",
1032 NM_TYPE_SECRET_AGENT_CAPABILITIES,
1033 NM_SECRET_AGENT_CAPABILITY_NONE,
1036 G_PARAM_STATIC_STRINGS));
1039 * NMSecretAgent::registration-result:
1040 * @agent: the agent that received the signal
1041 * @error: the error, if any, that occured while registering
1043 * Indicates the result of a registration request; if @error is NULL the
1044 * request was successful.
1046 signals[REGISTRATION_RESULT] =
1047 g_signal_new (NM_SECRET_AGENT_REGISTRATION_RESULT,
1048 G_OBJECT_CLASS_TYPE (object_class),
1050 0, NULL, NULL, NULL,
1051 G_TYPE_NONE, 1, G_TYPE_POINTER);
1053 dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class),
1054 &dbus_glib_nm_secret_agent_object_info);
1056 dbus_g_error_domain_register (NM_SECRET_AGENT_ERROR,
1057 NM_DBUS_INTERFACE_SECRET_AGENT,
1058 NM_TYPE_SECRET_AGENT_ERROR);