libgksu-2.0.12-revert-forkpty.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. diff --exclude-from=/home/dang/.scripts/diffrc -up -ruN libgksu-2.0.12.orig/libgksu/libgksu.c libgksu-2.0.12/libgksu/libgksu.c
  2. --- libgksu-2.0.12.orig/libgksu/libgksu.c 2009-06-29 13:48:24.000000000 -0400
  3. +++ libgksu-2.0.12/libgksu/libgksu.c 2010-01-12 07:32:10.450657456 -0500
  4. @@ -1,7 +1,6 @@
  5. /*
  6. * Gksu -- a library providing access to su functionality
  7. * Copyright (C) 2004-2009 Gustavo Noronha Silva
  8. - * Portions Copyright (C) 2009 VMware, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. @@ -56,9 +55,6 @@
  13. static void
  14. gksu_context_launch_complete (GksuContext *context);
  15. -static void
  16. -read_line (int fd, gchar *buffer, int n);
  17. -
  18. GType
  19. gksu_error_get_type (void)
  20. {
  21. @@ -2009,8 +2005,6 @@ gksu_su_fuller (GksuContext *context,
  22. for (i = 0 ; cmd[i] != NULL ; i++)
  23. g_free (cmd[i]);
  24. g_free(cmd);
  25. -
  26. - _exit(1);
  27. }
  28. else if (pid == -1)
  29. {
  30. @@ -2125,10 +2119,10 @@ gksu_su_fuller (GksuContext *context,
  31. /* drop the \n echoed on password entry if su did request
  32. a password */
  33. if (password_needed)
  34. - read_line (fdpty, buf, 255);
  35. + read (fdpty, buf, 255);
  36. if (context->debug)
  37. fprintf (stderr, "DEBUG (run:post-after-pass) buf: -%s-\n", buf);
  38. - read_line (fdpty, buf, 255);
  39. + read (fdpty, buf, 255);
  40. if (context->debug)
  41. fprintf (stderr, "DEBUG (run:post-after-pass) buf: -%s-\n", buf);
  42. }
  43. @@ -2142,9 +2136,7 @@ gksu_su_fuller (GksuContext *context,
  44. {
  45. int retval = 0;
  46. - /* Red Hat's su shows the full path to su in its error messages. */
  47. - if (!strncmp (buf, "su:", 3) ||
  48. - !strncmp (buf, "/bin/su:", 7))
  49. + if (!strncmp (buf, "su", 2))
  50. {
  51. gchar **strings;
  52. @@ -2155,11 +2147,7 @@ gksu_su_fuller (GksuContext *context,
  53. }
  54. strings = g_strsplit (buf, ":", 2);
  55. -
  56. - /* Red Hat and Fedora use 'incorrect password'. */
  57. - if (strings[1] &&
  58. - (g_str_has_prefix(strings[1], " Authentication failure") ||
  59. - g_str_has_prefix(strings[1], " incorrect password")))
  60. + if (strings[1] && !strncmp (strings[1], " Authentication failure", 23))
  61. {
  62. if (used_gnome_keyring)
  63. g_set_error (error, gksu_quark,
  64. @@ -2473,12 +2461,6 @@ gksu_sudo_fuller (GksuContext *context,
  65. {
  66. char **cmd;
  67. char buffer[256] = {0};
  68. - char *child_stderr = NULL;
  69. - /* This command is used to gain a token */
  70. - char *const verifycmd[] =
  71. - {
  72. - "/usr/bin/sudo", "-p", "GNOME_SUDO_PASS", "-v", NULL
  73. - };
  74. int argcount = 8;
  75. int i, j;
  76. @@ -2489,8 +2471,9 @@ gksu_sudo_fuller (GksuContext *context,
  77. pid_t pid;
  78. int status;
  79. - FILE *fdfile = NULL;
  80. - int fdpty = -1;
  81. + FILE *infile, *outfile;
  82. + int parent_pipe[2]; /* For talking to the parent */
  83. + int child_pipe[2]; /* For talking to the child */
  84. context->sudo_mode = TRUE;
  85. @@ -2565,10 +2548,6 @@ gksu_sudo_fuller (GksuContext *context,
  86. cmd[argcount] = g_strdup("-S");
  87. argcount++;
  88. - /* Make sudo noninteractive (we should already have a token) */
  89. - cmd[argcount] = g_strdup("-n");
  90. - argcount++;
  91. -
  92. /* Make sudo use next arg as prompt */
  93. cmd[argcount] = g_strdup("-p");
  94. argcount++;
  95. @@ -2647,21 +2626,26 @@ gksu_sudo_fuller (GksuContext *context,
  96. fprintf (stderr, "cmd[%d]: %s\n", i, cmd[i]);
  97. }
  98. - pid = forkpty(&fdpty, NULL, NULL, NULL);
  99. - if (pid == 0)
  100. + if ((pipe(parent_pipe)) == -1)
  101. {
  102. - // Child
  103. - setsid(); // make us session leader
  104. -
  105. - execv(verifycmd[0], verifycmd);
  106. + g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
  107. + _("Error creating pipe: %s"),
  108. + strerror(errno));
  109. + sudo_reset_xauth (context, xauth, xauth_env);
  110. + return FALSE;
  111. + }
  112. - g_set_error (error, gksu_quark, GKSU_ERROR_EXEC,
  113. - _("Failed to exec new process: %s"),
  114. + if ((pipe(child_pipe)) == -1)
  115. + {
  116. + g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
  117. + _("Error creating pipe: %s"),
  118. strerror(errno));
  119. sudo_reset_xauth (context, xauth, xauth_env);
  120. return FALSE;
  121. }
  122. - else if (pid == -1)
  123. +
  124. + pid = fork();
  125. + if (pid == -1)
  126. {
  127. g_set_error (error, gksu_quark, GKSU_ERROR_FORK,
  128. _("Failed to fork new process: %s"),
  129. @@ -2669,26 +2653,56 @@ gksu_sudo_fuller (GksuContext *context,
  130. sudo_reset_xauth (context, xauth, xauth_env);
  131. return FALSE;
  132. }
  133. + else if (pid == 0)
  134. + {
  135. + // Child
  136. + setsid(); // make us session leader
  137. + close(child_pipe[1]);
  138. + dup2(child_pipe[0], STDIN_FILENO);
  139. + dup2(parent_pipe[1], STDERR_FILENO);
  140. + execv(cmd[0], cmd);
  141. +
  142. + g_set_error (error, gksu_quark, GKSU_ERROR_EXEC,
  143. + _("Failed to exec new process: %s"),
  144. + strerror(errno));
  145. + sudo_reset_xauth (context, xauth, xauth_env);
  146. + return FALSE;
  147. + }
  148. else
  149. {
  150. gint counter = 0;
  151. gchar *cmdline = NULL;
  152. - struct termios tio;
  153. // Parent
  154. - fdfile = fdopen(fdpty, "w+");
  155. + close(parent_pipe[1]);
  156. - /* make sure we notice that ECHO is turned off, if it gets
  157. - turned off */
  158. - tcgetattr (fdpty, &tio);
  159. - for (counter = 0; (tio.c_lflag & ECHO) && counter < 15; counter++)
  160. - {
  161. - usleep (1000);
  162. - tcgetattr (fdpty, &tio);
  163. - }
  164. + infile = fdopen(parent_pipe[0], "r");
  165. + if (!infile)
  166. + {
  167. + g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
  168. + _("Error opening pipe: %s"),
  169. + strerror(errno));
  170. + sudo_reset_xauth (context, xauth, xauth_env);
  171. + return FALSE;
  172. + }
  173. - fcntl (fdpty, F_SETFL, O_NONBLOCK);
  174. + outfile = fdopen(child_pipe[1], "w");
  175. + if (!outfile)
  176. + {
  177. + g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
  178. + _("Error opening pipe: %s"),
  179. + strerror(errno));
  180. + sudo_reset_xauth (context, xauth, xauth_env);
  181. + return FALSE;
  182. + }
  183. +
  184. + /*
  185. + we are expecting to receive a GNOME_SUDO_PASS
  186. + if we don't there are two possibilities: an error
  187. + or a password is not needed
  188. + */
  189. + fcntl (parent_pipe[0], F_SETFL, O_NONBLOCK);
  190. { /* no matter if we can read, since we're using
  191. O_NONBLOCK; this is just to avoid the prompt
  192. @@ -2697,11 +2711,11 @@ gksu_sudo_fuller (GksuContext *context,
  193. struct timeval tv;
  194. FD_ZERO(&rfds);
  195. - FD_SET(fdpty, &rfds);
  196. + FD_SET(parent_pipe[0], &rfds);
  197. tv.tv_sec = 1;
  198. tv.tv_usec = 0;
  199. - select (fdpty + 1, &rfds, NULL, NULL, &tv);
  200. + select (parent_pipe[0] + 1, &rfds, NULL, NULL, &tv);
  201. }
  202. /* Try hard to find the prompt; it may happen that we're
  203. @@ -2713,7 +2727,7 @@ gksu_sudo_fuller (GksuContext *context,
  204. if (strncmp (buffer, "GNOME_SUDO_PASS", 15) == 0)
  205. break;
  206. - read_line (fdpty, buffer, 256);
  207. + read_line (parent_pipe[0], buffer, 256);
  208. if (context->debug)
  209. fprintf (stderr, "buffer: -%s-\n", buffer);
  210. @@ -2747,17 +2761,18 @@ gksu_sudo_fuller (GksuContext *context,
  211. usleep (1000);
  212. - write (fdpty, password, strlen(password) + 1);
  213. - write (fdpty, "\n", 1);
  214. + fprintf (outfile, "%s\n", password);
  215. + fclose (outfile);
  216. nullify_password (password);
  217. - fcntl(fdpty, F_SETFL, fcntl(fdpty, F_GETFL) & ~O_NONBLOCK);
  218. + /* turn NONBLOCK off */
  219. + fcntl(parent_pipe[0], F_SETFL, fcntl(parent_pipe[0], F_GETFL) & ~O_NONBLOCK);
  220. /* ignore the first newline that comes right after sudo receives
  221. the password */
  222. - fgets (buffer, 255, fdfile);
  223. - /* this is the status we are interested in */
  224. - fgets (buffer, 255, fdfile);
  225. + fgets (buffer, 255, infile);
  226. + /* this is the status we are interessted in */
  227. + fgets (buffer, 255, infile);
  228. }
  229. else
  230. {
  231. @@ -2766,7 +2781,7 @@ gksu_sudo_fuller (GksuContext *context,
  232. fprintf (stderr, "No password prompt found; we'll assume we don't need a password.\n");
  233. /* turn NONBLOCK off, also if have no prompt */
  234. - fcntl(fdpty, F_SETFL, fcntl(fdpty, F_GETFL) & ~O_NONBLOCK);
  235. + fcntl(parent_pipe[0], F_SETFL, fcntl(parent_pipe[0], F_GETFL) & ~O_NONBLOCK);
  236. should_display = gconf_client_get_bool (context->gconf_client,
  237. BASE_PATH "display-no-pass-info", NULL);
  238. @@ -2785,9 +2800,14 @@ gksu_sudo_fuller (GksuContext *context,
  239. fprintf (stderr, "%s", buffer);
  240. }
  241. - if (g_str_has_prefix (buffer, "Sorry, try again."))
  242. + if (!strcmp (buffer, "Sorry, try again.\n"))
  243. g_set_error (error, gksu_quark, GKSU_ERROR_WRONGPASS,
  244. _("Wrong password."));
  245. + else if (!strncmp (buffer, "Sorry, user ", 12))
  246. + g_set_error (error, gksu_quark, GKSU_ERROR_NOT_ALLOWED,
  247. + _("The underlying authorization mechanism (sudo) "
  248. + "does not allow you to run this program. Contact "
  249. + "the system administrator."));
  250. else
  251. {
  252. gchar *haystack = buffer;
  253. @@ -2805,10 +2825,6 @@ gksu_sudo_fuller (GksuContext *context,
  254. }
  255. }
  256. - /* If we have an error, let's just stop sudo right there. */
  257. - if (error)
  258. - close(fdpty);
  259. -
  260. cmdline = g_strdup("sudo");
  261. /* wait for the child process to end or become something other
  262. than sudo */
  263. @@ -2825,23 +2841,17 @@ gksu_sudo_fuller (GksuContext *context,
  264. if (context->sn_context)
  265. gksu_context_launch_complete (context);
  266. + while (read (parent_pipe[0], buffer, 255) > 0)
  267. + {
  268. + fprintf (stderr, "%s", buffer);
  269. + bzero(buffer, 256);
  270. + }
  271. +
  272. /* if the process is still active waitpid() on it */
  273. if (pid_exited != pid)
  274. waitpid(pid, &status, 0);
  275. sudo_reset_xauth (context, xauth, xauth_env);
  276. - /*
  277. - * Did token acquisition succeed? If so, spawn sudo in
  278. - * non-interactive mode. It should either succeed or die
  279. - * immediately if you're not allowed to run the command.
  280. - */
  281. - if (WEXITSTATUS(status) == 0)
  282. - {
  283. - g_spawn_sync(NULL, cmd, NULL, 0, NULL, NULL,
  284. - NULL, &child_stderr, &status,
  285. - error);
  286. - }
  287. -
  288. if (exit_status)
  289. {
  290. if (WIFEXITED(status)) {
  291. @@ -2853,13 +2863,6 @@ gksu_sudo_fuller (GksuContext *context,
  292. if (WEXITSTATUS(status))
  293. {
  294. - if (g_str_has_prefix(child_stderr, "Sorry, user "))
  295. - {
  296. - g_set_error (error, gksu_quark, GKSU_ERROR_NOT_ALLOWED,
  297. - _("The underlying authorization mechanism (sudo) "
  298. - "does not allow you to run this program. Contact "
  299. - "the system administrator."));
  300. - }
  301. if(cmdline)
  302. {
  303. /* sudo already exec()ed something else, don't report
  304. @@ -2868,7 +2871,6 @@ gksu_sudo_fuller (GksuContext *context,
  305. if (!g_str_has_suffix (cmdline, "sudo"))
  306. {
  307. g_free (cmdline);
  308. - g_free (child_stderr);
  309. return FALSE;
  310. }
  311. g_free (cmdline);
  312. @@ -2881,11 +2883,11 @@ gksu_sudo_fuller (GksuContext *context,
  313. }
  314. }
  315. - fprintf(stderr, child_stderr);
  316. - g_free(child_stderr);
  317. -
  318. /* if error is set we have found an error condition */
  319. - return (error == NULL);
  320. + if (error)
  321. + return FALSE;
  322. +
  323. + return TRUE;
  324. }
  325. /**