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"
31 #include "nmdbus-secret-agent.h"
32 #include "nmdbus-agent-manager.h"
34 static void nm_secret_agent_old_initable_iface_init (GInitableIface *iface);
35 static void nm_secret_agent_old_async_initable_iface_init (GAsyncInitableIface *iface);
36 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMSecretAgentOld, nm_secret_agent_old, G_TYPE_OBJECT,
37 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_secret_agent_old_initable_iface_init);
38 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_secret_agent_old_async_initable_iface_init);
41 #define NM_SECRET_AGENT_OLD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOldPrivate))
46 NMSecretAgentCapabilities capabilities;
51 NMDBusAgentManager *manager_proxy;
52 NMDBusSecretAgent *dbus_secret_agent;
54 /* GetSecretsInfo structs of in-flight GetSecrets requests */
58 gboolean auto_register;
59 gboolean suppress_auto;
60 } NMSecretAgentOldPrivate;
72 /*************************************************************/
75 _internal_unregister (NMSecretAgentOld *self)
77 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
79 if (priv->registered) {
80 g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent));
81 priv->registered = FALSE;
82 priv->registering = FALSE;
83 g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_OLD_REGISTERED);
90 GDBusMethodInvocation *context;
94 get_secrets_info_finalize (NMSecretAgentOld *self, GetSecretsInfo *info)
96 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
98 g_return_if_fail (info != NULL);
100 priv->pending_gets = g_slist_remove (priv->pending_gets, info);
103 g_free (info->setting_name);
104 memset (info, 0, sizeof (*info));
108 static inline gboolean
109 should_auto_register (NMSecretAgentOld *self)
111 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
113 return ( priv->auto_register
114 && !priv->suppress_auto
116 && !priv->registering);
120 name_owner_changed (GObject *proxy,
124 NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (user_data);
125 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
129 owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (proxy));
131 if (should_auto_register (self))
132 nm_secret_agent_old_register_async (self, NULL, NULL, NULL);
135 /* Cancel any pending secrets requests */
136 for (iter = priv->pending_gets; iter; iter = g_slist_next (iter)) {
137 GetSecretsInfo *info = iter->data;
139 NM_SECRET_AGENT_OLD_GET_CLASS (self)->cancel_get_secrets (self,
143 g_slist_free (priv->pending_gets);
144 priv->pending_gets = NULL;
146 _internal_unregister (self);
151 verify_sender (NMSecretAgentOld *self,
152 GDBusMethodInvocation *context,
155 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
160 GError *local = NULL;
162 g_return_val_if_fail (context != NULL, FALSE);
164 /* Private bus connection is always to NetworkManager, which is always
167 if (priv->private_bus)
170 /* Verify that the sender is the same as NetworkManager's bus name owner. */
172 nm_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy));
174 g_set_error_literal (error,
175 NM_SECRET_AGENT_ERROR,
176 NM_SECRET_AGENT_ERROR_PERMISSION_DENIED,
177 "NetworkManager bus name owner unknown.");
181 sender = g_dbus_method_invocation_get_sender (context);
183 g_set_error_literal (error,
184 NM_SECRET_AGENT_ERROR,
185 NM_SECRET_AGENT_ERROR_PERMISSION_DENIED,
186 "Failed to get request sender.");
191 /* Check that the sender matches the current NM bus name owner */
192 if (strcmp (sender, nm_owner) != 0) {
193 g_set_error_literal (error,
194 NM_SECRET_AGENT_ERROR,
195 NM_SECRET_AGENT_ERROR_PERMISSION_DENIED,
196 "Request sender does not match NetworkManager bus name owner.");
202 /* If we're connected to the session bus, then this must be a test program,
203 * so skip the UID check.
205 if (priv->session_bus)
208 /* Check the UID of the sender */
209 ret = g_dbus_connection_call_sync (priv->bus,
213 "GetConnectionUnixUser",
214 g_variant_new ("(s)", sender),
215 G_VARIANT_TYPE ("(u)"),
216 G_DBUS_CALL_FLAGS_NONE, -1,
219 char *remote_error = g_dbus_error_get_remote_error (local);
221 g_dbus_error_strip_remote_error (local);
223 NM_SECRET_AGENT_ERROR,
224 NM_SECRET_AGENT_ERROR_PERMISSION_DENIED,
225 "Failed to request unix user: (%s) %s.",
226 remote_error ? remote_error : "",
228 g_free (remote_error);
229 g_error_free (local);
232 g_variant_get (ret, "(u)", &sender_uid);
233 g_variant_unref (ret);
235 /* We only accept requests from NM, which always runs as root */
236 if (0 != sender_uid) {
237 g_set_error_literal (error,
238 NM_SECRET_AGENT_ERROR,
239 NM_SECRET_AGENT_ERROR_PERMISSION_DENIED,
240 "Request sender is not root.");
248 verify_request (NMSecretAgentOld *self,
249 GDBusMethodInvocation *context,
250 GVariant *connection_dict,
251 const char *connection_path,
252 NMConnection **out_connection,
255 NMConnection *connection = NULL;
256 GError *local = NULL;
258 if (!verify_sender (self, context, error))
261 /* No connection? If the sender verified, then we allow the request */
262 if (connection_dict == NULL)
265 /* If we have a connection dictionary, we require a path too */
266 if (connection_path == NULL) {
267 g_set_error_literal (error,
268 NM_SECRET_AGENT_ERROR,
269 NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
270 "Invalid connection: no connection path given.");
274 /* Make sure the given connection is valid */
275 g_assert (out_connection);
276 connection = nm_simple_connection_new_from_dbus (connection_dict, &local);
278 nm_connection_set_path (connection, connection_path);
279 *out_connection = connection;
282 NM_SECRET_AGENT_ERROR,
283 NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
284 "Invalid connection: %s", local->message);
285 g_clear_error (&local);
292 get_secrets_cb (NMSecretAgentOld *self,
293 NMConnection *connection,
298 GetSecretsInfo *info = user_data;
301 g_dbus_method_invocation_return_gerror (info->context, error);
303 g_variant_take_ref (secrets);
304 g_dbus_method_invocation_return_value (info->context,
305 g_variant_new ("(@a{sa{sv}})", secrets));
308 /* Remove the request from internal tracking */
309 get_secrets_info_finalize (self, info);
313 impl_secret_agent_old_get_secrets (NMSecretAgentOld *self,
314 GDBusMethodInvocation *context,
315 GVariant *connection_dict,
316 const char *connection_path,
317 const char *setting_name,
318 const char * const *hints,
322 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
323 GError *error = NULL;
324 NMConnection *connection = NULL;
325 GetSecretsInfo *info;
327 /* Make sure the request comes from NetworkManager and is valid */
328 if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) {
329 g_dbus_method_invocation_take_error (context, error);
333 info = g_malloc0 (sizeof (GetSecretsInfo));
334 info->path = g_strdup (connection_path);
335 info->setting_name = g_strdup (setting_name);
336 info->context = context;
337 priv->pending_gets = g_slist_append (priv->pending_gets, info);
339 NM_SECRET_AGENT_OLD_GET_CLASS (self)->get_secrets (self,
343 (const char **) hints,
347 g_object_unref (connection);
350 static GetSecretsInfo *
351 find_get_secrets_info (GSList *list, const char *path, const char *setting_name)
355 for (iter = list; iter; iter = g_slist_next (iter)) {
356 GetSecretsInfo *candidate = iter->data;
358 if ( g_strcmp0 (path, candidate->path) == 0
359 && g_strcmp0 (setting_name, candidate->setting_name) == 0)
366 impl_secret_agent_old_cancel_get_secrets (NMSecretAgentOld *self,
367 GDBusMethodInvocation *context,
368 const char *connection_path,
369 const char *setting_name,
372 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
373 GError *error = NULL;
374 GetSecretsInfo *info;
376 /* Make sure the request comes from NetworkManager and is valid */
377 if (!verify_request (self, context, NULL, NULL, NULL, &error)) {
378 g_dbus_method_invocation_take_error (context, error);
382 info = find_get_secrets_info (priv->pending_gets, connection_path, setting_name);
384 g_dbus_method_invocation_return_error (context,
385 NM_SECRET_AGENT_ERROR,
386 NM_SECRET_AGENT_ERROR_FAILED,
387 "No secrets request in progress for this connection.");
391 /* Send the cancel request up to the subclass and finalize it */
392 NM_SECRET_AGENT_OLD_GET_CLASS (self)->cancel_get_secrets (self,
395 g_dbus_method_invocation_return_value (context, NULL);
399 save_secrets_cb (NMSecretAgentOld *self,
400 NMConnection *connection,
404 GDBusMethodInvocation *context = user_data;
407 g_dbus_method_invocation_return_gerror (context, error);
409 g_dbus_method_invocation_return_value (context, NULL);
413 impl_secret_agent_old_save_secrets (NMSecretAgentOld *self,
414 GDBusMethodInvocation *context,
415 GVariant *connection_dict,
416 const char *connection_path,
419 GError *error = NULL;
420 NMConnection *connection = NULL;
422 /* Make sure the request comes from NetworkManager and is valid */
423 if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) {
424 g_dbus_method_invocation_take_error (context, error);
428 NM_SECRET_AGENT_OLD_GET_CLASS (self)->save_secrets (self,
433 g_object_unref (connection);
437 delete_secrets_cb (NMSecretAgentOld *self,
438 NMConnection *connection,
442 GDBusMethodInvocation *context = user_data;
445 g_dbus_method_invocation_return_gerror (context, error);
447 g_dbus_method_invocation_return_value (context, NULL);
451 impl_secret_agent_old_delete_secrets (NMSecretAgentOld *self,
452 GDBusMethodInvocation *context,
453 GVariant *connection_dict,
454 const char *connection_path,
457 GError *error = NULL;
458 NMConnection *connection = NULL;
460 /* Make sure the request comes from NetworkManager and is valid */
461 if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) {
462 g_dbus_method_invocation_take_error (context, error);
466 NM_SECRET_AGENT_OLD_GET_CLASS (self)->delete_secrets (self,
471 g_object_unref (connection);
474 /**************************************************************/
477 check_nm_running (NMSecretAgentOld *self, GError **error)
479 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
482 if (priv->private_bus)
484 owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy));
490 g_set_error (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED,
491 "NetworkManager is not running");
495 /**************************************************************/
498 * nm_secret_agent_old_register:
499 * @self: a #NMSecretAgentOld
500 * @cancellable: a #GCancellable, or %NULL
501 * @error: return location for a #GError, or %NULL
503 * Registers the #NMSecretAgentOld with the NetworkManager secret manager,
504 * indicating to NetworkManager that the agent is able to provide and save
505 * secrets for connections on behalf of its user.
507 * It is a programmer error to attempt to register an agent that is already
508 * registered, or in the process of registering.
510 * Returns: %TRUE if registration was successful, %FALSE on error.
513 nm_secret_agent_old_register (NMSecretAgentOld *self,
514 GCancellable *cancellable,
517 NMSecretAgentOldPrivate *priv;
518 NMSecretAgentOldClass *class;
520 g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE);
522 priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
524 g_return_val_if_fail (priv->registered == FALSE, FALSE);
525 g_return_val_if_fail (priv->registering == FALSE, FALSE);
526 g_return_val_if_fail (priv->bus != NULL, FALSE);
527 g_return_val_if_fail (priv->manager_proxy != NULL, FALSE);
529 /* Also make sure the subclass can actually respond to secrets requests */
530 class = NM_SECRET_AGENT_OLD_GET_CLASS (self);
531 g_return_val_if_fail (class->get_secrets != NULL, FALSE);
532 g_return_val_if_fail (class->save_secrets != NULL, FALSE);
533 g_return_val_if_fail (class->delete_secrets != NULL, FALSE);
535 if (!check_nm_running (self, error))
538 priv->suppress_auto = FALSE;
540 /* Export our secret agent interface before registering with the manager */
541 if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent),
543 NM_DBUS_PATH_SECRET_AGENT,
547 priv->registering = TRUE;
548 if (nmdbus_agent_manager_call_register_with_capabilities_sync (priv->manager_proxy,
554 /* Might be an old NetworkManager that doesn't support capabilities;
555 * fall back to old Register() method instead.
557 if (nmdbus_agent_manager_call_register_sync (priv->manager_proxy,
563 priv->registering = FALSE;
564 _internal_unregister (self);
568 priv->registering = FALSE;
569 priv->registered = TRUE;
570 g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_OLD_REGISTERED);
575 reg_result (NMSecretAgentOld *self, GSimpleAsyncResult *simple, GError *error)
577 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
579 priv->registering = FALSE;
582 g_simple_async_result_take_error (simple, error);
583 g_simple_async_result_complete (simple);
585 /* If registration failed we shouldn't expose ourselves on the bus */
586 _internal_unregister (self);
588 priv->registered = TRUE;
589 g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_OLD_REGISTERED);
591 g_simple_async_result_set_op_res_gboolean (simple, TRUE);
592 g_simple_async_result_complete (simple);
595 g_object_unref (simple);
599 reg_request_cb (GObject *proxy,
600 GAsyncResult *result,
603 GSimpleAsyncResult *simple = user_data;
604 NMSecretAgentOld *self;
605 NMSecretAgentOldPrivate *priv;
606 GError *error = NULL;
608 self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
609 g_object_unref (self); /* drop extra ref added by get_source_object() */
610 priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
612 if (!nmdbus_agent_manager_call_register_finish (NMDBUS_AGENT_MANAGER (proxy), result, &error))
613 g_dbus_error_strip_remote_error (error);
614 reg_result (self, simple, error);
615 g_clear_error (&error);
619 reg_with_caps_cb (GObject *proxy,
620 GAsyncResult *result,
623 GSimpleAsyncResult *simple = user_data;
624 NMSecretAgentOld *self;
625 NMSecretAgentOldPrivate *priv;
627 self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
628 g_object_unref (self); /* drop extra ref added by get_source_object() */
629 priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
631 if (nmdbus_agent_manager_call_register_with_capabilities_finish (NMDBUS_AGENT_MANAGER (proxy), result, NULL)) {
632 reg_result (self, simple, NULL);
636 /* Might be an old NetworkManager that doesn't support capabilities;
637 * fall back to old Register() method instead.
639 nmdbus_agent_manager_call_register (priv->manager_proxy,
641 NULL, reg_request_cb, simple);
645 * nm_secret_agent_old_register_async:
646 * @self: a #NMSecretAgentOld
647 * @cancellable: a #GCancellable, or %NULL
648 * @callback: callback to call when the agent is registered
649 * @user_data: data for @callback
651 * Asynchronously registers the #NMSecretAgentOld with the NetworkManager secret
652 * manager, indicating to NetworkManager that the agent is able to provide and
653 * save secrets for connections on behalf of its user.
655 * It is a programmer error to attempt to register an agent that is already
656 * registered, or in the process of registering.
659 nm_secret_agent_old_register_async (NMSecretAgentOld *self,
660 GCancellable *cancellable,
661 GAsyncReadyCallback callback,
664 NMSecretAgentOldPrivate *priv;
665 NMSecretAgentOldClass *class;
666 GSimpleAsyncResult *simple;
667 GError *error = NULL;
669 g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
671 priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
673 g_return_if_fail (priv->registered == FALSE);
674 g_return_if_fail (priv->registering == FALSE);
675 g_return_if_fail (priv->bus != NULL);
676 g_return_if_fail (priv->manager_proxy != NULL);
678 /* Also make sure the subclass can actually respond to secrets requests */
679 class = NM_SECRET_AGENT_OLD_GET_CLASS (self);
680 g_return_if_fail (class->get_secrets != NULL);
681 g_return_if_fail (class->save_secrets != NULL);
682 g_return_if_fail (class->delete_secrets != NULL);
684 simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
685 nm_secret_agent_old_register_async);
687 if (!check_nm_running (self, &error)) {
688 g_simple_async_result_take_error (simple, error);
689 g_simple_async_result_complete_in_idle (simple);
690 g_object_unref (simple);
694 /* Export our secret agent interface before registering with the manager */
695 if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent),
697 NM_DBUS_PATH_SECRET_AGENT,
699 g_simple_async_result_take_error (simple, error);
700 g_simple_async_result_complete_in_idle (simple);
701 g_object_unref (simple);
705 priv->suppress_auto = FALSE;
706 priv->registering = TRUE;
708 nmdbus_agent_manager_call_register_with_capabilities (priv->manager_proxy,
712 reg_with_caps_cb, simple);
716 * nm_secret_agent_old_register_finish:
717 * @self: a #NMSecretAgentOld
718 * @result: the result passed to the #GAsyncReadyCallback
719 * @error: return location for a #GError, or %NULL
721 * Gets the result of a call to nm_secret_agent_old_register_async().
723 * Returns: %TRUE if registration was successful, %FALSE on error.
726 nm_secret_agent_old_register_finish (NMSecretAgentOld *self,
727 GAsyncResult *result,
730 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), nm_secret_agent_old_register_async), FALSE);
732 if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
739 * nm_secret_agent_old_unregister:
740 * @self: a #NMSecretAgentOld
741 * @cancellable: a #GCancellable, or %NULL
742 * @error: return location for a #GError, or %NULL
744 * Unregisters the #NMSecretAgentOld with the NetworkManager secret manager,
745 * indicating to NetworkManager that the agent will no longer provide or
746 * store secrets on behalf of this user.
748 * It is a programmer error to attempt to unregister an agent that is not
751 * Returns: %TRUE if unregistration was successful, %FALSE on error
754 nm_secret_agent_old_unregister (NMSecretAgentOld *self,
755 GCancellable *cancellable,
758 NMSecretAgentOldPrivate *priv;
761 g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE);
763 priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
765 g_return_val_if_fail (priv->registered == TRUE, FALSE);
766 g_return_val_if_fail (priv->bus != NULL, FALSE);
767 g_return_val_if_fail (priv->manager_proxy != NULL, FALSE);
769 priv->suppress_auto = TRUE;
771 success = nmdbus_agent_manager_call_unregister_sync (priv->manager_proxy, cancellable, error);
773 g_dbus_error_strip_remote_error (*error);
774 _internal_unregister (self);
780 unregister_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
782 GSimpleAsyncResult *simple = user_data;
783 NMSecretAgentOld *self;
784 GError *error = NULL;
786 self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
787 g_object_unref (self); /* drop extra ref added by get_source_object() */
789 _internal_unregister (self);
791 if (nmdbus_agent_manager_call_unregister_finish (NMDBUS_AGENT_MANAGER (proxy),
793 g_simple_async_result_set_op_res_gboolean (simple, TRUE);
795 g_dbus_error_strip_remote_error (error);
796 g_simple_async_result_take_error (simple, error);
799 g_simple_async_result_complete (simple);
800 g_object_unref (simple);
804 * nm_secret_agent_old_unregister_async:
805 * @self: a #NMSecretAgentOld
806 * @cancellable: a #GCancellable, or %NULL
807 * @callback: callback to call when the agent is unregistered
808 * @user_data: data for @callback
810 * Asynchronously unregisters the #NMSecretAgentOld with the NetworkManager secret
811 * manager, indicating to NetworkManager that the agent will no longer provide
812 * or store secrets on behalf of this user.
814 * It is a programmer error to attempt to unregister an agent that is not
818 nm_secret_agent_old_unregister_async (NMSecretAgentOld *self,
819 GCancellable *cancellable,
820 GAsyncReadyCallback callback,
823 NMSecretAgentOldPrivate *priv;
824 GSimpleAsyncResult *simple;
825 GError *error = NULL;
827 g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
829 priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
831 g_return_if_fail (priv->registered == TRUE);
832 g_return_if_fail (priv->bus != NULL);
833 g_return_if_fail (priv->manager_proxy != NULL);
835 simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
836 nm_secret_agent_old_unregister_async);
838 if (!check_nm_running (self, &error)) {
839 g_simple_async_result_take_error (simple, error);
840 g_simple_async_result_complete_in_idle (simple);
841 g_object_unref (simple);
845 priv->suppress_auto = TRUE;
847 nmdbus_agent_manager_call_unregister (priv->manager_proxy, cancellable,
848 unregister_cb, simple);
852 * nm_secret_agent_old_unregister_finish:
853 * @self: a #NMSecretAgentOld
854 * @result: the result passed to the #GAsyncReadyCallback
855 * @error: return location for a #GError, or %NULL
857 * Gets the result of a call to nm_secret_agent_old_unregister_async().
859 * Returns: %TRUE if unregistration was successful, %FALSE on error.
862 nm_secret_agent_old_unregister_finish (NMSecretAgentOld *self,
863 GAsyncResult *result,
866 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), nm_secret_agent_old_unregister_async), FALSE);
868 if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
875 * nm_secret_agent_old_get_registered:
876 * @self: a #NMSecretAgentOld
878 * Returns: a %TRUE if the agent is registered, %FALSE if it is not.
881 nm_secret_agent_old_get_registered (NMSecretAgentOld *self)
883 g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE);
885 return NM_SECRET_AGENT_OLD_GET_PRIVATE (self)->registered;
888 /**************************************************************/
891 * nm_secret_agent_old_get_secrets:
892 * @self: a #NMSecretAgentOld
893 * @connection: the #NMConnection for which we're asked secrets
894 * @setting_name: the name of the secret setting
895 * @hints: (array zero-terminated=1): hints to the agent
896 * @flags: flags that modify the behavior of the request
897 * @callback: (scope async): a callback, to be invoked when the operation is done
898 * @user_data: (closure): caller-specific data to be passed to @callback
900 * Asynchronously retrieves secrets belonging to @connection for the
901 * setting @setting_name. @flags indicate specific behavior that the secret
902 * agent should use when performing the request, for example returning only
903 * existing secrets without user interaction, or requesting entirely new
904 * secrets from the user.
906 * Virtual: get_secrets
909 nm_secret_agent_old_get_secrets (NMSecretAgentOld *self,
910 NMConnection *connection,
911 const char *setting_name,
913 NMSecretAgentGetSecretsFlags flags,
914 NMSecretAgentOldGetSecretsFunc callback,
917 g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
918 g_return_if_fail (NM_IS_CONNECTION (connection));
919 g_return_if_fail (nm_connection_get_path (connection));
920 g_return_if_fail (setting_name != NULL);
921 g_return_if_fail (strlen (setting_name) > 0);
922 g_return_if_fail (!(flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM));
923 g_return_if_fail (!(flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS));
924 g_return_if_fail (callback != NULL);
926 NM_SECRET_AGENT_OLD_GET_CLASS (self)->get_secrets (self,
928 nm_connection_get_path (connection),
937 * nm_secret_agent_old_save_secrets:
938 * @self: a #NMSecretAgentOld
939 * @connection: a #NMConnection
940 * @callback: (scope async): a callback, to be invoked when the operation is done
941 * @user_data: (closure): caller-specific data to be passed to @callback
943 * Asynchronously ensures that all secrets inside @connection are stored to
946 * Virtual: save_secrets
949 nm_secret_agent_old_save_secrets (NMSecretAgentOld *self,
950 NMConnection *connection,
951 NMSecretAgentOldSaveSecretsFunc callback,
954 g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
955 g_return_if_fail (NM_IS_CONNECTION (connection));
956 g_return_if_fail (nm_connection_get_path (connection));
958 NM_SECRET_AGENT_OLD_GET_CLASS (self)->save_secrets (self,
960 nm_connection_get_path (connection),
966 * nm_secret_agent_old_delete_secrets:
967 * @self: a #NMSecretAgentOld
968 * @connection: a #NMConnection
969 * @callback: (scope async): a callback, to be invoked when the operation is done
970 * @user_data: (closure): caller-specific data to be passed to @callback
972 * Asynchronously asks the agent to delete all saved secrets belonging to
975 * Virtual: delete_secrets
978 nm_secret_agent_old_delete_secrets (NMSecretAgentOld *self,
979 NMConnection *connection,
980 NMSecretAgentOldDeleteSecretsFunc callback,
983 g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
984 g_return_if_fail (NM_IS_CONNECTION (connection));
985 g_return_if_fail (nm_connection_get_path (connection));
987 NM_SECRET_AGENT_OLD_GET_CLASS (self)->delete_secrets (self,
989 nm_connection_get_path (connection),
994 /**************************************************************/
997 validate_identifier (const char *identifier)
999 const char *p = identifier;
1002 /* Length between 3 and 255 characters inclusive */
1003 id_len = strlen (identifier);
1004 if (id_len < 3 || id_len > 255)
1007 if ((identifier[0] == '.') || (identifier[id_len - 1] == '.'))
1010 /* FIXME: do complete validation here */
1012 if (!g_ascii_isalnum (*p) && (*p != '_') && (*p != '-') && (*p != '.'))
1014 if ((*p == '.') && (*(p + 1) == '.'))
1023 nm_secret_agent_old_init (NMSecretAgentOld *self)
1025 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
1027 priv->dbus_secret_agent = nmdbus_secret_agent_skeleton_new ();
1028 _nm_dbus_bind_properties (self, priv->dbus_secret_agent);
1029 _nm_dbus_bind_methods (self, priv->dbus_secret_agent,
1030 "GetSecrets", impl_secret_agent_old_get_secrets,
1031 "CancelGetSecrets", impl_secret_agent_old_cancel_get_secrets,
1032 "DeleteSecrets", impl_secret_agent_old_delete_secrets,
1033 "SaveSecrets", impl_secret_agent_old_save_secrets,
1038 init_common (NMSecretAgentOld *self)
1040 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
1042 priv->private_bus = _nm_dbus_is_connection_private (priv->bus);
1044 if (priv->private_bus == FALSE) {
1045 priv->session_bus = _nm_dbus_bus_type () == G_BUS_TYPE_SESSION;
1047 g_signal_connect (priv->manager_proxy, "notify::g-name-owner",
1048 G_CALLBACK (name_owner_changed), self);
1053 init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
1055 NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable);
1056 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
1059 priv->bus = _nm_dbus_new_connection (cancellable, error);
1063 proxy = _nm_dbus_new_proxy_for_connection (priv->bus,
1064 NM_DBUS_PATH_AGENT_MANAGER,
1065 NM_DBUS_INTERFACE_AGENT_MANAGER,
1066 cancellable, error);
1069 priv->manager_proxy = NMDBUS_AGENT_MANAGER (proxy);
1073 if (priv->auto_register)
1074 return nm_secret_agent_old_register (self, cancellable, error);
1080 NMSecretAgentOld *self;
1081 GCancellable *cancellable;
1082 GSimpleAsyncResult *simple;
1083 } NMSecretAgentOldInitData;
1086 init_async_complete (NMSecretAgentOldInitData *init_data, GError *error)
1089 g_simple_async_result_set_op_res_gboolean (init_data->simple, TRUE);
1091 g_simple_async_result_take_error (init_data->simple, error);
1093 g_simple_async_result_complete_in_idle (init_data->simple);
1095 g_object_unref (init_data->simple);
1096 g_clear_object (&init_data->cancellable);
1097 g_slice_free (NMSecretAgentOldInitData, init_data);
1101 init_async_registered (GObject *object, GAsyncResult *result, gpointer user_data)
1103 NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (object);
1104 NMSecretAgentOldInitData *init_data = user_data;
1105 GError *error = NULL;
1107 nm_secret_agent_old_register_finish (self, result, &error);
1108 init_async_complete (init_data, error);
1112 init_async_got_proxy (GObject *object, GAsyncResult *result, gpointer user_data)
1114 NMSecretAgentOldInitData *init_data = user_data;
1115 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (init_data->self);
1117 GError *error = NULL;
1119 proxy = _nm_dbus_new_proxy_for_connection_finish (result, &error);
1121 init_async_complete (init_data, error);
1124 priv->manager_proxy = NMDBUS_AGENT_MANAGER (proxy);
1126 init_common (init_data->self);
1128 if (priv->auto_register) {
1129 nm_secret_agent_old_register_async (init_data->self, init_data->cancellable,
1130 init_async_registered, init_data);
1132 init_async_complete (init_data, NULL);
1136 init_async_got_bus (GObject *initable, GAsyncResult *result, gpointer user_data)
1138 NMSecretAgentOldInitData *init_data = user_data;
1139 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (init_data->self);
1140 GError *error = NULL;
1142 priv->bus = _nm_dbus_new_connection_finish (result, &error);
1144 init_async_complete (init_data, error);
1148 _nm_dbus_new_proxy_for_connection_async (priv->bus,
1149 NM_DBUS_PATH_AGENT_MANAGER,
1150 NM_DBUS_INTERFACE_AGENT_MANAGER,
1151 init_data->cancellable,
1152 init_async_got_proxy, init_data);
1156 init_async (GAsyncInitable *initable, int io_priority,
1157 GCancellable *cancellable, GAsyncReadyCallback callback,
1160 NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable);
1161 NMSecretAgentOldInitData *init_data;
1163 init_data = g_slice_new (NMSecretAgentOldInitData);
1164 init_data->self = self;
1165 init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1167 init_data->simple = g_simple_async_result_new (G_OBJECT (initable), callback,
1168 user_data, init_async);
1170 _nm_dbus_new_connection_async (cancellable, init_async_got_bus, init_data);
1174 init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error)
1176 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1178 if (g_simple_async_result_propagate_error (simple, error))
1185 get_property (GObject *object,
1190 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (object);
1193 case PROP_IDENTIFIER:
1194 g_value_set_string (value, priv->identifier);
1196 case PROP_AUTO_REGISTER:
1197 g_value_set_boolean (value, priv->auto_register);
1199 case PROP_REGISTERED:
1200 g_value_set_boolean (value, priv->registered);
1202 case PROP_CAPABILITIES:
1203 g_value_set_flags (value, priv->capabilities);
1206 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1212 set_property (GObject *object,
1214 const GValue *value,
1217 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (object);
1218 const char *identifier;
1221 case PROP_IDENTIFIER:
1222 identifier = g_value_get_string (value);
1224 g_return_if_fail (validate_identifier (identifier));
1226 g_free (priv->identifier);
1227 priv->identifier = g_strdup (identifier);
1229 case PROP_AUTO_REGISTER:
1230 priv->auto_register = g_value_get_boolean (value);
1232 case PROP_CAPABILITIES:
1233 priv->capabilities = g_value_get_flags (value);
1236 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1242 dispose (GObject *object)
1244 NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (object);
1245 NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
1247 if (priv->registered)
1248 nm_secret_agent_old_unregister_async (self, NULL, NULL, NULL);
1250 g_clear_pointer (&priv->identifier, g_free);
1252 while (priv->pending_gets)
1253 get_secrets_info_finalize (self, priv->pending_gets->data);
1255 g_signal_handlers_disconnect_matched (priv->dbus_secret_agent, G_SIGNAL_MATCH_DATA,
1256 0, 0, NULL, NULL, self);
1257 g_object_unref (priv->dbus_secret_agent);
1259 g_clear_object (&priv->manager_proxy);
1260 g_clear_object (&priv->bus);
1262 G_OBJECT_CLASS (nm_secret_agent_old_parent_class)->dispose (object);
1266 nm_secret_agent_old_class_init (NMSecretAgentOldClass *class)
1268 GObjectClass *object_class = G_OBJECT_CLASS (class);
1270 g_type_class_add_private (class, sizeof (NMSecretAgentOldPrivate));
1272 /* Virtual methods */
1273 object_class->dispose = dispose;
1274 object_class->get_property = get_property;
1275 object_class->set_property = set_property;
1278 * NMSecretAgentOld:identifier:
1280 * Identifies this agent; only one agent in each user session may use the
1281 * same identifier. Identifier formatting follows the same rules as
1282 * D-Bus bus names with the exception that the ':' character is not
1283 * allowed. The valid set of characters is "[A-Z][a-z][0-9]_-." and the
1284 * identifier is limited in length to 255 characters with a minimum
1285 * of 3 characters. An example valid identifier is 'org.gnome.nm-applet'
1288 g_object_class_install_property
1289 (object_class, PROP_IDENTIFIER,
1290 g_param_spec_string (NM_SECRET_AGENT_OLD_IDENTIFIER, "", "",
1293 G_PARAM_CONSTRUCT_ONLY |
1294 G_PARAM_STATIC_STRINGS));
1297 * NMSecretAgentOld:auto-register:
1299 * If %TRUE (the default), the agent will always be registered when
1300 * NetworkManager is running; if NetworkManager exits and restarts, the
1301 * agent will re-register itself automatically.
1303 * In particular, if this property is %TRUE at construct time, then the
1304 * agent will register itself with NetworkManager during
1305 * construction/initialization, and initialization will fail with an error
1306 * if the agent is unable to register itself.
1308 * If the property is %FALSE, the agent will not automatically register with
1309 * NetworkManager, and nm_secret_agent_old_register() or
1310 * nm_secret_agent_old_register_async() must be called to register it.
1312 * Calling nm_secret_agent_old_unregister() will suppress auto-registration
1313 * until nm_secret_agent_old_register() is called, which re-enables
1314 * auto-registration. This ensures that the agent remains un-registered when
1315 * you expect it to be unregistered.
1317 g_object_class_install_property
1318 (object_class, PROP_AUTO_REGISTER,
1319 g_param_spec_boolean (NM_SECRET_AGENT_OLD_AUTO_REGISTER, "", "",
1323 G_PARAM_STATIC_STRINGS));
1326 * NMSecretAgentOld:registered:
1328 * %TRUE if the agent is registered with NetworkManager, %FALSE if not.
1330 g_object_class_install_property
1331 (object_class, PROP_REGISTERED,
1332 g_param_spec_boolean (NM_SECRET_AGENT_OLD_REGISTERED, "", "",
1335 G_PARAM_STATIC_STRINGS));
1338 * NMSecretAgentOld:capabilities:
1340 * A bitfield of %NMSecretAgentCapabilities.
1342 g_object_class_install_property
1343 (object_class, PROP_CAPABILITIES,
1344 g_param_spec_flags (NM_SECRET_AGENT_OLD_CAPABILITIES, "", "",
1345 NM_TYPE_SECRET_AGENT_CAPABILITIES,
1346 NM_SECRET_AGENT_CAPABILITY_NONE,
1349 G_PARAM_STATIC_STRINGS));
1351 _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_AGENT_MANAGER,
1352 NMDBUS_TYPE_AGENT_MANAGER_PROXY);
1356 nm_secret_agent_old_initable_iface_init (GInitableIface *iface)
1358 iface->init = init_sync;
1362 nm_secret_agent_old_async_initable_iface_init (GAsyncInitableIface *iface)
1364 iface->init_async = init_async;
1365 iface->init_finish = init_finish;