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"
25 #include "nm-dbus-interface.h"
26 #include "nm-secret-agent-old.h"
27 #include "nm-enum-types.h"
28 #include "nm-dbus-helpers.h"
29 #include "nm-simple-connection.h"
30 #include "nm-core-internal.h"
32 #include "nmdbus-secret-agent.h"
33 #include "nmdbus-agent-manager.h"
35 static void nm_secret_agent_old_initable_iface_init (GInitableIface *iface);
36 static void nm_secret_agent_old_async_initable_iface_init (GAsyncInitableIface *iface);
37 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMSecretAgentOld, nm_secret_agent_old, G_TYPE_OBJECT,
38 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_secret_agent_old_initable_iface_init);
39 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_secret_agent_old_async_initable_iface_init);
42 #define NM_SECRET_AGENT_OLD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOldPrivate))
47 NMSecretAgentCapabilities capabilities;
52 NMDBusAgentManager *manager_proxy;
53 NMDBusSecretAgent *dbus_secret_agent;
55 /* GetSecretsInfo structs of in-flight GetSecrets requests */
59 gboolean auto_register;
60 gboolean suppress_auto;
61 } NMSecretAgentOldPrivate;
73 /*************************************************************/
76 _internal_unregister (NMSecretAgentOld *self)
78 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
80 if (priv->registered) {
81 g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent));
82 priv->registered = FALSE;
83 priv->registering = FALSE;
84 g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_OLD_REGISTERED);
91 GDBusMethodInvocation *context;
95 get_secrets_info_finalize (NMSecretAgentOld *self, GetSecretsInfo *info)
97 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
99 g_return_if_fail (info != NULL);
101 priv->pending_gets = g_slist_remove (priv->pending_gets, info);
104 g_free (info->setting_name);
105 memset (info, 0, sizeof (*info));
109 static inline gboolean
110 should_auto_register (NMSecretAgentOld *self)
112 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
114 return ( priv->auto_register
115 && !priv->suppress_auto
117 && !priv->registering);
121 name_owner_changed (GObject *proxy,
125 NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (user_data);
126 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
130 owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (proxy));
132 if (should_auto_register (self))
133 nm_secret_agent_old_register_async (self, NULL, NULL, NULL);
136 /* Cancel any pending secrets requests */
137 for (iter = priv->pending_gets; iter; iter = g_slist_next (iter)) {
138 GetSecretsInfo *info = iter->data;
140 NM_SECRET_AGENT_OLD_GET_CLASS (self)->cancel_get_secrets (self,
144 g_slist_free (priv->pending_gets);
145 priv->pending_gets = NULL;
147 _internal_unregister (self);
152 verify_sender (NMSecretAgentOld *self,
153 GDBusMethodInvocation *context,
156 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
161 GError *local = NULL;
163 g_return_val_if_fail (context != NULL, FALSE);
165 /* Private bus connection is always to NetworkManager, which is always
168 if (priv->private_bus)
171 /* Verify that the sender is the same as NetworkManager's bus name owner. */
173 nm_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy));
175 g_set_error_literal (error,
176 NM_SECRET_AGENT_ERROR,
177 NM_SECRET_AGENT_ERROR_PERMISSION_DENIED,
178 "NetworkManager bus name owner unknown.");
182 sender = g_dbus_method_invocation_get_sender (context);
184 g_set_error_literal (error,
185 NM_SECRET_AGENT_ERROR,
186 NM_SECRET_AGENT_ERROR_PERMISSION_DENIED,
187 "Failed to get request sender.");
192 /* Check that the sender matches the current NM bus name owner */
193 if (strcmp (sender, nm_owner) != 0) {
194 g_set_error_literal (error,
195 NM_SECRET_AGENT_ERROR,
196 NM_SECRET_AGENT_ERROR_PERMISSION_DENIED,
197 "Request sender does not match NetworkManager bus name owner.");
203 /* If we're connected to the session bus, then this must be a test program,
204 * so skip the UID check.
206 if (priv->session_bus)
209 /* Check the UID of the sender */
210 ret = g_dbus_connection_call_sync (priv->bus,
214 "GetConnectionUnixUser",
215 g_variant_new ("(s)", sender),
216 G_VARIANT_TYPE ("(u)"),
217 G_DBUS_CALL_FLAGS_NONE, -1,
220 char *remote_error = g_dbus_error_get_remote_error (local);
222 g_dbus_error_strip_remote_error (local);
224 NM_SECRET_AGENT_ERROR,
225 NM_SECRET_AGENT_ERROR_PERMISSION_DENIED,
226 "Failed to request unix user: (%s) %s.",
227 remote_error ? remote_error : "",
229 g_free (remote_error);
230 g_error_free (local);
233 g_variant_get (ret, "(u)", &sender_uid);
234 g_variant_unref (ret);
236 /* We only accept requests from NM, which always runs as root */
237 if (0 != sender_uid) {
238 g_set_error_literal (error,
239 NM_SECRET_AGENT_ERROR,
240 NM_SECRET_AGENT_ERROR_PERMISSION_DENIED,
241 "Request sender is not root.");
249 verify_request (NMSecretAgentOld *self,
250 GDBusMethodInvocation *context,
251 GVariant *connection_dict,
252 const char *connection_path,
253 NMConnection **out_connection,
256 NMConnection *connection = NULL;
257 GError *local = NULL;
259 if (!verify_sender (self, context, error))
262 /* No connection? If the sender verified, then we allow the request */
263 if (connection_dict == NULL)
266 /* If we have a connection dictionary, we require a path too */
267 if (connection_path == NULL) {
268 g_set_error_literal (error,
269 NM_SECRET_AGENT_ERROR,
270 NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
271 "Invalid connection: no connection path given.");
275 /* Make sure the given connection is valid */
276 g_assert (out_connection);
277 connection = _nm_simple_connection_new_from_dbus (connection_dict, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &local);
279 nm_connection_set_path (connection, connection_path);
280 *out_connection = connection;
283 NM_SECRET_AGENT_ERROR,
284 NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
285 "Invalid connection: %s", local->message);
286 g_clear_error (&local);
293 get_secrets_cb (NMSecretAgentOld *self,
294 NMConnection *connection,
299 GetSecretsInfo *info = user_data;
302 g_dbus_method_invocation_return_gerror (info->context, error);
304 g_variant_take_ref (secrets);
305 g_dbus_method_invocation_return_value (info->context,
306 g_variant_new ("(@a{sa{sv}})", secrets));
309 /* Remove the request from internal tracking */
310 get_secrets_info_finalize (self, info);
314 impl_secret_agent_old_get_secrets (NMSecretAgentOld *self,
315 GDBusMethodInvocation *context,
316 GVariant *connection_dict,
317 const char *connection_path,
318 const char *setting_name,
319 const char * const *hints,
323 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
324 GError *error = NULL;
325 NMConnection *connection = NULL;
326 GetSecretsInfo *info;
328 /* Make sure the request comes from NetworkManager and is valid */
329 if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) {
330 g_dbus_method_invocation_take_error (context, error);
334 info = g_malloc0 (sizeof (GetSecretsInfo));
335 info->path = g_strdup (connection_path);
336 info->setting_name = g_strdup (setting_name);
337 info->context = context;
338 priv->pending_gets = g_slist_append (priv->pending_gets, info);
340 NM_SECRET_AGENT_OLD_GET_CLASS (self)->get_secrets (self,
344 (const char **) hints,
348 g_object_unref (connection);
351 static GetSecretsInfo *
352 find_get_secrets_info (GSList *list, const char *path, const char *setting_name)
356 for (iter = list; iter; iter = g_slist_next (iter)) {
357 GetSecretsInfo *candidate = iter->data;
359 if ( g_strcmp0 (path, candidate->path) == 0
360 && g_strcmp0 (setting_name, candidate->setting_name) == 0)
367 impl_secret_agent_old_cancel_get_secrets (NMSecretAgentOld *self,
368 GDBusMethodInvocation *context,
369 const char *connection_path,
370 const char *setting_name,
373 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
374 GError *error = NULL;
375 GetSecretsInfo *info;
377 /* Make sure the request comes from NetworkManager and is valid */
378 if (!verify_request (self, context, NULL, NULL, NULL, &error)) {
379 g_dbus_method_invocation_take_error (context, error);
383 info = find_get_secrets_info (priv->pending_gets, connection_path, setting_name);
385 g_dbus_method_invocation_return_error (context,
386 NM_SECRET_AGENT_ERROR,
387 NM_SECRET_AGENT_ERROR_FAILED,
388 "No secrets request in progress for this connection.");
392 /* Send the cancel request up to the subclass and finalize it */
393 NM_SECRET_AGENT_OLD_GET_CLASS (self)->cancel_get_secrets (self,
396 g_dbus_method_invocation_return_value (context, NULL);
400 save_secrets_cb (NMSecretAgentOld *self,
401 NMConnection *connection,
405 GDBusMethodInvocation *context = user_data;
408 g_dbus_method_invocation_return_gerror (context, error);
410 g_dbus_method_invocation_return_value (context, NULL);
414 impl_secret_agent_old_save_secrets (NMSecretAgentOld *self,
415 GDBusMethodInvocation *context,
416 GVariant *connection_dict,
417 const char *connection_path,
420 GError *error = NULL;
421 NMConnection *connection = NULL;
423 /* Make sure the request comes from NetworkManager and is valid */
424 if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) {
425 g_dbus_method_invocation_take_error (context, error);
429 NM_SECRET_AGENT_OLD_GET_CLASS (self)->save_secrets (self,
434 g_object_unref (connection);
438 delete_secrets_cb (NMSecretAgentOld *self,
439 NMConnection *connection,
443 GDBusMethodInvocation *context = user_data;
446 g_dbus_method_invocation_return_gerror (context, error);
448 g_dbus_method_invocation_return_value (context, NULL);
452 impl_secret_agent_old_delete_secrets (NMSecretAgentOld *self,
453 GDBusMethodInvocation *context,
454 GVariant *connection_dict,
455 const char *connection_path,
458 GError *error = NULL;
459 NMConnection *connection = NULL;
461 /* Make sure the request comes from NetworkManager and is valid */
462 if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) {
463 g_dbus_method_invocation_take_error (context, error);
467 NM_SECRET_AGENT_OLD_GET_CLASS (self)->delete_secrets (self,
472 g_object_unref (connection);
475 /**************************************************************/
478 check_nm_running (NMSecretAgentOld *self, GError **error)
480 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
483 if (priv->private_bus)
485 owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy));
491 g_set_error (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED,
492 "NetworkManager is not running");
496 /**************************************************************/
499 * nm_secret_agent_old_register:
500 * @self: a #NMSecretAgentOld
501 * @cancellable: a #GCancellable, or %NULL
502 * @error: return location for a #GError, or %NULL
504 * Registers the #NMSecretAgentOld with the NetworkManager secret manager,
505 * indicating to NetworkManager that the agent is able to provide and save
506 * secrets for connections on behalf of its user.
508 * It is a programmer error to attempt to register an agent that is already
509 * registered, or in the process of registering.
511 * Returns: %TRUE if registration was successful, %FALSE on error.
514 nm_secret_agent_old_register (NMSecretAgentOld *self,
515 GCancellable *cancellable,
518 NMSecretAgentOldPrivate *priv;
519 NMSecretAgentOldClass *class;
521 g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE);
523 priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
525 g_return_val_if_fail (priv->registered == FALSE, FALSE);
526 g_return_val_if_fail (priv->registering == FALSE, FALSE);
527 g_return_val_if_fail (priv->bus != NULL, FALSE);
528 g_return_val_if_fail (priv->manager_proxy != NULL, FALSE);
530 /* Also make sure the subclass can actually respond to secrets requests */
531 class = NM_SECRET_AGENT_OLD_GET_CLASS (self);
532 g_return_val_if_fail (class->get_secrets != NULL, FALSE);
533 g_return_val_if_fail (class->save_secrets != NULL, FALSE);
534 g_return_val_if_fail (class->delete_secrets != NULL, FALSE);
536 if (!check_nm_running (self, error))
539 priv->suppress_auto = FALSE;
541 /* Export our secret agent interface before registering with the manager */
542 if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent),
544 NM_DBUS_PATH_SECRET_AGENT,
548 priv->registering = TRUE;
549 if (nmdbus_agent_manager_call_register_with_capabilities_sync (priv->manager_proxy,
555 /* Might be an old NetworkManager that doesn't support capabilities;
556 * fall back to old Register() method instead.
558 if (nmdbus_agent_manager_call_register_sync (priv->manager_proxy,
564 priv->registering = FALSE;
565 _internal_unregister (self);
569 priv->registering = FALSE;
570 priv->registered = TRUE;
571 g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_OLD_REGISTERED);
576 reg_result (NMSecretAgentOld *self, GSimpleAsyncResult *simple, GError *error)
578 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
580 priv->registering = FALSE;
583 g_simple_async_result_take_error (simple, error);
584 g_simple_async_result_complete (simple);
586 /* If registration failed we shouldn't expose ourselves on the bus */
587 _internal_unregister (self);
589 priv->registered = TRUE;
590 g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_OLD_REGISTERED);
592 g_simple_async_result_set_op_res_gboolean (simple, TRUE);
593 g_simple_async_result_complete (simple);
596 g_object_unref (simple);
600 reg_request_cb (GObject *proxy,
601 GAsyncResult *result,
604 GSimpleAsyncResult *simple = user_data;
605 NMSecretAgentOld *self;
606 NMSecretAgentOldPrivate *priv;
607 GError *error = NULL;
609 self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
610 g_object_unref (self); /* drop extra ref added by get_source_object() */
611 priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
613 if (!nmdbus_agent_manager_call_register_finish (NMDBUS_AGENT_MANAGER (proxy), result, &error))
614 g_dbus_error_strip_remote_error (error);
615 reg_result (self, simple, error);
616 g_clear_error (&error);
620 reg_with_caps_cb (GObject *proxy,
621 GAsyncResult *result,
624 GSimpleAsyncResult *simple = user_data;
625 NMSecretAgentOld *self;
626 NMSecretAgentOldPrivate *priv;
628 self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
629 g_object_unref (self); /* drop extra ref added by get_source_object() */
630 priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
632 if (nmdbus_agent_manager_call_register_with_capabilities_finish (NMDBUS_AGENT_MANAGER (proxy), result, NULL)) {
633 reg_result (self, simple, NULL);
637 /* Might be an old NetworkManager that doesn't support capabilities;
638 * fall back to old Register() method instead.
640 nmdbus_agent_manager_call_register (priv->manager_proxy,
642 NULL, reg_request_cb, simple);
646 * nm_secret_agent_old_register_async:
647 * @self: a #NMSecretAgentOld
648 * @cancellable: a #GCancellable, or %NULL
649 * @callback: callback to call when the agent is registered
650 * @user_data: data for @callback
652 * Asynchronously registers the #NMSecretAgentOld with the NetworkManager secret
653 * manager, indicating to NetworkManager that the agent is able to provide and
654 * save secrets for connections on behalf of its user.
656 * It is a programmer error to attempt to register an agent that is already
657 * registered, or in the process of registering.
660 nm_secret_agent_old_register_async (NMSecretAgentOld *self,
661 GCancellable *cancellable,
662 GAsyncReadyCallback callback,
665 NMSecretAgentOldPrivate *priv;
666 NMSecretAgentOldClass *class;
667 GSimpleAsyncResult *simple;
668 GError *error = NULL;
670 g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
672 priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
674 g_return_if_fail (priv->registered == FALSE);
675 g_return_if_fail (priv->registering == FALSE);
676 g_return_if_fail (priv->bus != NULL);
677 g_return_if_fail (priv->manager_proxy != NULL);
679 /* Also make sure the subclass can actually respond to secrets requests */
680 class = NM_SECRET_AGENT_OLD_GET_CLASS (self);
681 g_return_if_fail (class->get_secrets != NULL);
682 g_return_if_fail (class->save_secrets != NULL);
683 g_return_if_fail (class->delete_secrets != NULL);
685 simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
686 nm_secret_agent_old_register_async);
688 if (!check_nm_running (self, &error)) {
689 g_simple_async_result_take_error (simple, error);
690 g_simple_async_result_complete_in_idle (simple);
691 g_object_unref (simple);
695 /* Export our secret agent interface before registering with the manager */
696 if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent),
698 NM_DBUS_PATH_SECRET_AGENT,
700 g_simple_async_result_take_error (simple, error);
701 g_simple_async_result_complete_in_idle (simple);
702 g_object_unref (simple);
706 priv->suppress_auto = FALSE;
707 priv->registering = TRUE;
709 nmdbus_agent_manager_call_register_with_capabilities (priv->manager_proxy,
713 reg_with_caps_cb, simple);
717 * nm_secret_agent_old_register_finish:
718 * @self: a #NMSecretAgentOld
719 * @result: the result passed to the #GAsyncReadyCallback
720 * @error: return location for a #GError, or %NULL
722 * Gets the result of a call to nm_secret_agent_old_register_async().
724 * Returns: %TRUE if registration was successful, %FALSE on error.
727 nm_secret_agent_old_register_finish (NMSecretAgentOld *self,
728 GAsyncResult *result,
731 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), nm_secret_agent_old_register_async), FALSE);
733 if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
740 * nm_secret_agent_old_unregister:
741 * @self: a #NMSecretAgentOld
742 * @cancellable: a #GCancellable, or %NULL
743 * @error: return location for a #GError, or %NULL
745 * Unregisters the #NMSecretAgentOld with the NetworkManager secret manager,
746 * indicating to NetworkManager that the agent will no longer provide or
747 * store secrets on behalf of this user.
749 * It is a programmer error to attempt to unregister an agent that is not
752 * Returns: %TRUE if unregistration was successful, %FALSE on error
755 nm_secret_agent_old_unregister (NMSecretAgentOld *self,
756 GCancellable *cancellable,
759 NMSecretAgentOldPrivate *priv;
762 g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE);
764 priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
766 g_return_val_if_fail (priv->registered == TRUE, FALSE);
767 g_return_val_if_fail (priv->bus != NULL, FALSE);
768 g_return_val_if_fail (priv->manager_proxy != NULL, FALSE);
770 priv->suppress_auto = TRUE;
772 success = nmdbus_agent_manager_call_unregister_sync (priv->manager_proxy, cancellable, error);
774 g_dbus_error_strip_remote_error (*error);
775 _internal_unregister (self);
781 unregister_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
783 GSimpleAsyncResult *simple = user_data;
784 NMSecretAgentOld *self;
785 GError *error = NULL;
787 self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
788 g_object_unref (self); /* drop extra ref added by get_source_object() */
790 _internal_unregister (self);
792 if (nmdbus_agent_manager_call_unregister_finish (NMDBUS_AGENT_MANAGER (proxy),
794 g_simple_async_result_set_op_res_gboolean (simple, TRUE);
796 g_dbus_error_strip_remote_error (error);
797 g_simple_async_result_take_error (simple, error);
800 g_simple_async_result_complete (simple);
801 g_object_unref (simple);
805 * nm_secret_agent_old_unregister_async:
806 * @self: a #NMSecretAgentOld
807 * @cancellable: a #GCancellable, or %NULL
808 * @callback: callback to call when the agent is unregistered
809 * @user_data: data for @callback
811 * Asynchronously unregisters the #NMSecretAgentOld with the NetworkManager secret
812 * manager, indicating to NetworkManager that the agent will no longer provide
813 * or store secrets on behalf of this user.
815 * It is a programmer error to attempt to unregister an agent that is not
819 nm_secret_agent_old_unregister_async (NMSecretAgentOld *self,
820 GCancellable *cancellable,
821 GAsyncReadyCallback callback,
824 NMSecretAgentOldPrivate *priv;
825 GSimpleAsyncResult *simple;
826 GError *error = NULL;
828 g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
830 priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
832 g_return_if_fail (priv->registered == TRUE);
833 g_return_if_fail (priv->bus != NULL);
834 g_return_if_fail (priv->manager_proxy != NULL);
836 simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
837 nm_secret_agent_old_unregister_async);
839 if (!check_nm_running (self, &error)) {
840 g_simple_async_result_take_error (simple, error);
841 g_simple_async_result_complete_in_idle (simple);
842 g_object_unref (simple);
846 priv->suppress_auto = TRUE;
848 nmdbus_agent_manager_call_unregister (priv->manager_proxy, cancellable,
849 unregister_cb, simple);
853 * nm_secret_agent_old_unregister_finish:
854 * @self: a #NMSecretAgentOld
855 * @result: the result passed to the #GAsyncReadyCallback
856 * @error: return location for a #GError, or %NULL
858 * Gets the result of a call to nm_secret_agent_old_unregister_async().
860 * Returns: %TRUE if unregistration was successful, %FALSE on error.
863 nm_secret_agent_old_unregister_finish (NMSecretAgentOld *self,
864 GAsyncResult *result,
867 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), nm_secret_agent_old_unregister_async), FALSE);
869 if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
876 * nm_secret_agent_old_get_registered:
877 * @self: a #NMSecretAgentOld
879 * Returns: a %TRUE if the agent is registered, %FALSE if it is not.
882 nm_secret_agent_old_get_registered (NMSecretAgentOld *self)
884 g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE);
886 return NM_SECRET_AGENT_OLD_GET_PRIVATE (self)->registered;
889 /**************************************************************/
892 * nm_secret_agent_old_get_secrets:
893 * @self: a #NMSecretAgentOld
894 * @connection: the #NMConnection for which we're asked secrets
895 * @setting_name: the name of the secret setting
896 * @hints: (array zero-terminated=1): hints to the agent
897 * @flags: flags that modify the behavior of the request
898 * @callback: (scope async): a callback, to be invoked when the operation is done
899 * @user_data: (closure): caller-specific data to be passed to @callback
901 * Asynchronously retrieves secrets belonging to @connection for the
902 * setting @setting_name. @flags indicate specific behavior that the secret
903 * agent should use when performing the request, for example returning only
904 * existing secrets without user interaction, or requesting entirely new
905 * secrets from the user.
907 * Virtual: get_secrets
910 nm_secret_agent_old_get_secrets (NMSecretAgentOld *self,
911 NMConnection *connection,
912 const char *setting_name,
914 NMSecretAgentGetSecretsFlags flags,
915 NMSecretAgentOldGetSecretsFunc callback,
918 g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
919 g_return_if_fail (NM_IS_CONNECTION (connection));
920 g_return_if_fail (nm_connection_get_path (connection));
921 g_return_if_fail (setting_name != NULL);
922 g_return_if_fail (strlen (setting_name) > 0);
923 g_return_if_fail (!(flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM));
924 g_return_if_fail (!(flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS));
925 g_return_if_fail (callback != NULL);
927 NM_SECRET_AGENT_OLD_GET_CLASS (self)->get_secrets (self,
929 nm_connection_get_path (connection),
938 * nm_secret_agent_old_save_secrets:
939 * @self: a #NMSecretAgentOld
940 * @connection: a #NMConnection
941 * @callback: (scope async): a callback, to be invoked when the operation is done
942 * @user_data: (closure): caller-specific data to be passed to @callback
944 * Asynchronously ensures that all secrets inside @connection are stored to
947 * Virtual: save_secrets
950 nm_secret_agent_old_save_secrets (NMSecretAgentOld *self,
951 NMConnection *connection,
952 NMSecretAgentOldSaveSecretsFunc callback,
955 g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
956 g_return_if_fail (NM_IS_CONNECTION (connection));
957 g_return_if_fail (nm_connection_get_path (connection));
959 NM_SECRET_AGENT_OLD_GET_CLASS (self)->save_secrets (self,
961 nm_connection_get_path (connection),
967 * nm_secret_agent_old_delete_secrets:
968 * @self: a #NMSecretAgentOld
969 * @connection: a #NMConnection
970 * @callback: (scope async): a callback, to be invoked when the operation is done
971 * @user_data: (closure): caller-specific data to be passed to @callback
973 * Asynchronously asks the agent to delete all saved secrets belonging to
976 * Virtual: delete_secrets
979 nm_secret_agent_old_delete_secrets (NMSecretAgentOld *self,
980 NMConnection *connection,
981 NMSecretAgentOldDeleteSecretsFunc callback,
984 g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
985 g_return_if_fail (NM_IS_CONNECTION (connection));
986 g_return_if_fail (nm_connection_get_path (connection));
988 NM_SECRET_AGENT_OLD_GET_CLASS (self)->delete_secrets (self,
990 nm_connection_get_path (connection),
995 /**************************************************************/
998 validate_identifier (const char *identifier)
1000 const char *p = identifier;
1003 /* Length between 3 and 255 characters inclusive */
1004 id_len = strlen (identifier);
1005 if (id_len < 3 || id_len > 255)
1008 if ((identifier[0] == '.') || (identifier[id_len - 1] == '.'))
1011 /* FIXME: do complete validation here */
1013 if (!g_ascii_isalnum (*p) && (*p != '_') && (*p != '-') && (*p != '.'))
1015 if ((*p == '.') && (*(p + 1) == '.'))
1024 nm_secret_agent_old_init (NMSecretAgentOld *self)
1026 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
1028 priv->dbus_secret_agent = nmdbus_secret_agent_skeleton_new ();
1029 _nm_dbus_bind_properties (self, priv->dbus_secret_agent);
1030 _nm_dbus_bind_methods (self, priv->dbus_secret_agent,
1031 "GetSecrets", impl_secret_agent_old_get_secrets,
1032 "CancelGetSecrets", impl_secret_agent_old_cancel_get_secrets,
1033 "DeleteSecrets", impl_secret_agent_old_delete_secrets,
1034 "SaveSecrets", impl_secret_agent_old_save_secrets,
1039 init_common (NMSecretAgentOld *self)
1041 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
1043 priv->private_bus = _nm_dbus_is_connection_private (priv->bus);
1045 if (priv->private_bus == FALSE) {
1046 priv->session_bus = _nm_dbus_bus_type () == G_BUS_TYPE_SESSION;
1048 g_signal_connect (priv->manager_proxy, "notify::g-name-owner",
1049 G_CALLBACK (name_owner_changed), self);
1054 init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
1056 NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable);
1057 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
1060 priv->bus = _nm_dbus_new_connection (cancellable, error);
1064 proxy = _nm_dbus_new_proxy_for_connection (priv->bus,
1065 NM_DBUS_PATH_AGENT_MANAGER,
1066 NM_DBUS_INTERFACE_AGENT_MANAGER,
1067 cancellable, error);
1070 priv->manager_proxy = NMDBUS_AGENT_MANAGER (proxy);
1074 if (priv->auto_register)
1075 return nm_secret_agent_old_register (self, cancellable, error);
1081 NMSecretAgentOld *self;
1082 GCancellable *cancellable;
1083 GSimpleAsyncResult *simple;
1084 } NMSecretAgentOldInitData;
1087 init_async_complete (NMSecretAgentOldInitData *init_data, GError *error)
1090 g_simple_async_result_set_op_res_gboolean (init_data->simple, TRUE);
1092 g_simple_async_result_take_error (init_data->simple, error);
1094 g_simple_async_result_complete_in_idle (init_data->simple);
1096 g_object_unref (init_data->simple);
1097 g_clear_object (&init_data->cancellable);
1098 g_slice_free (NMSecretAgentOldInitData, init_data);
1102 init_async_registered (GObject *object, GAsyncResult *result, gpointer user_data)
1104 NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (object);
1105 NMSecretAgentOldInitData *init_data = user_data;
1106 GError *error = NULL;
1108 nm_secret_agent_old_register_finish (self, result, &error);
1109 init_async_complete (init_data, error);
1113 init_async_got_proxy (GObject *object, GAsyncResult *result, gpointer user_data)
1115 NMSecretAgentOldInitData *init_data = user_data;
1116 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (init_data->self);
1118 GError *error = NULL;
1120 proxy = _nm_dbus_new_proxy_for_connection_finish (result, &error);
1122 init_async_complete (init_data, error);
1125 priv->manager_proxy = NMDBUS_AGENT_MANAGER (proxy);
1127 init_common (init_data->self);
1129 if (priv->auto_register) {
1130 nm_secret_agent_old_register_async (init_data->self, init_data->cancellable,
1131 init_async_registered, init_data);
1133 init_async_complete (init_data, NULL);
1137 init_async_got_bus (GObject *initable, GAsyncResult *result, gpointer user_data)
1139 NMSecretAgentOldInitData *init_data = user_data;
1140 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (init_data->self);
1141 GError *error = NULL;
1143 priv->bus = _nm_dbus_new_connection_finish (result, &error);
1145 init_async_complete (init_data, error);
1149 _nm_dbus_new_proxy_for_connection_async (priv->bus,
1150 NM_DBUS_PATH_AGENT_MANAGER,
1151 NM_DBUS_INTERFACE_AGENT_MANAGER,
1152 init_data->cancellable,
1153 init_async_got_proxy, init_data);
1157 init_async (GAsyncInitable *initable, int io_priority,
1158 GCancellable *cancellable, GAsyncReadyCallback callback,
1161 NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable);
1162 NMSecretAgentOldInitData *init_data;
1164 init_data = g_slice_new (NMSecretAgentOldInitData);
1165 init_data->self = self;
1166 init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1168 init_data->simple = g_simple_async_result_new (G_OBJECT (initable), callback,
1169 user_data, init_async);
1171 _nm_dbus_new_connection_async (cancellable, init_async_got_bus, init_data);
1175 init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error)
1177 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1179 if (g_simple_async_result_propagate_error (simple, error))
1186 get_property (GObject *object,
1191 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (object);
1194 case PROP_IDENTIFIER:
1195 g_value_set_string (value, priv->identifier);
1197 case PROP_AUTO_REGISTER:
1198 g_value_set_boolean (value, priv->auto_register);
1200 case PROP_REGISTERED:
1201 g_value_set_boolean (value, priv->registered);
1203 case PROP_CAPABILITIES:
1204 g_value_set_flags (value, priv->capabilities);
1207 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1213 set_property (GObject *object,
1215 const GValue *value,
1218 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (object);
1219 const char *identifier;
1222 case PROP_IDENTIFIER:
1223 identifier = g_value_get_string (value);
1225 g_return_if_fail (validate_identifier (identifier));
1227 g_free (priv->identifier);
1228 priv->identifier = g_strdup (identifier);
1230 case PROP_AUTO_REGISTER:
1231 priv->auto_register = g_value_get_boolean (value);
1233 case PROP_CAPABILITIES:
1234 priv->capabilities = g_value_get_flags (value);
1237 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1243 dispose (GObject *object)
1245 NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (object);
1246 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
1248 if (priv->registered)
1249 nm_secret_agent_old_unregister_async (self, NULL, NULL, NULL);
1251 g_clear_pointer (&priv->identifier, g_free);
1253 while (priv->pending_gets)
1254 get_secrets_info_finalize (self, priv->pending_gets->data);
1256 g_signal_handlers_disconnect_matched (priv->dbus_secret_agent, G_SIGNAL_MATCH_DATA,
1257 0, 0, NULL, NULL, self);
1258 g_object_unref (priv->dbus_secret_agent);
1260 g_clear_object (&priv->manager_proxy);
1261 g_clear_object (&priv->bus);
1263 G_OBJECT_CLASS (nm_secret_agent_old_parent_class)->dispose (object);
1267 nm_secret_agent_old_class_init (NMSecretAgentOldClass *class)
1269 GObjectClass *object_class = G_OBJECT_CLASS (class);
1271 g_type_class_add_private (class, sizeof (NMSecretAgentOldPrivate));
1273 /* Virtual methods */
1274 object_class->dispose = dispose;
1275 object_class->get_property = get_property;
1276 object_class->set_property = set_property;
1279 * NMSecretAgentOld:identifier:
1281 * Identifies this agent; only one agent in each user session may use the
1282 * same identifier. Identifier formatting follows the same rules as
1283 * D-Bus bus names with the exception that the ':' character is not
1284 * allowed. The valid set of characters is "[A-Z][a-z][0-9]_-." and the
1285 * identifier is limited in length to 255 characters with a minimum
1286 * of 3 characters. An example valid identifier is 'org.gnome.nm-applet'
1289 g_object_class_install_property
1290 (object_class, PROP_IDENTIFIER,
1291 g_param_spec_string (NM_SECRET_AGENT_OLD_IDENTIFIER, "", "",
1294 G_PARAM_CONSTRUCT_ONLY |
1295 G_PARAM_STATIC_STRINGS));
1298 * NMSecretAgentOld:auto-register:
1300 * If %TRUE (the default), the agent will always be registered when
1301 * NetworkManager is running; if NetworkManager exits and restarts, the
1302 * agent will re-register itself automatically.
1304 * In particular, if this property is %TRUE at construct time, then the
1305 * agent will register itself with NetworkManager during
1306 * construction/initialization, and initialization will fail with an error
1307 * if the agent is unable to register itself.
1309 * If the property is %FALSE, the agent will not automatically register with
1310 * NetworkManager, and nm_secret_agent_old_register() or
1311 * nm_secret_agent_old_register_async() must be called to register it.
1313 * Calling nm_secret_agent_old_unregister() will suppress auto-registration
1314 * until nm_secret_agent_old_register() is called, which re-enables
1315 * auto-registration. This ensures that the agent remains un-registered when
1316 * you expect it to be unregistered.
1318 g_object_class_install_property
1319 (object_class, PROP_AUTO_REGISTER,
1320 g_param_spec_boolean (NM_SECRET_AGENT_OLD_AUTO_REGISTER, "", "",
1324 G_PARAM_STATIC_STRINGS));
1327 * NMSecretAgentOld:registered:
1329 * %TRUE if the agent is registered with NetworkManager, %FALSE if not.
1331 g_object_class_install_property
1332 (object_class, PROP_REGISTERED,
1333 g_param_spec_boolean (NM_SECRET_AGENT_OLD_REGISTERED, "", "",
1336 G_PARAM_STATIC_STRINGS));
1339 * NMSecretAgentOld:capabilities:
1341 * A bitfield of %NMSecretAgentCapabilities.
1343 g_object_class_install_property
1344 (object_class, PROP_CAPABILITIES,
1345 g_param_spec_flags (NM_SECRET_AGENT_OLD_CAPABILITIES, "", "",
1346 NM_TYPE_SECRET_AGENT_CAPABILITIES,
1347 NM_SECRET_AGENT_CAPABILITY_NONE,
1350 G_PARAM_STATIC_STRINGS));
1352 _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_AGENT_MANAGER,
1353 NMDBUS_TYPE_AGENT_MANAGER_PROXY);
1357 nm_secret_agent_old_initable_iface_init (GInitableIface *iface)
1359 iface->init = init_sync;
1363 nm_secret_agent_old_async_initable_iface_init (GAsyncInitableIface *iface)
1365 iface->init_async = init_async;
1366 iface->init_finish = init_finish;