Make use of openpty(3) to allocate a pseudo-tty required for the ssh

authentication. This allow to mount sftp shares using passwords with
any application relying on gvfs. With a lot of help from nicm@.

Packages already bumped but I failed again with cvs add.

Ok ajacoutot@, jasper@
This commit is contained in:
mpi 2012-07-10 10:15:19 +00:00
parent 98bc90f5bb
commit c59cfc290e
3 changed files with 197 additions and 0 deletions

View File

@ -0,0 +1,16 @@
$OpenBSD: patch-configure_ac,v 1.5 2012/07/10 10:15:19 mpi Exp $
--- configure.ac.orig Mon Apr 9 16:58:43 2012
+++ configure.ac Mon Apr 9 16:58:49 2012
@@ -108,8 +108,12 @@ AC_CHECK_FUNCS(getpt posix_openpt grantpt unlockpt pts
# Pull in the right libraries for various functions which might not be
# bundled into an exploded libc.
AC_CHECK_FUNC(socketpair,[have_socketpair=1],AC_CHECK_LIB(socket,socketpair,[have_socketpair=1; LIBS="$LIBS -lsocket"]))
+AC_CHECK_FUNC(openpty,[have_openpty=1],AC_CHECK_LIB(util,openpty,[have_openpty=1; LIBS="$LIBS -lutil"]))
if test x$have_socketpair = x1 ; then
AC_DEFINE(HAVE_SOCKETPAIR,1,[Define if you have the socketpair function.])
+fi
+if test x$have_openpty = x1 ; then
+ AC_DEFINE(HAVE_OPENPTY,1,[Define if you have the openpty function.])
fi
AC_SEARCH_LIBS(login_tty, util, [AC_DEFINE([HAVE_LOGIN_TTY],[],[Whether login_tty is available])])

View File

@ -0,0 +1,14 @@
$OpenBSD: patch-daemon_gvfsbackendsftp_c,v 1.1 2012/07/10 10:15:19 mpi Exp $
--- daemon/gvfsbackendsftp.c.orig Tue May 15 20:01:50 2012
+++ daemon/gvfsbackendsftp.c Mon Jul 9 12:24:52 2012
@@ -71,8 +71,8 @@
* fstat
*/
-#ifdef HAVE_GRANTPT
-/* We only use this on systems with unix98 ptys */
+#if defined(HAVE_GRANTPT) || defined(HAVE_OPENPTY)
+/* We only use this on systems with unix98 or BSD ptys */
#define USE_PTY 1
#endif

View File

@ -0,0 +1,167 @@
$OpenBSD: patch-daemon_pty_open_c,v 1.3 2012/07/10 10:15:19 mpi Exp $
Use openpty(3) rather than the Unix98 function family to be able to
login using a password.
--- daemon/pty_open.c.orig Tue May 15 20:01:50 2012
+++ daemon/pty_open.c Tue Jul 10 11:03:27 2012
@@ -72,6 +72,12 @@
#include <glib.h>
#include "pty_open.h"
+#if defined(HAVE_PTSNAME_R) || defined(HAVE_PTSNAME) || defined(TIOCGPTN)
+#define HAVE_UNIX98_PTY
+#else
+#undef HAVE_UNIX98_PTY
+#endif
+
int _pty_set_size(int master, int columns, int rows);
/* Solaris does not have the login_tty() function so implement locally. */
@@ -710,6 +716,8 @@ _pty_unlockpt(int fd)
#endif
}
+#if defined(HAVE_UNIX98_PTY)
+
static int
_pty_open_unix98(pid_t *child, guint flags, char **env_add,
const char *command, char **argv,
@@ -746,6 +754,114 @@ _pty_open_unix98(pid_t *child, guint flags, char **env
return fd;
}
+#elif defined(HAVE_OPENPTY)
+
+static int
+_pty_open_bsd(pid_t *child, const char *command, char **argv,
+ int *stdin_fd, int *stdout_fd, int *stderr_fd)
+{
+ int master, slave;
+ char **args, *arg;
+ int stdin_pipe[2];
+ int stdout_pipe[2];
+ int stderr_pipe[2];
+ pid_t pid;
+ int i;
+
+ if (pipe(stdin_pipe))
+ goto bail_stdin;
+ if (pipe(stdout_pipe))
+ goto bail_stdout;
+ if (pipe(stderr_pipe))
+ goto bail_stderr;
+
+ if (openpty(&master, &slave, NULL, NULL, NULL) == -1)
+ return (-1);
+
+ switch(pid = fork()) {
+ case -1:
+ goto bail_fork;
+ case 0:
+ /*
+ * Child
+ */
+ close(master);
+ close(stdin_pipe[1]);
+ close(stdout_pipe[0]);
+ close(stderr_pipe[0]);
+
+ setsid();
+ if (ioctl(slave, TIOCSCTTY, (char *)NULL) == -1)
+ _exit(0);
+
+ /* Set up stdin/out/err */
+ dup2(stdin_pipe[0], STDIN_FILENO);
+ dup2(stdout_pipe[1], STDOUT_FILENO);
+ dup2(stderr_pipe[1], STDERR_FILENO);
+ close(stdin_pipe[0]);
+ close(stdout_pipe[1]);
+ close(stderr_pipe[1]);
+
+ /* Reset our signals -- our parent may have done any number of
+ * weird things to them. */
+ _pty_reset_signal_handlers();
+
+ /* Outta here. */
+ if (argv != NULL) {
+ for (i = 0; (argv[i] != NULL); i++) ;
+ args = g_malloc0(sizeof(char*) * (i + 1));
+ for (i = 0; (argv[i] != NULL); i++) {
+ args[i] = g_strdup(argv[i]);
+ }
+ execvp(command, args);
+ } else {
+ arg = g_strdup(command);
+ execlp(command, arg, NULL);
+ }
+
+ /* Avoid calling any atexit() code. */
+ _exit(0);
+ g_assert_not_reached();
+ }
+
+ /*
+ * Parent
+ */
+
+ /* XXX Don't close the slave pty, it's now the control
+ * terminal of the child and ssh needs it to authenticate.
+ close(slave);
+ */
+ close(stdin_pipe[0]);
+ close(stdout_pipe[1]);
+ close(stderr_pipe[1]);
+
+ *child = pid;
+ *stdin_fd = stdin_pipe[1];
+ *stdout_fd = stdout_pipe[0];
+ *stderr_fd = stderr_pipe[0];
+
+ return (master);
+
+ bail_fork:
+ close(stderr_pipe[0]);
+ close(stderr_pipe[1]);
+ bail_stderr:
+ close(stdout_pipe[0]);
+ close(stdout_pipe[1]);
+ bail_stdout:
+ close(stdin_pipe[0]);
+ close(stdin_pipe[1]);
+ bail_stdin:
+
+ *child = -1;
+ return -1;
+}
+
+#else
+#error Have neither UNIX98 PTY nor BSD openpty!
+#endif /* HAVE_UNIX98_PTY */
+
/**
* pty_open:
* @child: location to store the new process's ID
@@ -774,11 +890,17 @@ pty_open(pid_t *child, guint flags, char **env_add,
int *stdin_fd, int *stdout_fd, int *stderr_fd)
{
int ret = -1;
- if (ret == -1) {
- ret = _pty_open_unix98(child, flags, env_add, command,
- argv, directory, columns, rows,
- stdin_fd, stdout_fd, stderr_fd);
- }
+
+#if defined(HAVE_UNIX98_PTY)
+ ret = _pty_open_unix98(child, flags, env_add, command, argv, directory,
+ columns, rows, stdin_fd, stdout_fd, stderr_fd);
+#elif defined(HAVE_OPENPTY)
+ ret = _pty_open_bsd(child, command, argv,
+ stdin_fd, stdout_fd, stderr_fd);
+#else
+#error Have neither UNIX98 PTY nor BSD openpty!
+#endif
+
return ret;
}