[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