patches/gnome-system-tools-02-forkpty.diff
author rohinis
Tue, 29 Nov 2011 17:32:55 +0000
branchs11express-2010-11
changeset 22234 c23e64da3e06
parent 15569 f5ee708e987d
child 21149 fa4e4a07e832
child 21308 9a98b77f065c
permissions -rw-r--r--
2011-11-29 Rohini S <[email protected]> * patches/Python26-22-audio.diff: Fixes CVE-2010-1634 * specs/SUNWPython26.spec: Fixes CR 7085446

--- gnome-system-tools-2.14.0.orig/src/common/gst-auth.c	2006-01-31 06:40:32.000000000 +0800
+++ gnome-system-tools-2.14.0/src/common/gst-auth.c	2008-12-12 14:10:17.161439000 +0800
@@ -43,16 +43,30 @@
 #ifdef __FreeBSD__
 # include <errno.h>
 # include <libutil.h>
+#elif defined(__sun)
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/stream.h>
+#include <sys/stropts.h>
 #else
 #include <pty.h>
 #endif
 
+#include <gksu.h>
+#include <gksuui-dialog.h>
+
 #include "gst-auth.h"
 #include "gst-tool.h"
 #include "gst-platform.h"
 
 #define GST_AUTH_RESPONSE_NP 1
 
+#ifdef __sun
+#define EMBEDDED_SU "/usr/lib/embedded_su"
+#endif /* __sun */
+
 static int root;			/* if we are root, no password is
 					   required */
 
@@ -118,6 +132,122 @@
 	return TRUE;	
 }
 
+#ifdef __sun
+/* forkpty() rmplacement for Solaris.
+ * This ignore the last two arguments
+ * for the moment
+ */
+#ifdef NOPTY
+/*
+ * This is implemented using pipes instead of pseudo tty to avoid
+ * bug 4907342.
+ */
+static
+int forkpty (int *amaster, char *name, void *unused1, void *unused2)
+{
+	pid_t pid;
+	int pp[2];
+
+	pipe (pp);
+	pid = fork ();
+	switch (pid)
+	{
+	case -1: /* Error */
+		return -1;
+	case 0: /* Child */
+		if (setsid() < 0)
+			return -1;
+		close (pp[1]);
+		dup2 (pp[0], 0);
+		return 0;
+	default: /* Parent */
+		close (pp[0]);
+		*amaster = pp[1];
+		return pid;
+	}
+
+	return -1;
+}
+#else
+int forkpty (int *amaster, char *name, void *unused1, void *unused2)
+{
+	int master, slave, fd;
+	char *slave_name;
+	pid_t pid;
+	void (*sig_saved)(int);
+
+	master = open("/dev/ptmx", O_RDWR | O_NOCTTY);
+	if (master < 0)
+		return -1;
+
+	sig_saved = signal (SIGCHLD, SIG_DFL);
+	if (grantpt (master) < 0)
+	{
+		signal (SIGCHLD, sig_saved);
+		close (master);
+		return -1;
+	}
+
+	if (unlockpt (master) < 0)
+	{
+		signal (SIGCHLD, sig_saved);
+		close (master);
+		return -1;
+	}
+	signal (SIGCHLD, sig_saved);
+
+	slave_name = ptsname (master);
+	if (slave_name == NULL)
+	{
+		close (master);
+		return -1;
+	}
+
+	slave = open (slave_name, O_RDWR | O_NOCTTY);
+	if (slave < 0)
+	{
+		close (master);
+		return -1;
+	}
+
+	if (ioctl (slave, I_PUSH, "ptem") < 0
+	    || ioctl (slave, I_PUSH, "ldterm") < 0
+	    || ioctl (slave, I_PUSH, "ttcompat") < 0)
+	{
+		close (slave);
+		close (master);
+		return -1;
+	}
+
+	if (amaster)
+		*amaster = master;
+
+	if (name)
+		strcpy (name, slave_name);
+
+	pid = fork ();
+	switch (pid)
+	{
+	case -1: /* Error */
+		return -1;
+	case 0: /* Child */
+		if (setsid() < 0)
+			return -1;
+		close (master);
+		dup2 (slave, STDIN_FILENO);
+		dup2 (slave, STDOUT_FILENO);
+		dup2 (slave, STDERR_FILENO);
+		return 0;
+	default: /* Parent */
+		close (slave);
+		return pid;
+	}
+
+	return -1;
+}
+#endif
+#endif
+
 /* runs a term with su in it */
 static void
 gst_auth_run_term (GstTool *tool, gchar *args[])
@@ -177,8 +307,15 @@
 	gchar        *s, *str;
 	gint          ret;
 
+#if defined(__sun) && defined (EMBEDDED_SU)
+        gst_tool_write_to_backend(tool, (gchar*)".\n"); /* Send empty text block to start conversation */
+#endif
 	while (!cont) {
+#if defined(__sun) && defined (EMBEDDED_SU)
+		s   = gst_tool_read_from_backend (tool, "SUCCESS", "\n.\n", NULL); /* Look for end of text block - a period (.) on a line by itself */
+#else
 		s   = gst_tool_read_from_backend (tool, "assword:", "/no)?", "\n", NULL);
+#endif /* __sun */
 		str = g_ascii_strup (s, -1);
 
 		/* FIXME: hope that someday we can get rid of this ssh output string parsing */
@@ -189,6 +326,11 @@
 			/* it's asking for the password */
 			cont = TRUE;
 			ret  = GST_AUTH_PASSWORD;
+#if defined(__sun) && defined (EMBEDDED_SU)
+		} else if (g_strrstr (str, "SUCCESS") != NULL) {
+			cont = TRUE;
+			ret  = GST_AUTH_PASSWORDLESS;
+#endif /* __sun */
 		} else if (g_strrstr (str, "\n") != NULL) {
 			/* this is the last case to test, it's the CR
 			   used to synchronize communication */
@@ -286,7 +428,77 @@
 	gchar *password;
 	gint result;
 	struct termios t;
+	GksuContext *context;
+	GError *error = NULL;
+	GtkWidget *gksuui_dialog;
+	gint response;
+	gchar *primary_text   = NULL;
+	gchar *secondary_text = NULL;
+
+
+#ifdef HAVE_GKSU
+	context = gksu_context_new ();
+#ifdef GST_DEBUG
+	gksu_context_set_debug (context, TRUE);
+#endif
+	gksu_context_set_command (context, args[3]);
+	gksu_context_set_wait_for_child_to_exit (context, FALSE);
+      	if (gksu_context_try_need_password (context) )
+	{
+	  password = NULL;
+	  gchar *pw_prompt = NULL;
+	  gksuui_dialog = gksuui_dialog_new ();
+	  gksuui_dialog_set_message (GKSUUI_DIALOG(gksuui_dialog), 
+			   /* SUN_BRANDING */
+			   g_strdup_printf(_("<b>You need %s privileges to use this tool. "
+					"Enter a password to modify your system configuration.</b>"),
+					context->user));
+	  gtk_widget_show (gksuui_dialog);
+
+	  response = gtk_dialog_run (GTK_DIALOG(gksuui_dialog));
+ 	  
+	  switch (response) {
+	  case GTK_RESPONSE_OK:
+		break;
+	  default:
+		/* Cancel */
+		exit (0);
+		break;
+	  }
+#ifdef GST_DEBUG
+	  fprintf (stderr, "response ID: %d\n", response);
+#endif	
+	  password = gksuui_dialog_get_password (GKSUUI_DIALOG(gksuui_dialog));
+	  gtk_widget_destroy ( gksuui_dialog );
+	  gksu_context_set_password (context, password);
+	}
+      
+      error = NULL;
+      gksu_context_run (context, &error);
+
+      if (error)
+	{
+	  /* SUN_BRANDING */
+	  primary_text   = g_strdup_printf (_("Authentication fails"));
+	  secondary_text = g_strdup (error->message);
+
+	  gst_auth_display_error_message (tool, primary_text, secondary_text);
+
+	  g_free (primary_text);
+	  g_free (secondary_text);
+	  exit (0);
+	}
 
+      tool->read_fd = gksu_context_get_child_stdin_fd (context);
+      tool->write_fd = gksu_context_get_child_stdout_fd (context);
+      tool->backend_pid = gksu_context_get_child_pid (context);
+      tool->timeout_id   = g_timeout_add (1000, (GSourceFunc) gst_auth_wait_child, tool);
+#ifdef GST_DEBUG
+      fprintf (stderr, "read_fd = %d, write_fd = %d\n", tool->read_fd, tool->write_fd);
+#endif
+      tool->read_stream = gksu_context_get_child_stdin_file (context);
+      tool->write_stream = gksu_context_get_child_stdout_file (context);
+#else
 	gst_auth_run_term (tool, args);
 	result = gst_auth_get_auth_required (tool);
 
@@ -296,7 +508,14 @@
 
 		if (strlen (password) > 0)
 			memset (password, 0, strlen (password));
+#if defined(__sun) && defined (EMBEDDED_SU) && 0
+                {
+                    gchar *s  = gst_tool_read_from_backend (tool, "\n.\n", "SUCCESS", "\n", NULL);
+                    g_free(s);
+                }
+#endif /* __sun */
 	}
+#endif
 
 	tool->root_access = ROOT_ACCESS_REAL;
 
@@ -368,7 +587,7 @@
 	GString *command;
 
 	command = g_string_new (NULL);
-	gst_auth_save_locale   (command);
+//	gst_auth_save_locale   (command);
 	command = g_string_append (command, tool->script_path);
 	command = g_string_append (command, " --report");
 
@@ -378,7 +597,11 @@
 	}
 
 	/* these are the su args */
+#if defined(__sun) && defined (EMBEDDED_SU)
+	su_args[0] = EMBEDDED_SU;
+#else
 	su_args[0] = SU_PATH;
+#endif /* __sun */
 	su_args[1] = "root";
 	su_args[2] = "-c";
 	su_args[3] = command->str;