Commit 86008e61 authored by David Zeuthen's avatar David Zeuthen

Only allow privileged apps to check authz and add ActionLookup interface

Also remove the ObtainAuthorization() call and allow apps to pass
details to CheckAuthorization.
parent e80ede9e
......@@ -14,6 +14,18 @@
<annotation name="org.gtk.EggDBus.DocString" value="The identifier for the action that the user is authentication for."/>
</arg>
<arg name="message" direction="in" type="s">
<annotation name="org.gtk.EggDBus.DocString" value="The message to display to the user. This is translated into the locale passed when registering the authentication agent using org.freedesktop.PolicyKit1.Authority.RegisterAuthenticationAgent()."/>
</arg>
<arg name="icon_name" direction="in" type="s">
<annotation name="org.gtk.EggDBus.DocString" value="The themed icon describing the action or the empty string if no icon is set."/>
</arg>
<arg name="details" direction="in" type="a{ss}">
<annotation name="org.gtk.EggDBus.DocString" value="Details about the authentication request. This is a dictionary of key/value pairs where both key and value are strings. These strings are translated into the locale passed when registering the authentication agent using org.freedesktop.PolicyKit1.Authority.RegisterAuthenticationAgent()."/>
</arg>
<arg name="cookie" direction="in" type="s">
<annotation name="org.gtk.EggDBus.DocString" value="A cookie identifying the authentication request."/>
</arg>
......
......@@ -213,6 +213,10 @@
<annotation name="org.gtk.EggDBus.DocString" value="Identifier for the action that @subject is attempting to do."/>
</arg>
<arg name="details" direction="in" type="a{ss}">
<annotation name="org.gtk.EggDBus.DocString" value="Details describing the action."/>
</arg>
<arg name="flags" direction="in" type="u">
<annotation name="org.gtk.EggDBus.Type" value="CheckAuthorizationFlags"/>
<annotation name="org.gtk.EggDBus.DocString" value="A set of #CheckAuthorizationFlags."/>
......@@ -238,33 +242,6 @@
<!-- ---------------------------------------------------------------------------------------------------- -->
<method name="ObtainAuthorization">
<annotation name="org.gtk.EggDBus.DocString" value="Obtains a temporary authorization for @subject to perform the action identified by @action_id. If @subject is already authorized, this method returns immediately without error. If the authorization could not be obtained or @action_id doesn't allow temporary authorizations, the %org.freedesktop.PolicyKit1.Error.Failed error is returned."/>
<arg name="subject" direction="in" type="(sa{sv})">
<annotation name="org.gtk.EggDBus.DocString" value="A #Subject struct."/>
<annotation name="org.gtk.EggDBus.Type" value="Subject"/>
</arg>
<arg name="action_id" direction="in" type="s">
<annotation name="org.gtk.EggDBus.DocString" value="Identifier for the action that @subject is attempting to do."/>
</arg>
<arg name="cancellation_id" direction="in" type="s">
<annotation name="org.gtk.EggDBus.DocString" value="A unique id used to cancel the the authentication check via org.freedesktop.PolicyKit1.Authority.CancelObtainAuthorization() or the empty string if cancellation is not needed."/>
</arg>
</method>
<method name="CancelObtainAuthorization">
<annotation name="org.gtk.EggDBus.DocString" value="Cancels an attempt to obtain an authorization."/>
<arg name="cancellation_id" direction="in" type="s">
<annotation name="org.gtk.EggDBus.DocString" value="The @cancellation_id passed to org.freedesktop.PolicyKit1.Authority.ObtainAuthorization()."/>
</arg>
</method>
<!-- ---------------------------------------------------------------------------------------------------- -->
<method name="RegisterAuthenticationAgent">
<annotation name="org.gtk.EggDBus.DocString" value="<para>Register an authentication agent.</para><para>Note that current versions of PolicyKit will only work if @session_id is set to the empty string. In the future it might work for non-empty strings if the caller is sufficiently privileged.</para>"/>
......@@ -272,6 +249,10 @@
<annotation name="org.gtk.EggDBus.DocString" value="The session to register the authentication for or blank for the session the caller of the method is in."/>
</arg>
<arg name="locale" direction="in" type="s">
<annotation name="org.gtk.EggDBus.DocString" value="The locale of the authentication agent."/>
</arg>
<arg name="object_path" direction="in" type="s">
<annotation name="org.gtk.EggDBus.DocString" value="The object path of authentication agent object on the unique name of the caller."/>
</arg>
......
......@@ -4,7 +4,7 @@ NULL =
AUTOMAKE_OPTIONS = 1.7
# The name of the module.
DOC_MODULE=polkit-1
DOC_MODULE=polkit
# The top-level SGML file.
DOC_MAIN_SGML_FILE=polkit-docs.xml
......
......@@ -91,6 +91,7 @@
<xi:include href="../polkitbackend/xml/polkitbackendactionpool.xml"/>
<xi:include href="../polkitbackend/xml/polkitbackendsessionmonitor.xml"/>
<xi:include href="../polkitbackend/xml/polkitbackendconfigsource.xml"/>
<xi:include href="../polkitbackend/xml/polkitbackendactionlookup.xml"/>
</reference>
<reference id="ref-authentication-agent-api">
......
......@@ -54,7 +54,6 @@ PolkitAuthorizationResult
polkit_authority_get
polkit_authority_enumerate_actions_sync
polkit_authority_check_authorization_sync
polkit_authority_obtain_authorization_sync
polkit_authority_register_authentication_agent_sync
polkit_authority_unregister_authentication_agent_sync
polkit_authority_authentication_agent_response_sync
......@@ -62,8 +61,6 @@ polkit_authority_enumerate_actions
polkit_authority_enumerate_actions_finish
polkit_authority_check_authorization
polkit_authority_check_authorization_finish
polkit_authority_obtain_authorization
polkit_authority_obtain_authorization_finish
polkit_authority_register_authentication_agent
polkit_authority_register_authentication_agent_finish
polkit_authority_unregister_authentication_agent
......
......@@ -4,7 +4,7 @@ NULL =
AUTOMAKE_OPTIONS = 1.7
# The name of the module.
DOC_MODULE=polkitagent-1
DOC_MODULE=polkitagent
# The top-level SGML file.
DOC_MAIN_SGML_FILE=polkitagent-docs.xml
......
......@@ -4,7 +4,7 @@ NULL =
AUTOMAKE_OPTIONS = 1.7
# The name of the module.
DOC_MODULE=polkitbackend-1
DOC_MODULE=polkitbackend
# The top-level SGML file.
DOC_MAIN_SGML_FILE=polkitbackend-docs.xml
......
......@@ -6,8 +6,6 @@ PolkitBackendAuthority
PolkitBackendAuthorityClass
polkit_backend_authority_check_authorization
polkit_backend_authority_check_authorization_finish
polkit_backend_authority_obtain_authorization
polkit_backend_authority_obtain_authorization_finish
polkit_backend_authority_register_authentication_agent
polkit_backend_authority_unregister_authentication_agent
polkit_backend_authority_authentication_agent_response
......@@ -30,6 +28,23 @@ POLKIT_BACKEND_IS_AUTHORITY_CLASS
POLKIT_BACKEND_AUTHORITY_GET_CLASS
</SECTION>
<SECTION>
<FILE>polkitbackendactionlookup</FILE>
<TITLE>PolkitBackendActionLookup</TITLE>
POLKIT_BACKEND_ACTION_LOOKUP_EXTENSION_POINT_NAME
PolkitBackendActionLookup
PolkitBackendActionLookupIface
polkit_backend_action_lookup_get_message
polkit_backend_action_lookup_get_icon_name
polkit_backend_action_lookup_get_details
<SUBSECTION Standard>
POLKIT_BACKEND_ACTION_LOOKUP
POLKIT_BACKEND_IS_ACTION_LOOKUP
POLKIT_BACKEND_TYPE_ACTION_LOOKUP
polkit_backend_action_lookup_get_type
POLKIT_BACKEND_ACTION_LOOKUP_GET_IFACE
</SECTION>
<SECTION>
<FILE>polkitbackendlocalauthority</FILE>
<TITLE>PolkitBackendLocalAuthority</TITLE>
......
polkit_backend_authority_get_type
polkit_backend_action_lookup_get_type
polkit_backend_local_authority_get_type
polkit_backend_action_pool_get_type
polkit_backend_session_monitor_get_type
......
......@@ -15,7 +15,7 @@ INCLUDES = \
-D_REENTRANT \
$(NULL)
noinst_PROGRAMS = cancel cancelobtain
noinst_PROGRAMS = cancel
cancel_SOURCES = cancel.c
......@@ -28,16 +28,5 @@ cancel_LDADD = \
$(top_builddir)/src/polkit/libpolkit-gobject-1.la \
$(NULL)
cancelobtain_SOURCES = cancelobtain.c
cancelobtain_CFLAGS = \
$(GLIB_CFLAGS) \
$(NULL)
cancelobtain_LDADD = \
$(GLIB_LDADD) \
$(top_builddir)/src/polkit/libpolkit-gobject-1.la \
$(NULL)
clean-local :
rm -f *~
......@@ -108,6 +108,7 @@ main (int argc, char *argv[])
polkit_authority_check_authorization (authority,
calling_process,
"org.freedesktop.policykit.grant",
NULL,
POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
cancellable,
(GAsyncReadyCallback) check_authorization_cb,
......
/*
* Copyright (C) 2009 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>
*/
/* Simple example that shows how to obtain an authorization including
* cancelling the request.
*/
#include <polkit/polkit.h>
static void
obtain_authorization_cb (PolkitAuthority *authority,
GAsyncResult *res,
GMainLoop *loop)
{
GError *error;
error = NULL;
if (!polkit_authority_obtain_authorization_finish (authority, res, &error))
{
g_print ("Error obtaining authorization: %s\n", error->message);
g_error_free (error);
}
g_main_loop_quit (loop);
}
static gboolean
do_cancel (GCancellable *cancellable)
{
g_print ("Timer has expired; cancelling request\n");
g_cancellable_cancel (cancellable);
return FALSE;
}
int
main (int argc, char *argv[])
{
int ret;
GMainLoop *loop;
PolkitSubject *calling_process;
PolkitAuthority *authority;
GCancellable *cancellable;
g_type_init ();
ret = 1;
if (argc != 2)
{
g_printerr ("usage: cancelobtain <actionid>\n");
goto out;
}
loop = g_main_loop_new (NULL, FALSE);
authority = polkit_authority_get ();
calling_process = polkit_unix_process_new (getppid ());
cancellable = g_cancellable_new ();
g_print ("Will cancel request in 10 seconds\n");
g_timeout_add (10 * 1000,
(GSourceFunc) do_cancel,
cancellable);
polkit_authority_obtain_authorization (authority,
calling_process,
argv[1],
cancellable,
(GAsyncReadyCallback) obtain_authorization_cb,
loop);
g_main_loop_run (loop);
g_object_unref (authority);
g_object_unref (calling_process);
g_object_unref (cancellable);
g_main_loop_unref (loop);
ret = 0;
out:
return ret;
}
......@@ -42,6 +42,7 @@ static void authority_check_authorization (PolkitBackendAuthority *author
PolkitSubject *caller,
PolkitSubject *subject,
const gchar *action_id,
GHashTable *details,
PolkitCheckAuthorizationFlags flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
......@@ -136,6 +137,7 @@ authority_check_authorization (PolkitBackendAuthority *authority,
PolkitSubject *caller,
PolkitSubject *subject,
const gchar *action_id,
GHashTable *details,
PolkitCheckAuthorizationFlags flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
......
This diff is collapsed.
......@@ -65,18 +65,14 @@ GList *polkit_authority_enumerate_groups_sync (PolkitAuthori
PolkitAuthorizationResult polkit_authority_check_authorization_sync (PolkitAuthority *authority,
PolkitSubject *subject,
const gchar *action_id,
GHashTable *details,
PolkitCheckAuthorizationFlags flags,
GCancellable *cancellable,
GError **error);
gboolean polkit_authority_obtain_authorization_sync (PolkitAuthority *authority,
PolkitSubject *subject,
const gchar *action_id,
GCancellable *cancellable,
GError **error);
gboolean polkit_authority_register_authentication_agent_sync (PolkitAuthority *authority,
const gchar *session_id,
const gchar *locale,
const gchar *object_path,
GCancellable *cancellable,
GError **error);
......@@ -107,6 +103,7 @@ GList * polkit_authority_enumerate_actions_finish (PolkitAuth
void polkit_authority_check_authorization (PolkitAuthority *authority,
PolkitSubject *subject,
const gchar *action_id,
GHashTable *details,
PolkitCheckAuthorizationFlags flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
......@@ -116,19 +113,9 @@ PolkitAuthorizationResult polkit_authority_check_authorization_finish (PolkitAu
GAsyncResult *res,
GError **error);
void polkit_authority_obtain_authorization (PolkitAuthority *authority,
PolkitSubject *subject,
const gchar *action_id,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean polkit_authority_obtain_authorization_finish (PolkitAuthority *authority,
GAsyncResult *res,
GError **error);
void polkit_authority_register_authentication_agent (PolkitAuthority *authority,
const gchar *session_id,
const gchar *locale,
const gchar *object_path,
GCancellable *cancellable,
GAsyncReadyCallback callback,
......
......@@ -104,6 +104,7 @@ server_register (Server *server,
local_error = NULL;
if (!polkit_authority_register_authentication_agent_sync (server->authority,
server->session_id,
g_getenv ("LANG"),
server->object_path,
NULL,
&local_error))
......@@ -358,6 +359,9 @@ 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)
......@@ -389,6 +393,9 @@ handle_begin_authentication (_PolkitAuthenticationAgent *instance,
polkit_agent_listener_initiate_authentication (server->listener,
action_id,
message,
icon_name,
details->data,
cookie,
list,
data->cancellable,
......@@ -447,6 +454,9 @@ polkit_agent_listener_class_init (PolkitAgentListenerClass *klass)
* polkit_agent_listener_initiate_authentication:
* @listener: A #PolkitAgentListener.
* @action_id: The action to authenticate for.
* @message: The message to present to the user.
* @icon_name: A themed icon name representing the action or %NULL.
* @details: A set of key/value string pairs describing the action.
* @cookie: The cookie for the authentication request.
* @identities: A list of #PolkitIdentity objects that the user can choose to authenticate as.
* @cancellable: A #GCancellable.
......@@ -467,6 +477,9 @@ polkit_agent_listener_class_init (PolkitAgentListenerClass *klass)
void
polkit_agent_listener_initiate_authentication (PolkitAgentListener *listener,
const gchar *action_id,
const gchar *message,
const gchar *icon_name,
GHashTable *details,
const gchar *cookie,
GList *identities,
GCancellable *cancellable,
......@@ -475,6 +488,9 @@ polkit_agent_listener_initiate_authentication (PolkitAgentListener *listener,
{
POLKIT_AGENT_LISTENER_GET_CLASS (listener)->initiate_authentication (listener,
action_id,
message,
icon_name,
details,
cookie,
identities,
cancellable,
......
......@@ -67,6 +67,9 @@ struct _PolkitAgentListenerClass
/* Vtable */
void (*initiate_authentication) (PolkitAgentListener *listener,
const gchar *action_id,
const gchar *message,
const gchar *icon_name,
GHashTable *details,
const gchar *cookie,
GList *identities,
GCancellable *cancellable,
......@@ -92,6 +95,9 @@ struct _PolkitAgentListenerClass
GType polkit_agent_listener_get_type (void) G_GNUC_CONST;
void polkit_agent_listener_initiate_authentication (PolkitAgentListener *listener,
const gchar *action_id,
const gchar *message,
const gchar *icon_name,
GHashTable *details,
const gchar *cookie,
GList *identities,
GCancellable *cancellable,
......
......@@ -43,6 +43,7 @@ libpolkit_backend_1include_HEADERS = \
polkitbackendactionpool.h \
polkitbackendsessionmonitor.h \
polkitbackendconfigsource.h \
polkitbackendactionlookup.h \
$(NULL)
libpolkit_backend_1_la_SOURCES = \
......@@ -56,6 +57,7 @@ libpolkit_backend_1_la_SOURCES = \
polkitbackendactionpool.h polkitbackendactionpool.c \
polkitbackendsessionmonitor.h polkitbackendsessionmonitor.c \
polkitbackendconfigsource.h polkitbackendconfigsource.c \
polkitbackendactionlookup.h polkitbackendactionlookup.c \
$(NULL)
libpolkit_backend_1_la_CFLAGS = \
......
......@@ -35,6 +35,7 @@
#include <polkitbackend/polkitbackendactionpool.h>
#include <polkitbackend/polkitbackendsessionmonitor.h>
#include <polkitbackend/polkitbackendconfigsource.h>
#include <polkitbackend/polkitbackendactionlookup.h>
#undef _POLKIT_BACKEND_INSIDE_POLKIT_BACKEND_H
#endif /* __POLKIT_BACKEND_H */
......
/*
* 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 <errno.h>
#include <pwd.h>
#include <string.h>
#include <polkit/polkit.h>
#include <polkit/polkitprivate.h>
#include "polkitbackendactionlookup.h"
#include "polkitbackendprivate.h"
/**
* SECTION:polkitbackendactionlookup
* @title: PolkitBackendActionLookup
* @short_description: Interface used to provide data to authentication dialogs
* @stability: Unstable
*
* An interface that is used by backends to provide localized data
* shown in authentication dialogs.
*
* This inteface is intended for mechanisms to customize the message
* to show - a mechanism can provide a #GIOModule that registers one
* or more extensions that implement this interface. Every time an
* authentication dialog is shown, the registered extensions are
* consulted in priority order.
*
* This is useful if your mechanism wants to put up a message such as
* "Authentication is required to install 'Totem Movie Player'",
* e.g. messages that include more information than just the action
* name.
*
* Code implementing this interface <emphasis>cannot</emphasis>
* block or do any IO when methods are invoked. If information is
* needed to format the message or details, prepare it in advance and
* pass it as part of the @details hash table when doing the
* polkit_authority_check_authorization() call. Then the code in this
* interface can use that information to return localized data.
*
* Note that setlocale() and the <literal>LANG</literal> environment
* variable will be set up to match the locale of the authentication
* agent that is the receiver of the information. This means that code
* implementing this interface can use dgettext() or similar machinery
* to look up translations.
*/
static void
base_init (gpointer g_iface)
{
}
GType
polkit_backend_action_lookup_get_type (void)
{
static GType iface_type = 0;
if (iface_type == 0)
{
static const GTypeInfo info =
{
sizeof (PolkitBackendActionLookupIface),
base_init, /* base_init */
NULL, /* base_finalize */
NULL, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
0, /* instance_size */
0, /* n_preallocs */
NULL, /* instance_init */
NULL /* value_table */
};
iface_type = g_type_register_static (G_TYPE_INTERFACE, "PolkitBackendActionLookup", &info, 0);
g_type_interface_add_prerequisite (iface_type, G_TYPE_OBJECT);
}
return iface_type;
}
/**
* polkit_backend_action_lookup_get_message:
* @lookup: A #PolkitBackendActionLookup.
* @action_id: The action to get the message for.
* @details: Details passed to polkit_authority_check_authorization().
* @action_description: A #PolkitActionDescription object for @action_id.
*
* Computes a message to show in an authentication dialog for
* @action_id and @details.
*
* Returns: A localized string to show in the authentication dialog or %NULL. Caller must free this string.
**/
gchar *
polkit_backend_action_lookup_get_message (PolkitBackendActionLookup *lookup,
const gchar *action_id,
GHashTable *details,
PolkitActionDescription *action_description)
{
PolkitBackendActionLookupIface *iface = POLKIT_BACKEND_ACTION_LOOKUP_GET_IFACE (lookup);
if (iface->get_message == NULL)
return NULL;
else
return iface->get_message (lookup, action_id, details, action_description);
}
/**
* polkit_backend_action_lookup_get_icon_name:
* @lookup: A #PolkitBackendActionLookup.
* @action_id: The action to get the themed icon for.
* @details: Details passed to polkit_authority_check_authorization().
* @action_description: A #PolkitActionDescription object for @action_id.
*
* Computes a themed icon name to show in an authentication dialog for
* @action_id and @details.
*
* Returns: A themed icon name or %NULL. Caller must free this string.
**/
gchar *
polkit_backend_action_lookup_get_icon_name (PolkitBackendActionLookup *lookup,
const gchar *action_id,
GHashTable *details,
PolkitActionDescription *action_description)
{
PolkitBackendActionLookupIface *iface = POLKIT_BACKEND_ACTION_LOOKUP_GET_IFACE (lookup);
if (iface->get_icon_name == NULL)
return NULL;
else
return iface->get_icon_name (lookup, action_id, details, action_description);
}
/**
* polkit_backend_action_lookup_get_details:
* @lookup: A #PolkitBackendActionLookup.
* @action_id: The action to get the details for.
* @details: Details passed to polkit_authority_check_authorization().
* @action_description: A #PolkitActionDescription object for @action_id.
*
* Computes localized details to show in an authentication dialog for
* @action_id and @details.
*
* Returns: A #GHashTable with localized details or %NULL. Caller must free the result.
**/
GHashTable *
polkit_backend_action_lookup_get_details (PolkitBackendActionLookup *lookup,