[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[gftp] Re: gftp does not tolerate ssh2 banner
- To: Phillip Vandry <vandry@tzone.org>
- Subject: [gftp] Re: gftp does not tolerate ssh2 banner
- From: Brian Masney <masneyb@gftp.org>
- Date: Fri, 10 Sep 2004 16:10:06 -0400
- Cc: gftp-users@seul.org
- Delivered-to: archiver@seul.org
- Delivered-to: gftp-users-outgoing@seul.org
- Delivered-to: gftp-users@seul.org
- Delivery-date: Fri, 10 Sep 2004 16:10:46 -0400
- In-reply-to: <20040908220120.GA22183@OZoNE.TZoNE.ORG>
- References: <20040908220120.GA22183@OZoNE.TZoNE.ORG>
- Reply-to: gftp-users@seul.org
- Sender: owner-gftp-users@seul.org
- User-agent: Mutt/1.5.5.1+cvs20040105i
Hi,
I improved the login sequence for SSH2 servers in my current CVS tree. I have
a tarball of my latest code online at http://www.gftp.org/gftp-test.tar.bz2. It
will handle login banners without any problems. I also removed the options for
use SSH subsystem, the sftp-server path and use the ssh-askpass utility. My
latest code always uses the SFTP subsystem.
Brian
On Wed, Sep 08, 2004 at 06:01:20PM -0400, Phillip Vandry wrote:
> Hello,
>
> I took a look at gftp while looking for a GUI SFTP client. It looks
> like gftp is a good match to this need and from what I have seen, it
> works well.
>
> The problem I had with it is that it was difficult to get it to connect.
>
> The default mode of operation does not use the ssh subsystem mechanism,
> but instead just tries to launch "sftp-server" as a comment on the remote
> system. I found that this did not work very well because "sftp-server"
> is not in my $PATH. On Debian systems it is in /usr/lib, and on my
> Solaris systems on which I have installed openssh myself it is in
> /opt/openssh/libexec. gftp has a configuration item that lets me specify
> the directory in which "sftp-server" is located so that is how I was able
> to get gftp to work at first but I don't really like that option because
> the user should not really be expected to supply this server specific
> information, and SFTP is supposed to be called an an ssh subsystem anyway.
>
> gftp supports launching the SFTP server as a subsystem but I had even
> less success with this. The problem in this case was simple: gftp mistook
> my ssh server's login banner for a corrupted SFTP message and closed the
> connection. In other words it cannot detect where a textual message from
> the ssh invocation stops and the SFTP protocol begins. It is possible
> that you only tested this feature of gftp so far against ssh servers
> that do not output a banner. I thought of several solutions to this.
>
> (1) launch the ssh client with the -q option to suppress messages.
> The disadvantage is that other important messages will be lost as well.
>
> (2) detect a textual message that precedes the SFTP protocol stream by
> scanning the input for a valid SFTP packet and assuming that everything
> that comes before is a text message.
>
> (3) Use an enhanced version of the gftp_exec_without_new_pty() function
> that creates seperate pipes for the ssh command's stdout and stderr. Read
> SFTP protocol data from the stdout pipe, and read textual messages which
> should be relayed to the user from the stderr pipe.
>
> My favorite solution is the third one, but it is the most complicated to
> implement and requires changing or extending the application's design a
> little bit. If this is the solution that is ultimately chosen then I'd
> like to at least hear your opinion of it before implementing it.
>
> What I implemented is the second solution. This seems to work fine and
> may actually be sufficient.
>
> Here's what else needs to be done:
>
> - I changed a message that gets output to the log to reflect that the
> server issued a message rather than assuming it is an error. The new
> message will need to be translated. I have only supplied two translations.
>
> - Change the type of this message to something other than an error.
>
> The patch is attached.
>
> -Phil
>
> --
> Q. Why can /dev/null accept only integers? A. You can't sink a float
> --- sshv2.c 2004/09/08 20:51:53 1.1
> +++ sshv2.c 2004/09/08 21:58:16 1.2
> @@ -18,7 +18,7 @@
> /*****************************************************************************/
>
> #include "gftp.h"
> -static const char cvsid[] = "$Id: sshv2.c,v 1.1 2004/09/08 20:51:53 vandry Exp $";
> +static const char cvsid[] = "$Id: sshv2.c,v 1.2 2004/09/08 21:58:16 vandry Exp $";
>
> #define SSH_MAX_HANDLE_SIZE 256
> #define SSH_MAX_STRING_SIZE 34000
> @@ -604,9 +604,10 @@
> sshv2_read_response (gftp_request * request, sshv2_message * message,
> int fd)
> {
> - char buf[6], error_buffer[255], *pos;
> + char buf[6], error_buffer[2], *pos;
> sshv2_params * params;
> ssize_t numread, rem;
> + int notok = 0;
>
> params = request->protocol_data;
>
> @@ -633,30 +634,68 @@
> request->logging_function (gftp_logging_error, request,
> _("Error: Message size %d too big from server\n"),
> message->length);
> + notok = 1;
> }
> else
> {
> + /* If the connection is not yet initialized, we might expect to see
> + either a harmless message (like a server banner) or an important
> + error message either before, or instead of the sftp data */
> +
> + /* We got here because the first four bytes of the stream represented
> + a ridiculous message length. Almost any ASCII message will trigger
> + this, which is good */
> +
> + /* What we will do is read one byte at a time until we get something
> + that looks valid -and- happens to be a SSH_FXP_VERSION message.
> + -pkv */
> +
> request->logging_function (gftp_logging_error, request,
> - _("There was an error initializing a SSH connection with the remote server. The error message from the remote server follows:\n"), buf);
> + _("The server reported the following message while initializing a SSH connection:\n"), buf);
>
> - request->logging_function (gftp_logging_error, request, "%s", buf);
> + error_buffer[0] = buf[0];
> + error_buffer[1] = 0;
> + request->logging_function (gftp_logging_error, request, "%s", error_buffer);
>
> if (gftp_fd_set_sockblocking (request, fd, 0) == -1)
> return (GFTP_EFATAL);
>
> - if ((numread = gftp_fd_read (NULL, error_buffer,
> - sizeof (error_buffer) - 1,
> - fd)) > 0)
> - {
> - error_buffer[numread] = '\0';
> - request->logging_function (gftp_logging_error, request,
> - "%s", error_buffer);
> - }
> + for (;;) {
> + /* shift the buffer by one */
> + buf[0] = buf[1]; buf[1] = buf[2];
> + buf[2] = buf[3]; buf[3] = buf[4];
> +
> + /* read only one byte into the end of the buffer */
> + if ((numread = gftp_fd_read(NULL, buf+4, 1, fd)) > 0) {
> + /* got one. try again to reinterpret the message. */
> + memcpy(&message->length, buf, 4);
> + message->length = ntohl(message->length);
> + if ((message->length <= 34000) && (buf[4] == SSH_FXP_VERSION))
> + break;
> +
> + /* still no good. One more character must be part of
> + the text message. */
> + error_buffer[0] = buf[0];
> + request->logging_function(gftp_logging_error,
> + request, "%s", error_buffer);
> + } else {
> + /* We ran out of bytes to read or an error occured. */
> + /* Assume the five bytes we already have are the tail
> + end of a text message, so log them */
> + buf[4] = 0;
> + request->logging_function(gftp_logging_error,
> + request, "%s", buf);
> + notok = 1;
> + }
> + }
> +
> }
>
> - memset (message, 0, sizeof (*message));
> - gftp_disconnect (request);
> - return (GFTP_EFATAL);
> + if (notok) {
> + memset (message, 0, sizeof (*message));
> + gftp_disconnect (request);
> + return (GFTP_EFATAL);
> + }
> }
>
> message->command = buf[4];
> --- fr.po 2004/09/08 21:48:22 1.1
> +++ fr.po 2004/09/08 21:58:21 1.2
> @@ -1304,11 +1304,9 @@
>
> #: lib/sshv2.c:640
> msgid ""
> -"There was an error initializing a SSH connection with the remote server. The "
> -"error message from the remote server follows:\n"
> +"The server reported the following message while initializing a SSH connection:\n"
> msgstr ""
> -"Il y a eu une erreur ?? l'initialisation de la connexion SSH avec le serveur "
> -"distant. Le message d'erreur du serveur distant suit??:\n"
> +"Le serveur a ??mis le message suivant au moment de l'initialisation de la connexion SSH:\n"
>
> #: lib/sshv2.c:869
> #, c-format
> --- ja.po 2004/09/08 21:51:24 1.1
> +++ ja.po 2004/09/08 21:58:24 1.2
> @@ -1256,11 +1256,9 @@
>
> #: lib/sshv2.c:640
> msgid ""
> -"There was an error initializing a SSH connection with the remote server. The "
> -"error message from the remote server follows:\n"
> +"The server reported the following message while initializing a SSH connection:\n"
> msgstr ""
> -"??????????????????????????? SSH ??????????????????????????????????????????????????????????????????????????????"
> -"?????????????????????:\n"
> +"SSH ?????????????????????????????????????????????????????????????????????????????????????????????:\n"
>
> #: lib/sshv2.c:869
> #, c-format