session_startup: manage server data before server identification

Fix the bug that libssh2 could not connect if the sftp server
sends data before sending the version string.

http://tools.ietf.org/html/rfc4253#section-4.2

"The server MAY send other lines of data before sending the version
string.  Each line SHOULD be terminated by a Carriage Return and Line
Feed.  Such lines MUST NOT begin with "SSH-", and SHOULD be encoded
in ISO-10646 UTF-8 [RFC3629] (language is not specified).  Clients
MUST be able to process such lines."
This commit is contained in:
Alfred Gebert 2011-01-31 15:50:27 +01:00 committed by Daniel Stenberg
parent ad88325b3f
commit 3ce2628140

View File

@ -1,5 +1,5 @@
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009-2010 by Daniel Stenberg * Copyright (c) 2009-2011 by Daniel Stenberg
* Copyright (c) 2010 Simon Josefsson <simon@josefsson.org> * Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
* All rights reserved. * All rights reserved.
* *
@ -89,7 +89,8 @@ LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
* *
* Wait for a hello from the remote host * Wait for a hello from the remote host
* Allocate a buffer and store the banner in session->remote.banner * Allocate a buffer and store the banner in session->remote.banner
* Returns: 0 on success, LIBSSH2_ERROR_EAGAIN if read would block, negative on failure * Returns: 0 on success, LIBSSH2_ERROR_EAGAIN if read would block, negative
* on failure
*/ */
static int static int
banner_receive(LIBSSH2_SESSION * session) banner_receive(LIBSSH2_SESSION * session)
@ -659,11 +660,14 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
} }
if (session->startup_state == libssh2_NB_state_sent) { if (session->startup_state == libssh2_NB_state_sent) {
rc = banner_receive(session); do {
if (rc) { session->banner_TxRx_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"Failed getting banner"); rc = banner_receive(session);
} if (rc)
return _libssh2_error(session, rc,
"Failed getting banner");
} while(strncmp("SSH-", (char *)session->remote.banner, 4));
session->startup_state = libssh2_NB_state_sent1; session->startup_state = libssh2_NB_state_sent1;
} }