diff options
author | David Zeuthen <davidz@redhat.com> | 2010-07-29 16:49:37 -0400 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2010-07-29 16:49:37 -0400 |
commit | 007b07f979b952744137b7a5b49712df87377014 (patch) | |
tree | 363f2f88c147bcfa5344a84c41e585b2ddb35685 | |
parent | 6eeb077bc90c9c7783360a526b2f04645b1b0848 (diff) | |
download | polkit-007b07f979b952744137b7a5b49712df87377014.tar.gz |
Port PolkitAgent to gdbus
Signed-off-by: David Zeuthen <davidz@redhat.com>
-rw-r--r-- | docs/polkit/polkit-1-sections.txt | 1 | ||||
-rw-r--r-- | src/polkit/polkitauthority.c | 183 | ||||
-rw-r--r-- | src/polkit/polkitauthority.h | 1 | ||||
-rw-r--r-- | src/polkitagent/polkitagentlistener.c | 415 |
4 files changed, 408 insertions, 192 deletions
diff --git a/docs/polkit/polkit-1-sections.txt b/docs/polkit/polkit-1-sections.txt index ac902b6..6b03fa2 100644 --- a/docs/polkit/polkit-1-sections.txt +++ b/docs/polkit/polkit-1-sections.txt @@ -22,6 +22,7 @@ PolkitAuthority PolkitAuthorityFeatures PolkitCheckAuthorizationFlags polkit_authority_get +polkit_authority_get_owner polkit_authority_get_backend_name polkit_authority_get_backend_version polkit_authority_get_backend_features diff --git a/src/polkit/polkitauthority.c b/src/polkit/polkitauthority.c index d224bcf..1a66add 100644 --- a/src/polkit/polkitauthority.c +++ b/src/polkit/polkitauthority.c @@ -85,6 +85,7 @@ enum enum { PROP_0, + PROP_OWNER, PROP_BACKEND_NAME, PROP_BACKEND_VERSION, PROP_BACKEND_FEATURES @@ -109,6 +110,15 @@ on_proxy_signal (GDBusProxy *proxy, } static void +on_notify_g_name_owner (GObject *object, + GParamSpec *ppsec, + gpointer user_data) +{ + PolkitAuthority *authority = POLKIT_AUTHORITY (user_data); + g_object_notify (G_OBJECT (authority), "owner"); +} + +static void polkit_authority_init (PolkitAuthority *authority) { GError *error; @@ -132,6 +142,10 @@ polkit_authority_init (PolkitAuthority *authority) "g-signal", G_CALLBACK (on_proxy_signal), authority); + g_signal_connect (authority->proxy, + "notify::g-name-owner", + G_CALLBACK (on_notify_g_name_owner), + authority); } static void @@ -160,6 +174,10 @@ polkit_authority_get_property (GObject *object, switch (prop_id) { + case PROP_OWNER: + g_value_take_string (value, polkit_authority_get_owner (authority)); + break; + case PROP_BACKEND_NAME: g_value_set_string (value, polkit_authority_get_backend_name (authority)); break; @@ -187,6 +205,24 @@ polkit_authority_class_init (PolkitAuthorityClass *klass) gobject_class->get_property = polkit_authority_get_property; /** + * PolkitAuthority:owner: + * + * The unique name of the owner of the org.freedesktop.PolicyKit1 + * D-Bus service or %NULL if there is no owner. Connect to the + * #GObject::notify signal to track changes to this property. + */ + g_object_class_install_property (gobject_class, + PROP_OWNER, + g_param_spec_string ("owner", + "Owner", + "Owner.", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + /** * PolkitAuthority:backend-name: * * The name of the currently used Authority backend. @@ -330,6 +366,19 @@ call_sync_free (CallSyncData *data) /* ---------------------------------------------------------------------------------------------------- */ +static void +generic_async_cb (GObject *source_obj, + GAsyncResult *res, + gpointer user_data) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data); + g_simple_async_result_set_op_res_gpointer (simple, g_object_ref (res), g_object_unref); + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/* ---------------------------------------------------------------------------------------------------- */ + /** * polkit_authority_enumerate_actions: * @authority: A #PolkitAuthority. @@ -356,8 +405,11 @@ polkit_authority_enumerate_actions (PolkitAuthority *authority, G_DBUS_CALL_FLAGS_NONE, -1, cancellable, - callback, - user_data); + generic_async_cb, + g_simple_async_result_new (G_OBJECT (authority), + callback, + user_data, + polkit_authority_enumerate_actions)); } /** @@ -381,10 +433,14 @@ polkit_authority_enumerate_actions_finish (PolkitAuthority *authority, GVariantIter iter; GVariant *child; GVariant *array; + GAsyncResult *_res; ret = NULL; - value = g_dbus_proxy_call_finish (authority->proxy, res, error); + g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_enumerate_actions); + _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))); + + value = g_dbus_proxy_call_finish (authority->proxy, _res, error); if (value == NULL) goto out; @@ -689,8 +745,11 @@ polkit_authority_register_authentication_agent (PolkitAuthority *authority, G_DBUS_CALL_FLAGS_NONE, -1, cancellable, - callback, - user_data); + generic_async_cb, + g_simple_async_result_new (G_OBJECT (authority), + callback, + user_data, + polkit_authority_register_authentication_agent)); g_variant_unref (subject_value); } @@ -711,10 +770,14 @@ polkit_authority_register_authentication_agent_finish (PolkitAuthority *authorit { gboolean ret; GVariant *value; + GAsyncResult *_res; ret = FALSE; - value = g_dbus_proxy_call_finish (authority->proxy, res, error); + g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_register_authentication_agent); + _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))); + + value = g_dbus_proxy_call_finish (authority->proxy, _res, error); if (value == NULL) goto out; ret = TRUE; @@ -795,8 +858,11 @@ polkit_authority_unregister_authentication_agent (PolkitAuthority *authorit G_DBUS_CALL_FLAGS_NONE, -1, cancellable, - callback, - user_data); + generic_async_cb, + g_simple_async_result_new (G_OBJECT (authority), + callback, + user_data, + polkit_authority_unregister_authentication_agent)); g_variant_unref (subject_value); } @@ -817,10 +883,14 @@ polkit_authority_unregister_authentication_agent_finish (PolkitAuthority *author { gboolean ret; GVariant *value; + GAsyncResult *_res; ret = FALSE; - value = g_dbus_proxy_call_finish (authority->proxy, res, error); + g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_unregister_authentication_agent); + _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))); + + value = g_dbus_proxy_call_finish (authority->proxy, _res, error); if (value == NULL) goto out; ret = TRUE; @@ -903,8 +973,11 @@ polkit_authority_authentication_agent_response (PolkitAuthority *authority, G_DBUS_CALL_FLAGS_NONE, -1, cancellable, - callback, - user_data); + generic_async_cb, + g_simple_async_result_new (G_OBJECT (authority), + callback, + user_data, + polkit_authority_authentication_agent_response)); g_variant_unref (identity_value); } @@ -925,10 +998,14 @@ polkit_authority_authentication_agent_response_finish (PolkitAuthority *authorit { gboolean ret; GVariant *value; + GAsyncResult *_res; ret = FALSE; - value = g_dbus_proxy_call_finish (authority->proxy, res, error); + g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_authentication_agent_response); + _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))); + + value = g_dbus_proxy_call_finish (authority->proxy, _res, error); if (value == NULL) goto out; ret = TRUE; @@ -1005,8 +1082,11 @@ polkit_authority_enumerate_temporary_authorizations (PolkitAuthority *author G_DBUS_CALL_FLAGS_NONE, -1, cancellable, - callback, - user_data); + generic_async_cb, + g_simple_async_result_new (G_OBJECT (authority), + callback, + user_data, + polkit_authority_enumerate_temporary_authorizations)); g_variant_unref (subject_value); } @@ -1031,10 +1111,14 @@ polkit_authority_enumerate_temporary_authorizations_finish (PolkitAuthority *aut GVariantIter iter; GVariant *child; GVariant *array; + GAsyncResult *_res; ret = NULL; - value = g_dbus_proxy_call_finish (authority->proxy, res, error); + g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_enumerate_temporary_authorizations); + _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))); + + value = g_dbus_proxy_call_finish (authority->proxy, _res, error); if (value == NULL) goto out; @@ -1116,8 +1200,11 @@ polkit_authority_revoke_temporary_authorizations (PolkitAuthority *authority G_DBUS_CALL_FLAGS_NONE, -1, cancellable, - callback, - user_data); + generic_async_cb, + g_simple_async_result_new (G_OBJECT (authority), + callback, + user_data, + polkit_authority_revoke_temporary_authorizations)); g_variant_unref (subject_value); } @@ -1138,10 +1225,14 @@ polkit_authority_revoke_temporary_authorizations_finish (PolkitAuthority *author { gboolean ret; GVariant *value; + GAsyncResult *_res; ret = FALSE; - value = g_dbus_proxy_call_finish (authority->proxy, res, error); + g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_revoke_temporary_authorizations); + _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))); + + value = g_dbus_proxy_call_finish (authority->proxy, _res, error); if (value == NULL) goto out; ret = TRUE; @@ -1210,8 +1301,11 @@ polkit_authority_revoke_temporary_authorization_by_id (PolkitAuthority *auth G_DBUS_CALL_FLAGS_NONE, -1, cancellable, - callback, - user_data); + generic_async_cb, + g_simple_async_result_new (G_OBJECT (authority), + callback, + user_data, + polkit_authority_revoke_temporary_authorization_by_id)); } /** @@ -1231,10 +1325,14 @@ polkit_authority_revoke_temporary_authorization_by_id_finish (PolkitAuthority *a { gboolean ret; GVariant *value; + GAsyncResult *_res; ret = FALSE; - value = g_dbus_proxy_call_finish (authority->proxy, res, error); + g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_revoke_temporary_authorization_by_id); + _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))); + + value = g_dbus_proxy_call_finish (authority->proxy, _res, error); if (value == NULL) goto out; ret = TRUE; @@ -1303,8 +1401,11 @@ polkit_authority_add_lockdown_for_action (PolkitAuthority *authority, G_DBUS_CALL_FLAGS_NONE, -1, cancellable, - callback, - user_data); + generic_async_cb, + g_simple_async_result_new (G_OBJECT (authority), + callback, + user_data, + polkit_authority_add_lockdown_for_action)); } /** @@ -1324,10 +1425,14 @@ polkit_authority_add_lockdown_for_action_finish (PolkitAuthority *authority, { gboolean ret; GVariant *value; + GAsyncResult *_res; ret = FALSE; - value = g_dbus_proxy_call_finish (authority->proxy, res, error); + g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_add_lockdown_for_action); + _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))); + + value = g_dbus_proxy_call_finish (authority->proxy, _res, error); if (value == NULL) goto out; ret = TRUE; @@ -1396,8 +1501,11 @@ polkit_authority_remove_lockdown_for_action (PolkitAuthority *authority, G_DBUS_CALL_FLAGS_NONE, -1, cancellable, - callback, - user_data); + generic_async_cb, + g_simple_async_result_new (G_OBJECT (authority), + callback, + user_data, + polkit_authority_remove_lockdown_for_action)); } /** @@ -1417,10 +1525,14 @@ polkit_authority_remove_lockdown_for_action_finish (PolkitAuthority *authority, { gboolean ret; GVariant *value; + GAsyncResult *_res; ret = FALSE; - value = g_dbus_proxy_call_finish (authority->proxy, res, error); + g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == polkit_authority_remove_lockdown_for_action); + _res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))); + + value = g_dbus_proxy_call_finish (authority->proxy, _res, error); if (value == NULL) goto out; ret = TRUE; @@ -1462,6 +1574,23 @@ polkit_authority_remove_lockdown_for_action_sync (PolkitAuthority *authority /* ---------------------------------------------------------------------------------------------------- */ /** + * polkit_authority_get_owner: + * @authority: A #PolkitAuthority. + * + * The unique name on the system message bus of the owner of the name + * <literal>org.freedesktop.PolicyKit1</literal> or %NULL if no-one + * currently owns the name. You may connect to the #GObject::notify + * signal to track changes to the #PolkitAuthority::owner property. + * + * Returns: %NULL or a string that should be freed with g_free(). + **/ +gchar * +polkit_authority_get_owner (PolkitAuthority *authority) +{ + return g_dbus_proxy_get_name_owner (authority->proxy); +} + +/** * polkit_authority_get_backend_name: * @authority: A #PolkitAuthority. * diff --git a/src/polkit/polkitauthority.h b/src/polkit/polkitauthority.h index e0ad31c..4140ff8 100644 --- a/src/polkit/polkitauthority.h +++ b/src/polkit/polkitauthority.h @@ -49,6 +49,7 @@ GType polkit_authority_get_type (void) G_GNUC_CONST; PolkitAuthority *polkit_authority_get (void); +gchar *polkit_authority_get_owner (PolkitAuthority *authority); const gchar *polkit_authority_get_backend_name (PolkitAuthority *authority); const gchar *polkit_authority_get_backend_version (PolkitAuthority *authority); PolkitAuthorityFeatures polkit_authority_get_backend_features (PolkitAuthority *authority); diff --git a/src/polkitagent/polkitagentlistener.c b/src/polkitagent/polkitagentlistener.c index c2ab69a..d7bd5f0 100644 --- a/src/polkitagent/polkitagentlistener.c +++ b/src/polkitagent/polkitagentlistener.c @@ -44,27 +44,15 @@ * To register a #PolkitAgentListener with the PolicyKit daemon, use polkit_agent_register_listener(). */ -/* private class for exporting a D-Bus interface */ - -#define TYPE_SERVER (server_get_type ()) -#define SERVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TYPE_SERVER, Server)) -#define SERVER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), POLKIT_AGENT_TYPE_LISTENER, ServerClass)) -#define SERVER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_SERVER, ServerClass)) -#define IS_SERVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TYPE_SERVER)) -#define IS_SERVER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_SERVER)) - -typedef struct _Server Server; -typedef struct _ServerClass ServerClass; - -struct _Server +typedef struct { GObject parent_instance; - EggDBusConnection *system_bus; - - EggDBusObjectProxy *authority_proxy; + GDBusConnection *system_bus; + guint auth_agent_registration_id; PolkitAuthority *authority; + gulong notify_owner_handler_id; gboolean is_registered; @@ -74,23 +62,46 @@ struct _Server gchar *object_path; GHashTable *cookie_to_pending_auth; +} Server; -}; - -struct _ServerClass +static void +server_free (Server *server) { - GObjectClass parent_class; + if (server->is_registered) + { + GError *error; + error = NULL; + if (!polkit_authority_unregister_authentication_agent_sync (server->authority, + server->subject, + server->object_path, + NULL, + &error)) + { + g_warning ("Error unregistering authentication agent: %s", error->message); + g_error_free (error); + } + } -}; + if (server->auth_agent_registration_id > 0) + g_dbus_connection_unregister_object (server->system_bus, server->auth_agent_registration_id); + + if (server->notify_owner_handler_id > 0) + g_signal_handler_disconnect (server->authority, server->notify_owner_handler_id); -static GType server_get_type (void) G_GNUC_CONST; + if (server->authority != NULL) + g_object_unref (server->authority); -static void authentication_agent_iface_init (_PolkitAuthenticationAgentIface *agent_iface); + if (server->system_bus != NULL) + g_object_unref (server->system_bus); -G_DEFINE_TYPE_WITH_CODE (Server, server, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (_POLKIT_TYPE_AUTHENTICATION_AGENT, - authentication_agent_iface_init) - ); + if (server->cookie_to_pending_auth != NULL) + g_hash_table_unref (server->cookie_to_pending_auth); + + if (server->subject != NULL) + g_object_unref (server->subject); + + g_free (server->object_path); +} static gboolean server_register (Server *server, @@ -122,15 +133,14 @@ server_register (Server *server, } static void -name_owner_notify (EggDBusObjectProxy *object_proxy, - GParamSpec *pspec, - gpointer user_data) +on_notify_authority_owner (GObject *object, + GParamSpec *pspec, + gpointer user_data) { - Server *server = SERVER (user_data); + Server *server = user_data; gchar *owner; - owner = egg_dbus_object_proxy_get_name_owner (server->authority_proxy); - + owner = polkit_authority_get_owner (server->authority); if (owner == NULL) { g_printerr ("PolicyKit daemon disconnected from the bus.\n"); @@ -162,85 +172,129 @@ name_owner_notify (EggDBusObjectProxy *object_proxy, } } } - g_free (owner); } -static void -server_init (Server *server) +static gboolean +server_init_sync (Server *server, + GCancellable *cancellable, + GError **error) { - server->cookie_to_pending_auth = g_hash_table_new (g_str_hash, g_str_equal); + gboolean ret; + + ret = FALSE; - server->system_bus = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM); + server->system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, cancellable, error); + if (server->system_bus == NULL) + goto out; server->authority = polkit_authority_get (); + if (server->authority == NULL) + goto out; /* the only use of this proxy is to re-register with the polkit daemon * if it jumps off the bus and comes back (which is useful for debugging) */ - server->authority_proxy = egg_dbus_connection_get_object_proxy (server->system_bus, - "org.freedesktop.PolicyKit1", - "/org/freedesktop/PolicyKit1/Authority"); - - g_signal_connect (server->authority_proxy, - "notify::name-owner", - G_CALLBACK (name_owner_notify), - server); + server->notify_owner_handler_id = g_signal_connect (server->authority, + "notify::owner", + G_CALLBACK (on_notify_authority_owner), + server); + + ret = TRUE; + + out: + return ret; } -static void -server_finalize (GObject *object) +static Server * +server_new (PolkitSubject *subject, + const gchar *object_path, + GCancellable *cancellable, + GError **error) { - Server *server = SERVER (object); + Server *server; - if (server->is_registered) - { - GError *error; + server = g_new0 (Server, 1); + server->subject = g_object_ref (subject); + server->object_path = object_path != NULL ? g_strdup (object_path) : + g_strdup ("/org/freedesktop/PolicyKit1/AuthenticationAgent"); + server->cookie_to_pending_auth = g_hash_table_new (g_str_hash, g_str_equal); - error = NULL; - if (!polkit_authority_unregister_authentication_agent_sync (server->authority, - server->subject, - server->object_path, - NULL, - &error)) - { - g_warning ("Error unregistering authentication agent: %s", error->message); - g_error_free (error); - } + if (!server_init_sync (server, cancellable, error)) + { + server_free (server); + goto out; } - g_object_unref (server->subject); - g_free (server->object_path); - - g_object_unref (server->authority); - - g_object_unref (server->authority_proxy); - - g_object_unref (server->system_bus); - - g_hash_table_unref (server->cookie_to_pending_auth); - - if (G_OBJECT_CLASS (server_parent_class)->finalize != NULL) - G_OBJECT_CLASS (server_parent_class)->finalize (object); + out: + return server; } static void -server_class_init (ServerClass *klass) +listener_died (gpointer user_data, + GObject *where_the_object_was) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + Server *server = user_data; - gobject_class->finalize = server_finalize; + server_free (server); } +static void auth_agent_handle_begin_authentication (Server *server, + GVariant *parameters, + GDBusMethodInvocation *invocation); + +static void auth_agent_handle_cancel_authentication (Server *server, + GVariant *parameters, + GDBusMethodInvocation *invocation); + static void -listener_died (gpointer user_data, - GObject *where_the_object_was) +auth_agent_handle_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) { - Server *server = SERVER (user_data); + Server *server = user_data; + + /* The shipped D-Bus policy also ensures that only uid 0 can invoke + * methods on our interface. So no need to check the caller. + */ - g_object_unref (server); + if (g_strcmp0 (method_name, "BeginAuthentication") == 0) + auth_agent_handle_begin_authentication (server, parameters, invocation); + else if (g_strcmp0 (method_name, "CancelAuthentication") == 0) + auth_agent_handle_cancel_authentication (server, parameters, invocation); + else + g_assert_not_reached (); } +static const gchar *auth_agent_introspection_data = + "<node>" + " <interface name='org.freedesktop.PolicyKit1.AuthenticationAgent'>" + " <method name='BeginAuthentication'>" + " <arg type='s' name='action_id' direction='in'/>" + " <arg type='s' name='message' direction='in'/>" + " <arg type='s' name='icon_name' direction='in'/>" + " <arg type='a{ss}' name='details' direction='in'/>" + " <arg type='s' name='cookie' direction='in'/>" + " <arg type='a(sa{sv})' name='identities' direction='in'/>" + " </method>" + " <method name='CancelAuthentication'>" + " <arg type='s' name='cookie' direction='in'/>" + " </method>" + " </interface>" + "</node>"; + +static const GDBusInterfaceVTable auth_agent_vtable = +{ + auth_agent_handle_method_call, + NULL, /* _handle_get_property */ + NULL /* _handle_set_property */ +}; + /** * polkit_agent_register_listener: * @listener: An instance of a class that is derived from #PolkitAgentListener. @@ -270,66 +324,69 @@ polkit_agent_register_listener (PolkitAgentListener *listener, GError **error) { Server *server; + gboolean ret; + GDBusNodeInfo *node_info; - server = SERVER (g_object_new (TYPE_SERVER, NULL)); - server->subject = g_object_ref (subject); - server->object_path = object_path != NULL ? g_strdup (object_path) : - g_strdup ("/org/freedesktop/PolicyKit1/AuthenticationAgent"); - server->listener = listener; + ret = FALSE; + + server = server_new (subject, object_path, NULL, error); + if (server == NULL) + goto out; - egg_dbus_connection_register_interface (server->system_bus, - server->object_path, - _POLKIT_TYPE_AUTHENTICATION_AGENT, - G_OBJECT (server), - G_TYPE_INVALID); + node_info = g_dbus_node_info_new_for_xml (auth_agent_introspection_data, error); + if (node_info == NULL) + goto out; + + server->listener = listener; + server->auth_agent_registration_id = g_dbus_connection_register_object (server->system_bus, + server->object_path, + g_dbus_node_info_lookup_interface (node_info, "org.freedesktop.PolicyKit1.AuthenticationAgent"), + &auth_agent_vtable, + server, + NULL, /* user_data GDestroyNotify */ + error); + g_dbus_node_info_unref (node_info); + + if (server->auth_agent_registration_id == 0) + { + server_free (server); + goto out; + } if (!server_register (server, error)) { - g_object_unref (server); - return FALSE; + server_free (server); + goto out; } /* take a weak ref and kill server when listener dies */ g_object_weak_ref (G_OBJECT (server->listener), listener_died, server); - return TRUE; + ret = TRUE; + + out: + return ret; } typedef struct { Server *server; gchar *cookie; - EggDBusMethodInvocation *method_invocation; + GDBusMethodInvocation *invocation; GCancellable *cancellable; } AuthData; -static AuthData * -auth_data_new (Server *server, - const gchar *cookie, - EggDBusMethodInvocation *method_invocation, - GCancellable *cancellable) -{ - AuthData *data; - - data = g_new0 (AuthData, 1); - data->server = g_object_ref (server); - data->cookie = g_strdup (cookie); - data->method_invocation = g_object_ref (method_invocation); - data->cancellable = g_object_ref (cancellable); - - return data; -} - static void auth_data_free (AuthData *data) { - g_object_unref (data->server); g_free (data->cookie); - g_object_unref (data->method_invocation); + g_object_unref (data->invocation); g_object_unref (data->cancellable); g_free (data); } +/* ---------------------------------------------------------------------------------------------------- */ + static void auth_cb (GObject *source_object, GAsyncResult *res, @@ -343,12 +400,12 @@ auth_cb (GObject *source_object, res, &error)) { - egg_dbus_method_invocation_return_gerror (data->method_invocation, error); + g_dbus_method_invocation_return_gerror (data->invocation, error); g_error_free (error); } else { - _polkit_authentication_agent_handle_begin_authentication_finish (data->method_invocation); + g_dbus_method_invocation_return_value (data->invocation, NULL); } g_hash_table_remove (data->server->cookie_to_pending_auth, data->cookie); @@ -357,89 +414,117 @@ auth_cb (GObject *source_object, } static void -handle_begin_authentication (_PolkitAuthenticationAgent *instance, - const gchar *action_id, - const gchar *message, - const gchar *icon_name, - EggDBusHashMap *details, - const gchar *cookie, - EggDBusArraySeq *identities, - EggDBusMethodInvocation *method_invocation) +auth_agent_handle_begin_authentication (Server *server, + GVariant *parameters, + GDBusMethodInvocation *invocation) { - Server *server = SERVER (instance); - AuthData *data; - GList *list; + const gchar *action_id; + const gchar *message; + const gchar *icon_name; + GVariant *details_gvariant; + const gchar *cookie; + GVariant *identities_gvariant; + GList *identities; + PolkitDetails *details; + GVariantIter iter; + GVariant *child; guint n; - GCancellable *cancellable; - PolkitDetails *_details; + AuthData *data; + + identities = NULL; + details = NULL; + + g_variant_get (parameters, + "(&s&s&s@a{ss}&s@a(sa{sv}))", + &action_id, + &message, + &icon_name, + &details_gvariant, + &cookie, + &identities_gvariant); - list = NULL; - for (n = 0; n < identities->size; n++) + details = polkit_details_new_for_gvariant (details_gvariant); + + g_variant_iter_init (&iter, identities_gvariant); + n = 0; + while ((child = g_variant_iter_next_value (&iter)) != NULL) { - _PolkitIdentity *real_identity = _POLKIT_IDENTITY (identities->data.v_ptr[n]); + PolkitIdentity *identity; + GError *error; + error = NULL; + identity = polkit_identity_new_for_gvariant (child, &error); + g_variant_unref (child); - list = g_list_prepend (list, polkit_identity_new_for_real (real_identity)); - } + if (identity == NULL) + { + g_prefix_error (&error, "Error extracting identity %d: ", n); + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); + goto out; + } + n++; - list = g_list_reverse (list); + identities = g_list_prepend (identities, identity); + } + identities = g_list_reverse (identities); - cancellable = g_cancellable_new (); - data = auth_data_new (server, - cookie, - method_invocation, - cancellable); - g_object_unref (cancellable); + data = g_new0 (AuthData, 1); + data->server = server; + data->cookie = g_strdup (cookie); + data->invocation = g_object_ref (invocation); + data->cancellable = g_cancellable_new (); g_hash_table_insert (server->cookie_to_pending_auth, (gpointer) cookie, data); - _details = polkit_details_new_for_hash (details->data); - polkit_agent_listener_initiate_authentication (server->listener, action_id, message, icon_name, - _details, + details, cookie, - list, + identities, data->cancellable, auth_cb, data); - g_list_free (list); - g_object_unref (_details); + out: + g_list_foreach (identities, (GFunc) g_object_unref, NULL); + g_list_free (identities); + g_object_unref (details); + g_variant_unref (details_gvariant); + g_variant_unref (identities_gvariant); } +/* ---------------------------------------------------------------------------------------------------- */ + static void -handle_cancel_authentication (_PolkitAuthenticationAgent *instance, - const gchar *cookie, - EggDBusMethodInvocation *method_invocation) +auth_agent_handle_cancel_authentication (Server *server, + GVariant *parameters, + GDBusMethodInvocation *invocation) { - Server *server = SERVER (instance); AuthData *data; + const gchar *cookie; + + g_variant_get (parameters, + "(&s)", + &cookie); data = g_hash_table_lookup (server->cookie_to_pending_auth, cookie); if (data == NULL) { - egg_dbus_method_invocation_return_error (method_invocation, - POLKIT_ERROR, - POLKIT_ERROR_FAILED, - "No pending authentication request for cookie '%s'", - cookie); + g_dbus_method_invocation_return_error (invocation, + POLKIT_ERROR, + POLKIT_ERROR_FAILED, + "No pending authentication request for cookie '%s'", + cookie); } else { g_cancellable_cancel (data->cancellable); - _polkit_authentication_agent_handle_cancel_authentication_finish (method_invocation); + g_dbus_method_invocation_return_value (invocation, NULL); } } -static void -authentication_agent_iface_init (_PolkitAuthenticationAgentIface *agent_iface) -{ - agent_iface->handle_begin_authentication = handle_begin_authentication; - agent_iface->handle_cancel_authentication = handle_cancel_authentication; -} - /* ---------------------------------------------------------------------------------------------------- */ G_DEFINE_ABSTRACT_TYPE (PolkitAgentListener, polkit_agent_listener, G_TYPE_OBJECT); |