# HG changeset patch # User masneyb # Date 1057499563 0 # Node ID 82ebd1b053450ed762e8be326d724af81fcfa3aa # Parent d79e2782eb1bcfae680fa7e51b8b1afd9ed9dd77 2003-7-6 Brian Masney * lib/pty.c lib/gftp.h - added gftp_exec_with_new_pty() and gftp_exec_without_new_pty() * lib/sshv2.c - use the 2 new functions above * lib/pty.c lib/gftp.h - split open_ptys() to _gftp_ptym_open() and _gftp_ptys_open() * lib/sslcommon.c - don't do thread setup if we are compiling against glib 1.2. I do not want to link against the pthread library because that would make the text port dependant on pthreads being installed on the box diff -r d79e2782eb1b -r 82ebd1b05345 ChangeLog --- a/ChangeLog Sat Jul 05 17:30:14 2003 +0000 +++ b/ChangeLog Sun Jul 06 13:52:43 2003 +0000 @@ -1,3 +1,17 @@ +2003-7-6 Brian Masney + * lib/pty.c lib/gftp.h - added gftp_exec_with_new_pty() and + gftp_exec_without_new_pty() + + * lib/sshv2.c - use the 2 new functions above + + * lib/pty.c lib/gftp.h - split open_ptys() to _gftp_ptym_open() + and _gftp_ptys_open() + + * lib/sslcommon.c - don't do thread setup if we are compiling against + glib 1.2. I do not want to link against the pthread library because + that would make the text port dependant on pthreads being installed on + the box + 2003-7-5 Brian Masney * lib/protocols.c (gftp_get_line) - fixed bug where the read function was being called one extra time after the end of file was reached @@ -1167,7 +1181,7 @@ * cvsclean - added this script - * *.[ch] - added $Id: ChangeLog,v 1.105 2003/07/05 17:30:13 masneyb Exp $ tags + * *.[ch] - added $Id: ChangeLog,v 1.106 2003/07/06 13:52:42 masneyb Exp $ tags * debian/* - updated files from Debian maintainer diff -r d79e2782eb1b -r 82ebd1b05345 lib/gftp.h --- a/lib/gftp.h Sat Jul 05 17:30:14 2003 +0000 +++ b/lib/gftp.h Sun Jul 06 13:52:43 2003 +0000 @@ -90,10 +90,13 @@ #ifdef HAVE_PTY_H #include +#include /* for login_tty */ #elif HAVE_LIBUTIL_H #include +#include /* for login_tty */ #else extern int openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize * winp); +extern int login_tty(int fd); #endif #ifdef HAVE_GETADDRINFO @@ -945,13 +948,15 @@ mode_t perms ); /* pty.c */ -char * get_pty_impl ( void ); +char * gftp_get_pty_impl ( void ); -int open_ptys ( gftp_request * request, +pid_t gftp_exec_with_new_pty ( gftp_request * request, int *fdm, - int *fds ); + char **args ); -int tty_raw ( int fd ); +pid_t gftp_exec_without_new_pty ( gftp_request * request, + int *fdm, + char **args ); #ifdef USE_SSL /* sslcommon.c */ diff -r d79e2782eb1b -r 82ebd1b05345 lib/pty.c --- a/lib/pty.c Sat Jul 05 17:30:14 2003 +0000 +++ b/lib/pty.c Sun Jul 06 13:52:43 2003 +0000 @@ -24,100 +24,134 @@ #ifdef __sgi char * -get_pty_impl (void) +gftp_get_pty_impl (void) { return ("sgi"); } -int -open_ptys (gftp_request * request, int *fdm, int *fds) +static int +_gftp_ptym_open (char *pts_name, size_t len, int *fds) { - char *pts_name; + char *new_pts_name; + int fdm; - if ((pts_name = _getpty (fdm, O_RDWR, 0600, 0)) == NULL) + if ((new_pts_name = _getpty (&fdm, O_RDWR, 0600, 0)) == NULL) return (GFTP_ERETRYABLE); - if ((*fds = open (pts_name, O_RDWR)) < 0) + strncpy (pts_name, new_pts_name, len); + + return (fdm); +} + + +static int +_gftp_ptys_open (int fdm, int fds, char *pts_name) +{ + int new_fds; + + if ((new_fds = open (pts_name, O_RDWR)) < 0) { - close (*fdm); - return (GFTP_ERETRYABLE); + close (fdm); + return (-1); } - return (0); + return (new_fds); } #elif HAVE_GRANTPT char * -get_pty_impl (void) +gftp_get_pty_impl (void) { return ("unix98"); } -int -open_ptys (gftp_request * request, int *fdm, int *fds) +static int +_gftp_ptym_open (char *pts_name, size_t len, int *fds) { - char *pts_name; + char *new_pts_name; + int fdm; - if ((*fdm = open ("/dev/ptmx", O_RDWR)) < 0) + if ((fdm = open ("/dev/ptmx", O_RDWR)) < 0) return (GFTP_ERETRYABLE); - if (grantpt (*fdm) < 0) + if (grantpt (fdm) < 0) { - close (*fdm); + close (fdm); + return (GFTP_ERETRYABLE); + } + + if (unlockpt (fdm) < 0) + { + close (fdm); return (GFTP_ERETRYABLE); } - if (unlockpt (*fdm) < 0) + if ((new_pts_name = ptsname (fdm)) == NULL) { - close (*fdm); + close (fdm); return (GFTP_ERETRYABLE); } - if ((pts_name = ptsname (*fdm)) == NULL) + strncpy (pts_name, new_pts_name, len); + + return (fdm); +} + + +static int +_gftp_ptys_open (int fdm, int fds, char *pts_name) +{ + int new_fds; + + if ((new_fds = open (pts_name, O_RDWR)) < 0) { - close (*fdm); - return (GFTP_ERETRYABLE); - } - - if ((*fds = open (pts_name, O_RDWR)) < 0) - { - close (*fdm); - return (GFTP_ERETRYABLE); + close (fdm); + return (-1); } #ifdef SYSV /* I intentionally ignore these errors */ - ioctl (*fds, I_PUSH, "ptem"); - ioctl (*fds, I_PUSH, "ldterm"); - ioctl (*fds, I_PUSH, "ttcompat"); + ioctl (new_fds, I_PUSH, "ptem"); + ioctl (new_fds, I_PUSH, "ldterm"); + ioctl (new_fds, I_PUSH, "ttcompat"); #endif - return (0); + return (new_fds); } #elif HAVE_OPENPTY char * -get_pty_impl (void) +gftp_get_pty_impl (void) { return ("openpty"); } -int -open_ptys (gftp_request * request, int *fdm, int *fds) +static int +_gftp_ptym_open (char *pts_name, size_t len, int *fds) { - char *pts_name; + int fdm; - if (openpty (fdm, fds, &pts_name, NULL, NULL ) < 0) + if (openpty (&fdm, fds, pts_name, NULL, NULL) < 0) return (GFTP_ERETRYABLE); ioctl (*fds, TIOCSCTTY, NULL); - return (0); + return (fdm); +} + + +static int +_gftp_ptys_open (int fdm, int fds, char *pts_name) +{ + if (login_tty (fds) < 0) + return (GFTP_EFATAL); + + return (fds); } #else /* !HAVE_OPENPTY */ @@ -125,53 +159,65 @@ /* Fall back to *BSD... */ char * -get_pty_impl (void) +gftp_get_pty_impl (void) { return ("bsd"); } -int -open_ptys (gftp_request * request, int *fdm, int *fds) +static int +_gftp_ptym_open (char *pts_name, size_t len, int *fds) { - char pts_name[20], *pos1, *pos2; + char *pos1, *pos2; + int fdm; - strncpy (pts_name, "/dev/ptyXY", sizeof (pts_name)); + g_return_val_if_fail (len >= 10, GFTP_EFATAL); + + strncpy (pts_name, "/dev/ptyXY", len); for (pos1 = "pqrstuvwxyzPQRST"; *pos1 != '\0'; pos1++) { pts_name[8] = *pos1; for (pos2 = "0123456789abcdef"; *pos2 != '\0'; pos2++) { pts_name[9] = *pos2; - if ((*fdm = open (pts_name, O_RDWR)) < 0) + if ((fdm = open (pts_name, O_RDWR)) < 0) continue; pts_name[5] = 't'; chmod (pts_name, S_IRUSR | S_IWUSR); chown (pts_name, getuid (), -1); - if ((*fds = open (pts_name, O_RDWR)) < 0) - { - pts_name[5] = 'p'; - continue; - } - -#if defined(TIOCSCTTY) && !defined(CIBAUD) - ioctl (*fds, TIOCSCTTY, NULL); -#endif - - return (0); + return (fdm); } } return (GFTP_ERETRYABLE); } + +static int +_gftp_ptys_open (int fdm, int fds, char *pts_name) +{ + int new_fds; + + if ((new_fds = open (pts_name, O_RDWR)) < 0) + { + close (fdm); + return (-1); + } + +#if defined(TIOCSCTTY) && !defined(CIBAUD) + ioctl (new_fds, TIOCSCTTY, NULL); +#endif + + return (new_fds); +} + #endif /* __sgi */ -int -tty_raw (int fd) +static int +_gftp_tty_raw (int fd) { struct termios buf; @@ -195,3 +241,123 @@ } +static void +_gftp_close_all_fds (void) +{ + int i, maxfds; + +#ifdef HAVE_GETDTABLESIZE + maxfds = getdtablesize () - 1; +#elif defined (OPEN_MAX) + maxfds = OPEN_MAX; +#else + maxfds = -1; +#endif + + for (i=3; ilogging_function (gftp_logging_error, request, + _("Cannot create a socket pair: %s\n"), + g_strerror (errno)); + return (-1); + } + + if ((child = fork ()) == 0) + { + setsid (); + + close (s[0]); + + _gftp_tty_raw (s[1]); + dup2 (s[1], 0); + dup2 (s[1], 1); + dup2 (s[1], 2); + _gftp_close_all_fds (); + + execvp (args[0], args); + + printf (_("Error: Cannot execute ssh: %s\n"), g_strerror (errno)); + exit (1); + } + else if (child > 0) + { + close (s[1]); + _gftp_tty_raw (s[0]); + *fdm = s[0]; + return (child); + } + else + { + request->logging_function (gftp_logging_error, request->user_data, + _("Cannot fork another process: %s\n"), + g_strerror (errno)); + return (-1); + } +} + + +pid_t +gftp_exec_with_new_pty (gftp_request * request, int *fdm, char **args) +{ + char pts_name[64]; + pid_t child; + int fds; + + *pts_name = '\0'; + if ((*fdm = _gftp_ptym_open (pts_name, sizeof (pts_name), &fds)) < 0) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Cannot open master pty %s: %s\n"), pts_name, + g_strerror (errno)); + return (-1); + } + + if ((child = fork ()) == 0) + { + setsid (); + + if ((fds = _gftp_ptys_open (*fdm, fds, pts_name)) < 0) + { + printf ("Cannot open slave pts %s: %s\n", pts_name, + g_strerror (errno)); + return (-1); + } + + close (*fdm); + + _gftp_tty_raw (fds); + dup2 (fds, 0); + dup2 (fds, 1); + dup2 (fds, 2); + _gftp_close_all_fds (); + + execvp (args[0], args); + + printf (_("Error: Cannot execute ssh: %s\n"), g_strerror (errno)); + exit (1); + } + else if (child > 0) + { + _gftp_tty_raw (*fdm); + return (child); + } + else + { + request->logging_function (gftp_logging_error, request->user_data, + _("Cannot fork another process: %s\n"), + g_strerror (errno)); + return (-1); + } +} + diff -r d79e2782eb1b -r 82ebd1b05345 lib/sshv2.c --- a/lib/sshv2.c Sat Jul 05 17:30:14 2003 +0000 +++ b/lib/sshv2.c Sun Jul 06 13:52:43 2003 +0000 @@ -813,7 +813,7 @@ static int sshv2_connect (gftp_request * request) { - int version, s[2], ret, ssh_use_askpass, sshv2_use_sftp_subsys; + int version, ret, ssh_use_askpass, sshv2_use_sftp_subsys, fdm; char **args, *tempstr, *p1, p2, *exepath, *ssh2_sftp_path; struct servent serv_struct; sshv2_message message; @@ -867,90 +867,56 @@ args = sshv2_gen_exec_args (request, exepath, sshv2_use_sftp_subsys); if (ssh_use_askpass || sshv2_use_sftp_subsys) - { - if (socketpair (AF_LOCAL, SOCK_STREAM, 0, s) < 0) - { - request->logging_function (gftp_logging_error, request, - _("Cannot create a socket pair: %s\n"), - g_strerror (errno)); - return (GFTP_ERETRYABLE); - } - } + child = gftp_exec_without_new_pty (request, &fdm, args); else - { - if ((ret = open_ptys (request, &s[0], &s[1])) < 0) - return (ret); - } - - if ((child = fork ()) == 0) + child = gftp_exec_with_new_pty (request, &fdm, args); + + if (child == 0) + exit (0); + else if (child < 0) + return (GFTP_ERETRYABLE); + + if (!sshv2_use_sftp_subsys) { - setsid (); - close (s[0]); - - tty_raw (s[1]); - dup2 (s[1], 0); - dup2 (s[1], 1); - dup2 (s[1], 2); - execvp (args[0], args); - - printf (_("Error: Cannot execute ssh: %s\n"), g_strerror (errno)); - exit (1); - } - else if (child > 0) - { - close (s[1]); - tty_raw (s[0]); - - if (!sshv2_use_sftp_subsys) + tempstr = sshv2_start_login_sequence (request, fdm); + if (!tempstr || !(strlen (tempstr) > 4 && strcmp (tempstr + strlen (tempstr) - 5, + "xsftp") == 0)) { - tempstr = sshv2_start_login_sequence (request, s[0]); - if (!tempstr || - !(strlen (tempstr) > 4 && strcmp (tempstr + strlen (tempstr) - 5, - "xsftp") == 0)) - { - sshv2_free_args (args); - g_free (exepath); - return (GFTP_EFATAL); - } - g_free (tempstr); + sshv2_free_args (args); + g_free (exepath); + return (GFTP_EFATAL); } - sshv2_free_args (args); - g_free (exepath); - - request->datafd = s[0]; + g_free (tempstr); + } - version = htonl (SSH_MY_VERSION); - if ((ret = sshv2_send_command (request, SSH_FXP_INIT, (char *) - &version, 4)) < 0) - return (ret); + sshv2_free_args (args); + g_free (exepath); - memset (&message, 0, sizeof (message)); - if ((ret = sshv2_read_response (request, &message, -1)) != SSH_FXP_VERSION) - { - request->logging_function (gftp_logging_error, request, - _("Received wrong response from server, disconnecting\n")); - sshv2_message_free (&message); - gftp_disconnect (request); + request->datafd = fdm; - if (ret < 0) - return (ret); - else - return (GFTP_ERETRYABLE); - } - sshv2_message_free (&message); + version = htonl (SSH_MY_VERSION); + if ((ret = sshv2_send_command (request, SSH_FXP_INIT, (char *) + &version, 4)) < 0) + return (ret); - request->logging_function (gftp_logging_misc, request, - _("Successfully logged into SSH server %s\n"), - request->hostname); - } - else + memset (&message, 0, sizeof (message)); + if ((ret = sshv2_read_response (request, &message, -1)) != SSH_FXP_VERSION) { request->logging_function (gftp_logging_error, request, - _("Cannot fork another process: %s\n"), - g_strerror (errno)); - g_free (args); - return (GFTP_ERETRYABLE); + _("Received wrong response from server, disconnecting\n")); + sshv2_message_free (&message); + gftp_disconnect (request); + + if (ret < 0) + return (ret); + else + return (GFTP_ERETRYABLE); } + sshv2_message_free (&message); + + request->logging_function (gftp_logging_misc, request, + _("Successfully logged into SSH server %s\n"), + request->hostname); if (sshv2_getcwd (request) < 0) { diff -r d79e2782eb1b -r 82ebd1b05345 lib/sslcommon.c --- a/lib/sslcommon.c Sat Jul 05 17:30:14 2003 +0000 +++ b/lib/sslcommon.c Sun Jul 06 13:52:43 2003 +0000 @@ -206,7 +206,8 @@ #if GLIB_MAJOR_VERSION > 1 return ((unsigned long) g_thread_self ()); #else - /* FIXME _ call pthread version */ + /* FIXME _ call pthread version. Once this is done, the #ifdef below can be + removed */ return (0); #endif } @@ -248,6 +249,11 @@ { int i; +#ifdef G_MAJOR_VERSION == 1 + /* Thread setup isn't supported in glib 1.2 yet */ + return; +#endif + gftp_ssl_mutexes = g_malloc (CRYPTO_num_locks( ) * sizeof (*gftp_ssl_mutexes)); for (i = 0; i < CRYPTO_num_locks ( ); i++)