libssh2_poll() no longer relies on C99 features but instead uses alloca()
on systems that have it - and uses a fixed-size array on those that don't. session.c was also cleaned from a large amount of trailing whitespace.
This commit is contained in:
@@ -248,6 +248,8 @@ AC_CHECK_HEADERS([sys/select.h sys/socket.h sys/ioctl.h sys/time.h])
|
|||||||
AC_CHECK_HEADERS([arpa/inet.h netinet/in.h])
|
AC_CHECK_HEADERS([arpa/inet.h netinet/in.h])
|
||||||
AC_CHECK_FUNCS(poll gettimeofday select)
|
AC_CHECK_FUNCS(poll gettimeofday select)
|
||||||
|
|
||||||
|
AC_FUNC_ALLOCA
|
||||||
|
|
||||||
# Checks for typedefs, structures, and compiler characteristics.
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
AC_C_CONST
|
AC_C_CONST
|
||||||
AC_C_INLINE
|
AC_C_INLINE
|
||||||
|
|||||||
205
src/session.c
205
src/session.c
@@ -46,6 +46,9 @@
|
|||||||
#ifdef HAVE_GETTIMEOFDAY
|
#ifdef HAVE_GETTIMEOFDAY
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_ALLOCA_H
|
||||||
|
#include <alloca.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* {{{ libssh2_default_alloc
|
/* {{{ libssh2_default_alloc
|
||||||
*/
|
*/
|
||||||
@@ -86,12 +89,12 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
|||||||
|
|
||||||
if (session->banner_TxRx_state == libssh2_NB_state_idle) {
|
if (session->banner_TxRx_state == libssh2_NB_state_idle) {
|
||||||
banner_len = 0;
|
banner_len = 0;
|
||||||
|
|
||||||
session->banner_TxRx_state = libssh2_NB_state_created;
|
session->banner_TxRx_state = libssh2_NB_state_created;
|
||||||
} else {
|
} else {
|
||||||
banner_len = session->banner_TxRx_total_send;
|
banner_len = session->banner_TxRx_total_send;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((banner_len < (int)sizeof(session->banner_TxRx_banner)) &&
|
while ((banner_len < (int)sizeof(session->banner_TxRx_banner)) &&
|
||||||
((banner_len == 0) || (session->banner_TxRx_banner[banner_len-1] != '\n'))) {
|
((banner_len == 0) || (session->banner_TxRx_banner[banner_len-1] != '\n'))) {
|
||||||
char c = '\0';
|
char c = '\0';
|
||||||
@@ -104,16 +107,16 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
|||||||
case WSAEWOULDBLOCK:
|
case WSAEWOULDBLOCK:
|
||||||
errno = EAGAIN;
|
errno = EAGAIN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WSAENOTSOCK:
|
case WSAENOTSOCK:
|
||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WSAENOTCONN:
|
case WSAENOTCONN:
|
||||||
case WSAECONNABORTED:
|
case WSAECONNABORTED:
|
||||||
errno = WSAENOTCONN;
|
errno = WSAENOTCONN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WSAEINTR:
|
case WSAEINTR:
|
||||||
errno = EINTR;
|
errno = EINTR;
|
||||||
break;
|
break;
|
||||||
@@ -143,7 +146,7 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (banner_len &&
|
while (banner_len &&
|
||||||
((session->banner_TxRx_banner[banner_len-1] == '\n') ||
|
((session->banner_TxRx_banner[banner_len-1] == '\n') ||
|
||||||
(session->banner_TxRx_banner[banner_len-1] == '\r'))) {
|
(session->banner_TxRx_banner[banner_len-1] == '\r'))) {
|
||||||
banner_len--;
|
banner_len--;
|
||||||
}
|
}
|
||||||
@@ -151,7 +154,7 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
|||||||
/* From this point on, we are done here */
|
/* From this point on, we are done here */
|
||||||
session->banner_TxRx_state = libssh2_NB_state_idle;
|
session->banner_TxRx_state = libssh2_NB_state_idle;
|
||||||
session->banner_TxRx_total_send = 0;
|
session->banner_TxRx_total_send = 0;
|
||||||
|
|
||||||
if (!banner_len) return 1;
|
if (!banner_len) return 1;
|
||||||
|
|
||||||
session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1);
|
session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1);
|
||||||
@@ -189,7 +192,7 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
|
|||||||
banner_len = strlen((char *)session->local.banner);
|
banner_len = strlen((char *)session->local.banner);
|
||||||
banner = (char *)session->local.banner;
|
banner = (char *)session->local.banner;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LIBSSH2DEBUG
|
#ifdef LIBSSH2DEBUG
|
||||||
/* Hack and slash to avoid sending CRLF in debug output */
|
/* Hack and slash to avoid sending CRLF in debug output */
|
||||||
if (banner_len < 256) {
|
if (banner_len < 256) {
|
||||||
@@ -202,13 +205,13 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
|
|||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Sending Banner: %s", banner_dup);
|
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Sending Banner: %s", banner_dup);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
session->banner_TxRx_state = libssh2_NB_state_created;
|
session->banner_TxRx_state = libssh2_NB_state_created;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = send(session->socket_fd, banner+session->banner_TxRx_total_send, banner_len-session->banner_TxRx_total_send,
|
ret = send(session->socket_fd, banner+session->banner_TxRx_total_send, banner_len-session->banner_TxRx_total_send,
|
||||||
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||||
|
|
||||||
if (ret != (banner_len-session->banner_TxRx_total_send)) {
|
if (ret != (banner_len-session->banner_TxRx_total_send)) {
|
||||||
if ((ret > 0 ) || ((ret == -1) && (errno == EAGAIN))) {
|
if ((ret > 0 ) || ((ret == -1) && (errno == EAGAIN))) {
|
||||||
/* the whole packet could not be sent, save the what was */
|
/* the whole packet could not be sent, save the what was */
|
||||||
@@ -219,11 +222,11 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
|
|||||||
session->banner_TxRx_total_send = 0;
|
session->banner_TxRx_total_send = 0;
|
||||||
return PACKET_FAIL;
|
return PACKET_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the state back to idle */
|
/* Set the state back to idle */
|
||||||
session->banner_TxRx_state = libssh2_NB_state_idle;
|
session->banner_TxRx_state = libssh2_NB_state_idle;
|
||||||
session->banner_TxRx_total_send = 0;
|
session->banner_TxRx_total_send = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -241,7 +244,7 @@ static int _libssh2_nonblock(int sockfd, /* operate on this */
|
|||||||
#ifdef HAVE_O_NONBLOCK
|
#ifdef HAVE_O_NONBLOCK
|
||||||
/* most recent unix versions */
|
/* most recent unix versions */
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
flags = fcntl(sockfd, F_GETFL, 0);
|
flags = fcntl(sockfd, F_GETFL, 0);
|
||||||
if (nonblock)
|
if (nonblock)
|
||||||
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||||
@@ -250,34 +253,34 @@ static int _libssh2_nonblock(int sockfd, /* operate on this */
|
|||||||
#undef SETBLOCK
|
#undef SETBLOCK
|
||||||
#define SETBLOCK 1
|
#define SETBLOCK 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
|
#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
|
||||||
/* older unix versions */
|
/* older unix versions */
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
flags = nonblock;
|
flags = nonblock;
|
||||||
return ioctl(sockfd, FIONBIO, &flags);
|
return ioctl(sockfd, FIONBIO, &flags);
|
||||||
#undef SETBLOCK
|
#undef SETBLOCK
|
||||||
#define SETBLOCK 2
|
#define SETBLOCK 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
|
#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
|
||||||
/* Windows? */
|
/* Windows? */
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
flags = nonblock;
|
flags = nonblock;
|
||||||
|
|
||||||
return ioctlsocket(sockfd, FIONBIO, &flags);
|
return ioctlsocket(sockfd, FIONBIO, &flags);
|
||||||
#undef SETBLOCK
|
#undef SETBLOCK
|
||||||
#define SETBLOCK 3
|
#define SETBLOCK 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
|
#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
|
||||||
/* presumably for Amiga */
|
/* presumably for Amiga */
|
||||||
return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
|
return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
|
||||||
#undef SETBLOCK
|
#undef SETBLOCK
|
||||||
#define SETBLOCK 4
|
#define SETBLOCK 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
|
#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
|
||||||
/* BeOS */
|
/* BeOS */
|
||||||
long b = nonblock ? 1 : 0;
|
long b = nonblock ? 1 : 0;
|
||||||
@@ -285,13 +288,13 @@ static int _libssh2_nonblock(int sockfd, /* operate on this */
|
|||||||
#undef SETBLOCK
|
#undef SETBLOCK
|
||||||
#define SETBLOCK 5
|
#define SETBLOCK 5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_DISABLED_NONBLOCKING
|
#ifdef HAVE_DISABLED_NONBLOCKING
|
||||||
return 0; /* returns success */
|
return 0; /* returns success */
|
||||||
#undef SETBLOCK
|
#undef SETBLOCK
|
||||||
#define SETBLOCK 6
|
#define SETBLOCK 6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (SETBLOCK == 0)
|
#if (SETBLOCK == 0)
|
||||||
#error "no non-blocking method was found/used/set"
|
#error "no non-blocking method was found/used/set"
|
||||||
#endif
|
#endif
|
||||||
@@ -308,7 +311,7 @@ static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */
|
|||||||
#ifdef HAVE_O_NONBLOCK
|
#ifdef HAVE_O_NONBLOCK
|
||||||
/* most recent unix versions */
|
/* most recent unix versions */
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
if ((flags = fcntl(sockfd, F_GETFL, 0)) == -1) {
|
if ((flags = fcntl(sockfd, F_GETFL, 0)) == -1) {
|
||||||
/* Assume blocking on error */
|
/* Assume blocking on error */
|
||||||
return 1;
|
return 1;
|
||||||
@@ -317,7 +320,7 @@ static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */
|
|||||||
#undef GETBLOCK
|
#undef GETBLOCK
|
||||||
#define GETBLOCK 1
|
#define GETBLOCK 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WSAEWOULDBLOCK) && (GETBLOCK == 0)
|
#if defined(WSAEWOULDBLOCK) && (GETBLOCK == 0)
|
||||||
/* Windows? */
|
/* Windows? */
|
||||||
unsigned int option_value;
|
unsigned int option_value;
|
||||||
@@ -331,7 +334,7 @@ static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */
|
|||||||
#undef GETBLOCK
|
#undef GETBLOCK
|
||||||
#define GETBLOCK 2
|
#define GETBLOCK 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_SO_NONBLOCK) && (GETBLOCK == 0)
|
#if defined(HAVE_SO_NONBLOCK) && (GETBLOCK == 0)
|
||||||
/* BeOS */
|
/* BeOS */
|
||||||
long b;
|
long b;
|
||||||
@@ -343,13 +346,13 @@ static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */
|
|||||||
#undef GETBLOCK
|
#undef GETBLOCK
|
||||||
#define GETBLOCK 5
|
#define GETBLOCK 5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_DISABLED_NONBLOCKING
|
#ifdef HAVE_DISABLED_NONBLOCKING
|
||||||
return 1; /* returns blocking */
|
return 1; /* returns blocking */
|
||||||
#undef GETBLOCK
|
#undef GETBLOCK
|
||||||
#define GETBLOCK 6
|
#define GETBLOCK 6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (GETBLOCK == 0)
|
#if (GETBLOCK == 0)
|
||||||
#error "no non-blocking method was found/used/get"
|
#error "no non-blocking method was found/used/get"
|
||||||
#endif
|
#endif
|
||||||
@@ -432,8 +435,12 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
|
|||||||
/* {{{ libssh2_session_callback_set
|
/* {{{ libssh2_session_callback_set
|
||||||
* Set (or reset) a callback function
|
* Set (or reset) a callback function
|
||||||
* Returns the prior address
|
* Returns the prior address
|
||||||
|
*
|
||||||
|
* FIXME: this function relies on that we can typecast function pointers
|
||||||
|
* to void pointers, which isn't allowed in ISO C!
|
||||||
*/
|
*/
|
||||||
LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callback)
|
LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session,
|
||||||
|
int cbtype, void *callback)
|
||||||
{
|
{
|
||||||
void *oldcb;
|
void *oldcb;
|
||||||
|
|
||||||
@@ -480,9 +487,9 @@ LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbt
|
|||||||
LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (session->startup_state == libssh2_NB_state_idle) {
|
if (session->startup_state == libssh2_NB_state_idle) {
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||||
"session_startup for socket %d", socket);
|
"session_startup for socket %d", socket);
|
||||||
/* FIXME: on some platforms (like win32) sockets are unsigned */
|
/* FIXME: on some platforms (like win32) sockets are unsigned */
|
||||||
if (socket < 0) {
|
if (socket < 0) {
|
||||||
@@ -491,7 +498,7 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
|||||||
return LIBSSH2_ERROR_SOCKET_NONE;
|
return LIBSSH2_ERROR_SOCKET_NONE;
|
||||||
}
|
}
|
||||||
session->socket_fd = socket;
|
session->socket_fd = socket;
|
||||||
|
|
||||||
session->socket_block = !_libssh2_get_socket_nonblocking(session->socket_fd);
|
session->socket_block = !_libssh2_get_socket_nonblocking(session->socket_fd);
|
||||||
if (session->socket_block) {
|
if (session->socket_block) {
|
||||||
/*
|
/*
|
||||||
@@ -501,12 +508,12 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
|||||||
*/
|
*/
|
||||||
_libssh2_nonblock(session->socket_fd, 0);
|
_libssh2_nonblock(session->socket_fd, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
session->startup_state = libssh2_NB_state_created;
|
session->startup_state = libssh2_NB_state_created;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Liveness check */
|
/* TODO: Liveness check */
|
||||||
|
|
||||||
if (session->startup_state == libssh2_NB_state_created) {
|
if (session->startup_state == libssh2_NB_state_created) {
|
||||||
rc = libssh2_banner_send(session);
|
rc = libssh2_banner_send(session);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
@@ -518,10 +525,10 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
|||||||
libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND, "Error sending banner to remote host", 0);
|
libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND, "Error sending banner to remote host", 0);
|
||||||
return LIBSSH2_ERROR_BANNER_SEND;
|
return LIBSSH2_ERROR_BANNER_SEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
session->startup_state = libssh2_NB_state_sent;
|
session->startup_state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->startup_state == libssh2_NB_state_sent) {
|
if (session->startup_state == libssh2_NB_state_sent) {
|
||||||
rc = libssh2_banner_receive(session);
|
rc = libssh2_banner_receive(session);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
@@ -533,10 +540,10 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
|||||||
libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE, "Timeout waiting for banner", 0);
|
libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE, "Timeout waiting for banner", 0);
|
||||||
return LIBSSH2_ERROR_BANNER_NONE;
|
return LIBSSH2_ERROR_BANNER_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
session->startup_state = libssh2_NB_state_sent1;
|
session->startup_state = libssh2_NB_state_sent1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->startup_state == libssh2_NB_state_sent1) {
|
if (session->startup_state == libssh2_NB_state_sent1) {
|
||||||
rc = libssh2_kex_exchange(session, 0, &session->startup_key_state);
|
rc = libssh2_kex_exchange(session, 0, &session->startup_key_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
@@ -547,21 +554,21 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
|||||||
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, "Unable to exchange encryption keys", 0);
|
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, "Unable to exchange encryption keys", 0);
|
||||||
return LIBSSH2_ERROR_KEX_FAILURE;
|
return LIBSSH2_ERROR_KEX_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
session->startup_state = libssh2_NB_state_sent2;
|
session->startup_state = libssh2_NB_state_sent2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->startup_state == libssh2_NB_state_sent2) {
|
if (session->startup_state == libssh2_NB_state_sent2) {
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Requesting userauth service");
|
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Requesting userauth service");
|
||||||
|
|
||||||
/* Request the userauth service */
|
/* Request the userauth service */
|
||||||
session->startup_service[0] = SSH_MSG_SERVICE_REQUEST;
|
session->startup_service[0] = SSH_MSG_SERVICE_REQUEST;
|
||||||
libssh2_htonu32(session->startup_service + 1, sizeof("ssh-userauth") - 1);
|
libssh2_htonu32(session->startup_service + 1, sizeof("ssh-userauth") - 1);
|
||||||
memcpy(session->startup_service + 5, "ssh-userauth", sizeof("ssh-userauth") - 1);
|
memcpy(session->startup_service + 5, "ssh-userauth", sizeof("ssh-userauth") - 1);
|
||||||
|
|
||||||
session->startup_state = libssh2_NB_state_sent3;
|
session->startup_state = libssh2_NB_state_sent3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->startup_state == libssh2_NB_state_sent3) {
|
if (session->startup_state == libssh2_NB_state_sent3) {
|
||||||
rc = libssh2_packet_write(session, session->startup_service, sizeof("ssh-userauth") + 5 - 1);
|
rc = libssh2_packet_write(session, session->startup_service, sizeof("ssh-userauth") + 5 - 1);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
@@ -572,12 +579,12 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
|||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to ask for ssh-userauth service", 0);
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to ask for ssh-userauth service", 0);
|
||||||
return LIBSSH2_ERROR_SOCKET_SEND;
|
return LIBSSH2_ERROR_SOCKET_SEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
session->startup_state = libssh2_NB_state_sent4;
|
session->startup_state = libssh2_NB_state_sent4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->startup_state == libssh2_NB_state_sent4) {
|
if (session->startup_state == libssh2_NB_state_sent4) {
|
||||||
rc = libssh2_packet_require_ex(session, SSH_MSG_SERVICE_ACCEPT, &session->startup_data, &session->startup_data_len,
|
rc = libssh2_packet_require_ex(session, SSH_MSG_SERVICE_ACCEPT, &session->startup_data, &session->startup_data_len,
|
||||||
0, NULL, 0, &session->startup_req_state);
|
0, NULL, 0, &session->startup_req_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return LIBSSH2_ERROR_EAGAIN;
|
return LIBSSH2_ERROR_EAGAIN;
|
||||||
@@ -586,7 +593,7 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
|||||||
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
|
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
|
||||||
}
|
}
|
||||||
session->startup_service_length = libssh2_ntohu32(session->startup_data + 1);
|
session->startup_service_length = libssh2_ntohu32(session->startup_data + 1);
|
||||||
|
|
||||||
if ((session->startup_service_length != (sizeof("ssh-userauth") - 1)) ||
|
if ((session->startup_service_length != (sizeof("ssh-userauth") - 1)) ||
|
||||||
strncmp("ssh-userauth", (char *)session->startup_data + 5, session->startup_service_length)) {
|
strncmp("ssh-userauth", (char *)session->startup_data + 5, session->startup_service_length)) {
|
||||||
LIBSSH2_FREE(session, session->startup_data);
|
LIBSSH2_FREE(session, session->startup_data);
|
||||||
@@ -596,12 +603,12 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
|||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, session->startup_data);
|
LIBSSH2_FREE(session, session->startup_data);
|
||||||
session->startup_data = NULL;
|
session->startup_data = NULL;
|
||||||
|
|
||||||
session->startup_state = libssh2_NB_state_idle;
|
session->startup_state = libssh2_NB_state_idle;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* just for safety return some error */
|
/* just for safety return some error */
|
||||||
return LIBSSH2_ERROR_INVAL;
|
return LIBSSH2_ERROR_INVAL;
|
||||||
}
|
}
|
||||||
@@ -614,13 +621,13 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
|||||||
LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
|
LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (session->free_state == libssh2_NB_state_idle) {
|
if (session->free_state == libssh2_NB_state_idle) {
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource", session->remote.banner);
|
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource", session->remote.banner);
|
||||||
|
|
||||||
session->state = libssh2_NB_state_created;
|
session->state = libssh2_NB_state_created;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->free_state == libssh2_NB_state_created) {
|
if (session->free_state == libssh2_NB_state_created) {
|
||||||
while (session->channels.head) {
|
while (session->channels.head) {
|
||||||
LIBSSH2_CHANNEL *tmp = session->channels.head;
|
LIBSSH2_CHANNEL *tmp = session->channels.head;
|
||||||
@@ -642,7 +649,7 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
|
|||||||
/* reverse linking isn't important here, we're killing the structure */
|
/* reverse linking isn't important here, we're killing the structure */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session->state = libssh2_NB_state_sent;
|
session->state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -653,10 +660,10 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
|
|||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session->state = libssh2_NB_state_sent1;
|
session->state = libssh2_NB_state_sent1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->state & LIBSSH2_STATE_NEWKEYS) {
|
if (session->state & LIBSSH2_STATE_NEWKEYS) {
|
||||||
/* hostkey */
|
/* hostkey */
|
||||||
if (session->hostkey && session->hostkey->dtor) {
|
if (session->hostkey && session->hostkey->dtor) {
|
||||||
@@ -811,12 +818,12 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
|
|||||||
if (session->scpSend_err_msg) {
|
if (session->scpSend_err_msg) {
|
||||||
LIBSSH2_FREE(session, session->scpSend_err_msg);
|
LIBSSH2_FREE(session, session->scpSend_err_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the error message, if we ar supposed to */
|
/* Free the error message, if we ar supposed to */
|
||||||
if (session->err_msg && session->err_should_free) {
|
if (session->err_msg && session->err_should_free) {
|
||||||
LIBSSH2_FREE(session, session->err_msg);
|
LIBSSH2_FREE(session, session->err_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup any remaining packets */
|
/* Cleanup any remaining packets */
|
||||||
while (session->packets.head) {
|
while (session->packets.head) {
|
||||||
LIBSSH2_PACKET *tmp = session->packets.head;
|
LIBSSH2_PACKET *tmp = session->packets.head;
|
||||||
@@ -830,7 +837,7 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LIBSSH2_FREE(session, session);
|
LIBSSH2_FREE(session, session);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -875,7 +882,7 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
|
|||||||
memcpy(s, lang, lang_len);
|
memcpy(s, lang, lang_len);
|
||||||
s += lang_len;
|
s += lang_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
session->disconnect_state = libssh2_NB_state_created;
|
session->disconnect_state = libssh2_NB_state_created;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -906,43 +913,43 @@ LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int me
|
|||||||
case LIBSSH2_METHOD_KEX:
|
case LIBSSH2_METHOD_KEX:
|
||||||
method = session->kex;
|
method = session->kex;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_HOSTKEY:
|
case LIBSSH2_METHOD_HOSTKEY:
|
||||||
method = (LIBSSH2_KEX_METHOD*)session->hostkey;
|
method = (LIBSSH2_KEX_METHOD*)session->hostkey;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_CRYPT_CS:
|
case LIBSSH2_METHOD_CRYPT_CS:
|
||||||
method = (LIBSSH2_KEX_METHOD*)session->local.crypt;
|
method = (LIBSSH2_KEX_METHOD*)session->local.crypt;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_CRYPT_SC:
|
case LIBSSH2_METHOD_CRYPT_SC:
|
||||||
method = (LIBSSH2_KEX_METHOD*)session->remote.crypt;
|
method = (LIBSSH2_KEX_METHOD*)session->remote.crypt;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_MAC_CS:
|
case LIBSSH2_METHOD_MAC_CS:
|
||||||
method = (LIBSSH2_KEX_METHOD*)session->local.mac;
|
method = (LIBSSH2_KEX_METHOD*)session->local.mac;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_MAC_SC:
|
case LIBSSH2_METHOD_MAC_SC:
|
||||||
method = (LIBSSH2_KEX_METHOD*)session->remote.mac;
|
method = (LIBSSH2_KEX_METHOD*)session->remote.mac;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_COMP_CS:
|
case LIBSSH2_METHOD_COMP_CS:
|
||||||
method = (LIBSSH2_KEX_METHOD*)session->local.comp;
|
method = (LIBSSH2_KEX_METHOD*)session->local.comp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_COMP_SC:
|
case LIBSSH2_METHOD_COMP_SC:
|
||||||
method = (LIBSSH2_KEX_METHOD*)session->remote.comp;
|
method = (LIBSSH2_KEX_METHOD*)session->remote.comp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_LANG_CS:
|
case LIBSSH2_METHOD_LANG_CS:
|
||||||
return "";
|
return "";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_METHOD_LANG_SC:
|
case LIBSSH2_METHOD_LANG_SC:
|
||||||
return "";
|
return "";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid parameter specified for method_type", 0);
|
libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid parameter specified for method_type", 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1051,7 +1058,7 @@ LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int val
|
|||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ _libssh2_session_set_blocking
|
/* {{{ _libssh2_session_set_blocking
|
||||||
* Set a session's blocking mode on or off, return the previous status
|
* Set a session's blocking mode on or off, return the previous status
|
||||||
* when this function is called.
|
* when this function is called.
|
||||||
*/
|
*/
|
||||||
int _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
|
int _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
|
||||||
@@ -1063,9 +1070,9 @@ int _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
|
|||||||
return bl;
|
return bl;
|
||||||
}
|
}
|
||||||
session->socket_block = blocking;
|
session->socket_block = blocking;
|
||||||
|
|
||||||
_libssh2_nonblock(session->socket_fd, !blocking);
|
_libssh2_nonblock(session->socket_fd, !blocking);
|
||||||
|
|
||||||
return bl;
|
return bl;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -1142,12 +1149,16 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
|||||||
unsigned int i, active_fds;
|
unsigned int i, active_fds;
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
LIBSSH2_SESSION *session = NULL;
|
LIBSSH2_SESSION *session = NULL;
|
||||||
struct pollfd sockets[nfds];
|
#ifdef HAVE_ALLOCA
|
||||||
/* FIXME: (dast) this is not C89 code! However, the prototype for this
|
struct pollfd *sockets = alloca(sizeof(struct pollfd) * nfds);
|
||||||
function doesn't provide a session struct so we can't easily use
|
#else
|
||||||
the user-provided malloc replacement here... I suggest we modify
|
struct pollfd sockets[256];
|
||||||
the proto to make it possible. */
|
|
||||||
|
if(nfds > 256)
|
||||||
|
/* systems without alloca use a fixed-size array, this can be fixed
|
||||||
|
if we really want to, at least if the compiler is a C99 capable one */
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
/* Setup sockets for polling */
|
/* Setup sockets for polling */
|
||||||
for(i = 0; i < nfds; i++) {
|
for(i = 0; i < nfds; i++) {
|
||||||
fds[i].revents = 0;
|
fds[i].revents = 0;
|
||||||
@@ -1157,21 +1168,21 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
|||||||
sockets[i].events = fds[i].events;
|
sockets[i].events = fds[i].events;
|
||||||
sockets[i].revents = 0;
|
sockets[i].revents = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_POLLFD_CHANNEL:
|
case LIBSSH2_POLLFD_CHANNEL:
|
||||||
sockets[i].fd = fds[i].fd.channel->session->socket_fd;
|
sockets[i].fd = fds[i].fd.channel->session->socket_fd;
|
||||||
sockets[i].events = POLLIN;
|
sockets[i].events = POLLIN;
|
||||||
sockets[i].revents = 0;
|
sockets[i].revents = 0;
|
||||||
if (!session) session = fds[i].fd.channel->session;
|
if (!session) session = fds[i].fd.channel->session;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_POLLFD_LISTENER:
|
case LIBSSH2_POLLFD_LISTENER:
|
||||||
sockets[i].fd = fds[i].fd.listener->session->socket_fd;
|
sockets[i].fd = fds[i].fd.listener->session->socket_fd;
|
||||||
sockets[i].events = POLLIN;
|
sockets[i].events = POLLIN;
|
||||||
sockets[i].revents = 0;
|
sockets[i].revents = 0;
|
||||||
if (!session) session = fds[i].fd.listener->session;
|
if (!session) session = fds[i].fd.listener->session;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (session) libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
|
if (session) libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
|
||||||
"Invalid descriptor passed to libssh2_poll()", 0);
|
"Invalid descriptor passed to libssh2_poll()", 0);
|
||||||
@@ -1192,29 +1203,35 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
|||||||
case LIBSSH2_POLLFD_SOCKET:
|
case LIBSSH2_POLLFD_SOCKET:
|
||||||
if (fds[i].events & LIBSSH2_POLLFD_POLLIN) {
|
if (fds[i].events & LIBSSH2_POLLFD_POLLIN) {
|
||||||
FD_SET(fds[i].fd.socket, &rfds);
|
FD_SET(fds[i].fd.socket, &rfds);
|
||||||
if (fds[i].fd.socket > maxfd) maxfd = fds[i].fd.socket;
|
if (fds[i].fd.socket > maxfd)
|
||||||
|
maxfd = fds[i].fd.socket;
|
||||||
}
|
}
|
||||||
if (fds[i].events & LIBSSH2_POLLFD_POLLOUT) {
|
if (fds[i].events & LIBSSH2_POLLFD_POLLOUT) {
|
||||||
FD_SET(fds[i].fd.socket, &wfds);
|
FD_SET(fds[i].fd.socket, &wfds);
|
||||||
if (fds[i].fd.socket > maxfd) maxfd = fds[i].fd.socket;
|
if (fds[i].fd.socket > maxfd)
|
||||||
|
maxfd = fds[i].fd.socket;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_POLLFD_CHANNEL:
|
case LIBSSH2_POLLFD_CHANNEL:
|
||||||
FD_SET(fds[i].fd.channel->session->socket_fd, &rfds);
|
FD_SET(fds[i].fd.channel->session->socket_fd, &rfds);
|
||||||
if (fds[i].fd.channel->session->socket_fd > maxfd) maxfd = fds[i].fd.channel->session->socket_fd;
|
if (fds[i].fd.channel->session->socket_fd > maxfd)
|
||||||
|
maxfd = fds[i].fd.channel->session->socket_fd;
|
||||||
if (!session) session = fds[i].fd.channel->session;
|
if (!session) session = fds[i].fd.channel->session;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_POLLFD_LISTENER:
|
case LIBSSH2_POLLFD_LISTENER:
|
||||||
FD_SET(fds[i].fd.listener->session->socket_fd, &rfds);
|
FD_SET(fds[i].fd.listener->session->socket_fd, &rfds);
|
||||||
if (fds[i].fd.listener->session->socket_fd > maxfd) maxfd = fds[i].fd.listener->session->socket_fd;
|
if (fds[i].fd.listener->session->socket_fd > maxfd)
|
||||||
|
maxfd = fds[i].fd.listener->session->socket_fd;
|
||||||
if (!session) session = fds[i].fd.listener->session;
|
if (!session) session = fds[i].fd.listener->session;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (session) libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
|
if (session)
|
||||||
"Invalid descriptor passed to libssh2_poll()", 0);
|
libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
|
||||||
|
"Invalid descriptor passed to libssh2_poll()",
|
||||||
|
0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1257,7 +1274,7 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
|||||||
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
|
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_POLLFD_LISTENER:
|
case LIBSSH2_POLLFD_LISTENER:
|
||||||
if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want a connection */
|
if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want a connection */
|
||||||
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { /* No connections known of yet */
|
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { /* No connections known of yet */
|
||||||
@@ -1368,14 +1385,14 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
|||||||
active_fds++;
|
active_fds++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_POLLFD_CHANNEL:
|
case LIBSSH2_POLLFD_CHANNEL:
|
||||||
if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) {
|
if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) {
|
||||||
/* Spin session until no data available */
|
/* Spin session until no data available */
|
||||||
while (libssh2_packet_read(fds[i].fd.channel->session) > 0);
|
while (libssh2_packet_read(fds[i].fd.channel->session) > 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIBSSH2_POLLFD_LISTENER:
|
case LIBSSH2_POLLFD_LISTENER:
|
||||||
if (FD_ISSET(fds[i].fd.listener->session->socket_fd, &rfds)) {
|
if (FD_ISSET(fds[i].fd.listener->session->socket_fd, &rfds)) {
|
||||||
/* Spin session until no data available */
|
/* Spin session until no data available */
|
||||||
|
|||||||
Reference in New Issue
Block a user