diff options
author | David Zeuthen <davidz@redhat.com> | 2009-01-20 14:56:28 -0500 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2009-01-20 14:56:28 -0500 |
commit | ccacb4e8fa8a12259e352ed206c426ec5a0d9fa6 (patch) | |
tree | 3ac30651bff6d9f44951b6c415d8e8d3f33660dc | |
parent | 83bf3b054fe1caeb16155da92e3f9e5df9f00809 (diff) |
add infrastructure for registering/unregistering authentication agents
19 files changed, 1190 insertions, 204 deletions
diff --git a/data/Makefile.am b/data/Makefile.am index afe5f06..3794c98 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -1,5 +1,7 @@ ## Process this file with automake to produce Makefile.in +NULL = + servicedir = $(datadir)/dbus-1/system-services service_in_files = org.freedesktop.PolicyKit1.service.in service_DATA = $(service_in_files:.service.in=.service) @@ -24,13 +26,16 @@ pkgconfig_DATA = polkit-gobject-1.pc polkit-backend-1.pc polkit-agent-1.pc CLEANFILES = $(BUILT_SOURCES) -EXTRA_DIST = \ - org.freedesktop.PolicyKit1.Authority.xml \ - $(service_in_files) \ - $(dbusconf_in_files) \ - polkit-gobject-1.in \ - polkit-backend-1.in \ - polkit-agent-1.in +EXTRA_DIST = \ + org.freedesktop.PolicyKit1.Authority.xml \ + org.freedesktop.PolicyKit1.AuthenticationAgent.xml \ + $(service_in_files) \ + $(dbusconf_in_files) \ + polkit-gobject-1.in \ + polkit-backend-1.in \ + polkit-agent-1.in \ + $(NULL) + clean-local : rm -f *~ $(service_DATA) $(dbusconf_DATA) diff --git a/data/org.freedesktop.PolicyKit1.AuthenticationAgent.xml b/data/org.freedesktop.PolicyKit1.AuthenticationAgent.xml new file mode 100644 index 0000000..1a2063c --- /dev/null +++ b/data/org.freedesktop.PolicyKit1.AuthenticationAgent.xml @@ -0,0 +1,29 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> + +<node name="/"> + + <interface name="org.freedesktop.PolicyKit1.AuthenticationAgent"> + + <method name="BeginAuthentication"> + + <!-- The action id for the action that the user is authentication for --> + <arg name="action_id" direction="in" type="s"/> + + <!-- A cookie identifying the authentication request --> + <arg name="cookie" direction="in" type="s"/> + + <!-- A list of identities of that the user can use for authentication --> + <arg name="identities" direction="in" type="a(sa{sv})"/> + + </method> + + <method name="EndAuthentication"> + + <arg name="cookie" direction="in" type="s"/> + + </method> + + </interface> + +</node> diff --git a/data/org.freedesktop.PolicyKit1.Authority.xml b/data/org.freedesktop.PolicyKit1.Authority.xml index 6b33bc1..840a79a 100644 --- a/data/org.freedesktop.PolicyKit1.Authority.xml +++ b/data/org.freedesktop.PolicyKit1.Authority.xml @@ -178,5 +178,17 @@ </arg> </method> + <method name="RegisterAuthenticationAgent"> + <arg name="object_path" direction="in" type="s"> + <annotation name="org.gtk.EggDBus.DocString" value="Path of authentication agent object on the unique name of the caller"/> + </arg> + </method> + + <method name="UnregisterAuthenticationAgent"> + <arg name="object_path" direction="in" type="s"> + <annotation name="org.gtk.EggDBus.DocString" value="Path of authentication agent object on the unique name of the caller"/> + </arg> + </method> + </interface> </node> diff --git a/src/polkit/polkitauthority.c b/src/polkit/polkitauthority.c index 6a17036..3d36c14 100644 --- a/src/polkit/polkitauthority.c +++ b/src/polkit/polkitauthority.c @@ -860,3 +860,189 @@ polkit_authority_remove_authorization_sync (PolkitAuthority *authority, } /* ---------------------------------------------------------------------------------------------------- */ + +static guint +polkit_authority_register_authentication_agent_async (PolkitAuthority *authority, + const gchar *object_path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + guint call_id; + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new (G_OBJECT (authority), + callback, + user_data, + polkit_authority_register_authentication_agent_async); + + call_id = _polkit_authority_register_authentication_agent (authority->real, + EGG_DBUS_CALL_FLAGS_NONE, + object_path, + cancellable, + generic_async_cb, + simple); + + return call_id; +} + +void +polkit_authority_register_authentication_agent (PolkitAuthority *authority, + const gchar *object_path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + polkit_authority_register_authentication_agent_async (authority, + object_path, + cancellable, + callback, + user_data); +} + +gboolean +polkit_authority_register_authentication_agent_finish (PolkitAuthority *authority, + GAsyncResult *res, + GError **error) +{ + GSimpleAsyncResult *simple; + GAsyncResult *real_res; + gboolean ret; + + simple = G_SIMPLE_ASYNC_RESULT (res); + real_res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (simple)); + + g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_authority_register_authentication_agent_async); + + ret = _polkit_authority_register_authentication_agent_finish (authority->real, + real_res, + error); + + if (!ret) + goto out; + + out: + g_object_unref (real_res); + return ret; +} + + +gboolean +polkit_authority_register_authentication_agent_sync (PolkitAuthority *authority, + const gchar *object_path, + GCancellable *cancellable, + GError **error) +{ + guint call_id; + GAsyncResult *res; + gboolean ret; + + call_id = polkit_authority_register_authentication_agent_async (authority, + object_path, + cancellable, + generic_cb, + &res); + + egg_dbus_connection_pending_call_block (authority->system_bus, call_id); + + ret = polkit_authority_register_authentication_agent_finish (authority, res, error); + + g_object_unref (res); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static guint +polkit_authority_unregister_authentication_agent_async (PolkitAuthority *authority, + const gchar *object_path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + guint call_id; + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new (G_OBJECT (authority), + callback, + user_data, + polkit_authority_unregister_authentication_agent_async); + + call_id = _polkit_authority_unregister_authentication_agent (authority->real, + EGG_DBUS_CALL_FLAGS_NONE, + object_path, + cancellable, + generic_async_cb, + simple); + + return call_id; +} + +void +polkit_authority_unregister_authentication_agent (PolkitAuthority *authority, + const gchar *object_path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + polkit_authority_unregister_authentication_agent_async (authority, + object_path, + cancellable, + callback, + user_data); +} + +gboolean +polkit_authority_unregister_authentication_agent_finish (PolkitAuthority *authority, + GAsyncResult *res, + GError **error) +{ + GSimpleAsyncResult *simple; + GAsyncResult *real_res; + gboolean ret; + + simple = G_SIMPLE_ASYNC_RESULT (res); + real_res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (simple)); + + g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_authority_unregister_authentication_agent_async); + + ret = _polkit_authority_unregister_authentication_agent_finish (authority->real, + real_res, + error); + + if (!ret) + goto out; + + out: + g_object_unref (real_res); + return ret; +} + + +gboolean +polkit_authority_unregister_authentication_agent_sync (PolkitAuthority *authority, + const gchar *object_path, + GCancellable *cancellable, + GError **error) +{ + guint call_id; + GAsyncResult *res; + gboolean ret; + + call_id = polkit_authority_unregister_authentication_agent_async (authority, + object_path, + cancellable, + generic_cb, + &res); + + egg_dbus_connection_pending_call_block (authority->system_bus, call_id); + + ret = polkit_authority_unregister_authentication_agent_finish (authority, res, error); + + g_object_unref (res); + + return ret; +} + +/* ---------------------------------------------------------------------------------------------------- */ diff --git a/src/polkit/polkitauthority.h b/src/polkit/polkitauthority.h index bd41107..e6ece8e 100644 --- a/src/polkit/polkitauthority.h +++ b/src/polkit/polkitauthority.h @@ -83,6 +83,16 @@ gboolean polkit_authority_remove_authorization_sync (PolkitAut GCancellable *cancellable, GError **error); +gboolean polkit_authority_register_authentication_agent_sync (PolkitAuthority *authority, + const gchar *object_path, + GCancellable *cancellable, + GError **error); + +gboolean polkit_authority_unregister_authentication_agent_sync (PolkitAuthority *authority, + const gchar *object_path, + GCancellable *cancellable, + GError **error); + /* ---------------------------------------------------------------------------------------------------- */ void polkit_authority_enumerate_actions (PolkitAuthority *authority, @@ -158,6 +168,26 @@ gboolean polkit_authority_remove_authorization_finish (PolkitA GError **error); +void polkit_authority_register_authentication_agent (PolkitAuthority *authority, + const gchar *object_path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean polkit_authority_register_authentication_agent_finish (PolkitAuthority *authority, + GAsyncResult *res, + GError **error); + +void polkit_authority_unregister_authentication_agent (PolkitAuthority *authority, + const gchar *object_path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean polkit_authority_unregister_authentication_agent_finish (PolkitAuthority *authority, + GAsyncResult *res, + GError **error); + /* ---------------------------------------------------------------------------------------------------- */ G_END_DECLS diff --git a/src/polkitagent/Makefile.am b/src/polkitagent/Makefile.am index ac74bd5..d227661 100644 --- a/src/polkitagent/Makefile.am +++ b/src/polkitagent/Makefile.am @@ -12,23 +12,41 @@ INCLUDES = \ -DPACKAGE_LIB_DIR=\""$(libdir)"\" \ -D_POSIX_PTHREAD_SEMANTICS \ -D_REENTRANT \ + -DEGG_DBUS_I_KNOW_API_IS_SUBJECT_TO_CHANGE \ $(NULL) +BUILT_SOURCES = \ + _polkitagentauthenticationagent.c _polkitagentauthenticationagent.h \ + _polkitagentbindings.c _polkitagentbindings.h \ + _polkitagentbindingsmarshal.list \ + _polkitagentbindingsmarshal.c _polkitagentbindingsmarshal.h \ + _polkitagentbindingstypes.h \ + $(NULL) + +$(BUILT_SOURCES) : Makefile.am $(top_srcdir)/data/org.freedesktop.PolicyKit1.AuthenticationAgent.xml + eggdbus-binding-tool \ + --namespace "_PolkitAgent" \ + --dbus-namespace "org.freedesktop.PolicyKit1" \ + --introspection-xml $(top_srcdir)/data/org.freedesktop.PolicyKit1.AuthenticationAgent.xml \ + $(NULL) lib_LTLIBRARIES=libpolkit-agent-1.la libpolkit_agent_1includedir=$(includedir)/polkit-1/polkitagent -libpolkit_agent_1include_HEADERS = \ - polkitagent.h \ - polkitagenttypes.h \ - polkitauthenticationsession.h \ +libpolkit_agent_1include_HEADERS = \ + polkitagent.h \ + polkitagenttypes.h \ + polkitagentauthenticationsession.h \ + polkitagentauthenticationagent.h \ $(NULL) -libpolkit_agent_1_la_SOURCES = \ - polkitagent.h \ - polkitagenttypes.h \ - polkitauthenticationsession.h polkitauthenticationsession.c \ +libpolkit_agent_1_la_SOURCES = \ + polkitagent.h \ + polkitagenttypes.h \ + polkitagentauthenticationsession.h polkitagentauthenticationsession.c \ + polkitagentauthenticationagent.h polkitagentauthenticationagent.c \ + $(BUILT_SOURCES) \ $(NULL) libpolkit_agent_1_la_CFLAGS = \ diff --git a/src/polkitagent/polkitagent.h b/src/polkitagent/polkitagent.h index b6c2ffb..0bc8fdc 100644 --- a/src/polkitagent/polkitagent.h +++ b/src/polkitagent/polkitagent.h @@ -23,7 +23,8 @@ #define __POLKIT_AGENT_H #define _POLKIT_AGENT_INSIDE_POLKIT_AGENT_H 1 -#include <polkitagent/polkitauthenticationsession.h> +#include <polkitagent/polkitagentauthenticationagent.h> +#include <polkitagent/polkitagentauthenticationsession.h> #undef _POLKIT_AGENT_INSIDE_POLKIT_AGENT_H #endif /* __POLKIT_AGENT_H */ diff --git a/src/polkitagent/polkitagentauthenticationagent.c b/src/polkitagent/polkitagentauthenticationagent.c new file mode 100644 index 0000000..844a32e --- /dev/null +++ b/src/polkitagent/polkitagentauthenticationagent.c @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#include "config.h" + +#include <polkit/polkitprivate.h> +#include "_polkitagentbindings.h" + +#include "polkitagentauthenticationagent.h" + +struct _PolkitAgentAuthenticationAgent +{ + GObject parent_instance; + + EggDBusConnection *system_bus; + + PolkitAuthority *authority; + + PolkitAgentAuthenticationAgentBeginFunc begin_func; + PolkitAgentAuthenticationAgentEndFunc end_func; + gpointer user_data; +}; + +struct _PolkitAgentAuthenticationAgentClass +{ + GObjectClass parent_class; + +}; + +static void authentication_agent_iface_init (_PolkitAgentAuthenticationAgentIface *agent_iface); + +G_DEFINE_TYPE_WITH_CODE (PolkitAgentAuthenticationAgent, polkit_agent_authentication_agent, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (_POLKIT_AGENT_TYPE_AUTHENTICATION_AGENT, + authentication_agent_iface_init) + ); + +static void +polkit_agent_authentication_agent_init (PolkitAgentAuthenticationAgent *agent) +{ + agent->system_bus = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM); + + egg_dbus_connection_register_interface (agent->system_bus, + "/org/freedesktop/PolicyKit1/AuthenticationAgent", + _POLKIT_AGENT_TYPE_AUTHENTICATION_AGENT, + G_OBJECT (agent), + G_TYPE_INVALID); + + agent->authority = polkit_authority_get (); +} + +static void +polkit_agent_authentication_agent_finalize (GObject *object) +{ + PolkitAgentAuthenticationAgent *agent = POLKIT_AGENT_AUTHENTICATION_AGENT (object); + GError *error; + + error = NULL; + if (!polkit_authority_unregister_authentication_agent_sync (agent->authority, + "/org/freedesktop/PolicyKit1/AuthenticationAgent", + NULL, + &error)) + { + g_warning ("Error unregistering authentication agent: %s", error->message); + g_error_free (error); + } + + g_object_unref (agent->authority); + + g_object_unref (agent->system_bus); + + if (G_OBJECT_CLASS (polkit_agent_authentication_agent_parent_class)->finalize != NULL) + G_OBJECT_CLASS (polkit_agent_authentication_agent_parent_class)->finalize (object); +} + +static void +polkit_agent_authentication_agent_class_init (PolkitAgentAuthenticationAgentClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = polkit_agent_authentication_agent_finalize; +} + +PolkitAgentAuthenticationAgent * +polkit_agent_authentication_agent_new (PolkitAgentAuthenticationAgentBeginFunc begin_func, + PolkitAgentAuthenticationAgentEndFunc end_func, + gpointer user_data, + GError **error) +{ + PolkitAgentAuthenticationAgent *agent; + + agent = POLKIT_AGENT_AUTHENTICATION_AGENT (g_object_new (POLKIT_AGENT_TYPE_AUTHENTICATION_AGENT, NULL)); + + agent->begin_func = begin_func; + agent->end_func = end_func; + agent->user_data = user_data; + + if (!polkit_authority_register_authentication_agent_sync (agent->authority, + "/org/freedesktop/PolicyKit1/AuthenticationAgent", + NULL, + error)) + { + g_object_unref (agent); + agent = NULL; + } + + return agent; +} + +static void +handle_begin_authentication (_PolkitAgentAuthenticationAgent *instance, + const gchar *action_id, + const gchar *cookie, + EggDBusArraySeq *identities, + EggDBusMethodInvocation *method_invocation) +{ + PolkitAgentAuthenticationAgent *agent = POLKIT_AGENT_AUTHENTICATION_AGENT (instance); + GList *list; + guint n; + GError *error; + + list = NULL; + for (n = 0; n < identities->size; n++) + { + _PolkitIdentity *real_identity = _POLKIT_IDENTITY (identities->data.v_ptr[n]); + + list = g_list_prepend (list, polkit_identity_new_for_real (real_identity)); + } + + list = g_list_reverse (list); + + error = NULL; + if (!agent->begin_func (agent, + action_id, + cookie, + list, + &error, + agent->user_data)) + { + egg_dbus_method_invocation_return_gerror (method_invocation, error); + g_error_free (error); + } + else + { + _polkit_agent_authentication_agent_handle_begin_authentication_finish (method_invocation); + } + + g_list_free (list); +} + +static void +handle_end_authentication (_PolkitAgentAuthenticationAgent *instance, + const gchar *cookie, + EggDBusMethodInvocation *method_invocation) +{ + PolkitAgentAuthenticationAgent *agent = POLKIT_AGENT_AUTHENTICATION_AGENT (instance); + + agent->end_func (agent, + cookie, + agent->user_data); + + _polkit_agent_authentication_agent_handle_end_authentication_finish (method_invocation); +} + +static void +authentication_agent_iface_init (_PolkitAgentAuthenticationAgentIface *agent_iface) +{ + agent_iface->handle_begin_authentication = handle_begin_authentication; + agent_iface->handle_end_authentication = handle_end_authentication; +} diff --git a/src/polkitagent/polkitagentauthenticationagent.h b/src/polkitagent/polkitagentauthenticationagent.h new file mode 100644 index 0000000..9d315ff --- /dev/null +++ b/src/polkitagent/polkitagentauthenticationagent.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#ifndef __POLKIT_AGENT_AUTHENTICATION_SESSION_H +#define __POLKIT_AGENT_AUTHENTICATION_SESSION_H + +#include <polkit/polkit.h> +#include <polkitagent/polkitagenttypes.h> + +G_BEGIN_DECLS + +#define POLKIT_AGENT_TYPE_AUTHENTICATION_AGENT (polkit_agent_authentication_agent_get_type ()) +#define POLKIT_AGENT_AUTHENTICATION_AGENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_AGENT_TYPE_AUTHENTICATION_AGENT, PolkitAgentAuthenticationAgent)) +#define POLKIT_AGENT_AUTHENTICATION_AGENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), POLKIT_AGENT_TYPE_AUTHENTICATION_AGENT, PolkitAgentAuthenticationAgentClass)) +#define POLKIT_AGENT_AUTHENTICATION_AGENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_AGENT_TYPE_AUTHENTICATION_AGENT,PolkitAgentAuthenticationAgentClass)) +#define POLKIT_AGENT_IS_AUTHENTICATION_AGENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_AGENT_TYPE_AUTHENTICATION_AGENT)) +#define POLKIT_AGENT_IS_AUTHENTICATION_AGENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_AGENT_TYPE_AUTHENTICATION_AGENT)) + +#if 0 +typedef struct _PolkitAgentAuthenticationAgent PolkitAgentAuthenticationAgent; +#endif +typedef struct _PolkitAgentAuthenticationAgentClass PolkitAgentAuthenticationAgentClass; + +/* TODO: we probably want to express this interface in another way but this is good enough for now */ + +typedef gboolean (*PolkitAgentAuthenticationAgentBeginFunc) (PolkitAgentAuthenticationAgent *agent, + const gchar *action_id, + const gchar *cookie, + GList *identities, + GError **error, + gpointer user_data); + +typedef void (*PolkitAgentAuthenticationAgentEndFunc) (PolkitAgentAuthenticationAgent *agent, + const gchar *cookie, + gpointer user_data); + +GType polkit_agent_authentication_agent_get_type (void) G_GNUC_CONST; +PolkitAgentAuthenticationAgent *polkit_agent_authentication_agent_new (PolkitAgentAuthenticationAgentBeginFunc begin_func, + PolkitAgentAuthenticationAgentEndFunc end_func, + gpointer user_data, + GError **error); + +/* --- */ + +G_END_DECLS + +#endif /* __POLKIT_AGENT_AUTHENTICATION_SESSION_H */ diff --git a/src/polkitagent/polkitauthenticationsession.c b/src/polkitagent/polkitagentauthenticationsession.c index 62dcd7a..2c6bc65 100644 --- a/src/polkitagent/polkitauthenticationsession.c +++ b/src/polkitagent/polkitagentauthenticationsession.c @@ -36,9 +36,9 @@ #include <sys/wait.h> #include <pwd.h> -#include "polkitauthenticationsession.h" +#include "polkitagentauthenticationsession.h" -struct _PolkitAuthenticationSession +struct _PolkitAgentAuthenticationSession { GObject parent_instance; @@ -56,62 +56,62 @@ struct _PolkitAuthenticationSession gboolean success; gboolean helper_is_running; - PolkitAuthenticationSessionConversationPromptEchoOff func_prompt_echo_off; - PolkitAuthenticationSessionConversationPromptEchoOn func_prompt_echo_on; - PolkitAuthenticationSessionConversationErrorMessage func_error_message; - PolkitAuthenticationSessionConversationTextInfo func_text_info; - PolkitAuthenticationSessionDone func_done; + PolkitAgentAuthenticationSessionConversationPromptEchoOff func_prompt_echo_off; + PolkitAgentAuthenticationSessionConversationPromptEchoOn func_prompt_echo_on; + PolkitAgentAuthenticationSessionConversationErrorMessage func_error_message; + PolkitAgentAuthenticationSessionConversationTextInfo func_text_info; + PolkitAgentAuthenticationSessionDone func_done; void *user_data; }; -struct _PolkitAuthenticationSessionClass +struct _PolkitAgentAuthenticationSessionClass { GObjectClass parent_class; }; -G_DEFINE_TYPE (PolkitAuthenticationSession, polkit_authentication_session, G_TYPE_OBJECT); +G_DEFINE_TYPE (PolkitAgentAuthenticationSession, polkit_agent_authentication_session, G_TYPE_OBJECT); static void -polkit_authentication_session_init (PolkitAuthenticationSession *session) +polkit_agent_authentication_session_init (PolkitAgentAuthenticationSession *session) { } static void -polkit_authentication_session_finalize (GObject *object) +polkit_agent_authentication_session_finalize (GObject *object) { - PolkitAuthenticationSession *session; + PolkitAgentAuthenticationSession *session; - session = POLKIT_AUTHENTICATION_SESSION (object); + session = POLKIT_AGENT_AUTHENTICATION_SESSION (object); g_free (session->cookie); if (session->identity != NULL) g_object_unref (session->identity); - if (G_OBJECT_CLASS (polkit_authentication_session_parent_class)->finalize != NULL) - G_OBJECT_CLASS (polkit_authentication_session_parent_class)->finalize (object); + if (G_OBJECT_CLASS (polkit_agent_authentication_session_parent_class)->finalize != NULL) + G_OBJECT_CLASS (polkit_agent_authentication_session_parent_class)->finalize (object); } static void -polkit_authentication_session_class_init (PolkitAuthenticationSessionClass *klass) +polkit_agent_authentication_session_class_init (PolkitAgentAuthenticationSessionClass *klass) { GObjectClass *gobject_class; gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = polkit_authentication_session_finalize; + gobject_class->finalize = polkit_agent_authentication_session_finalize; } -PolkitAuthenticationSession * -polkit_authentication_session_new (PolkitIdentity *identity, +PolkitAgentAuthenticationSession * +polkit_agent_authentication_session_new (PolkitIdentity *identity, const gchar *cookie) { - PolkitAuthenticationSession *session; + PolkitAgentAuthenticationSession *session; - session = POLKIT_AUTHENTICATION_SESSION (g_object_new (POLKIT_TYPE_AUTHENTICATION_SESSION, NULL)); + session = POLKIT_AGENT_AUTHENTICATION_SESSION (g_object_new (POLKIT_AGENT_TYPE_AUTHENTICATION_SESSION, NULL)); session->identity = g_object_ref (identity); session->cookie = g_strdup (cookie); @@ -120,12 +120,12 @@ polkit_authentication_session_new (PolkitIdentity *identity, } void -polkit_authentication_session_set_functions (PolkitAuthenticationSession *session, - PolkitAuthenticationSessionConversationPromptEchoOff func_prompt_echo_off, - PolkitAuthenticationSessionConversationPromptEchoOn func_prompt_echo_on, - PolkitAuthenticationSessionConversationErrorMessage func_error_message, - PolkitAuthenticationSessionConversationTextInfo func_text_info, - PolkitAuthenticationSessionDone func_done, +polkit_agent_authentication_session_set_functions (PolkitAgentAuthenticationSession *session, + PolkitAgentAuthenticationSessionConversationPromptEchoOff func_prompt_echo_off, + PolkitAgentAuthenticationSessionConversationPromptEchoOn func_prompt_echo_on, + PolkitAgentAuthenticationSessionConversationErrorMessage func_error_message, + PolkitAgentAuthenticationSessionConversationTextInfo func_text_info, + PolkitAgentAuthenticationSessionDone func_done, void *user_data) { session->func_prompt_echo_off = func_prompt_echo_off; @@ -139,7 +139,7 @@ polkit_authentication_session_set_functions (PolkitAuthenticationSession *sessio static void child_watch_func (GPid pid, gint status, gpointer user_data) { - PolkitAuthenticationSession *session = POLKIT_AUTHENTICATION_SESSION (user_data); + PolkitAgentAuthenticationSession *session = POLKIT_AGENT_AUTHENTICATION_SESSION (user_data); gint exit_code; gboolean input_was_bogus; @@ -163,7 +163,7 @@ child_watch_func (GPid pid, gint status, gpointer user_data) static gboolean io_watch_have_data (GIOChannel *channel, GIOCondition condition, gpointer user_data) { - PolkitAuthenticationSession *session = POLKIT_AUTHENTICATION_SESSION (user_data); + PolkitAgentAuthenticationSession *session = POLKIT_AGENT_AUTHENTICATION_SESSION (user_data); char *line; size_t line_len; gchar *id; @@ -259,7 +259,7 @@ io_watch_have_data (GIOChannel *channel, GIOCondition condition, gpointer user_d } gboolean -polkit_authentication_session_initiate_auth (PolkitAuthenticationSession *session) +polkit_agent_authentication_session_initiate_auth (PolkitAgentAuthenticationSession *session) { uid_t uid; GError *error; @@ -335,7 +335,7 @@ error: void -polkit_authentication_session_cancel (PolkitAuthenticationSession *session) +polkit_agent_authentication_session_cancel (PolkitAgentAuthenticationSession *session) { GPid pid; diff --git a/src/polkitagent/polkitagentauthenticationsession.h b/src/polkitagent/polkitagentauthenticationsession.h new file mode 100644 index 0000000..b1239fe --- /dev/null +++ b/src/polkitagent/polkitagentauthenticationsession.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen <davidz@redhat.com> + */ + +#ifndef __POLKIT_AGENT_AUTHENTICATION_SESSION_H +#define __POLKIT_AGENT_AUTHENTICATION_SESSION_H + +#include <polkit/polkit.h> +#include <polkitagent/polkitagenttypes.h> + +G_BEGIN_DECLS + +#define POLKIT_AGENT_TYPE_AUTHENTICATION_SESSION (polkit_agent_authentication_session_get_type()) +#define POLKIT_AGENT_AUTHENTICATION_SESSION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_AGENT_TYPE_AUTHENTICATION_SESSION, PolkitAgentAuthenticationSession)) +#define POLKIT_AGENT_AUTHENTICATION_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), POLKIT_AGENT_TYPE_AUTHENTICATION_SESSION, PolkitAgentAuthenticationSessionClass)) +#define POLKIT_AGENT_AUTHENTICATION_SESSION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_AGENT_TYPE_AUTHENTICATION_SESSION, PolkitAgentAuthenticationSessionClass)) +#define POLKIT_AGENT_IS_AUTHENTICATION_SESSION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_AGENT_TYPE_AUTHENTICATION_SESSION)) +#define POLKIT_AGENT_IS_AUTHENTICATION_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_AGENT_TYPE_AUTHENTICATION_SESSION)) + +/** + * PolkitAgentAuthenticationSessionConversationPromptEchoOff: + * @session: A #PolkitAgentAuthenticationSession. + * @prompt: prompt passed by the authentication layer; do not free this string + * @user_data: user data pointer as passed into polkit_agent_authorization_session_set_functions() + * + * Type for callback function that is invoked when the authentication + * layer needs to ask the user a secret and the UI should NOT echo what + * the user types on the screen. + * + * Returns: the answer obtained from the user; must be allocated with + * malloc(3) and will be freed by the #PolkitAgentAuthenticationSession class. + **/ +typedef char* (*PolkitAgentAuthenticationSessionConversationPromptEchoOff) (PolkitAgentAuthenticationSession *session, + const gchar *prompt, + gpointer user_data); + +/** + * PolkitAgentAuthenticationSessionConversationPromptEchoOn: + * @session: A #PolkitAgentAuthenticationSession. + * @prompt: prompt passed by the authentication layer; do not free this string + * @user_data: user data pointer as passed into polkit_agent_authorization_session_set_functions() + * + * Type for callback function that is invoked when the authentication + * layer needs to ask the user a secret and the UI should echo what + * the user types on the screen. + * + * Returns: the answer obtained from the user; must be allocated with + * malloc(3) and will be freed by the #PolkitAgentAuthenticationSession class. + **/ +typedef char* (*PolkitAgentAuthenticationSessionConversationPromptEchoOn) (PolkitAgentAuthenticationSession *session, + const gchar *prompt, + gpointer user_data); + +/** + * PolkitAgentAuthenticationSessionConversationErrorMessage: + * @session: A #PolkitAgentAuthenticationSession. + * @error_message: error message passed by the authentication layer; do not free this string + * @user_data: user data pointer as passed into polkit_agent_authorization_session_set_functions() + * + * Type for callback function that is invoked when the authentication + * layer produces an error message that should be displayed in the UI. + **/ +typedef void (*PolkitAgentAuthenticationSessionConversationErrorMessage) (PolkitAgentAuthenticationSession *session, + const gchar *error_message, + gpointer user_data); + +/** + * PolkitAgentAuthenticationSessionConversationTextInfo: + * @session: A #PolkitAgentAuthenticationSession. + * @text_info: information passed by the authentication layer; do not free this string + * @user_data: user data pointer as passed into polkit_agent_authorization_session_set_functions() + * + * Type for callback function that is invoked when the authentication + * layer produces an informational message that should be displayed in + * the UI. + **/ +typedef void (*PolkitAgentAuthenticationSessionConversationTextInfo) (PolkitAgentAuthenticationSession *session, + const gchar *text_info, + gpointer user_data); + +/** + * PolkitAgentAuthenticationSessionDone: + * @session: A #PolkitAgentAuthenticationSession. + * @gained_authorization: whether the authorization was obtained + * @invalid_data: whether the input data was bogus (not including bad passwords) + * @user_data: user data pointer as passed into polkit_agent_authorization_session_set_functions() + * + * This function is called when the granting process ends; either if + * successful or if it was canceled using e.g. polkit_agent_authorization_session_cancel_auth(). + **/ +typedef void (*PolkitAgentAuthenticationSessionDone) (PolkitAgentAuthenticationSession *session, + gboolean gained_authorization, + gboolean invalid_data, + gpointer user_data); + + +#if 0 +typedef struct _PolkitAgentAuthenticationSession PolkitAgentAuthenticationSession; +#endif +typedef struct _PolkitAgentAuthenticationSessionClass PolkitAgentAuthenticationSessionClass; + +GType polkit_agent_authentication_session_get_type (void) G_GNUC_CONST; +PolkitAgentAuthenticationSession *polkit_agent_authentication_session_new (PolkitIdentity *identity, + const gchar *cookie); + +/* TODO: would be much nicer to use signals here */ +void polkit_agent_authentication_session_set_functions + (PolkitAgentAuthenticationSession *session, + PolkitAgentAuthenticationSessionConversationPromptEchoOff func_prompt_echo_off, + PolkitAgentAuthenticationSessionConversationPromptEchoOn func_prompt_echo_on, + PolkitAgentAuthenticationSessionConversationErrorMessage func_error_message, + PolkitAgentAuthenticationSessionConversationTextInfo func_text_info, + PolkitAgentAuthenticationSessionDone func_done, + void *user_data); + +gboolean polkit_agent_authentication_session_initiate_auth (PolkitAgentAuthenticationSession *session); + +void polkit_agent_authentication_session_cancel (PolkitAgentAuthenticationSession *session); + +G_END_DECLS + +#endif /* __POLKIT_AGENT_AUTHENTICATION_SESSION_H */ diff --git a/src/polkitagent/polkitagenttypes.h b/src/polkitagent/polkitagenttypes.h index de62caa..c82ed1a 100644 --- a/src/polkitagent/polkitagenttypes.h +++ b/src/polkitagent/polkitagenttypes.h @@ -26,8 +26,11 @@ G_BEGIN_DECLS -struct _PolkitAuthenticationSession; -typedef struct _PolkitAuthenticationSession PolkitAuthenticationSession; +struct _PolkitAgentAuthenticationSession; +typedef struct _PolkitAgentAuthenticationSession PolkitAgentAuthenticationSession; + +struct _PolkitAgentAuthenticationAgent; +typedef struct _PolkitAgentAuthenticationAgent PolkitAgentAuthenticationAgent; G_END_DECLS diff --git a/src/polkitagent/polkitauthenticationsession.h b/src/polkitagent/polkitauthenticationsession.h deleted file mode 100644 index 1ccc4ca..0000000 --- a/src/polkitagent/polkitauthenticationsession.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2008 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#ifndef __POLKIT_AUTHENTICATION_SESSION_H -#define __POLKIT_AUTHENTICATION_SESSION_H - -#include <polkit/polkit.h> -#include <polkitagent/polkitagenttypes.h> - -G_BEGIN_DECLS - -#define POLKIT_TYPE_AUTHENTICATION_SESSION (polkit_authentication_session_get_type()) -#define POLKIT_AUTHENTICATION_SESSION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_AUTHENTICATION_SESSION, PolkitAuthenticationSession)) -#define POLKIT_AUTHENTICATION_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), POLKIT_TYPE_AUTHENTICATION_SESSION, PolkitAuthenticationSessionClass)) -#define POLKIT_AUTHENTICATION_SESSION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_TYPE_AUTHENTICATION_SESSION, PolkitAuthenticationSessionClass)) -#define POLKIT_IS_AUTHENTICATION_SESSION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_AUTHENTICATION_SESSION)) -#define POLKIT_IS_AUTHENTICATION_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_TYPE_AUTHENTICATION_SESSION)) - -/** - * PolkitAuthenticationSessionConversationPromptEchoOff: - * @session: A #PolkitAuthenticationSession. - * @prompt: prompt passed by the authentication layer; do not free this string - * @user_data: user data pointer as passed into polkit_authorization_session_set_functions() - * - * Type for callback function that is invoked when the authentication - * layer needs to ask the user a secret and the UI should NOT echo what - * the user types on the screen. - * - * Returns: the answer obtained from the user; must be allocated with - * malloc(3) and will be freed by the #PolkitAuthenticationSession class. - **/ -typedef char* (*PolkitAuthenticationSessionConversationPromptEchoOff) (PolkitAuthenticationSession *session, - const gchar *prompt, - gpointer user_data); - -/** - * PolkitAuthenticationSessionConversationPromptEchoOn: - * @session: A #PolkitAuthenticationSession. - * @prompt: prompt passed by the authentication layer; do not free this string - * @user_data: user data pointer as passed into polkit_authorization_session_set_functions() - * - * Type for callback function that is invoked when the authentication - * layer needs to ask the user a secret and the UI should echo what - * the user types on the screen. - * - * Returns: the answer obtained from the user; must be allocated with - * malloc(3) and will be freed by the #PolkitAuthenticationSession class. - **/ -typedef char* (*PolkitAuthenticationSessionConversationPromptEchoOn) (PolkitAuthenticationSession *session, - const gchar *prompt, - gpointer user_data); - -/** - * PolkitAuthenticationSessionConversationErrorMessage: - * @session: A #PolkitAuthenticationSession. - * @error_message: error message passed by the authentication layer; do not free this string - * @user_data: user data pointer as passed into polkit_authorization_session_set_functions() - * - * Type for callback function that is invoked when the authentication - * layer produces an error message that should be displayed in the UI. - **/ -typedef void (*PolkitAuthenticationSessionConversationErrorMessage) (PolkitAuthenticationSession *session, - const gchar *error_message, - gpointer user_data); - -/** - * PolkitAuthenticationSessionConversationTextInfo: - * @session: A #PolkitAuthenticationSession. - * @text_info: information passed by the authentication layer; do not free this string - * @user_data: user data pointer as passed into polkit_authorization_session_set_functions() - * - * Type for callback function that is invoked when the authentication - * layer produces an informational message that should be displayed in - * the UI. - **/ -typedef void (*PolkitAuthenticationSessionConversationTextInfo) (PolkitAuthenticationSession *session, - const gchar *text_info, - gpointer user_data); - -/** - * PolkitAuthenticationSessionDone: - * @session: A #PolkitAuthenticationSession. - * @gained_authorization: whether the authorization was obtained - * @invalid_data: whether the input data was bogus (not including bad passwords) - * @user_data: user data pointer as passed into polkit_authorization_session_set_functions() - * - * This function is called when the granting process ends; either if - * successful or if it was canceled using e.g. polkit_authorization_session_cancel_auth(). - **/ -typedef void (*PolkitAuthenticationSessionDone) (PolkitAuthenticationSession *session, - gboolean gained_authorization, - gboolean invalid_data, - gpointer user_data); - - -#if 0 -typedef struct _PolkitAuthenticationSession PolkitAuthenticationSession; -#endif -typedef struct _PolkitAuthenticationSessionClass PolkitAuthenticationSessionClass; - -GType polkit_authentication_session_get_type (void) G_GNUC_CONST; -PolkitAuthenticationSession *polkit_authentication_session_new (PolkitIdentity *identity, - const gchar *cookie); - -/* TODO: would be much nicer to use signals here */ -void polkit_authentication_session_set_functions - (PolkitAuthenticationSession *session, - PolkitAuthenticationSessionConversationPromptEchoOff func_prompt_echo_off, - PolkitAuthenticationSessionConversationPromptEchoOn func_prompt_echo_on, - PolkitAuthenticationSessionConversationErrorMessage func_error_message, - PolkitAuthenticationSessionConversationTextInfo func_text_info, - PolkitAuthenticationSessionDone func_done, - void *user_data); - -gboolean polkit_authentication_session_initiate_auth (PolkitAuthenticationSession *session); - -void polkit_authentication_session_cancel (PolkitAuthenticationSession *session); - -G_END_DECLS - -#endif /* __POLKIT_AUTHENTICATION_SESSION_H */ diff --git a/src/polkitbackend/polkitbackendauthority.c b/src/polkitbackend/polkitbackendauthority.c index b18ac0f..399b4c7 100644 --- a/src/polkitbackend/polkitbackendauthority.c +++ b/src/polkitbackend/polkitbackendauthority.c @@ -39,6 +39,19 @@ polkit_backend_authority_class_init (PolkitBackendAuthorityClass *klass) } void +polkit_backend_authority_system_bus_name_owner_changed (PolkitBackendAuthority *authority, + const gchar *name, + const gchar *old_owner, + const gchar *new_owner) +{ + PolkitBackendAuthorityClass *klass; + + klass = POLKIT_BACKEND_AUTHORITY_GET_CLASS (authority); + + klass->system_bus_name_owner_changed (authority, name, old_owner, new_owner); +} + +void polkit_backend_authority_enumerate_actions (PolkitBackendAuthority *authority, const gchar *locale, PolkitBackendPendingCall *pending_call) @@ -123,3 +136,28 @@ polkit_backend_authority_remove_authorization (PolkitBackendAuthority *autho klass->remove_authorization (authority, identity, authorization, pending_call); } + +void +polkit_backend_authority_register_authentication_agent (PolkitBackendAuthority *authority, + const gchar *object_path, + PolkitBackendPendingCall *pending_call) +{ + PolkitBackendAuthorityClass *klass; + + klass = POLKIT_BACKEND_AUTHORITY_GET_CLASS (authority); + + klass->register_authentication_agent (authority, object_path, pending_call); +} + +void +polkit_backend_authority_unregister_authentication_agent (PolkitBackendAuthority *authority, + const gchar *object_path, + PolkitBackendPendingCall *pending_call) +{ + PolkitBackendAuthorityClass *klass; + + klass = POLKIT_BACKEND_AUTHORITY_GET_CLASS (authority); + + klass->unregister_authentication_agent (authority, object_path, pending_call); +} + diff --git a/src/polkitbackend/polkitbackendauthority.h b/src/polkitbackend/polkitbackendauthority.h index 09ef3f5..a35ad7e 100644 --- a/src/polkitbackend/polkitbackendauthority.h +++ b/src/polkitbackend/polkitbackendauthority.h @@ -51,6 +51,12 @@ struct _PolkitBackendAuthorityClass /*< public >*/ + /* TODO: need something more efficient such that we don't watch all name changes */ + void (*system_bus_name_owner_changed) (PolkitBackendAuthority *authority, + const gchar *name, + const gchar *old_owner, + const gchar *new_owner); + void (*enumerate_actions) (PolkitBackendAuthority *authority, const gchar *locale, PolkitBackendPendingCall *pending_call); @@ -81,6 +87,14 @@ struct _PolkitBackendAuthorityClass PolkitAuthorization *authorization, PolkitBackendPendingCall *pending_call); + void (*register_authentication_agent) (PolkitBackendAuthority *authority, + const gchar *object_path, + PolkitBackendPendingCall *pending_call); + + void (*unregister_authentication_agent) (PolkitBackendAuthority *authority, + const gchar *object_path, + PolkitBackendPendingCall *pending_call); + /*< private >*/ /* Padding for future expansion */ void (*_polkit_reserved1) (void); @@ -97,6 +111,11 @@ GType polkit_backend_authority_get_type (void) G_GNUC_CONST; /* --- */ +void polkit_backend_authority_system_bus_name_owner_changed (PolkitBackendAuthority *authority, + const gchar *name, + const gchar *old_owner, + const gchar *new_owner); + void polkit_backend_authority_enumerate_actions (PolkitBackendAuthority *authority, const gchar *locale, PolkitBackendPendingCall *pending_call); @@ -127,6 +146,14 @@ void polkit_backend_authority_remove_authorization (PolkitBackendAuthor PolkitAuthorization *authorization, PolkitBackendPendingCall *pending_call); +void polkit_backend_authority_register_authentication_agent (PolkitBackendAuthority *authority, + const gchar *object_path, + PolkitBackendPendingCall *pending_call); + +void polkit_backend_authority_unregister_authentication_agent (PolkitBackendAuthority *authority, + const gchar *object_path, + PolkitBackendPendingCall *pending_call); + /* --- */ void polkit_backend_authority_enumerate_actions_finish (PolkitBackendPendingCall *pending_call, @@ -148,6 +175,9 @@ void polkit_backend_authority_add_authorization_finish (PolkitBackend void polkit_backend_authority_remove_authorization_finish (PolkitBackendPendingCall *pending_call); +void polkit_backend_authority_register_authentication_agent_finish (PolkitBackendPendingCall *pending_call); +void polkit_backend_authority_unregister_authentication_agent_finish (PolkitBackendPendingCall *pending_call); + G_END_DECLS diff --git a/src/polkitbackend/polkitbackendlocalauthority.c b/src/polkitbackend/polkitbackendlocalauthority.c index fdb6449..067d0c2 100644 --- a/src/polkitbackend/polkitbackendlocalauthority.c +++ b/src/polkitbackend/polkitbackendlocalauthority.c @@ -40,6 +40,8 @@ typedef struct GHashTable *hash_identity_to_authority_store; + GHashTable *hash_session_to_authentication_agent; + } PolkitBackendLocalAuthorityPrivate; /* ---------------------------------------------------------------------------------------------------- */ @@ -49,13 +51,21 @@ typedef struct AuthorizationStore AuthorizationStore; static void authorization_store_free (AuthorizationStore *store); -/* ---------------------------------------------------------------------------------------------------- */ - static AuthorizationStore *get_authorization_store_for_identity (PolkitBackendLocalAuthority *authority, PolkitIdentity *identity); /* ---------------------------------------------------------------------------------------------------- */ +struct AuthenticationAgent; +typedef struct AuthenticationAgent AuthenticationAgent; + +static void authentication_agent_free (AuthenticationAgent *agent); + +static AuthenticationAgent *get_authentication_agent_for_subject (PolkitBackendLocalAuthority *authority, + PolkitSubject *subject); + +/* ---------------------------------------------------------------------------------------------------- */ + static gboolean check_authorization_for_identity (PolkitBackendLocalAuthority *authority, PolkitIdentity *identity, const gchar *action_id); @@ -83,6 +93,11 @@ static gboolean remove_authorization_for_identity (PolkitBackendLocalAuthority * /* ---------------------------------------------------------------------------------------------------- */ +static void polkit_backend_local_authority_system_bus_name_owner_changed (PolkitBackendAuthority *authority, + const gchar *name, + const gchar *old_owner, + const gchar *new_owner); + static void polkit_backend_local_authority_enumerate_actions (PolkitBackendAuthority *authority, const gchar *locale, PolkitBackendPendingCall *pending_call); @@ -119,6 +134,14 @@ static void polkit_backend_local_authority_remove_authorization (PolkitBackendAu PolkitAuthorization *authorization, PolkitBackendPendingCall *pending_call); +static void polkit_backend_local_authority_register_authentication_agent (PolkitBackendAuthority *authority, + const gchar *object_path, + PolkitBackendPendingCall *pending_call); + +static void polkit_backend_local_authority_unregister_authentication_agent (PolkitBackendAuthority *authority, + const gchar *object_path, + PolkitBackendPendingCall *pending_call); + /* ---------------------------------------------------------------------------------------------------- */ G_DEFINE_TYPE (PolkitBackendLocalAuthority, polkit_backend_local_authority, POLKIT_BACKEND_TYPE_AUTHORITY); @@ -142,6 +165,11 @@ polkit_backend_local_authority_init (PolkitBackendLocalAuthority *local_authorit (GDestroyNotify) g_object_unref, (GDestroyNotify) authorization_store_free); + priv->hash_session_to_authentication_agent = g_hash_table_new_full ((GHashFunc) polkit_subject_hash, + (GEqualFunc) polkit_subject_equal, + (GDestroyNotify) g_object_unref, + (GDestroyNotify) authentication_agent_free); + priv->session_monitor = polkit_backend_session_monitor_new (); } @@ -162,6 +190,8 @@ polkit_backend_local_authority_finalize (GObject *object) g_hash_table_unref (priv->hash_identity_to_authority_store); + g_hash_table_unref (priv->hash_session_to_authentication_agent); + G_OBJECT_CLASS (polkit_backend_local_authority_parent_class)->finalize (object); } @@ -176,13 +206,16 @@ polkit_backend_local_authority_class_init (PolkitBackendLocalAuthorityClass *kla gobject_class->finalize = polkit_backend_local_authority_finalize; - authority_class->enumerate_actions = polkit_backend_local_authority_enumerate_actions; - authority_class->enumerate_users = polkit_backend_local_authority_enumerate_users; - authority_class->enumerate_groups = polkit_backend_local_authority_enumerate_groups; - authority_class->check_authorization = polkit_backend_local_authority_check_authorization; - authority_class->enumerate_authorizations = polkit_backend_local_authority_enumerate_authorizations; - authority_class->add_authorization = polkit_backend_local_authority_add_authorization; - authority_class->remove_authorization = polkit_backend_local_authority_remove_authorization; + authority_class->system_bus_name_owner_changed = polkit_backend_local_authority_system_bus_name_owner_changed; + authority_class->enumerate_actions = polkit_backend_local_authority_enumerate_actions; + authority_class->enumerate_users = polkit_backend_local_authority_enumerate_users; + authority_class->enumerate_groups = polkit_backend_local_authority_enumerate_groups; + authority_class->check_authorization = polkit_backend_local_authority_check_authorization; + authority_class->enumerate_authorizations = polkit_backend_local_authority_enumerate_authorizations; + authority_class->add_authorization = polkit_backend_local_authority_add_authorization; + authority_class->remove_authorization = polkit_backend_local_authority_remove_authorization; + authority_class->register_authentication_agent = polkit_backend_local_authority_register_authentication_agent; + authority_class->unregister_authentication_agent = polkit_backend_local_authority_unregister_authentication_agent; g_type_class_add_private (klass, sizeof (PolkitBackendLocalAuthorityPrivate)); } @@ -682,6 +715,203 @@ polkit_backend_local_authority_remove_authorization (PolkitBackendAuthority *a /* ---------------------------------------------------------------------------------------------------- */ +struct AuthenticationAgent +{ + PolkitSubject *session; + + gchar *object_path; + gchar *unique_system_bus_name; +}; + +static void +authentication_agent_free (AuthenticationAgent *agent) +{ + g_object_unref (agent->session); + g_free (agent->object_path); + g_free (agent->unique_system_bus_name); + g_free (agent); +} + +static AuthenticationAgent * +authentication_agent_new (PolkitSubject *session, + const gchar *unique_system_bus_name, + const gchar *object_path) +{ + AuthenticationAgent *agent; + + agent = g_new0 (AuthenticationAgent, 1); + + agent->session = g_object_ref (session); + agent->object_path = g_strdup (object_path); + agent->unique_system_bus_name = g_strdup (unique_system_bus_name); + + return agent; +} + +static AuthenticationAgent * +get_authentication_agent_for_subject (PolkitBackendLocalAuthority *authority, + PolkitSubject *subject) +{ + PolkitBackendLocalAuthorityPrivate *priv; + PolkitSubject *session_for_subject; + AuthenticationAgent *agent; + + priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (authority); + + agent = NULL; + session_for_subject = NULL; + + session_for_subject = polkit_backend_session_monitor_get_session_for_subject (priv->session_monitor, + subject, + NULL); + if (session_for_subject == NULL) + goto out; + + agent = g_hash_table_lookup (priv->hash_session_to_authentication_agent, session_for_subject); + + out: + if (session_for_subject != NULL) + g_object_unref (session_for_subject); +} + +static AuthenticationAgent * +get_authentication_agent_by_unique_system_bus_name (PolkitBackendLocalAuthority *authority, + const gchar *unique_system_bus_name) +{ + PolkitBackendLocalAuthorityPrivate *priv; + GHashTableIter hash_iter; + AuthenticationAgent *agent; + + priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (authority); + + g_hash_table_iter_init (&hash_iter, priv->hash_session_to_authentication_agent); + while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &agent)) + { + if (strcmp (agent->unique_system_bus_name, unique_system_bus_name) == 0) + goto out; + } + + agent = NULL; + + out: + return agent; +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +polkit_backend_local_authority_register_authentication_agent (PolkitBackendAuthority *authority, + const gchar *object_path, + PolkitBackendPendingCall *pending_call) +{ + PolkitBackendLocalAuthority *local_authority; + PolkitBackendLocalAuthorityPrivate *priv; + PolkitSubject *caller; + PolkitSubject *session_for_caller; + AuthenticationAgent *agent; + GError *error; + + error = NULL; + session_for_caller = NULL; + + local_authority = POLKIT_BACKEND_LOCAL_AUTHORITY (authority); + priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (local_authority); + + caller = polkit_backend_pending_call_get_caller (pending_call); + + session_for_caller = polkit_backend_session_monitor_get_session_for_subject (priv->session_monitor, + caller, + &error); + + if (session_for_caller == NULL) + { + polkit_backend_pending_call_return_error (pending_call, + POLKIT_ERROR, + POLKIT_ERROR_FAILED, + "Cannot determine session"); + + goto out; + } + + agent = g_hash_table_lookup (priv->hash_session_to_authentication_agent, session_for_caller); + if (agent != NULL) + { + polkit_backend_pending_call_return_error (pending_call, + POLKIT_ERROR, + POLKIT_ERROR_FAILED, + "An authentication agent already exists for session"); + goto out; + } + + /* TODO: validate that object path is well-formed */ + + agent = authentication_agent_new (session_for_caller, + polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller)), + object_path); + + g_hash_table_insert (priv->hash_session_to_authentication_agent, + g_object_ref (session_for_caller), + agent); + + g_debug ("Added authentication agent for session %s at name %s, object path %s", + polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (session_for_caller)), + polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller)), + object_path); + + polkit_backend_authority_register_authentication_agent_finish (pending_call); + + out: + if (session_for_caller != NULL) + g_object_unref (session_for_caller); +} + +static void +polkit_backend_local_authority_unregister_authentication_agent (PolkitBackendAuthority *authority, + const gchar *object_path, + PolkitBackendPendingCall *pending_call) +{ + polkit_backend_pending_call_return_error (pending_call, + POLKIT_ERROR, + POLKIT_ERROR_FAILED, + "Not implemented"); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +polkit_backend_local_authority_system_bus_name_owner_changed (PolkitBackendAuthority *authority, + const gchar *name, + const gchar *old_owner, + const gchar *new_owner) +{ + PolkitBackendLocalAuthority *local_authority; + PolkitBackendLocalAuthorityPrivate *priv; + AuthenticationAgent *agent; + + local_authority = POLKIT_BACKEND_LOCAL_AUTHORITY (authority); + priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (local_authority); + + //g_debug ("name-owner-changed: '%s' '%s' '%s'", name, old_owner, new_owner); + + if (name[0] == ':' && strlen (new_owner) == 0) + { + agent = get_authentication_agent_by_unique_system_bus_name (local_authority, name); + if (agent != NULL) + { + g_debug ("Removing authentication agent for session %s at name %s, object path %s (disconnected from bus)", + polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (agent->session)), + agent->unique_system_bus_name, + agent->object_path); + + /* this works because we have exactly one agent per session */ + g_hash_table_remove (priv->hash_session_to_authentication_agent, agent->session); + } + } + +} + +/* ---------------------------------------------------------------------------------------------------- */ + struct AuthorizationStore { PolkitIdentity *identity; diff --git a/src/polkitbackend/polkitbackendserver.c b/src/polkitbackend/polkitbackendserver.c index 9ed4127..2414bde 100644 --- a/src/polkitbackend/polkitbackendserver.c +++ b/src/polkitbackend/polkitbackendserver.c @@ -35,6 +35,14 @@ struct _PolkitBackendServer GObject parent_instance; PolkitBackendAuthority *authority; + + EggDBusConnection *system_bus; + + EggDBusObjectProxy *bus_proxy; + + EggDBusBus *bus; + + gulong name_owner_changed_id; }; struct _PolkitBackendServerClass @@ -60,6 +68,12 @@ polkit_backend_server_finalize (GObject *object) server = POLKIT_BACKEND_SERVER (object); + g_signal_handler_disconnect (server->bus, server->name_owner_changed_id); + + g_object_unref (server->bus_proxy); + + g_object_unref (server->system_bus); + g_object_unref (server->authority); } @@ -73,6 +87,16 @@ polkit_backend_server_class_init (PolkitBackendServerClass *klass) gobject_class->finalize = polkit_backend_server_finalize; } +static void +name_owner_changed (EggDBusBus *instance, + gchar *name, + gchar *old_owner, + gchar *new_owner, + PolkitBackendServer *server) +{ + polkit_backend_authority_system_bus_name_owner_changed (server->authority, name, old_owner, new_owner); +} + PolkitBackendServer * polkit_backend_server_new (PolkitBackendAuthority *authority) { @@ -82,6 +106,20 @@ polkit_backend_server_new (PolkitBackendAuthority *authority) server->authority = g_object_ref (authority); + /* TODO: it's a bit wasteful listening to all name-owner-changed signals... needs to be optimized */ + + server->system_bus = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM); + server->bus_proxy = egg_dbus_connection_get_object_proxy (server->system_bus, + "org.freedesktop.DBus", + "/org/freedesktop/DBus"); + + server->bus = EGG_DBUS_QUERY_INTERFACE_BUS (server->bus_proxy); + + server->name_owner_changed_id = g_signal_connect (server->bus, + "name-owner-changed", + (GCallback) name_owner_changed, + server); + return server; } @@ -387,13 +425,63 @@ polkit_backend_authority_remove_authorization_finish (PolkitBackendPendingCall /* ---------------------------------------------------------------------------------------------------- */ static void +authority_handle_register_authentication_agent (_PolkitAuthority *instance, + const gchar *object_path, + EggDBusMethodInvocation *method_invocation) +{ + PolkitBackendServer *server = POLKIT_BACKEND_SERVER (instance); + PolkitBackendPendingCall *pending_call; + + pending_call = _polkit_backend_pending_call_new (method_invocation, server); + + polkit_backend_authority_register_authentication_agent (server->authority, + object_path, + pending_call); +} + +void +polkit_backend_authority_register_authentication_agent_finish (PolkitBackendPendingCall *pending_call) +{ + _polkit_authority_handle_register_authentication_agent_finish (_polkit_backend_pending_call_get_method_invocation (pending_call)); + g_object_unref (pending_call); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +authority_handle_unregister_authentication_agent (_PolkitAuthority *instance, + const gchar *object_path, + EggDBusMethodInvocation *method_invocation) +{ + PolkitBackendServer *server = POLKIT_BACKEND_SERVER (instance); + PolkitBackendPendingCall *pending_call; + + pending_call = _polkit_backend_pending_call_new (method_invocation, server); + + polkit_backend_authority_unregister_authentication_agent (server->authority, + object_path, + pending_call); +} + +void +polkit_backend_authority_unregister_authentication_agent_finish (PolkitBackendPendingCall *pending_call) +{ + _polkit_authority_handle_unregister_authentication_agent_finish (_polkit_backend_pending_call_get_method_invocation (pending_call)); + g_object_unref (pending_call); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void authority_iface_init (_PolkitAuthorityIface *authority_iface) { - authority_iface->handle_enumerate_actions = authority_handle_enumerate_actions; - authority_iface->handle_enumerate_users = authority_handle_enumerate_users; - authority_iface->handle_enumerate_groups = authority_handle_enumerate_groups; - authority_iface->handle_check_authorization = authority_handle_check_authorization; - authority_iface->handle_enumerate_authorizations = authority_handle_enumerate_authorizations; - authority_iface->handle_add_authorization = authority_handle_add_authorization; - authority_iface->handle_remove_authorization = authority_handle_remove_authorization; + authority_iface->handle_enumerate_actions = authority_handle_enumerate_actions; + authority_iface->handle_enumerate_users = authority_handle_enumerate_users; + authority_iface->handle_enumerate_groups = authority_handle_enumerate_groups; + authority_iface->handle_check_authorization = authority_handle_check_authorization; + authority_iface->handle_enumerate_authorizations = authority_handle_enumerate_authorizations; + authority_iface->handle_add_authorization = authority_handle_add_authorization; + authority_iface->handle_remove_authorization = authority_handle_remove_authorization; + authority_iface->handle_register_authentication_agent = authority_handle_register_authentication_agent; + authority_iface->handle_unregister_authentication_agent = authority_handle_unregister_authentication_agent; } diff --git a/src/polkitbackend/polkitbackendsessionmonitor.c b/src/polkitbackend/polkitbackendsessionmonitor.c index ee225ca..61fc86a 100644 --- a/src/polkitbackend/polkitbackendsessionmonitor.c +++ b/src/polkitbackend/polkitbackendsessionmonitor.c @@ -432,3 +432,63 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor return user; } + +/** + * polkit_backend_session_monitor_get_session_for_subject: + * @monitor: A #PolkitBackendSessionMonitor. + * @subject: A #PolkitSubject. + * @error: Return location for error. + * + * Gets the session corresponding to @subject or %NULL if no session exists. + * + * Returns: %NULL if @error is set otherwise a #PolkitUnixSession that should be freed with g_object_unref(). + */ +PolkitSubject * +polkit_backend_session_monitor_get_session_for_subject (PolkitBackendSessionMonitor *monitor, + PolkitSubject *subject, + GError **error) +{ + PolkitSubject *session; + + session = NULL; + + if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) + { + pid_t pid; + gchar *session_id; + + /* TODO: cache this stuff */ + if (!egg_dbus_bus_get_connection_unix_process_id_sync (egg_dbus_connection_get_bus (monitor->system_bus), + EGG_DBUS_CALL_FLAGS_NONE, + polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (subject)), + &pid, + NULL, + error)) + goto out; + + if (!ck_manager_get_session_for_unix_process_sync (monitor->ck_manager, + EGG_DBUS_CALL_FLAGS_NONE, + pid, + &session_id, + NULL, + error)) + goto out; + + session = polkit_unix_session_new (session_id); + + g_free (session_id); + } + else + { + g_set_error (error, + POLKIT_ERROR, + POLKIT_ERROR_NOT_SUPPORTED, + "Cannot get user for subject of type %s", + g_type_name (G_TYPE_FROM_INSTANCE (subject))); + } + + out: + + return session; +} + diff --git a/src/polkitbackend/polkitbackendsessionmonitor.h b/src/polkitbackend/polkitbackendsessionmonitor.h index 8569266..a4194a9 100644 --- a/src/polkitbackend/polkitbackendsessionmonitor.h +++ b/src/polkitbackend/polkitbackendsessionmonitor.h @@ -51,6 +51,10 @@ PolkitIdentity *polkit_backend_session_monitor_get_user_for_subject PolkitSubject *subject, GError **error); +PolkitSubject *polkit_backend_session_monitor_get_session_for_subject (PolkitBackendSessionMonitor *monitor, + PolkitSubject *subject, + GError **error); + G_END_DECLS #endif /* __POLKIT_BACKEND_SESSION_MONITOR_H */ |