[Xfce4-commits] [xfce/xfce4-power-manager] 01/01: Use pkexec for pm-helper (Bug 10943)
noreply at xfce.org
noreply at xfce.org
Sat Aug 9 21:28:34 CEST 2014
This is an automated email from the git hooks/post-receive script.
eric pushed a commit to branch master
in repository xfce/xfce4-power-manager.
commit 9ec0514fd9972373c1875ff3b80054145a445d9f
Author: Eric Koegel <eric.koegel at gmail.com>
Date: Sat Aug 9 22:21:56 2014 +0300
Use pkexec for pm-helper (Bug 10943)
Switch to using pkexec instead of the sudo helper. This allows
users to use things such as fingerprint readers and other auth
methods to verify credentials. A default polkit rule is shipped
in this patch as well in the org.xfce.power.policy.
---
common/xfpm-power-common.h | 2 +
src/Makefile.am | 33 +--
src/org.xfce.power.policy.in2 | 15 ++
src/xfpm-pm-helper.c | 92 +++++---
src/xfpm-power.c | 92 +-------
src/xfpm-suspend.c | 505 +++--------------------------------------
src/xfpm-suspend.h | 50 +---
7 files changed, 145 insertions(+), 644 deletions(-)
diff --git a/common/xfpm-power-common.h b/common/xfpm-power-common.h
index 63db7ad..a18f486 100644
--- a/common/xfpm-power-common.h
+++ b/common/xfpm-power-common.h
@@ -39,6 +39,8 @@
#define POLKIT_AUTH_SUSPEND_LOGIND "org.freedesktop.login1.suspend"
#define POLKIT_AUTH_HIBERNATE_LOGIND "org.freedesktop.login1.hibernate"
+#define POLKIT_AUTH_SUSPEND_XFPM "org.xfce.power.xfce4-pm-helper"
+#define POLKIT_AUTH_HIBERNATE_XFPM "org.xfce.power.xfce4-pm-helper"
const gchar *xfpm_power_translate_device_type (guint type);
diff --git a/src/Makefile.am b/src/Makefile.am
index c758a03..6ac0b06 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,4 @@
-bin_PROGRAMS = xfce4-power-manager \
- xfce4-pm-helper
+bin_PROGRAMS = xfce4-power-manager
xfce4_power_manager_SOURCES = \
$(BUILT_SOURCES) \
@@ -45,7 +44,8 @@ xfce4_power_manager_CFLAGS = \
-I$(top_srcdir)/libdbus \
-DLOCALEDIR=\"$(localedir)\" \
-DG_LOG_DOMAIN=\"xfce4-power-manager\" \
- -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DSBINDIR=\"$(sbindir)\" \
-DUPOWER_ENABLE_DEPRECATED \
-DXFPM_SUSPEND_HELPER_CMD=\"$(prefix)/bin/xfce4-pm-helper\" \
$(GOBJECT_CFLAGS) \
@@ -77,19 +77,10 @@ xfce4_power_manager_LDADD = \
$(XRANDR_LIBS) \
$(DPMS_LIBS)
-xfce4_pm_helper_SOURCES = \
- xfpm-pm-helper.c
-
-xfce4_pm_helper_CFLAGS = \
- -I$(top_srcdir) \
- $(LIBXFCE4UTIL_CFLAGS)
-
-xfce4_pm_helper_LDFLAGS = \
- $(LIBXFCE4UTIL_LIBS)
-
if ENABLE_POLKIT
-sbin_PROGRAMS = xfpm-power-backlight-helper
+sbin_PROGRAMS = xfpm-power-backlight-helper \
+ xfce4-pm-helper
xfpm_power_backlight_helper_SOURCES = \
xfpm-backlight-helper.c
@@ -103,6 +94,20 @@ xfpm_power_backlight_helper_CFLAGS = \
$(PLATFORM_CPPFLAGS) \
$(PLATFORM_CFLAGS)
+xfce4_pm_helper_SOURCES = \
+ xfpm-pm-helper.c
+
+xfce4_pm_helper_CFLAGS = \
+ -I$(top_srcdir) \
+ $(GLIB_CFLAGS) \
+ $(PLATFORM_CPPFLAGS) \
+ $(PLATFORM_CFLAGS) \
+ $(LIBXFCE4UTIL_CFLAGS)
+
+xfce4_pm_helper_LDFLAGS = \
+ $(LIBXFCE4UTIL_LIBS) \
+ $(GLIB_LIBS)
+
polkit_policydir = $(datadir)/polkit-1/actions
polkit_policy_DATA = \
org.xfce.power.policy
diff --git a/src/org.xfce.power.policy.in2 b/src/org.xfce.power.policy.in2
index 5a05964..34cb836 100644
--- a/src/org.xfce.power.policy.in2
+++ b/src/org.xfce.power.policy.in2
@@ -28,5 +28,20 @@
<annotate key="org.freedesktop.policykit.exec.path">@sbindir@/xfpm-power-backlight-helper</annotate>
</action>
+ <action id="org.xfce.power.xfce4-pm-helper">
+ <!-- SECURITY:
+ - A normal active user on the local machine does not need permission
+ to suspend or hibernate their system.
+ -->
+ <_description>Suspend or hibernate the system</_description>
+ <_message>Authentication is required to place the system in suspend or hibernate mode</_message>
+ <defaults>
+ <allow_any>auth_admin</allow_any>
+ <allow_inactive>auth_admin</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ <annotate key="org.freedesktop.policykit.exec.path">@sbindir@/xfce4-pm-helper</annotate>
+ </action>
+
</policyconfig>
diff --git a/src/xfpm-pm-helper.c b/src/xfpm-pm-helper.c
index bbef9a1..6802094 100644
--- a/src/xfpm-pm-helper.c
+++ b/src/xfpm-pm-helper.c
@@ -51,6 +51,12 @@
#include <glib.h>
/* XXX */
+#define EXIT_CODE_SUCCESS 0
+#define EXIT_CODE_FAILED 1
+#define EXIT_CODE_ARGUMENTS_INVALID 3
+#define EXIT_CODE_INVALID_USER 4
+
+
#ifdef UP_BACKEND_SUSPEND_COMMAND
#undef UP_BACKEND_SUSPEND_COMMAND
#endif
@@ -60,7 +66,7 @@
#ifdef BACKEND_TYPE_FREEBSD
-#define UP_BACKEND_SUSPEND_COMMAND "/usr/sbin/zzz"
+#define UP_BACKEND_SUSPEND_COMMAND "/usr/sbin/acpiconf -s 3"
#define UP_BACKEND_HIBERNATE_COMMAND "/usr/sbin/acpiconf -s 4"
#endif
#ifdef BACKEND_TYPE_LINUX
@@ -69,7 +75,7 @@
#endif
#ifdef BACKEND_TYPE_OPENBSD
#define UP_BACKEND_SUSPEND_COMMAND "/usr/sbin/zzz"
-#define UP_BACKEND_HIBERNATE_COMMAND "/dev/null"
+#define UP_BACKEND_HIBERNATE_COMMAND "/usr/sbin/ZZZ"
#endif
@@ -125,34 +131,66 @@ run (const gchar *command)
int
main (int argc, char **argv)
{
- gboolean succeed = FALSE;
- char action[1024];
-
- /* display banner */
- fprintf (stdout, "XFPM_SUDO_DONE ");
- fflush (stdout);
-
- if (fgets (action, 1024, stdin) == NULL)
- {
- fprintf (stdout, "FAILED\n");
- return EXIT_FAILURE;
- }
-
- if (strncasecmp (action, "SUSPEND", 7) == 0)
+ GOptionContext *context;
+ gint uid;
+ gint euid;
+ const gchar *pkexec_uid_str;
+ gboolean suspend = FALSE;
+ gboolean hibernate = FALSE;
+
+ const GOptionEntry options[] = {
+ { "suspend", '\0', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &suspend, "Suspend the system", NULL },
+ { "hibernate", '\0', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &hibernate, "Hibernate the system", NULL },
+ { NULL }
+ };
+
+ context = g_option_context_new (NULL);
+ g_option_context_set_summary (context, "XFCE Power Management Helper");
+ g_option_context_add_main_entries (context, options, NULL);
+ g_option_context_parse (context, &argc, &argv, NULL);
+ g_option_context_free (context);
+
+ /* no input */
+ if (!suspend && !hibernate) {
+ puts ("No valid option was specified");
+ return EXIT_CODE_ARGUMENTS_INVALID;
+ }
+
+ /* get calling process */
+ uid = getuid ();
+ euid = geteuid ();
+ if (uid != 0 || euid != 0) {
+ puts ("This program can only be used by the root user");
+ return EXIT_CODE_ARGUMENTS_INVALID;
+ }
+
+ /* check we're not being spoofed */
+ pkexec_uid_str = g_getenv ("PKEXEC_UID");
+ if (pkexec_uid_str == NULL) {
+ puts ("This program must only be run through pkexec");
+ return EXIT_CODE_INVALID_USER;
+ }
+
+ /* run the command */
+ if(suspend)
+ {
+ if (run (UP_BACKEND_SUSPEND_COMMAND))
{
- succeed = run (UP_BACKEND_SUSPEND_COMMAND);
+ return EXIT_CODE_SUCCESS;
+ } else {
+ return EXIT_CODE_FAILED;
}
- else if (strncasecmp (action, "HIBERNATE", 9) == 0)
- {
- succeed = run (UP_BACKEND_HIBERNATE_COMMAND);
- }
-
- if (succeed)
+ }
+ else if (hibernate)
+ {
+ if(run (UP_BACKEND_HIBERNATE_COMMAND))
{
- fprintf (stdout, "SUCCEED\n");
- return EXIT_SUCCESS;
+ return EXIT_CODE_SUCCESS;
+ } else {
+ return EXIT_CODE_FAILED;
}
+ }
- fprintf (stdout, "FAILED\n");
- return EXIT_FAILURE;
+ /* how did we get here? */
+ return EXIT_CODE_FAILED;
}
diff --git a/src/xfpm-power.c b/src/xfpm-power.c
index df44cf5..5535f77 100644
--- a/src/xfpm-power.c
+++ b/src/xfpm-power.c
@@ -84,9 +84,6 @@ static void xfpm_update_blank_time (XfpmPower *power);
static void xfpm_power_dbus_class_init (XfpmPowerClass * klass);
static void xfpm_power_dbus_init (XfpmPower *power);
-#if UP_CHECK_VERSION(0, 99, 0)
-static gboolean xfpm_power_prompt_password (XfpmPower *power);
-#endif
#define XFPM_POWER_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), XFPM_TYPE_POWER, XfpmPowerPrivate))
@@ -123,8 +120,6 @@ struct XfpmPowerPrivate
gboolean auth_suspend;
gboolean auth_hibernate;
- XfpmSuspend *suspend;
-
/* Properties */
gboolean on_low_battery;
gboolean lid_is_present;
@@ -186,8 +181,13 @@ xfpm_power_check_polkit_auth (XfpmPower *power)
}
else
{
+#if !UP_CHECK_VERSION(0, 99, 0)
suspend = POLKIT_AUTH_SUSPEND_UPOWER;
hibernate = POLKIT_AUTH_HIBERNATE_UPOWER;
+#else
+ suspend = POLKIT_AUTH_SUSPEND_XFPM;
+ hibernate = POLKIT_AUTH_HIBERNATE_XFPM;
+#endif
}
power->priv->auth_suspend = xfpm_polkit_check_auth (power->priv->polkit,
suspend);
@@ -338,22 +338,6 @@ xfpm_power_sleep (XfpmPower *power, const gchar *sleep_time, gboolean force)
return;
}
-/* Upower dropped support for doing anything power related */
-#if UP_CHECK_VERSION(0, 99, 0)
- if ( !LOGIND_RUNNING () )
- {
- /* See if we require a password for sudo to call suspend */
- if ( xfpm_suspend_password_required (power->priv->suspend) )
- {
- if ( !xfpm_power_prompt_password (power) )
- {
- xfpm_power_report_error (power, _("Incorrect password entered"), "dialog-error");
- return;
- }
- }
- }
-#endif
-
g_signal_emit (G_OBJECT (power), signals [SLEEPING], 0);
/* Get the current brightness level so we can use it after we suspend */
brightness = xfpm_brightness_new();
@@ -419,13 +403,11 @@ xfpm_power_sleep (XfpmPower *power, const gchar *sleep_time, gboolean force)
#else
if (!g_strcmp0 (sleep_time, "Hibernate"))
{
- if (xfpm_suspend_sudo_get_state (power->priv->suspend) == SUDO_AVAILABLE)
- xfpm_suspend_sudo_try_action (power->priv->suspend, XFPM_HIBERNATE, &error);
+ xfpm_suspend_try_action (XFPM_HIBERNATE);
}
else
{
- if (xfpm_suspend_sudo_get_state (power->priv->suspend) == SUDO_AVAILABLE)
- xfpm_suspend_sudo_try_action (power->priv->suspend, XFPM_SUSPEND, &error);
+ xfpm_suspend_try_action (XFPM_SUSPEND);
}
#endif
}
@@ -1132,7 +1114,6 @@ xfpm_power_init (XfpmPower *power)
power->priv->presentation_mode = FALSE;
power->priv->on_ac_blank = 15;
power->priv->on_battery_blank = 10;
- power->priv->suspend = xfpm_suspend_get ();
power->priv->inhibit = xfpm_inhibit_new ();
power->priv->notify = xfpm_notify_new ();
@@ -1420,65 +1401,6 @@ xfpm_power_is_in_presentation_mode (XfpmPower *power)
return power->priv->presentation_mode;
}
-/* ifdef this out to prevent an unused function warning */
-#if UP_CHECK_VERSION(0, 99, 0)
-static gboolean
-xfpm_power_prompt_password (XfpmPower *power)
-{
- GtkWidget *dialog = gtk_message_dialog_new (NULL,
- GTK_DIALOG_MODAL,
- GTK_MESSAGE_OTHER,
- GTK_BUTTONS_OK_CANCEL,
- _("The requested operation requires elevated privileges.\n"
- "Please enter your password."));
- GtkWidget *content_area = gtk_dialog_get_content_area (GTK_DIALOG(dialog));
- GtkWidget *password_entry = gtk_entry_new ();
- GtkWidget *password_label, *hbox;
- gint result;
- XfpmPassState state = PASSWORD_FAILED;
-
- /* Set the dialog's title */
- gtk_window_set_title (GTK_WINDOW(dialog), _("xfce4-power-manager"));
-
- /* setup password label */
- password_label = gtk_label_new (_("Password:"));
-
- /* Setup the password entry */
- gtk_entry_set_visibility (GTK_ENTRY (password_entry), FALSE);
- gtk_entry_set_max_length (GTK_ENTRY (password_entry), 1024);
- gtk_entry_set_activates_default (GTK_ENTRY (password_entry), TRUE);
-
- /* pack the password label and entry into an hbox */
- hbox = gtk_hbox_new (FALSE, 4);
- gtk_box_pack_start (GTK_BOX (hbox), password_label, FALSE, FALSE, 4);
- gtk_box_pack_end (GTK_BOX (hbox), password_entry, TRUE, TRUE, 4);
-
- /* Add it to the dialog */
- gtk_box_pack_end (GTK_BOX (content_area), hbox, TRUE, TRUE, 8);
-
- /* show it */
- gtk_widget_show (password_entry);
- gtk_widget_show (password_label);
- gtk_widget_show (hbox);
-
- /* make enter default to ok */
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-
- /* Run the password prompt */
- result = gtk_dialog_run (GTK_DIALOG(dialog));
-
- if (result == GTK_RESPONSE_OK)
- {
- state = xfpm_suspend_sudo_send_password (power->priv->suspend, gtk_entry_get_text (GTK_ENTRY (password_entry)));
- XFPM_DEBUG ("password state: %s", state == PASSWORD_FAILED ? "PASSWORD_FAILED" : "PASSWORD_SUCCEED");
- }
-
- gtk_widget_destroy (dialog);
-
- return state == PASSWORD_FAILED ? FALSE : TRUE;
-}
-#endif
-
/*
*
diff --git a/src/xfpm-suspend.c b/src/xfpm-suspend.c
index 63f4bf6..d7f460d 100644
--- a/src/xfpm-suspend.c
+++ b/src/xfpm-suspend.c
@@ -48,474 +48,6 @@
#include "xfpm-suspend.h"
-static void xfpm_suspend_sudo_free (XfpmSuspend *suspend);
-
-static void xfpm_suspend_sudo_childwatch (GPid pid,
- gint status,
- gpointer data);
-
-static gboolean xfpm_suspend_sudo_init (XfpmSuspend *suspend,
- GError **error);
-
-
-#define XFPM_SUSPEND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), XFPM_TYPE_SUSPEND, XfpmSuspendPrivate))
-
-struct XfpmSuspendPrivate
-{
- /* sudo helper */
- HelperState helper_state;
- pid_t helper_pid;
- FILE *helper_infile;
- FILE *helper_outfile;
- guint helper_watchid;
- gboolean helper_require_password;
-};
-
-
-G_DEFINE_TYPE (XfpmSuspend, xfpm_suspend, G_TYPE_OBJECT)
-
-static void
-xfpm_suspend_init (XfpmSuspend *suspend)
-{
- GError *error = NULL;
-
- suspend->priv = XFPM_SUSPEND_GET_PRIVATE (suspend);
- suspend->priv->helper_state = SUDO_NOT_INITIAZED;
- suspend->priv->helper_require_password = FALSE;
- suspend->priv->helper_infile = NULL;
- suspend->priv->helper_outfile = NULL;
- suspend->priv->helper_pid = 0;
- suspend->priv->helper_watchid = 0;
-
- if (!xfpm_suspend_sudo_init (suspend, &error))
- {
- g_warning ("xfpm_suspend_sudo_init failed : %s", error->message);
- g_error_free (error);
- }
-}
-
-static void
-xfpm_suspend_finalize (GObject *object)
-{
- XfpmSuspend *suspend = XFPM_SUSPEND (object);
-
- /* close down helper */
- xfpm_suspend_sudo_free (suspend);
-
- G_OBJECT_CLASS (xfpm_suspend_parent_class)->finalize (object);
-}
-
-static void
-xfpm_suspend_class_init (XfpmSuspendClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = xfpm_suspend_finalize;
-
- g_type_class_add_private (klass, sizeof (XfpmSuspendPrivate));
-}
-
-XfpmSuspend *
-xfpm_suspend_get (void)
-{
- static gpointer xfpm_suspend_object = NULL;
-
- if ( G_LIKELY (xfpm_suspend_object != NULL ) )
- {
- g_object_ref (xfpm_suspend_object);
- }
- else
- {
- xfpm_suspend_object = g_object_new (XFPM_TYPE_SUSPEND, NULL);
- g_object_add_weak_pointer (xfpm_suspend_object, &xfpm_suspend_object);
- }
-
- return XFPM_SUSPEND (xfpm_suspend_object);
-}
-
-static void
-xfpm_suspend_sudo_free (XfpmSuspend *suspend)
-{
- gint status;
-
- /* close down helper */
- if (suspend->priv->helper_infile != NULL)
- {
- fclose (suspend->priv->helper_infile);
- suspend->priv->helper_infile = NULL;
- }
-
- if (suspend->priv->helper_outfile != NULL)
- {
- fclose (suspend->priv->helper_outfile);
- suspend->priv->helper_outfile = NULL;
- }
-
- if (suspend->priv->helper_watchid > 0)
- {
- g_source_remove (suspend->priv->helper_watchid);
- suspend->priv->helper_watchid = 0;
- }
-
- if (suspend->priv->helper_pid > 0)
- {
- waitpid (suspend->priv->helper_pid, &status, 0);
- suspend->priv->helper_pid = 0;
- }
-
- /* reset state */
- suspend->priv->helper_state = SUDO_NOT_INITIAZED;
-}
-
-static void
-xfpm_suspend_sudo_childwatch (GPid pid,
- gint status,
- gpointer data)
-{
- /* close down sudo stuff */
- xfpm_suspend_sudo_free (XFPM_SUSPEND (data));
-}
-
-static gboolean
-xfpm_suspend_sudo_init (XfpmSuspend *suspend,
- GError **error)
-{
- gchar *cmd;
-#ifdef HAVE_SYS_RESOURCE_H
- struct rlimit rlp;
-#endif
- gchar buf[15];
- gint parent_pipe[2];
- gint child_pipe[2];
- gint n;
-
- /* return state if we succeeded */
- if (suspend->priv->helper_state != SUDO_NOT_INITIAZED)
- return suspend->priv->helper_state == SUDO_AVAILABLE;
-
- g_return_val_if_fail (suspend->priv->helper_infile == NULL, FALSE);
- g_return_val_if_fail (suspend->priv->helper_outfile == NULL, FALSE);
- g_return_val_if_fail (suspend->priv->helper_watchid == 0, FALSE);
- g_return_val_if_fail (suspend->priv->helper_pid == 0, FALSE);
-
- /* assume it won't work for now */
- suspend->priv->helper_state = SUDO_FAILED;
-
- cmd = g_find_program_in_path ("sudo");
- if (G_UNLIKELY (cmd == NULL))
- {
- g_set_error_literal (error, 1, 0,
- "The program \"sudo\" was not found");
- return FALSE;
- }
-
- if (pipe (parent_pipe) == -1)
- {
- g_set_error (error, 1, 0,
- "Unable to create parent pipe: %s",
- strerror (errno));
- goto err0;
- }
-
- if (pipe (child_pipe) == -1)
- {
- g_set_error (error, 1, 0,
- "Unable to create child pipe: %s",
- strerror (errno));
- goto err1;
- }
-
- suspend->priv->helper_pid = fork ();
- if (suspend->priv->helper_pid < 0)
- {
- g_set_error (error, 1, 0,
- "Unable to fork sudo helper: %s",
- strerror (errno));
- goto err2;
- }
- else if (suspend->priv->helper_pid == 0)
- {
- /* setup signals */
- signal (SIGPIPE, SIG_IGN);
-
- /* setup environment */
- g_setenv ("LC_ALL", "C", TRUE);
- g_setenv ("LANG", "C", TRUE);
- g_setenv ("LANGUAGE", "C", TRUE);
-
- /* setup the 3 standard file handles */
- dup2 (child_pipe[0], STDIN_FILENO);
- dup2 (parent_pipe[1], STDOUT_FILENO);
- dup2 (parent_pipe[1], STDERR_FILENO);
-
-#ifdef HAVE_SYS_RESOURCE_H
- /* close all other file handles */
- getrlimit (RLIMIT_NOFILE, &rlp);
- for (n = 0; n < (gint) rlp.rlim_cur; ++n)
- {
- if (n != STDIN_FILENO && n != STDOUT_FILENO && n != STDERR_FILENO)
- close (n);
- }
-#endif
-
- /* execute sudo with the helper */
- execl (cmd, "sudo", "-H", "-S", "-p",
- "XFPM_SUDO_PASS ", "--",
- XFPM_SUSPEND_HELPER_CMD, NULL);
-
- g_free (cmd);
- cmd = NULL;
-
- _exit (127);
- }
- else
- {
- /* watch the sudo helper */
- suspend->priv->helper_watchid = g_child_watch_add (suspend->priv->helper_pid,
- xfpm_suspend_sudo_childwatch,
- suspend);
- }
-
- /* read sudo/helper answer */
- n = read (parent_pipe[0], buf, sizeof (buf));
- if (n < 15)
- {
- g_set_error (error, 1, 0,
- "Unable to read response from sudo helper: %s",
- n < 0 ? strerror (errno) : "Unknown error");
- goto err2;
- }
-
- /* open pipe to receive replies from sudo */
- suspend->priv->helper_infile = fdopen (parent_pipe[0], "r");
- if (suspend->priv->helper_infile == NULL)
- {
- g_set_error (error, 1, 0,
- "Unable to open parent pipe: %s",
- strerror (errno));
- goto err2;
- }
- close (parent_pipe[1]);
-
- /* open pipe to send passwords to sudo */
- suspend->priv->helper_outfile = fdopen (child_pipe[1], "w");
- if (suspend->priv->helper_outfile == NULL)
- {
- g_set_error (error, 1, 0,
- "Unable to open parent pipe: %s",
- strerror (errno));
- goto err2;
- }
- close (child_pipe[0]);
-
- /* check if NOPASSWD is set in /etc/sudoers */
- if (memcmp (buf, "XFPM_SUDO_PASS ", 15) == 0)
- {
- suspend->priv->helper_require_password = TRUE;
- }
- else if (memcmp (buf, "XFPM_SUDO_DONE ", 15) == 0)
- {
- suspend->priv->helper_require_password = FALSE;
- }
- else
- {
- g_set_error (error, 1, 0,
- "Got unexpected reply from sudo pm helper");
- goto err2;
- }
-
- XFPM_DEBUG ("suspend->priv->helper_require_password %s",
- suspend->priv->helper_require_password ? "Required" : "Not required");
-
- /* if we try again */
- suspend->priv->helper_state = SUDO_AVAILABLE;
-
- return TRUE;
-
-err2:
- xfpm_suspend_sudo_free (suspend);
-
- close (child_pipe[0]);
- close (child_pipe[1]);
-
-err1:
- close (parent_pipe[0]);
- close (parent_pipe[1]);
-
-err0:
- g_free (cmd);
-
- suspend->priv->helper_pid = 0;
-
- return FALSE;
-}
-
-gboolean
-xfpm_suspend_sudo_try_action (XfpmSuspend *suspend,
- XfpmActionType type,
- GError **error)
-{
- const gchar *action;
- gchar reply[256];
-
- TRACE("entering");
-
- g_return_val_if_fail (suspend->priv->helper_state == SUDO_AVAILABLE, FALSE);
- g_return_val_if_fail (suspend->priv->helper_outfile != NULL, FALSE);
- g_return_val_if_fail (suspend->priv->helper_infile != NULL, FALSE);
-
- /* the command we send to sudo */
- if (type == XFPM_SUSPEND)
- action = "SUSPEND";
- else if (type == XFPM_HIBERNATE)
- action = "HIBERNATE";
- else
- return FALSE;
-
- /* write action to sudo helper */
- if (fprintf (suspend->priv->helper_outfile, "%s\n", action) > 0)
- fflush (suspend->priv->helper_outfile);
-
- /* check if the write succeeded */
- if (ferror (suspend->priv->helper_outfile) != 0)
- {
- /* probably succeeded but the helper got killed */
- if (errno == EINTR)
- return TRUE;
-
- g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
- _("Error sending command to pm helper: %s"),
- strerror (errno));
- return FALSE;
- }
-
- /* get responce from sudo helper */
- if (fgets (reply, sizeof (reply), suspend->priv->helper_infile) == NULL)
- {
- /* probably succeeded but the helper got killed */
- if (errno == EINTR)
- return TRUE;
-
- g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
- _("Error receiving response from pm helper: %s"),
- strerror (errno));
- return FALSE;
- }
-
- if (strncmp (reply, "SUCCEED", 7) != 0)
- {
- g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
- _("Sleep command failed"));
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-XfpmPassState
-xfpm_suspend_sudo_send_password (XfpmSuspend *suspend,
- const gchar *password)
-{
- gchar buf[1024];
- gsize len_buf, len_send;
- gint fd;
- gsize len;
- gssize result;
- gint attempts;
- const gchar *errmsg = NULL;
-
- g_return_val_if_fail (suspend->priv->helper_state == SUDO_AVAILABLE, PASSWORD_FAILED);
- g_return_val_if_fail (suspend->priv->helper_outfile != NULL, PASSWORD_FAILED);
- g_return_val_if_fail (suspend->priv->helper_infile != NULL, PASSWORD_FAILED);
- g_return_val_if_fail (suspend->priv->helper_require_password, PASSWORD_FAILED);
- g_return_val_if_fail (password != NULL, PASSWORD_FAILED);
-
- /* write password to sudo helper */
- g_snprintf (buf, sizeof (buf), "%s\n", password);
- len_buf = strlen (buf);
- len_send = fwrite (buf, 1, len_buf, suspend->priv->helper_outfile);
- fflush (suspend->priv->helper_outfile);
- bzero (buf, len_buf);
-
- if (len_send != len_buf || ferror (suspend->priv->helper_outfile) != 0)
- {
- errmsg = "Failed to send password to sudo";
- goto err1;
- }
-
- fd = fileno (suspend->priv->helper_infile);
-
- for (len = 0, attempts = 0;;)
- {
- result = read (fd, buf + len, 256 - len);
-
- if (result < 0)
- {
- errmsg = "Failed to read data from sudo";
- goto err1;
- }
- else if (result == 0)
- {
- /* don't try too often */
- if (++attempts > 20)
- {
- errmsg = "Too many password attempts";
- goto err1;
- }
-
- continue;
- }
- else if (result + len >= sizeof (buf))
- {
- errmsg = "Received too much data from sudo";
- goto err1;
- }
-
- len += result;
- buf[len] = '\0';
-
- if (len >= 15)
- {
- if (g_str_has_suffix (buf, "XFPM_SUDO_PASS "))
- {
- return PASSWORD_RETRY;
- }
- else if (g_str_has_suffix (buf, "XFPM_SUDO_DONE "))
- {
- /* sudo is unlocked, no further passwords required */
- suspend->priv->helper_require_password = FALSE;
-
- return PASSWORD_SUCCEED;
- }
- }
- }
-
- return PASSWORD_FAILED;
-
-err1:
- g_printerr (PACKAGE_NAME ": %s.\n\n", errmsg);
- return PASSWORD_FAILED;
-}
-
-gboolean
-xfpm_suspend_password_required (XfpmSuspend *suspend)
-{
- g_return_val_if_fail (XFPM_IS_SUSPEND (suspend), TRUE);
-
- return suspend->priv->helper_require_password;
-}
-
-HelperState
-xfpm_suspend_sudo_get_state (XfpmSuspend *suspend)
-{
- g_return_val_if_fail (XFPM_IS_SUSPEND (suspend), SUDO_NOT_INITIAZED);
-
- return suspend->priv->helper_state;
-}
-
-
-
#ifdef BACKEND_TYPE_FREEBSD
static gchar *
@@ -627,8 +159,43 @@ xfpm_suspend_can_hibernate (void)
return linux_supports_sleep_state ("hibernate");
#endif
#ifdef BACKEND_TYPE_OPENBSD
- return FALSE;
+ return TRUE;
#endif
return FALSE;
}
+
+gboolean
+xfpm_suspend_try_action (XfpmActionType type)
+{
+ const gchar *action;
+ gboolean ret;
+ GError *error = NULL;
+ gint exit_status = 0;
+ gchar *command = NULL;
+
+ TRACE("entering");
+
+ if (type == XFPM_SUSPEND)
+ action = "suspend";
+ else if (type == XFPM_HIBERNATE)
+ action = "hibernate";
+ else
+ return FALSE;
+
+ command = g_strdup_printf ("pkexec " SBINDIR "/xfce4-pm-helper --%s", action);
+ ret = g_spawn_command_line_sync (command, NULL, NULL, &exit_status, &error);
+ if ( !ret )
+ {
+ g_warning ("xfce4-pm-helper: failed to suspend/hibernate: %s", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ XFPM_DEBUG ("executed %s; retval: %i", command, exit_status);
+ ret = (exit_status == 0);
+ }
+
+ g_free (command);
+ return ret;
+}
diff --git a/src/xfpm-suspend.h b/src/xfpm-suspend.h
index f012e69..02dfa47 100644
--- a/src/xfpm-suspend.h
+++ b/src/xfpm-suspend.h
@@ -22,32 +22,6 @@
#include <glib-object.h>
-G_BEGIN_DECLS
-
-#define XFPM_TYPE_SUSPEND (xfpm_suspend_get_type () )
-#define XFPM_SUSPEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XFPM_TYPE_SUSPEND, XfpmSuspend))
-#define XFPM_IS_SUSPEND(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XFPM_TYPE_SUSPEND))
-
-typedef struct XfpmSuspendPrivate XfpmSuspendPrivate;
-
-typedef struct
-{
- GObject parent;
- XfpmSuspendPrivate *priv;
-} XfpmSuspend;
-
-typedef struct
-{
- GObjectClass parent_class;
-} XfpmSuspendClass;
-
-typedef enum
-{
- SUDO_NOT_INITIAZED,
- SUDO_AVAILABLE,
- SUDO_FAILED
-} HelperState;
-
typedef enum
{
XFPM_ASK_0 = 0,
@@ -55,31 +29,9 @@ typedef enum
XFPM_HIBERNATE,
} XfpmActionType;
-typedef enum
-{
- PASSWORD_RETRY,
- PASSWORD_SUCCEED,
- PASSWORD_FAILED
-} XfpmPassState;
-
-GType xfpm_suspend_get_type (void) G_GNUC_CONST;
-
-XfpmSuspend *xfpm_suspend_get (void);
-
gboolean xfpm_suspend_can_suspend (void);
gboolean xfpm_suspend_can_hibernate (void);
-gboolean xfpm_suspend_password_required (XfpmSuspend *suspend);
-
-gboolean xfpm_suspend_sudo_try_action (XfpmSuspend *suspend,
- XfpmActionType type,
- GError **error);
-
-XfpmPassState xfpm_suspend_sudo_send_password (XfpmSuspend *suspend,
- const gchar *password);
-
-HelperState xfpm_suspend_sudo_get_state (XfpmSuspend *suspend);
-
-G_END_DECLS
+gboolean xfpm_suspend_try_action (XfpmActionType type);
#endif /* __XFPM_SUSPEND_H */
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the Xfce4-commits
mailing list