summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2010-07-29 16:49:37 -0400
committerDavid Zeuthen <davidz@redhat.com>2010-07-29 16:49:37 -0400
commit007b07f979b952744137b7a5b49712df87377014 (patch)
tree363f2f88c147bcfa5344a84c41e585b2ddb35685
parent6eeb077bc90c9c7783360a526b2f04645b1b0848 (diff)
downloadpolkit-007b07f979b952744137b7a5b49712df87377014.tar.gz
Port PolkitAgent to gdbus
Signed-off-by: David Zeuthen <davidz@redhat.com>
-rw-r--r--docs/polkit/polkit-1-sections.txt1
-rw-r--r--src/polkit/polkitauthority.c183
-rw-r--r--src/polkit/polkitauthority.h1
-rw-r--r--src/polkitagent/polkitagentlistener.c415
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);