summaryrefslogtreecommitdiff
path: root/libs/libssh2/src/session.c
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2023-06-09 21:40:16 +0300
committerGeorge Hazan <george.hazan@gmail.com>2023-06-09 21:40:16 +0300
commit927f00cc19b7239a1fe12abe30b472d61b753d8d (patch)
tree68a190dd83dc2dcceb82464a1953f2701af2a109 /libs/libssh2/src/session.c
parent1b241cad53b8c3c5300409fe681de18e636dcf3d (diff)
fixes #3551 (Update libssh2 to 1.11.0)
Diffstat (limited to 'libs/libssh2/src/session.c')
-rw-r--r--libs/libssh2/src/session.c439
1 files changed, 234 insertions, 205 deletions
diff --git a/libs/libssh2/src/session.c b/libs/libssh2/src/session.c
index e439acde57..4d9edc5c8c 100644
--- a/libs/libssh2/src/session.c
+++ b/libs/libssh2/src/session.c
@@ -1,6 +1,6 @@
-/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
- * Copyright (c) 2009-2015 by Daniel Stenberg
- * Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
+/* Copyright (C) Sara Golemon <sarag@libssh2.org>
+ * Copyright (C) Daniel Stenberg
+ * Copyright (C) Simon Josefsson <simon@josefsson.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -35,35 +35,45 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
-#include <errno.h>
+
+#ifdef WIN32
+#include <ws2tcpip.h> /* for socklen_t */
+#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#include <stdlib.h>
-#include <fcntl.h>
-
-#ifdef HAVE_GETTIMEOFDAY
-#include <sys/time.h>
-#endif
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif
+#include <errno.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
#include "transport.h"
#include "session.h"
#include "channel.h"
#include "mac.h"
-#include "misc.h"
+
+#if defined(WIN32)
+#define libssh2_usec_t long
+#elif defined(__APPLE__)
+#define libssh2_usec_t suseconds_t
+#else
+#undef libssh2_usec_t
+#endif
/* libssh2_default_alloc
*/
static
LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
{
- (void) abstract;
+ (void)abstract;
return malloc(count);
}
@@ -72,7 +82,7 @@ LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
static
LIBSSH2_FREE_FUNC(libssh2_default_free)
{
- (void) abstract;
+ (void)abstract;
free(ptr);
}
@@ -81,7 +91,7 @@ LIBSSH2_FREE_FUNC(libssh2_default_free)
static
LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
{
- (void) abstract;
+ (void)abstract;
return realloc(ptr, count);
}
@@ -96,8 +106,8 @@ LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
static int
banner_receive(LIBSSH2_SESSION * session)
{
- int ret;
- int banner_len;
+ ssize_t ret;
+ size_t banner_len;
if(session->banner_TxRx_state == libssh2_NB_state_idle) {
banner_len = 0;
@@ -108,25 +118,25 @@ banner_receive(LIBSSH2_SESSION * session)
banner_len = session->banner_TxRx_total_send;
}
- while((banner_len < (int) sizeof(session->banner_TxRx_banner)) &&
- ((banner_len == 0)
- || (session->banner_TxRx_banner[banner_len - 1] != '\n'))) {
+ while((banner_len < sizeof(session->banner_TxRx_banner)) &&
+ ((banner_len == 0)
+ || (session->banner_TxRx_banner[banner_len - 1] != '\n'))) {
char c = '\0';
/* no incoming block yet! */
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;
ret = LIBSSH2_RECV(session, &c, 1,
- LIBSSH2_SOCKET_RECV_FLAGS(session));
+ LIBSSH2_SOCKET_RECV_FLAGS(session));
if(ret < 0) {
if(session->api_block_mode || (ret != -EAGAIN))
/* ignore EAGAIN when non-blocking */
- _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
- "Error recving %d bytes: %d", 1, -ret);
+ _libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
+ "Error recving %d bytes: %d", 1, (int)-ret));
}
else
- _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
- "Recved %d bytes banner", ret);
+ _libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
+ "Recved %d bytes banner", (int)ret));
if(ret < 0) {
if(ret == -EAGAIN) {
@@ -147,6 +157,10 @@ banner_receive(LIBSSH2_SESSION * session)
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
}
+ if((c == '\r' || c == '\n') && banner_len == 0) {
+ continue;
+ }
+
if(c == '\0') {
/* NULLs are not allowed in SSH banners */
session->banner_TxRx_state = libssh2_NB_state_idle;
@@ -158,8 +172,8 @@ banner_receive(LIBSSH2_SESSION * session)
}
while(banner_len &&
- ((session->banner_TxRx_banner[banner_len - 1] == '\n') ||
- (session->banner_TxRx_banner[banner_len - 1] == '\r'))) {
+ ((session->banner_TxRx_banner[banner_len - 1] == '\n') ||
+ (session->banner_TxRx_banner[banner_len - 1] == '\r'))) {
banner_len--;
}
@@ -180,8 +194,8 @@ banner_receive(LIBSSH2_SESSION * session)
}
memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len);
session->remote.banner[banner_len] = '\0';
- _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Received Banner: %s",
- session->remote.banner);
+ _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Received Banner: %s",
+ session->remote.banner));
return LIBSSH2_ERROR_NONE;
}
@@ -199,11 +213,8 @@ static int
banner_send(LIBSSH2_SESSION * session)
{
char *banner = (char *) LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF;
- int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1;
+ size_t banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1;
ssize_t ret;
-#ifdef LIBSSH2DEBUG
- char banner_dup[256];
-#endif
if(session->banner_TxRx_state == libssh2_NB_state_idle) {
if(session->local.banner) {
@@ -212,18 +223,22 @@ banner_send(LIBSSH2_SESSION * session)
banner = (char *) session->local.banner;
}
#ifdef LIBSSH2DEBUG
- /* Hack and slash to avoid sending CRLF in debug output */
- if(banner_len < 256) {
- memcpy(banner_dup, banner, banner_len - 2);
- banner_dup[banner_len - 2] = '\0';
- }
- else {
- memcpy(banner_dup, banner, 255);
- banner[255] = '\0';
- }
+ {
+ char banner_dup[256];
- _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Sending Banner: %s",
- banner_dup);
+ /* Hack and slash to avoid sending CRLF in debug output */
+ if(banner_len < 256) {
+ memcpy(banner_dup, banner, banner_len - 2);
+ banner_dup[banner_len - 2] = '\0';
+ }
+ else {
+ memcpy(banner_dup, banner, 255);
+ banner_dup[255] = '\0';
+ }
+
+ _libssh2_debug((session, LIBSSH2_TRACE_TRANS,
+ "Sending Banner: %s", banner_dup));
+ }
#endif
session->banner_TxRx_state = libssh2_NB_state_created;
@@ -233,20 +248,20 @@ banner_send(LIBSSH2_SESSION * session)
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND;
ret = LIBSSH2_SEND(session,
- banner + session->banner_TxRx_total_send,
- banner_len - session->banner_TxRx_total_send,
- LIBSSH2_SOCKET_SEND_FLAGS(session));
+ banner + session->banner_TxRx_total_send,
+ banner_len - session->banner_TxRx_total_send,
+ LIBSSH2_SOCKET_SEND_FLAGS(session));
if(ret < 0)
- _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
+ _libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
"Error sending %d bytes: %d",
- banner_len - session->banner_TxRx_total_send, -ret);
+ banner_len - session->banner_TxRx_total_send, -ret));
else
- _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
+ _libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
"Sent %d/%d bytes at %p+%d", ret,
banner_len - session->banner_TxRx_total_send,
- banner, session->banner_TxRx_total_send);
+ banner, session->banner_TxRx_total_send));
- if(ret != (banner_len - session->banner_TxRx_total_send)) {
+ if(ret != (ssize_t)(banner_len - session->banner_TxRx_total_send)) {
if(ret >= 0 || ret == -EAGAIN) {
/* the whole packet could not be sent, save the what was */
session->socket_block_directions =
@@ -276,8 +291,6 @@ static int
session_nonblock(libssh2_socket_t sockfd, /* operate on this */
int nonblock /* TRUE or FALSE */ )
{
-#undef SETBLOCK
-#define SETBLOCK 0
#ifdef HAVE_O_NONBLOCK
/* most recent unix versions */
int flags;
@@ -287,66 +300,39 @@ session_nonblock(libssh2_socket_t sockfd, /* operate on this */
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
else
return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
-#undef SETBLOCK
-#define SETBLOCK 1
-#endif
-
-#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
- /* older unix versions and VMS*/
+#elif defined(HAVE_FIONBIO)
+ /* older unix versions and VMS */
int flags;
flags = nonblock;
return ioctl(sockfd, FIONBIO, &flags);
-#undef SETBLOCK
-#define SETBLOCK 2
-#endif
-
-#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
- /* Windows? */
- unsigned long flags;
- flags = nonblock;
-
- return ioctlsocket(sockfd, FIONBIO, &flags);
-#undef SETBLOCK
-#define SETBLOCK 3
-#endif
-
-#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
+#elif defined(HAVE_IOCTLSOCKET_CASE)
/* presumably for Amiga */
return IoctlSocket(sockfd, FIONBIO, (long) nonblock);
-#undef SETBLOCK
-#define SETBLOCK 4
-#endif
-
-#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
+#elif defined(HAVE_SO_NONBLOCK)
/* BeOS */
long b = nonblock ? 1 : 0;
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
-#undef SETBLOCK
-#define SETBLOCK 5
-#endif
+#elif defined(WIN32)
+ unsigned long flags;
-#ifdef HAVE_DISABLED_NONBLOCKING
+ flags = nonblock;
+ return ioctlsocket(sockfd, FIONBIO, &flags);
+#else
+ (void)sockfd;
+ (void)nonblock;
return 0; /* returns success */
-#undef SETBLOCK
-#define SETBLOCK 6
-#endif
-
-#if(SETBLOCK == 0)
-#error "no non-blocking method was found/used/set"
#endif
}
/*
- * get_socket_nonblocking()
+ * get_socket_nonblocking
*
* gets the given blocking or non-blocking state of the socket.
*/
static int
-get_socket_nonblocking(int sockfd)
+get_socket_nonblocking(libssh2_socket_t sockfd)
{ /* operate on this */
-#undef GETBLOCK
-#define GETBLOCK 0
#ifdef HAVE_O_NONBLOCK
/* most recent unix versions */
int flags = fcntl(sockfd, F_GETFL, 0);
@@ -356,26 +342,7 @@ get_socket_nonblocking(int sockfd)
return 1;
}
return (flags & O_NONBLOCK);
-#undef GETBLOCK
-#define GETBLOCK 1
-#endif
-
-#if defined(WSAEWOULDBLOCK) && (GETBLOCK == 0)
- /* Windows? */
- unsigned int option_value;
- socklen_t option_len = sizeof(option_value);
-
- if(getsockopt
- (sockfd, SOL_SOCKET, SO_ERROR, (void *) &option_value, &option_len)) {
- /* Assume blocking on error */
- return 1;
- }
- return (int) option_value;
-#undef GETBLOCK
-#define GETBLOCK 2
-#endif
-
-#if defined(HAVE_SO_NONBLOCK) && (GETBLOCK == 0)
+#elif defined(HAVE_SO_NONBLOCK)
/* BeOS */
long b;
if(getsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b))) {
@@ -383,12 +350,7 @@ get_socket_nonblocking(int sockfd)
return 1;
}
return (int) b;
-#undef GETBLOCK
-#define GETBLOCK 5
-#endif
-
-#if defined(SO_STATE) && defined(__VMS) && (GETBLOCK == 0)
-
+#elif defined(SO_STATE) && defined(__VMS)
/* VMS TCP/IP Services */
size_t sockstat = 0;
@@ -396,23 +358,27 @@ get_socket_nonblocking(int sockfd)
size_t size = sizeof(int);
callstat = getsockopt(sockfd, SOL_SOCKET, SO_STATE,
- (char *)&sockstat, &size);
- if(callstat == -1) return 0;
- if((sockstat&SS_NBIO) != 0) return 1;
+ (char *)&sockstat, &size);
+ if(callstat == -1) {
+ return 0;
+ }
+ if((sockstat&SS_NBIO) != 0) {
+ return 1;
+ }
return 0;
+#elif defined(WIN32)
+ unsigned int option_value;
+ socklen_t option_len = sizeof(option_value);
-#undef GETBLOCK
-#define GETBLOCK 6
-#endif
-
-#ifdef HAVE_DISABLED_NONBLOCKING
+ if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
+ (void *) &option_value, &option_len)) {
+ /* Assume blocking on error */
+ return 1;
+ }
+ return (int) option_value;
+#else
+ (void)sockfd;
return 1; /* returns blocking */
-#undef GETBLOCK
-#define GETBLOCK 7
-#endif
-
-#if(GETBLOCK == 0)
-#error "no non-blocking method was found/used/get"
#endif
}
@@ -442,8 +408,8 @@ libssh2_session_banner_set(LIBSSH2_SESSION * session, const char *banner)
/* first zero terminate like this so that the debug output is nice */
session->local.banner[banner_len] = '\0';
- _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting local Banner: %s",
- session->local.banner);
+ _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Setting local Banner: %s",
+ session->local.banner));
session->local.banner[banner_len++] = '\r';
session->local.banner[banner_len++] = '\n';
session->local.banner[banner_len] = '\0';
@@ -500,8 +466,11 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
session->abstract = abstract;
session->api_timeout = 0; /* timeout-free API by default */
session->api_block_mode = 1; /* blocking API by default */
- _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
- "New session resource allocated");
+ session->packet_read_timeout = LIBSSH2_DEFAULT_READ_TIMEOUT;
+ session->flag.quote_paths = 1; /* default behavior is to quote paths
+ for the scp subsystem */
+ _libssh2_debug((session, LIBSSH2_TRACE_TRANS,
+ "New session resource allocated"));
_libssh2_init_if_needed();
}
return session;
@@ -516,8 +485,14 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
* ALERT: this function relies on that we can typecast function pointers
* to void pointers, which isn't allowed in ISO C!
*/
+#ifdef _MSC_VER
+#pragma warning(push)
+/* nonstandard extension, function/data pointer conversion in expression */
+#pragma warning(disable:4152)
+#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
LIBSSH2_API void *
libssh2_session_callback_set(LIBSSH2_SESSION * session,
int cbtype, void *callback)
@@ -559,16 +534,35 @@ libssh2_session_callback_set(LIBSSH2_SESSION * session,
oldcb = session->recv;
session->recv = callback;
return oldcb;
+
+ case LIBSSH2_CALLBACK_AUTHAGENT:
+ oldcb = session->authagent;
+ session->authagent = callback;
+ return oldcb;
+
+ case LIBSSH2_CALLBACK_AUTHAGENT_IDENTITIES:
+ oldcb = session->addLocalIdentities;
+ session->addLocalIdentities = callback;
+ return oldcb;
+
+ case LIBSSH2_CALLBACK_AUTHAGENT_SIGN:
+ oldcb = session->agentSignCallback;
+ session->agentSignCallback = callback;
+ return oldcb;
}
- _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting Callback %d",
- cbtype);
+ _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Setting Callback %d",
+ cbtype));
return NULL;
}
+#ifdef _MSC_VER
+#pragma warning(pop)
+#else
#pragma GCC diagnostic pop
+#endif
/*
- * _libssh2_wait_socket()
+ * _libssh2_wait_socket
*
* Utility function that waits for action on the socket. Returns 0 when ready
* to run again or error on timeout.
@@ -589,7 +583,7 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t start_time)
session->err_code = LIBSSH2_ERROR_NONE;
rc = libssh2_keepalive_send(session, &seconds_to_next);
- if(rc < 0)
+ if(rc)
return rc;
ms_to_next = seconds_to_next * 1000;
@@ -598,8 +592,8 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t start_time)
dir = libssh2_session_block_directions(session);
if(!dir) {
- _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
- "Nothing to wait for in wait_socket");
+ _libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
+ "Nothing to wait for in wait_socket"));
/* To avoid that we hang below just because there's nothing set to
wait for, we timeout on 1 second to also avoid busy-looping
during this condition */
@@ -638,7 +632,7 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t start_time)
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
sockets[0].events |= POLLOUT;
- rc = poll(sockets, 1, has_timeout?ms_to_next: -1);
+ rc = poll(sockets, 1, has_timeout ? (int)ms_to_next : -1);
}
#else
{
@@ -649,7 +643,11 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t start_time)
struct timeval tv;
tv.tv_sec = ms_to_next / 1000;
+#ifdef libssh2_usec_t
+ tv.tv_usec = (libssh2_usec_t)((ms_to_next - tv.tv_sec*1000) * 1000);
+#else
tv.tv_usec = (ms_to_next - tv.tv_sec*1000) * 1000;
+#endif
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) {
FD_ZERO(&rfd);
@@ -663,7 +661,7 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t start_time)
writefd = &wfd;
}
- rc = select(session->socket_fd + 1, readfd, writefd, NULL,
+ rc = select((int)(session->socket_fd + 1), readfd, writefd, NULL,
has_timeout ? &tv : NULL);
}
#endif
@@ -685,8 +683,8 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
int rc;
if(session->startup_state == libssh2_NB_state_idle) {
- _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
- "session_startup for socket %d", sock);
+ _libssh2_debug((session, LIBSSH2_TRACE_TRANS,
+ "session_startup for socket %d", sock));
if(LIBSSH2_INVALID_SOCKET == sock) {
/* Did we forget something? */
return _libssh2_error(session, LIBSSH2_ERROR_BAD_SOCKET,
@@ -730,7 +728,7 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
else if(rc)
return _libssh2_error(session, rc,
"Failed getting banner");
- } while(strncmp("SSH-", (char *)session->remote.banner, 4));
+ } while(strncmp("SSH-", (const char *)session->remote.banner, 4));
session->startup_state = libssh2_NB_state_sent1;
}
@@ -747,8 +745,8 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
}
if(session->startup_state == libssh2_NB_state_sent2) {
- _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
- "Requesting userauth service");
+ _libssh2_debug((session, LIBSSH2_TRACE_TRANS,
+ "Requesting userauth service"));
/* Request the userauth service */
session->startup_service[0] = SSH_MSG_SERVICE_REQUEST;
@@ -780,7 +778,9 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
&session->startup_data_len, 0, NULL, 0,
&session->startup_req_state);
if(rc)
- return rc;
+ return _libssh2_error(session, rc,
+ "Failed to get response to "
+ "ssh-userauth request");
if(session->startup_data_len < 5) {
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
@@ -792,7 +792,8 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
if((session->startup_service_length != (sizeof("ssh-userauth") - 1))
- || strncmp("ssh-userauth", (char *) session->startup_data + 5,
+ || strncmp("ssh-userauth",
+ (const char *) session->startup_data + 5,
session->startup_service_length)) {
LIBSSH2_FREE(session, session->startup_data);
session->startup_data = NULL;
@@ -812,7 +813,7 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
}
/*
- * libssh2_session_handshake()
+ * libssh2_session_handshake
*
* session: LIBSSH2_SESSION struct allocated and owned by the calling program
* sock: *must* be populated with an opened and connected socket.
@@ -824,13 +825,13 @@ libssh2_session_handshake(LIBSSH2_SESSION *session, libssh2_socket_t sock)
{
int rc;
- BLOCK_ADJUST(rc, session, session_startup(session, sock) );
+ BLOCK_ADJUST(rc, session, session_startup(session, sock));
return rc;
}
/*
- * libssh2_session_startup()
+ * libssh2_session_startup
*
* DEPRECATED. Use libssh2_session_handshake() instead! This function is not
* portable enough.
@@ -847,7 +848,7 @@ libssh2_session_startup(LIBSSH2_SESSION *session, int sock)
}
/*
- * libssh2_session_free
+ * session_free
*
* Frees the memory allocated to the session
* Also closes and frees any channels attached to this session
@@ -862,16 +863,16 @@ session_free(LIBSSH2_SESSION *session)
int packets_left = 0;
if(session->free_state == libssh2_NB_state_idle) {
- _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
+ _libssh2_debug((session, LIBSSH2_TRACE_TRANS,
"Freeing session resource",
- session->remote.banner);
+ session->remote.banner));
session->free_state = libssh2_NB_state_created;
}
if(session->free_state == libssh2_NB_state_created) {
- while((ch = _libssh2_list_first(&session->channels))) {
-
+ /* !checksrc! disable EQUALSNULL 1 */
+ while((ch = _libssh2_list_first(&session->channels)) != NULL) {
rc = _libssh2_channel_free(ch);
if(rc == LIBSSH2_ERROR_EAGAIN)
return rc;
@@ -881,7 +882,8 @@ session_free(LIBSSH2_SESSION *session)
}
if(session->free_state == libssh2_NB_state_sent) {
- while((l = _libssh2_list_first(&session->listeners))) {
+ /* !checksrc! disable EQUALSNULL 1 */
+ while((l = _libssh2_list_first(&session->listeners)) != NULL) {
rc = _libssh2_channel_forward_cancel(l);
if(rc == LIBSSH2_ERROR_EAGAIN)
return rc;
@@ -981,6 +983,12 @@ session_free(LIBSSH2_SESSION *session)
if(session->remote.lang_prefs) {
LIBSSH2_FREE(session, session->remote.lang_prefs);
}
+ if(session->server_sign_algorithms) {
+ LIBSSH2_FREE(session, session->server_sign_algorithms);
+ }
+ if(session->sign_algo_prefs) {
+ LIBSSH2_FREE(session, session->sign_algo_prefs);
+ }
/*
* Make sure all memory used in the state variables are free
@@ -994,6 +1002,9 @@ session_free(LIBSSH2_SESSION *session)
if(session->userauth_list_data) {
LIBSSH2_FREE(session, session->userauth_list_data);
}
+ if(session->userauth_banner) {
+ LIBSSH2_FREE(session, session->userauth_banner);
+ }
if(session->userauth_pswd_data) {
LIBSSH2_FREE(session, session->userauth_pswd_data);
}
@@ -1058,10 +1069,11 @@ session_free(LIBSSH2_SESSION *session)
}
/* Cleanup all remaining packets */
- while((pkg = _libssh2_list_first(&session->packets))) {
+ /* !checksrc! disable EQUALSNULL 1 */
+ while((pkg = _libssh2_list_first(&session->packets)) != NULL) {
packets_left++;
- _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
- "packet left with id %d", pkg->data[0]);
+ _libssh2_debug((session, LIBSSH2_TRACE_TRANS,
+ "packet left with id %d", pkg->data[0]));
/* unlink the node */
_libssh2_list_remove(&pkg->node);
@@ -1069,15 +1081,16 @@ session_free(LIBSSH2_SESSION *session)
LIBSSH2_FREE(session, pkg->data);
LIBSSH2_FREE(session, pkg);
}
- _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
- "Extra packets left %d", packets_left);
+ (void)packets_left;
+ _libssh2_debug((session, LIBSSH2_TRACE_TRANS,
+ "Extra packets left %d", packets_left));
if(session->socket_prev_blockstate) {
/* if the socket was previously blocking, put it back so */
rc = session_nonblock(session->socket_fd, 0);
if(rc) {
- _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
- "unable to reset socket's blocking state");
+ _libssh2_debug((session, LIBSSH2_TRACE_TRANS,
+ "unable to reset socket's blocking state"));
}
}
@@ -1107,13 +1120,13 @@ libssh2_session_free(LIBSSH2_SESSION * session)
{
int rc;
- BLOCK_ADJUST(rc, session, session_free(session) );
+ BLOCK_ADJUST(rc, session, session_free(session));
return rc;
}
/*
- * libssh2_session_disconnect_ex
+ * session_disconnect
*/
static int
session_disconnect(LIBSSH2_SESSION *session, int reason,
@@ -1121,13 +1134,13 @@ session_disconnect(LIBSSH2_SESSION *session, int reason,
const char *lang)
{
unsigned char *s;
- unsigned long descr_len = 0, lang_len = 0;
+ size_t descr_len = 0, lang_len = 0;
int rc;
if(session->disconnect_state == libssh2_NB_state_idle) {
- _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
+ _libssh2_debug((session, LIBSSH2_TRACE_TRANS,
"Disconnecting: reason=%d, desc=%s, lang=%s", reason,
- description, lang);
+ description, lang));
if(description)
descr_len = strlen(description);
@@ -1138,6 +1151,10 @@ session_disconnect(LIBSSH2_SESSION *session, int reason,
return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
"too long description");
+ if(lang_len > 256)
+ return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
+ "too long language string");
+
/* 13 = packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */
session->disconnect_data_len = descr_len + lang_len + 13;
@@ -1147,14 +1164,14 @@ session_disconnect(LIBSSH2_SESSION *session, int reason,
_libssh2_store_u32(&s, reason);
_libssh2_store_str(&s, description, descr_len);
/* store length only, lang is sent separately */
- _libssh2_store_u32(&s, lang_len);
+ _libssh2_store_u32(&s, (uint32_t)lang_len);
session->disconnect_state = libssh2_NB_state_created;
}
rc = _libssh2_transport_send(session, session->disconnect_data,
session->disconnect_data_len,
- (unsigned char *)lang, lang_len);
+ (const unsigned char *)lang, lang_len);
if(rc == LIBSSH2_ERROR_EAGAIN)
return rc;
@@ -1303,7 +1320,7 @@ libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg,
}
if(errmsg_len) {
- *errmsg_len = msglen;
+ *errmsg_len = (int)msglen;
}
return session->err_code;
@@ -1336,7 +1353,7 @@ libssh2_session_set_last_error(LIBSSH2_SESSION* session,
LIBSSH2_ERR_FLAG_DUP);
}
-/* Libssh2_session_flag
+/* libssh2_session_flag
*
* Set/Get session flags
*
@@ -1352,6 +1369,9 @@ libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value)
case LIBSSH2_FLAG_COMPRESS:
session->flag.compress = value;
break;
+ case LIBSSH2_FLAG_QUOTE_PATHS:
+ session->flag.quote_paths = value;
+ break;
default:
/* unknown flag */
return LIBSSH2_ERROR_INVAL;
@@ -1370,8 +1390,8 @@ int
_libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
{
int bl = session->api_block_mode;
- _libssh2_debug(session, LIBSSH2_TRACE_CONN,
- "Setting blocking mode %s", blocking?"ON":"OFF");
+ _libssh2_debug((session, LIBSSH2_TRACE_CONN,
+ "Setting blocking mode %s", blocking ? "ON" : "OFF"));
session->api_block_mode = blocking;
return bl;
@@ -1385,7 +1405,7 @@ _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
LIBSSH2_API void
libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking)
{
- (void) _libssh2_session_set_blocking(session, blocking);
+ (void)_libssh2_session_set_blocking(session, blocking);
}
/* libssh2_session_get_blocking
@@ -1420,6 +1440,30 @@ libssh2_session_get_timeout(LIBSSH2_SESSION * session)
return session->api_timeout;
}
+/* libssh2_session_set_read_timeout
+ *
+ * Set a session's timeout (in sec) when reading packets,
+ * or 0 to use default of 60 seconds.
+ */
+LIBSSH2_API void
+libssh2_session_set_read_timeout(LIBSSH2_SESSION * session, long timeout)
+{
+ if(timeout <= 0) {
+ timeout = LIBSSH2_DEFAULT_READ_TIMEOUT;
+ }
+ session->packet_read_timeout = timeout;
+}
+
+/* libssh2_session_get_read_timeout
+ *
+ * Returns a session's timeout. Default is 60 seconds.
+ */
+LIBSSH2_API long
+libssh2_session_get_read_timeout(LIBSSH2_SESSION * session)
+{
+ return session->packet_read_timeout;
+}
+
/*
* libssh2_poll_channel_read
*
@@ -1513,7 +1557,7 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
switch(fds[i].type) {
case LIBSSH2_POLLFD_SOCKET:
sockets[i].fd = fds[i].fd.socket;
- sockets[i].events = fds[i].events;
+ sockets[i].events = (short)fds[i].events;
sockets[i].revents = 0;
break;
@@ -1675,23 +1719,15 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
}
#ifdef HAVE_POLL
-#ifdef HAVE_LIBSSH2_GETTIMEOFDAY
{
struct timeval tv_begin, tv_end;
- _libssh2_gettimeofday((struct timeval *) &tv_begin, NULL);
- sysret = poll(sockets, nfds, timeout_remaining);
- _libssh2_gettimeofday((struct timeval *) &tv_end, NULL);
+ gettimeofday(&tv_begin, NULL);
+ sysret = poll(sockets, nfds, (int)timeout_remaining);
+ gettimeofday(&tv_end, NULL);
timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000;
timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000;
}
-#else
- /* If the platform doesn't support gettimeofday,
- * then just make the call non-blocking and walk away
- */
- sysret = poll(sockets, nfds, timeout_remaining);
- timeout_remaining = 0;
-#endif /* HAVE_GETTIMEOFDAY */
if(sysret > 0) {
for(i = 0; i < nfds; i++) {
@@ -1738,24 +1774,17 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
#elif defined(HAVE_SELECT)
tv.tv_sec = timeout_remaining / 1000;
tv.tv_usec = (timeout_remaining % 1000) * 1000;
-#ifdef HAVE_LIBSSH2_GETTIMEOFDAY
+
{
struct timeval tv_begin, tv_end;
- _libssh2_gettimeofday((struct timeval *) &tv_begin, NULL);
- sysret = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
- _libssh2_gettimeofday((struct timeval *) &tv_end, NULL);
+ gettimeofday(&tv_begin, NULL);
+ sysret = select((int)(maxfd + 1), &rfds, &wfds, NULL, &tv);
+ gettimeofday(&tv_end, NULL);
timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000;
timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000;
}
-#else
- /* If the platform doesn't support gettimeofday,
- * then just make the call non-blocking and walk away
- */
- sysret = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
- timeout_remaining = 0;
-#endif
if(sysret > 0) {
for(i = 0; i < nfds; i++) {
@@ -1822,10 +1851,10 @@ LIBSSH2_API const char *
libssh2_session_banner_get(LIBSSH2_SESSION *session)
{
/* to avoid a coredump when session is NULL */
- if(NULL == session)
+ if(!session)
return NULL;
- if(NULL == session->remote.banner)
+ if(!session->remote.banner)
return NULL;
return (const char *) session->remote.banner;