Not finished yet...
-SUBDIRS = polkit polkitbackend polkitd programs
+SUBDIRS = polkit polkitbackend polkitagent polkitd programs
clean-local :
rm -f *~
--- /dev/null
+NULL =
+
+INCLUDES = \
+ -I$(top_builddir)/src \
+ -I$(top_srcdir)/src \
+ -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
+ -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
+ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+ -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
+ -DPACKAGE_LOCALSTATE_DIR=\""$(localstatedir)"\" \
+ -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
+ -DPACKAGE_LIB_DIR=\""$(libdir)"\" \
+ -D_POSIX_PTHREAD_SEMANTICS \
+ -D_REENTRANT \
+ $(NULL)
+
+
+lib_LTLIBRARIES=libpolkit-agent-1.la
+
+libpolkit_agent_1includedir=$(includedir)/polkit-1/polkitagent
+
+libpolkit_agent_1include_HEADERS = \
+ polkitagent.h \
+ polkitagenttypes.h \
+ polkitauthenticationsession.h \
+ $(NULL)
+
+libpolkit_agent_1_la_SOURCES = \
+ polkitagent.h \
+ polkitagenttypes.h \
+ polkitauthenticationsession.h polkitauthenticationsession.c \
+ $(NULL)
+
+libpolkit_agent_1_la_CFLAGS = \
+ -D_POLKIT_AGENT_COMPILATION \
+ $(GLIB_CFLAGS) \
+ $(EGG_DBUS_CFLAGS) \
+ $(NULL)
+
+libpolkit_agent_1_la_LIBADD = \
+ $(GLIB_LIBS) \
+ $(EGG_DBUS_LIBS) \
+ $(top_builddir)/src/polkit/libpolkit-gobject-1.la \
+ $(EXPAT_LIBS) \
+ $(NULL)
+
+libexec_PROGRAMS = polkit-agent-helper-1
+
+polkit_agent_helper_1_SOURCES = polkitagenthelper.c
+polkit_agent_helper_1_LDADD = $(AUTH_LIBS)
+
+# polkit-agent-helper-1 need to be setuid root because it's used to
+# authenticate not only the invoking user, but possibly also root
+# and/or other users.
+#
+install-exec-hook:
+ -chown root $(DESTDIR)$(libexecdir)/polkit-agent-helper-1
+ -chmod 4755 $(DESTDIR)$(libexecdir)/polkit-agent-helper-1
+
+CLEANFILES = $(BUILT_SOURCES)
+
+clean-local :
+ rm -f *~
--- /dev/null
+/*
+ * 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_H
+#define __POLKIT_AGENT_H
+
+#define _POLKIT_AGENT_INSIDE_POLKIT_AGENT_H 1
+#include <polkitagent/polkitauthenticationsession.h>
+#undef _POLKIT_AGENT_INSIDE_POLKIT_AGENT_H
+
+#endif /* __POLKIT_AGENT_H */
--- /dev/null
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <syslog.h>
+#include <security/pam_appl.h>
+
+#ifdef HAVE_SOLARIS
+# define LOG_AUTHPRIV (10<<3)
+#endif
+
+/* Development aid: define PAH_DEBUG to get debugging output. Do _NOT_
+ * enable this in production builds; it may leak passwords and other
+ * sensitive information.
+ */
+#undef PAH_DEBUG
+#define PAH_DEBUG
+
+static int conversation_function (int n, const struct pam_message **msg, struct pam_response **resp, void *data);
+
+int
+main (int argc, char *argv[])
+{
+ int rc;
+ const char *user_to_auth;
+ const char *cookie;
+ struct pam_conv pam_conversation;
+ pam_handle_t *pam_h;
+ const void *authed_user;
+
+ rc = 0;
+ pam_h = NULL;
+
+ /* clear the entire environment to avoid attacks using with libraries honoring environment variables */
+ if (clearenv () != 0)
+ goto error;
+
+ /* set a minimal environment */
+ setenv ("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1);
+
+ /* check that we are setuid root */
+ if (geteuid () != 0)
+ {
+ fprintf (stderr, "polkit-grant-helper-pam: needs to be setuid root\n");
+ goto error;
+ }
+
+ openlog ("polkit-agent-helper-1", LOG_CONS | LOG_PID, LOG_AUTHPRIV);
+
+ /* check for correct invocation */
+ if (argc != 3)
+ {
+ syslog (LOG_NOTICE, "inappropriate use of helper, wrong number of arguments [uid=%d]", getuid ());
+ fprintf (stderr, "polkit-agent-helper-1: wrong number of arguments. This incident has been logged.\n");
+ goto error;
+ }
+
+ user_to_auth = argv[1];
+ cookie = argv[2];
+
+ if (getuid () != 0)
+ {
+ /* check we're running with a non-tty stdin */
+ if (isatty (STDIN_FILENO) != 0)
+ {
+ syslog (LOG_NOTICE, "inappropriate use of helper, stdin is a tty [uid=%d]", getuid ());
+ fprintf (stderr, "polkit-agent-helper-1: inappropriate use of helper, stdin is a tty. This incident has been logged.\n");
+ goto error;
+ }
+ }
+
+#ifdef PAH_DEBUG
+ fprintf (stderr, "polkit-agent-helper-1: user to auth is '%s'.\n", user_to_auth);
+#endif /* PAH_DEBUG */
+
+ pam_conversation.conv = conversation_function;
+ pam_conversation.appdata_ptr = NULL;
+
+ /* start the pam stack */
+ rc = pam_start ("polkit-1",
+ user_to_auth,
+ &pam_conversation,
+ &pam_h);
+ if (rc != PAM_SUCCESS)
+ {
+ fprintf (stderr, "polkit-agent-helper-1: pam_start failed: %s\n", pam_strerror (pam_h, rc));
+ goto error;
+ }
+
+ /* set the requesting user */
+ rc = pam_set_item (pam_h, PAM_RUSER, user_to_auth);
+ if (rc != PAM_SUCCESS)
+ {
+ fprintf (stderr, "polkit-agent-helper-1: pam_set_item failed: %s\n", pam_strerror (pam_h, rc));
+ goto error;
+ }
+
+ /* is user really user? */
+ rc = pam_authenticate (pam_h, 0);
+ if (rc != PAM_SUCCESS)
+ {
+ fprintf (stderr, "polkit-agent-helper-1: pam_authenticated failed: %s\n", pam_strerror (pam_h, rc));
+ goto error;
+ }
+
+ /* permitted access? */
+ rc = pam_acct_mgmt (pam_h, 0);
+ if (rc != PAM_SUCCESS)
+ {
+ fprintf (stderr, "polkit-agent-helper-1: pam_acct_mgmt failed: %s\n", pam_strerror (pam_h, rc));
+ goto error;
+ }
+
+ /* did we auth the right user? */
+ rc = pam_get_item (pam_h, PAM_USER, &authed_user);
+ if (rc != PAM_SUCCESS)
+ {
+ fprintf (stderr, "polkit-agent-helper-1: pam_get_item failed: %s\n", pam_strerror (pam_h, rc));
+ goto error;
+ }
+
+ if (strcmp (authed_user, user_to_auth) != 0)
+ {
+ fprintf (stderr, "polkit-agent-helper-1: Tried to auth user '%s' but we got auth for user '%s' instead",
+ user_to_auth, (const char *) authed_user);
+ goto error;
+ }
+
+#ifdef PAH_DEBUG
+ fprintf (stderr, "polkit-agent-helper-1: successfully authenticated user '%s'.\n", user_to_auth);
+#endif /* PAH_DEBUG */
+
+ /* TODO: now send a D-Bus message to the PolicyKit daemon that
+ * includes a) the cookie; and b) the user we authenticated
+ */
+
+ fprintf (stdout, "SUCCESS\n");
+ fflush (stdout);
+
+ pam_end (pam_h, rc);
+ return 0;
+
+error:
+ if (pam_h != NULL)
+ pam_end (pam_h, rc);
+
+ fprintf (stdout, "FAILURE\n");
+ fflush (stdout);
+ return 1;
+}
+
+static int
+conversation_function (int n, const struct pam_message **msg, struct pam_response **resp, void *data)
+{
+ struct pam_response *aresp;
+ char buf[PAM_MAX_RESP_SIZE];
+ int i;
+
+ data = data;
+ if (n <= 0 || n > PAM_MAX_NUM_MSG)
+ return PAM_CONV_ERR;
+
+ if ((aresp = calloc(n, sizeof *aresp)) == NULL)
+ return PAM_BUF_ERR;
+
+ for (i = 0; i < n; ++i)
+ {
+ aresp[i].resp_retcode = 0;
+ aresp[i].resp = NULL;
+ switch (msg[i]->msg_style)
+ {
+
+ case PAM_PROMPT_ECHO_OFF:
+ fprintf (stdout, "PAM_PROMPT_ECHO_OFF ");
+ goto conv1;
+
+ case PAM_PROMPT_ECHO_ON:
+ fprintf (stdout, "PAM_PROMPT_ECHO_ON ");
+ conv1:
+ fputs (msg[i]->msg, stdout);
+ if (strlen (msg[i]->msg) > 0 && msg[i]->msg[strlen (msg[i]->msg) - 1] != '\n')
+ fputc ('\n', stdout);
+ fflush (stdout);
+
+ if (fgets (buf, sizeof buf, stdin) == NULL)
+ goto error;
+
+ if (strlen (buf) > 0 &&
+ buf[strlen (buf) - 1] == '\n')
+ buf[strlen (buf) - 1] = '\0';
+
+ aresp[i].resp = strdup (buf);
+ if (aresp[i].resp == NULL)
+ goto error;
+ break;
+
+ case PAM_ERROR_MSG:
+ fprintf (stdout, "PAM_ERROR_MSG ");
+ goto conv2;
+
+ case PAM_TEXT_INFO:
+ fprintf (stdout, "PAM_TEXT_INFO ");
+ conv2:
+ fputs (msg[i]->msg, stdout);
+ if (strlen (msg[i]->msg) > 0 &&
+ msg[i]->msg[strlen (msg[i]->msg) - 1] != '\n')
+ fputc ('\n', stdout);
+ fflush (stdout);
+ break;
+
+ default:
+ goto error;
+ }
+ }
+
+ *resp = aresp;
+ return PAM_SUCCESS;
+
+error:
+
+ for (i = 0; i < n; ++i)
+ {
+ if (aresp[i].resp != NULL) {
+ memset (aresp[i].resp, 0, strlen(aresp[i].resp));
+ free (aresp[i].resp);
+ }
+ }
+ memset (aresp, 0, n * sizeof *aresp);
+ *resp = NULL;
+ return PAM_CONV_ERR;
+}
--- /dev/null
+/*
+ * 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_TYPES_H
+#define __POLKIT_AGENT_TYPES_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+struct _PolkitAuthenticationSession;
+typedef struct _PolkitAuthenticationSession PolkitAuthenticationSession;
+
+
+G_END_DECLS
+
+#endif /* __POLKIT_AGENT_TYPES_H */
--- /dev/null
+/*
+ * 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>
+ */
+
+/* TODO: This whole class needs to be rewritten so it uses the main loop etc. etc.
+ *
+ * And we REALLY REALLY really really should use signals instead of callbacks...
+ */
+
+
+/* for getline(), see below */
+#define _GNU_SOURCE
+
+#include "config.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <pwd.h>
+
+#include "polkitauthenticationsession.h"
+
+struct _PolkitAuthenticationSession
+{
+ GObject parent_instance;
+
+ gchar *cookie;
+ PolkitIdentity *identity;
+
+ int child_stdin;
+ int child_stdout;
+ GPid child_pid;
+ FILE *child_stdout_f;
+
+ int child_watch_id;
+ int io_watch_id;
+
+ 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;
+ void *user_data;
+};
+
+struct _PolkitAuthenticationSessionClass
+{
+ GObjectClass parent_class;
+
+};
+
+G_DEFINE_TYPE (PolkitAuthenticationSession, polkit_authentication_session, G_TYPE_OBJECT);
+
+static void
+polkit_authentication_session_init (PolkitAuthenticationSession *session)
+{
+}
+
+static void
+polkit_authentication_session_finalize (GObject *object)
+{
+ PolkitAuthenticationSession *session;
+
+ session = POLKIT_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);
+}
+
+static void
+polkit_authentication_session_class_init (PolkitAuthenticationSessionClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = polkit_authentication_session_finalize;
+
+
+
+}
+
+PolkitAuthenticationSession *
+polkit_authentication_session_new (PolkitIdentity *identity,
+ const gchar *cookie)
+{
+ PolkitAuthenticationSession *session;
+
+ session = POLKIT_AUTHENTICATION_SESSION (g_object_new (POLKIT_TYPE_AUTHENTICATION_SESSION, NULL));
+
+ session->identity = g_object_ref (identity);
+ session->cookie = g_strdup (cookie);
+
+ return session;
+}
+
+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)
+{
+ session->func_prompt_echo_off = func_prompt_echo_off;
+ session->func_prompt_echo_on = func_prompt_echo_on;
+ session->func_error_message = func_error_message;
+ session->func_text_info = func_text_info;
+ session->func_done = func_done;
+ session->user_data = user_data;
+}
+
+static void
+child_watch_func (GPid pid, gint status, gpointer user_data)
+{
+ PolkitAuthenticationSession *session = POLKIT_AUTHENTICATION_SESSION (user_data);
+ gint exit_code;
+ gboolean input_was_bogus;
+
+ g_return_if_fail (session->helper_is_running);
+
+ exit_code = WEXITSTATUS (status);
+
+ g_debug ("pid %d terminated", pid);
+ waitpid (pid, &status, 0);
+
+ if (exit_code >= 2)
+ input_was_bogus = TRUE;
+ else
+ input_was_bogus = FALSE;
+
+ session->success = (exit_code == 0);
+ session->helper_is_running = FALSE;
+ session->func_done (session, session->success, input_was_bogus, session->user_data);
+}
+
+static gboolean
+io_watch_have_data (GIOChannel *channel, GIOCondition condition, gpointer user_data)
+{
+ PolkitAuthenticationSession *session = POLKIT_AUTHENTICATION_SESSION (user_data);
+ char *line;
+ size_t line_len;
+ gchar *id;
+ size_t id_len;
+ gchar *response;
+ gchar *response_prefix;
+ int fd;
+
+ g_return_val_if_fail (session->helper_is_running, FALSE);
+
+ fd = g_io_channel_unix_get_fd (channel);
+
+ line = NULL;
+ line_len = 0;
+
+ /* TODO: getline is GNU only, see kit_getline() in old polkit */
+ while (getline (&line, &line_len, session->child_stdout_f) != -1)
+ {
+ if (strlen (line) > 0 && line[strlen (line) - 1] == '\n')
+ line[strlen (line) - 1] = '\0';
+
+ response = NULL;
+ response_prefix = NULL;
+
+ id = "PAM_PROMPT_ECHO_OFF ";
+ if (g_str_has_prefix (line, id))
+ {
+ id_len = strlen (id);
+ response_prefix = "";
+ response = session->func_prompt_echo_off (session,
+ line + id_len,
+ session->user_data);
+ goto processed;
+ }
+
+ id = "PAM_PROMPT_ECHO_ON ";
+ if (g_str_has_prefix (line, id))
+ {
+ id_len = strlen (id);
+ response_prefix = "";
+ response = session->func_prompt_echo_on (session,
+ line + id_len,
+ session->user_data);
+ goto processed;
+ }
+
+ id = "PAM_ERROR_MSG ";
+ if (g_str_has_prefix (line, id))
+ {
+ id_len = strlen (id);
+ session->func_error_message (session,
+ line + id_len,
+ session->user_data);
+ goto processed;
+ }
+
+ id = "PAM_TEXT_INFO ";
+ if (g_str_has_prefix (line, id))
+ {
+ id_len = strlen (id);
+ session->func_text_info (session,
+ line + id_len,
+ session->user_data);
+ goto processed;
+ }
+
+ processed:
+ if (response != NULL && response_prefix != NULL)
+ {
+ char *buf;
+ gboolean add_newline;
+
+ /* add a newline if there isn't one already... */
+ add_newline = FALSE;
+ if (response[strlen (response) - 1] != '\n')
+ {
+ add_newline = TRUE;
+ }
+ buf = g_strdup_printf ("%s%s%c",
+ response_prefix,
+ response,
+ add_newline ? '\n' : '\0');
+ write (session->child_stdin, buf, strlen (buf));
+ g_free (buf);
+ g_free (response);
+ }
+ }
+
+ if (line != NULL)
+ free (line);
+
+ return FALSE;
+}
+
+gboolean
+polkit_authentication_session_initiate_auth (PolkitAuthenticationSession *session)
+{
+ uid_t uid;
+ GError *error;
+ gchar *helper_argv[4];
+ GIOChannel *channel;
+ gboolean ret;
+ struct passwd *passwd;
+
+ ret = FALSE;
+
+ /* TODO: also support authorization for other kinds of identities */
+ if (!POLKIT_IS_UNIX_USER (session->identity))
+ {
+ g_warning ("Unsupported identity type");
+ goto error;
+ }
+
+ uid = polkit_unix_user_get_uid (POLKIT_UNIX_USER (session->identity));
+
+ passwd = getpwuid (uid);
+ if (passwd == NULL)
+ {
+ g_warning ("No user with uid %d", uid);
+ goto error;
+ }
+
+ helper_argv[0] = PACKAGE_LIBEXEC_DIR "/polkit-session-helper-1";
+ helper_argv[1] = passwd->pw_name;
+ helper_argv[2] = session->cookie;
+ helper_argv[3] = NULL;
+
+ session->child_stdin = -1;
+ session->child_stdout = -1;
+
+ error = NULL;
+ if (!g_spawn_async_with_pipes (NULL,
+ (char **) helper_argv,
+ NULL,
+ G_SPAWN_DO_NOT_REAP_CHILD |
+ 0,//G_SPAWN_STDERR_TO_DEV_NULL,
+ NULL,
+ NULL,
+ &session->child_pid,
+ &session->child_stdin,
+ &session->child_stdout,
+ NULL,
+ &error))
+ {
+ g_warning ("Cannot spawn helper: %s\n", error->message);
+ g_error_free (error);
+ goto error;
+ }
+
+ session->child_watch_id = g_child_watch_add (session->child_pid, child_watch_func, session);
+
+ channel = g_io_channel_unix_new (session->child_stdout);
+ session->io_watch_id = g_io_add_watch (channel, G_IO_IN, io_watch_have_data, session);
+ g_io_channel_unref (channel);
+
+ /* so we can use getline... */
+ session->child_stdout_f = fdopen (session->child_stdout, "r");
+
+ session->success = FALSE;
+
+ session->helper_is_running = TRUE;
+
+ ret = TRUE;
+
+error:
+
+ return ret;
+}
+
+
+void
+polkit_authentication_session_cancel (PolkitAuthenticationSession *session)
+{
+ GPid pid;
+
+ g_return_if_fail (session->helper_is_running);
+
+ pid = session->child_pid;
+ session->child_pid = 0;
+ if (pid > 0)
+ {
+ int status;
+ kill (pid, SIGTERM);
+ waitpid (pid, &status, 0);
+ session->helper_is_running = FALSE;
+ }
+ session->func_done (session, FALSE, FALSE, session->user_data);
+}
--- /dev/null
+/*
+ * 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 */