1
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
2
* Copyright (C) Daniel Stenberg
3
* Copyright (C) Simon Josefsson <simon@josefsson.org>
6
* Redistribution and use in source and binary forms,
7
* with or without modification, are permitted provided
8
* that the following conditions are met:
10
* Redistributions of source code must retain the above
11
* copyright notice, this list of conditions and the
12
* following disclaimer.
14
* Redistributions in binary form must reproduce the above
15
* copyright notice, this list of conditions and the following
16
* disclaimer in the documentation and/or other materials
17
* provided with the distribution.
19
* Neither the name of the copyright holder nor the names
20
* of any other contributors may be used to endorse or
21
* promote products derived from this software without
22
* specific prior written permission.
24
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
25
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
26
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
34
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
36
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
39
* SPDX-License-Identifier: BSD-3-Clause
42
#include "libssh2_priv.h"
45
#include <ws2tcpip.h> /* for socklen_t */
64
#define libssh2_usec_t long
65
#elif defined(__APPLE__)
66
#define libssh2_usec_t suseconds_t
71
/* libssh2_default_alloc
74
LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
80
/* libssh2_default_free
83
LIBSSH2_FREE_FUNC(libssh2_default_free)
89
/* libssh2_default_realloc
92
LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
95
return realloc(ptr, count);
101
* Wait for a hello from the remote host
102
* Allocate a buffer and store the banner in session->remote.banner
103
* Returns: 0 on success, LIBSSH2_ERROR_EAGAIN if read would block, negative
107
banner_receive(LIBSSH2_SESSION * session)
112
if(session->banner_TxRx_state == libssh2_NB_state_idle) {
115
session->banner_TxRx_state = libssh2_NB_state_created;
118
banner_len = session->banner_TxRx_total_send;
121
while((banner_len < sizeof(session->banner_TxRx_banner)) &&
123
|| (session->banner_TxRx_banner[banner_len - 1] != '\n'))) {
126
/* no incoming block yet! */
127
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;
129
ret = LIBSSH2_RECV(session, &c, 1,
130
LIBSSH2_SOCKET_RECV_FLAGS(session));
132
if(session->api_block_mode || (ret != -EAGAIN))
133
/* ignore EAGAIN when non-blocking */
134
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
135
"Error recving %d bytes: %ld", 1, (long)-ret));
138
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
139
"Recved %ld bytes banner", (long)ret));
143
session->socket_block_directions =
144
LIBSSH2_SESSION_BLOCK_INBOUND;
145
session->banner_TxRx_total_send = banner_len;
146
return LIBSSH2_ERROR_EAGAIN;
149
/* Some kinda error */
150
session->banner_TxRx_state = libssh2_NB_state_idle;
151
session->banner_TxRx_total_send = 0;
152
return LIBSSH2_ERROR_SOCKET_RECV;
156
session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
157
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
160
if((c == '\r' || c == '\n') && banner_len == 0) {
165
/* NULLs are not allowed in SSH banners */
166
session->banner_TxRx_state = libssh2_NB_state_idle;
167
session->banner_TxRx_total_send = 0;
168
return LIBSSH2_ERROR_BANNER_RECV;
171
session->banner_TxRx_banner[banner_len++] = c;
175
((session->banner_TxRx_banner[banner_len - 1] == '\n') ||
176
(session->banner_TxRx_banner[banner_len - 1] == '\r'))) {
180
/* From this point on, we are done here */
181
session->banner_TxRx_state = libssh2_NB_state_idle;
182
session->banner_TxRx_total_send = 0;
185
return LIBSSH2_ERROR_BANNER_RECV;
187
if(session->remote.banner)
188
LIBSSH2_FREE(session, session->remote.banner);
190
session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1);
191
if(!session->remote.banner) {
192
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
193
"Error allocating space for remote banner");
195
memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len);
196
session->remote.banner[banner_len] = '\0';
197
_libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Received Banner: %s",
198
session->remote.banner));
199
return LIBSSH2_ERROR_NONE;
205
* Send the default banner, or the one set via libssh2_setopt_string
207
* Returns LIBSSH2_ERROR_EAGAIN if it would block - and if it does so, you
208
* should call this function again as soon as it is likely that more data can
209
* be sent, and this function should then be called with the same argument set
210
* (same data pointer and same data_len) until zero or failure is returned.
213
banner_send(LIBSSH2_SESSION * session)
215
char *banner = (char *) LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF;
216
size_t banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1;
219
if(session->banner_TxRx_state == libssh2_NB_state_idle) {
220
if(session->local.banner) {
221
/* setopt_string will have given us our \r\n characters */
222
banner_len = strlen((char *) session->local.banner);
223
banner = (char *) session->local.banner;
227
char banner_dup[256];
229
/* Hack and slash to avoid sending CRLF in debug output */
230
if(banner_len < 256) {
231
memcpy(banner_dup, banner, banner_len - 2);
232
banner_dup[banner_len - 2] = '\0';
235
memcpy(banner_dup, banner, 255);
236
banner_dup[255] = '\0';
239
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
240
"Sending Banner: %s", banner_dup));
244
session->banner_TxRx_state = libssh2_NB_state_created;
247
/* no outgoing block yet! */
248
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND;
250
ret = LIBSSH2_SEND(session,
251
banner + session->banner_TxRx_total_send,
252
banner_len - session->banner_TxRx_total_send,
253
LIBSSH2_SOCKET_SEND_FLAGS(session));
255
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
256
"Error sending %ld bytes: %ld",
257
(long)(banner_len - session->banner_TxRx_total_send),
260
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
261
"Sent %ld/%ld bytes at %p+%ld", (long)ret,
262
(long)(banner_len - session->banner_TxRx_total_send),
263
(void *)banner, (long)session->banner_TxRx_total_send));
265
if(ret != (ssize_t)(banner_len - session->banner_TxRx_total_send)) {
266
if(ret >= 0 || ret == -EAGAIN) {
267
/* the whole packet could not be sent, save the what was */
268
session->socket_block_directions =
269
LIBSSH2_SESSION_BLOCK_OUTBOUND;
271
session->banner_TxRx_total_send += ret;
272
return LIBSSH2_ERROR_EAGAIN;
274
session->banner_TxRx_state = libssh2_NB_state_idle;
275
session->banner_TxRx_total_send = 0;
276
return LIBSSH2_ERROR_SOCKET_RECV;
279
/* Set the state back to idle */
280
session->banner_TxRx_state = libssh2_NB_state_idle;
281
session->banner_TxRx_total_send = 0;
287
* session_nonblock() sets the given socket to either blocking or
288
* non-blocking mode based on the 'nonblock' boolean argument. This function
289
* is copied from the libcurl sources with permission.
292
session_nonblock(libssh2_socket_t sockfd, /* operate on this */
293
int nonblock /* TRUE or FALSE */ )
295
#ifdef HAVE_O_NONBLOCK
296
/* most recent unix versions */
299
flags = fcntl(sockfd, F_GETFL, 0);
301
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
303
return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
304
#elif defined(HAVE_FIONBIO)
305
/* older unix versions and VMS */
309
return ioctl(sockfd, FIONBIO, &flags);
310
#elif defined(HAVE_IOCTLSOCKET_CASE)
311
/* presumably for Amiga */
312
return IoctlSocket(sockfd, FIONBIO, (long) nonblock);
313
#elif defined(HAVE_SO_NONBLOCK)
315
long b = nonblock ? 1 : 0;
316
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
321
return ioctlsocket(sockfd, FIONBIO, &flags);
325
return 0; /* returns success */
330
* get_socket_nonblocking
332
* gets the given blocking or non-blocking state of the socket.
335
get_socket_nonblocking(libssh2_socket_t sockfd)
336
{ /* operate on this */
337
#ifdef HAVE_O_NONBLOCK
338
/* most recent unix versions */
339
int flags = fcntl(sockfd, F_GETFL, 0);
342
/* Assume blocking on error */
345
return (flags & O_NONBLOCK);
346
#elif defined(HAVE_SO_NONBLOCK)
349
if(getsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b))) {
350
/* Assume blocking on error */
354
#elif defined(SO_STATE) && defined(__VMS)
355
/* VMS TCP/IP Services */
359
size_t size = sizeof(int);
361
callstat = getsockopt(sockfd, SOL_SOCKET, SO_STATE,
362
(char *)&sockstat, &size);
366
if((sockstat&SS_NBIO) != 0) {
371
unsigned int option_value;
372
socklen_t option_len = sizeof(option_value);
374
if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
375
(void *) &option_value, &option_len)) {
376
/* Assume blocking on error */
379
return (int) option_value;
382
return 1; /* returns blocking */
386
/* libssh2_session_banner_set
387
* Set the local banner to use in the server handshake.
390
libssh2_session_banner_set(LIBSSH2_SESSION * session, const char *banner)
392
size_t banner_len = banner ? strlen(banner) : 0;
394
if(session->local.banner) {
395
LIBSSH2_FREE(session, session->local.banner);
396
session->local.banner = NULL;
402
session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3);
403
if(!session->local.banner) {
404
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
405
"Unable to allocate memory for local banner");
408
memcpy(session->local.banner, banner, banner_len);
410
/* first zero terminate like this so that the debug output is nice */
411
session->local.banner[banner_len] = '\0';
412
_libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Setting local Banner: %s",
413
session->local.banner));
414
session->local.banner[banner_len++] = '\r';
415
session->local.banner[banner_len++] = '\n';
416
session->local.banner[banner_len] = '\0';
421
#ifndef LIBSSH2_NO_DEPRECATED
423
* Set the local banner. DEPRECATED VERSION
426
libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner)
428
return libssh2_session_banner_set(session, banner);
433
* libssh2_session_init_ex
435
* Allocate and initialize a libssh2 session structure. Allows for malloc
436
* callbacks in case the calling program has its own memory manager It's
437
* allowable (but unadvisable) to define some but not all of the malloc
438
* callbacks An additional pointer value may be optionally passed to be sent
439
* to the callbacks (so they know who's asking)
441
LIBSSH2_API LIBSSH2_SESSION *
442
libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
443
LIBSSH2_FREE_FUNC((*my_free)),
444
LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract)
446
LIBSSH2_ALLOC_FUNC((*local_alloc)) = libssh2_default_alloc;
447
LIBSSH2_FREE_FUNC((*local_free)) = libssh2_default_free;
448
LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc;
449
LIBSSH2_SESSION *session;
452
local_alloc = my_alloc;
455
local_free = my_free;
458
local_realloc = my_realloc;
461
session = local_alloc(sizeof(LIBSSH2_SESSION), &abstract);
463
memset(session, 0, sizeof(LIBSSH2_SESSION));
464
session->alloc = local_alloc;
465
session->free = local_free;
466
session->realloc = local_realloc;
467
session->send = _libssh2_send;
468
session->recv = _libssh2_recv;
469
session->abstract = abstract;
470
session->api_timeout = 0; /* timeout-free API by default */
471
session->api_block_mode = 1; /* blocking API by default */
472
session->state = LIBSSH2_STATE_INITIAL_KEX;
473
session->fullpacket_required_type = 0;
474
session->packet_read_timeout = LIBSSH2_DEFAULT_READ_TIMEOUT;
475
session->flag.quote_paths = 1; /* default behavior is to quote paths
476
for the scp subsystem */
477
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
478
"New session resource allocated"));
479
_libssh2_init_if_needed();
485
* libssh2_session_callback_set2
487
* Set (or reset) a callback function
488
* Returns the prior address
490
LIBSSH2_API libssh2_cb_generic *
491
libssh2_session_callback_set2(LIBSSH2_SESSION *session, int cbtype,
492
libssh2_cb_generic *callback)
494
libssh2_cb_generic *oldcb;
497
case LIBSSH2_CALLBACK_IGNORE:
498
oldcb = (libssh2_cb_generic *)session->ssh_msg_ignore;
499
session->ssh_msg_ignore = (LIBSSH2_IGNORE_FUNC((*)))callback;
502
case LIBSSH2_CALLBACK_DEBUG:
503
oldcb = (libssh2_cb_generic *)session->ssh_msg_debug;
504
session->ssh_msg_debug = (LIBSSH2_DEBUG_FUNC((*)))callback;
507
case LIBSSH2_CALLBACK_DISCONNECT:
508
oldcb = (libssh2_cb_generic *)session->ssh_msg_disconnect;
509
session->ssh_msg_disconnect = (LIBSSH2_DISCONNECT_FUNC((*)))callback;
512
case LIBSSH2_CALLBACK_MACERROR:
513
oldcb = (libssh2_cb_generic *)session->macerror;
514
session->macerror = (LIBSSH2_MACERROR_FUNC((*)))callback;
517
case LIBSSH2_CALLBACK_X11:
518
oldcb = (libssh2_cb_generic *)session->x11;
519
session->x11 = (LIBSSH2_X11_OPEN_FUNC((*)))callback;
522
case LIBSSH2_CALLBACK_SEND:
523
oldcb = (libssh2_cb_generic *)session->send;
524
session->send = (LIBSSH2_SEND_FUNC((*)))callback;
527
case LIBSSH2_CALLBACK_RECV:
528
oldcb = (libssh2_cb_generic *)session->recv;
529
session->recv = (LIBSSH2_RECV_FUNC((*)))callback;
532
case LIBSSH2_CALLBACK_AUTHAGENT:
533
oldcb = (libssh2_cb_generic *)session->authagent;
534
session->authagent = (LIBSSH2_AUTHAGENT_FUNC((*)))callback;
537
case LIBSSH2_CALLBACK_AUTHAGENT_IDENTITIES:
538
oldcb = (libssh2_cb_generic *)session->addLocalIdentities;
539
session->addLocalIdentities =
540
(LIBSSH2_ADD_IDENTITIES_FUNC((*)))callback;
543
case LIBSSH2_CALLBACK_AUTHAGENT_SIGN:
544
oldcb = (libssh2_cb_generic *)session->agentSignCallback;
545
session->agentSignCallback =
546
(LIBSSH2_AUTHAGENT_SIGN_FUNC((*)))callback;
549
_libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Setting Callback %d",
556
* libssh2_session_callback_set (DEPRECATED, DO NOT USE!)
558
* Set (or reset) a callback function
559
* Returns the prior address
561
* ALERT: this function relies on that we can typecast function pointers
562
* to void pointers, which isn't allowed in ISO C!
566
/* 'type cast': from data pointer to function pointer */
567
#pragma warning(disable:4054)
568
/* 'type cast': from function pointer to data pointer */
569
#pragma warning(disable:4055)
571
#pragma GCC diagnostic push
572
#pragma GCC diagnostic ignored "-Wpedantic"
575
libssh2_session_callback_set(LIBSSH2_SESSION * session,
576
int cbtype, void *callback)
578
return (void *)libssh2_session_callback_set2(session, cbtype,
579
(libssh2_cb_generic *)callback);
584
#pragma GCC diagnostic pop
588
* _libssh2_wait_socket
590
* Utility function that waits for action on the socket. Returns 0 when ready
591
* to run again or error on timeout.
593
int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t start_time)
602
/* since libssh2 often sets EAGAIN internally before this function is
603
called, we can decrease some amount of confusion in user programs by
604
resetting the error code in this function to reduce the risk of EAGAIN
605
being stored as error when a blocking function has returned */
606
session->err_code = LIBSSH2_ERROR_NONE;
608
rc = libssh2_keepalive_send(session, &seconds_to_next);
612
ms_to_next = seconds_to_next * 1000;
614
/* figure out what to wait for */
615
dir = libssh2_session_block_directions(session);
618
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
619
"Nothing to wait for in wait_socket"));
620
/* To avoid that we hang below just because there's nothing set to
621
wait for, we timeout on 1 second to also avoid busy-looping
622
during this condition */
626
if(session->api_timeout > 0 &&
627
(seconds_to_next == 0 ||
628
ms_to_next > session->api_timeout)) {
629
time_t now = time(NULL);
630
elapsed_ms = (long)(1000*difftime(now, start_time));
631
if(elapsed_ms > session->api_timeout) {
632
return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
633
"API timeout expired");
635
ms_to_next = (session->api_timeout - elapsed_ms);
638
else if(ms_to_next > 0) {
646
struct pollfd sockets[1];
648
sockets[0].fd = session->socket_fd;
649
sockets[0].events = 0;
650
sockets[0].revents = 0;
652
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
653
sockets[0].events |= POLLIN;
655
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
656
sockets[0].events |= POLLOUT;
658
rc = poll(sockets, 1, has_timeout ? (int)ms_to_next : -1);
664
fd_set *writefd = NULL;
665
fd_set *readfd = NULL;
668
tv.tv_sec = ms_to_next / 1000;
670
tv.tv_usec = (libssh2_usec_t)((ms_to_next - tv.tv_sec*1000) * 1000);
672
tv.tv_usec = (ms_to_next - tv.tv_sec*1000) * 1000;
675
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) {
678
#pragma GCC diagnostic push
679
#pragma GCC diagnostic ignored "-Wsign-conversion"
681
FD_SET(session->socket_fd, &rfd);
683
#pragma GCC diagnostic pop
688
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) {
691
#pragma GCC diagnostic push
692
#pragma GCC diagnostic ignored "-Wsign-conversion"
694
FD_SET(session->socket_fd, &wfd);
696
#pragma GCC diagnostic pop
701
rc = select((int)(session->socket_fd + 1), readfd, writefd, NULL,
702
has_timeout ? &tv : NULL);
706
return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
707
"Timed out waiting on socket");
712
err = _libssh2_wsa2errno();
716
/* Profiling tools that use SIGPROF can cause EINTR responses.
717
poll() / select() do not set any descriptor states on EINTR,
718
but some fds may be ready, so the caller should try again */
722
return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
723
"Error waiting on socket");
726
return 0; /* ready to try again */
730
session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
734
if(session->startup_state == libssh2_NB_state_idle) {
735
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
736
"session_startup for socket %ld", (long)sock));
737
if(LIBSSH2_INVALID_SOCKET == sock) {
738
/* Did we forget something? */
739
return _libssh2_error(session, LIBSSH2_ERROR_BAD_SOCKET,
740
"Bad socket provided");
742
session->socket_fd = sock;
744
session->socket_prev_blockstate =
745
!get_socket_nonblocking(session->socket_fd);
747
if(session->socket_prev_blockstate) {
748
/* If in blocking state change to non-blocking */
749
rc = session_nonblock(session->socket_fd, 1);
751
return _libssh2_error(session, rc,
752
"Failed changing socket's "
753
"blocking state to non-blocking");
757
session->startup_state = libssh2_NB_state_created;
760
if(session->startup_state == libssh2_NB_state_created) {
761
rc = banner_send(session);
762
if(rc == LIBSSH2_ERROR_EAGAIN)
765
return _libssh2_error(session, rc,
766
"Failed sending banner");
768
session->startup_state = libssh2_NB_state_sent;
769
session->banner_TxRx_state = libssh2_NB_state_idle;
772
if(session->startup_state == libssh2_NB_state_sent) {
774
rc = banner_receive(session);
775
if(rc == LIBSSH2_ERROR_EAGAIN)
778
return _libssh2_error(session, rc,
779
"Failed getting banner");
780
} while(strncmp("SSH-", (const char *)session->remote.banner, 4));
782
session->startup_state = libssh2_NB_state_sent1;
785
if(session->startup_state == libssh2_NB_state_sent1) {
786
rc = _libssh2_kex_exchange(session, 0, &session->startup_key_state);
787
if(rc == LIBSSH2_ERROR_EAGAIN)
790
return _libssh2_error(session, rc,
791
"Unable to exchange encryption keys");
793
session->startup_state = libssh2_NB_state_sent2;
796
if(session->startup_state == libssh2_NB_state_sent2) {
797
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
798
"Requesting userauth service"));
800
/* Request the userauth service */
801
session->startup_service[0] = SSH_MSG_SERVICE_REQUEST;
802
_libssh2_htonu32(session->startup_service + 1,
803
sizeof("ssh-userauth") - 1);
804
memcpy(session->startup_service + 5, "ssh-userauth",
805
sizeof("ssh-userauth") - 1);
807
session->startup_state = libssh2_NB_state_sent3;
810
if(session->startup_state == libssh2_NB_state_sent3) {
811
rc = _libssh2_transport_send(session, session->startup_service,
812
sizeof("ssh-userauth") + 5 - 1,
814
if(rc == LIBSSH2_ERROR_EAGAIN)
817
return _libssh2_error(session, rc,
818
"Unable to ask for ssh-userauth service");
821
session->startup_state = libssh2_NB_state_sent4;
824
if(session->startup_state == libssh2_NB_state_sent4) {
825
rc = _libssh2_packet_require(session, SSH_MSG_SERVICE_ACCEPT,
826
&session->startup_data,
827
&session->startup_data_len, 0, NULL, 0,
828
&session->startup_req_state);
830
return _libssh2_error(session, rc,
831
"Failed to get response to "
832
"ssh-userauth request");
834
if(session->startup_data_len < 5) {
835
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
836
"Unexpected packet length");
839
session->startup_service_length =
840
_libssh2_ntohu32(session->startup_data + 1);
843
if((session->startup_service_length != (sizeof("ssh-userauth") - 1))
844
|| strncmp("ssh-userauth",
845
(const char *) session->startup_data + 5,
846
session->startup_service_length)) {
847
LIBSSH2_FREE(session, session->startup_data);
848
session->startup_data = NULL;
849
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
850
"Invalid response received from server");
852
LIBSSH2_FREE(session, session->startup_data);
853
session->startup_data = NULL;
855
session->startup_state = libssh2_NB_state_idle;
860
/* just for safety return some error */
861
return LIBSSH2_ERROR_INVAL;
865
* libssh2_session_handshake
867
* session: LIBSSH2_SESSION struct allocated and owned by the calling program
868
* sock: *must* be populated with an opened and connected socket.
870
* Returns: 0 on success, or non-zero on failure
873
libssh2_session_handshake(LIBSSH2_SESSION *session, libssh2_socket_t sock)
877
BLOCK_ADJUST(rc, session, session_startup(session, sock));
882
#ifndef LIBSSH2_NO_DEPRECATED
884
* libssh2_session_startup
886
* DEPRECATED. Use libssh2_session_handshake() instead! This function is not
889
* session: LIBSSH2_SESSION struct allocated and owned by the calling program
890
* sock: *must* be populated with an opened and connected socket.
892
* Returns: 0 on success, or non-zero on failure
895
libssh2_session_startup(LIBSSH2_SESSION *session, int sock)
897
return libssh2_session_handshake(session, (libssh2_socket_t) sock);
904
* Frees the memory allocated to the session
905
* Also closes and frees any channels attached to this session
908
session_free(LIBSSH2_SESSION *session)
914
int packets_left = 0;
916
if(session->free_state == libssh2_NB_state_idle) {
917
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
918
"Freeing session resource %p",
919
(void *)session->remote.banner));
921
session->free_state = libssh2_NB_state_created;
924
if(session->free_state == libssh2_NB_state_created) {
925
/* !checksrc! disable EQUALSNULL 1 */
926
while((ch = _libssh2_list_first(&session->channels)) != NULL) {
927
rc = _libssh2_channel_free(ch);
928
if(rc == LIBSSH2_ERROR_EAGAIN)
932
session->free_state = libssh2_NB_state_sent;
935
if(session->free_state == libssh2_NB_state_sent) {
936
/* !checksrc! disable EQUALSNULL 1 */
937
while((l = _libssh2_list_first(&session->listeners)) != NULL) {
938
rc = _libssh2_channel_forward_cancel(l);
939
if(rc == LIBSSH2_ERROR_EAGAIN)
943
session->free_state = libssh2_NB_state_sent1;
946
if(session->state & LIBSSH2_STATE_NEWKEYS) {
948
if(session->hostkey && session->hostkey->dtor) {
949
session->hostkey->dtor(session, &session->server_hostkey_abstract);
952
/* Client to Server */
954
if(session->local.crypt && session->local.crypt->dtor) {
955
session->local.crypt->dtor(session,
956
&session->local.crypt_abstract);
959
if(session->local.comp && session->local.comp->dtor) {
960
session->local.comp->dtor(session, 1,
961
&session->local.comp_abstract);
964
if(session->local.mac && session->local.mac->dtor) {
965
session->local.mac->dtor(session, &session->local.mac_abstract);
968
/* Server to Client */
970
if(session->remote.crypt && session->remote.crypt->dtor) {
971
session->remote.crypt->dtor(session,
972
&session->remote.crypt_abstract);
975
if(session->remote.comp && session->remote.comp->dtor) {
976
session->remote.comp->dtor(session, 0,
977
&session->remote.comp_abstract);
980
if(session->remote.mac && session->remote.mac->dtor) {
981
session->remote.mac->dtor(session, &session->remote.mac_abstract);
985
if(session->session_id) {
986
LIBSSH2_FREE(session, session->session_id);
991
if(session->remote.banner) {
992
LIBSSH2_FREE(session, session->remote.banner);
994
if(session->local.banner) {
995
LIBSSH2_FREE(session, session->local.banner);
998
/* Free preference(s) */
999
if(session->kex_prefs) {
1000
LIBSSH2_FREE(session, session->kex_prefs);
1002
if(session->hostkey_prefs) {
1003
LIBSSH2_FREE(session, session->hostkey_prefs);
1006
if(session->local.kexinit) {
1007
LIBSSH2_FREE(session, session->local.kexinit);
1009
if(session->local.crypt_prefs) {
1010
LIBSSH2_FREE(session, session->local.crypt_prefs);
1012
if(session->local.mac_prefs) {
1013
LIBSSH2_FREE(session, session->local.mac_prefs);
1015
if(session->local.comp_prefs) {
1016
LIBSSH2_FREE(session, session->local.comp_prefs);
1018
if(session->local.lang_prefs) {
1019
LIBSSH2_FREE(session, session->local.lang_prefs);
1022
if(session->remote.kexinit) {
1023
LIBSSH2_FREE(session, session->remote.kexinit);
1025
if(session->remote.crypt_prefs) {
1026
LIBSSH2_FREE(session, session->remote.crypt_prefs);
1028
if(session->remote.mac_prefs) {
1029
LIBSSH2_FREE(session, session->remote.mac_prefs);
1031
if(session->remote.comp_prefs) {
1032
LIBSSH2_FREE(session, session->remote.comp_prefs);
1034
if(session->remote.lang_prefs) {
1035
LIBSSH2_FREE(session, session->remote.lang_prefs);
1037
if(session->server_sign_algorithms) {
1038
LIBSSH2_FREE(session, session->server_sign_algorithms);
1040
if(session->sign_algo_prefs) {
1041
LIBSSH2_FREE(session, session->sign_algo_prefs);
1045
* Make sure all memory used in the state variables are free
1047
if(session->kexinit_data) {
1048
LIBSSH2_FREE(session, session->kexinit_data);
1050
if(session->startup_data) {
1051
LIBSSH2_FREE(session, session->startup_data);
1053
if(session->userauth_list_data) {
1054
LIBSSH2_FREE(session, session->userauth_list_data);
1056
if(session->userauth_banner) {
1057
LIBSSH2_FREE(session, session->userauth_banner);
1059
if(session->userauth_pswd_data) {
1060
LIBSSH2_FREE(session, session->userauth_pswd_data);
1062
if(session->userauth_pswd_newpw) {
1063
LIBSSH2_FREE(session, session->userauth_pswd_newpw);
1065
if(session->userauth_host_packet) {
1066
LIBSSH2_FREE(session, session->userauth_host_packet);
1068
if(session->userauth_host_method) {
1069
LIBSSH2_FREE(session, session->userauth_host_method);
1071
if(session->userauth_host_data) {
1072
LIBSSH2_FREE(session, session->userauth_host_data);
1074
if(session->userauth_pblc_data) {
1075
LIBSSH2_FREE(session, session->userauth_pblc_data);
1077
if(session->userauth_pblc_packet) {
1078
LIBSSH2_FREE(session, session->userauth_pblc_packet);
1080
if(session->userauth_pblc_method) {
1081
LIBSSH2_FREE(session, session->userauth_pblc_method);
1083
if(session->userauth_kybd_data) {
1084
LIBSSH2_FREE(session, session->userauth_kybd_data);
1086
if(session->userauth_kybd_packet) {
1087
LIBSSH2_FREE(session, session->userauth_kybd_packet);
1089
if(session->userauth_kybd_auth_instruction) {
1090
LIBSSH2_FREE(session, session->userauth_kybd_auth_instruction);
1092
if(session->open_packet) {
1093
LIBSSH2_FREE(session, session->open_packet);
1095
if(session->open_data) {
1096
LIBSSH2_FREE(session, session->open_data);
1098
if(session->direct_message) {
1099
LIBSSH2_FREE(session, session->direct_message);
1101
if(session->fwdLstn_packet) {
1102
LIBSSH2_FREE(session, session->fwdLstn_packet);
1104
if(session->pkeyInit_data) {
1105
LIBSSH2_FREE(session, session->pkeyInit_data);
1107
if(session->scpRecv_command) {
1108
LIBSSH2_FREE(session, session->scpRecv_command);
1110
if(session->scpSend_command) {
1111
LIBSSH2_FREE(session, session->scpSend_command);
1113
if(session->sftpInit_sftp) {
1114
LIBSSH2_FREE(session, session->sftpInit_sftp);
1117
/* Free payload buffer */
1118
if(session->packet.total_num) {
1119
LIBSSH2_FREE(session, session->packet.payload);
1122
/* Cleanup all remaining packets */
1123
/* !checksrc! disable EQUALSNULL 1 */
1124
while((pkg = _libssh2_list_first(&session->packets)) != NULL) {
1126
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
1127
"packet left with id %d", pkg->data[0]));
1128
/* unlink the node */
1129
_libssh2_list_remove(&pkg->node);
1132
LIBSSH2_FREE(session, pkg->data);
1133
LIBSSH2_FREE(session, pkg);
1136
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
1137
"Extra packets left %d", packets_left));
1139
if(session->socket_prev_blockstate) {
1140
/* if the socket was previously blocking, put it back so */
1141
rc = session_nonblock(session->socket_fd, 0);
1143
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
1144
"unable to reset socket's blocking state"));
1148
if(session->server_hostkey) {
1149
LIBSSH2_FREE(session, session->server_hostkey);
1153
if(session->err_msg &&
1154
((session->err_flags & LIBSSH2_ERR_FLAG_DUP) != 0)) {
1155
LIBSSH2_FREE(session, (char *)session->err_msg);
1158
LIBSSH2_FREE(session, session);
1164
* libssh2_session_free
1166
* Frees the memory allocated to the session
1167
* Also closes and frees any channels attached to this session
1170
libssh2_session_free(LIBSSH2_SESSION * session)
1174
BLOCK_ADJUST(rc, session, session_free(session));
1180
* session_disconnect
1183
session_disconnect(LIBSSH2_SESSION *session, int reason,
1184
const char *description,
1188
size_t descr_len = 0, lang_len = 0;
1191
if(session->disconnect_state == libssh2_NB_state_idle) {
1192
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
1193
"Disconnecting: reason=%d, desc=%s, lang=%s", reason,
1194
description, lang));
1196
descr_len = strlen(description);
1199
lang_len = strlen(lang);
1202
return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
1203
"too long description");
1206
return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
1207
"too long language string");
1209
/* 13 = packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */
1210
session->disconnect_data_len = descr_len + lang_len + 13;
1212
s = session->disconnect_data;
1214
*(s++) = SSH_MSG_DISCONNECT;
1215
_libssh2_store_u32(&s, reason);
1216
_libssh2_store_str(&s, description, descr_len);
1217
/* store length only, lang is sent separately */
1218
_libssh2_store_u32(&s, (uint32_t)lang_len);
1220
session->disconnect_state = libssh2_NB_state_created;
1223
rc = _libssh2_transport_send(session, session->disconnect_data,
1224
session->disconnect_data_len,
1225
(const unsigned char *)lang, lang_len);
1226
if(rc == LIBSSH2_ERROR_EAGAIN)
1229
session->disconnect_state = libssh2_NB_state_idle;
1235
* libssh2_session_disconnect_ex
1238
libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason,
1239
const char *desc, const char *lang)
1242
session->state &= ~LIBSSH2_STATE_INITIAL_KEX;
1243
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
1244
BLOCK_ADJUST(rc, session,
1245
session_disconnect(session, reason, desc, lang));
1250
/* libssh2_session_methods
1252
* Return the currently active methods for method_type
1254
* NOTE: Currently lang_cs and lang_sc are ALWAYS set to empty string
1255
* regardless of actual negotiation Strings should NOT be freed
1257
LIBSSH2_API const char *
1258
libssh2_session_methods(LIBSSH2_SESSION * session, int method_type)
1260
/* All methods have char *name as their first element */
1261
const LIBSSH2_KEX_METHOD *method = NULL;
1263
switch(method_type) {
1264
case LIBSSH2_METHOD_KEX:
1265
method = session->kex;
1268
case LIBSSH2_METHOD_HOSTKEY:
1269
method = (LIBSSH2_KEX_METHOD *) session->hostkey;
1272
case LIBSSH2_METHOD_CRYPT_CS:
1273
method = (LIBSSH2_KEX_METHOD *) session->local.crypt;
1276
case LIBSSH2_METHOD_CRYPT_SC:
1277
method = (LIBSSH2_KEX_METHOD *) session->remote.crypt;
1280
case LIBSSH2_METHOD_MAC_CS:
1281
method = (LIBSSH2_KEX_METHOD *) session->local.mac;
1284
case LIBSSH2_METHOD_MAC_SC:
1285
method = (LIBSSH2_KEX_METHOD *) session->remote.mac;
1288
case LIBSSH2_METHOD_COMP_CS:
1289
method = (LIBSSH2_KEX_METHOD *) session->local.comp;
1292
case LIBSSH2_METHOD_COMP_SC:
1293
method = (LIBSSH2_KEX_METHOD *) session->remote.comp;
1296
case LIBSSH2_METHOD_LANG_CS:
1299
case LIBSSH2_METHOD_LANG_SC:
1303
_libssh2_error(session, LIBSSH2_ERROR_INVAL,
1304
"Invalid parameter specified for method_type");
1309
_libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
1310
"No method negotiated");
1314
return method->name;
1317
/* libssh2_session_abstract
1318
* Retrieve a pointer to the abstract property
1321
libssh2_session_abstract(LIBSSH2_SESSION * session)
1323
return &session->abstract;
1326
/* libssh2_session_last_error
1328
* Returns error code and populates an error string into errmsg If want_buf is
1329
* non-zero then the string placed into errmsg must be freed by the calling
1330
* program. Otherwise it is assumed to be owned by libssh2
1333
libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg,
1334
int *errmsg_len, int want_buf)
1338
/* No error to report */
1339
if(!session->err_code) {
1342
*errmsg = LIBSSH2_ALLOC(session, 1);
1348
*errmsg = (char *) "";
1358
const char *error = session->err_msg ? session->err_msg : "";
1360
msglen = strlen(error);
1363
/* Make a copy so the calling program can own it */
1364
*errmsg = LIBSSH2_ALLOC(session, msglen + 1);
1366
memcpy(*errmsg, error, msglen);
1367
(*errmsg)[msglen] = 0;
1371
*errmsg = (char *)error;
1375
*errmsg_len = (int)msglen;
1378
return session->err_code;
1381
/* libssh2_session_last_errno
1383
* Returns error code
1386
libssh2_session_last_errno(LIBSSH2_SESSION * session)
1388
return session->err_code;
1391
/* libssh2_session_set_last_error
1393
* Sets the internal error code for the session.
1395
* This function is available specifically to be used by high level
1396
* language wrappers (i.e. Python or Perl) that may extend the library
1397
* features while still relying on its error reporting mechanism.
1400
libssh2_session_set_last_error(LIBSSH2_SESSION* session,
1404
return _libssh2_error_flags(session, errcode, errmsg,
1405
LIBSSH2_ERR_FLAG_DUP);
1408
/* libssh2_session_flag
1410
* Set/Get session flags
1412
* Return error code.
1415
libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value)
1418
case LIBSSH2_FLAG_SIGPIPE:
1419
session->flag.sigpipe = value;
1421
case LIBSSH2_FLAG_COMPRESS:
1422
session->flag.compress = value;
1424
case LIBSSH2_FLAG_QUOTE_PATHS:
1425
session->flag.quote_paths = value;
1429
return LIBSSH2_ERROR_INVAL;
1432
return LIBSSH2_ERROR_NONE;
1435
/* _libssh2_session_set_blocking
1437
* Set a session's blocking mode on or off, return the previous status when
1438
* this function is called. Note this function does not alter the state of the
1439
* actual socket involved.
1442
_libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
1444
int bl = session->api_block_mode;
1445
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
1446
"Setting blocking mode %s", blocking ? "ON" : "OFF"));
1447
session->api_block_mode = blocking;
1452
/* libssh2_session_set_blocking
1454
* Set a channel's blocking mode on or off, similar to a socket's
1455
* fcntl(fd, F_SETFL, O_NONBLOCK); type command
1458
libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking)
1460
(void)_libssh2_session_set_blocking(session, blocking);
1463
/* libssh2_session_get_blocking
1465
* Returns a session's blocking mode on or off
1468
libssh2_session_get_blocking(LIBSSH2_SESSION * session)
1470
return session->api_block_mode;
1474
/* libssh2_session_set_timeout
1476
* Set a session's timeout (in msec) for blocking mode,
1477
* or 0 to disable timeouts.
1480
libssh2_session_set_timeout(LIBSSH2_SESSION * session, long timeout)
1482
session->api_timeout = timeout;
1485
/* libssh2_session_get_timeout
1487
* Returns a session's timeout, or 0 if disabled
1490
libssh2_session_get_timeout(LIBSSH2_SESSION * session)
1492
return session->api_timeout;
1495
/* libssh2_session_set_read_timeout
1497
* Set a session's timeout (in sec) when reading packets,
1498
* or 0 to use default of 60 seconds.
1501
libssh2_session_set_read_timeout(LIBSSH2_SESSION * session, long timeout)
1504
timeout = LIBSSH2_DEFAULT_READ_TIMEOUT;
1506
session->packet_read_timeout = timeout;
1509
/* libssh2_session_get_read_timeout
1511
* Returns a session's timeout. Default is 60 seconds.
1514
libssh2_session_get_read_timeout(LIBSSH2_SESSION * session)
1516
return session->packet_read_timeout;
1520
* libssh2_poll_channel_read
1522
* Returns 0 if no data is waiting on channel,
1523
* non-0 if data is available
1526
libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended)
1528
LIBSSH2_SESSION *session;
1529
LIBSSH2_PACKET *packet;
1532
return LIBSSH2_ERROR_BAD_USE;
1534
session = channel->session;
1535
packet = _libssh2_list_first(&session->packets);
1538
if(packet->data_len < 5) {
1539
return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
1540
"Packet too small");
1543
if(channel->local.id == _libssh2_ntohu32(packet->data + 1)) {
1545
(packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA
1546
|| packet->data[0] == SSH_MSG_CHANNEL_DATA)) {
1549
else if(extended == 0 &&
1550
packet->data[0] == SSH_MSG_CHANNEL_DATA) {
1553
/* else - no data of any type is ready to be read */
1555
packet = _libssh2_list_next(&packet->node);
1562
* poll_channel_write
1564
* Returns 0 if writing to channel would block,
1565
* non-0 if data can be written without blocking
1568
poll_channel_write(LIBSSH2_CHANNEL * channel)
1570
return channel->local.window_size ? 1 : 0;
1573
/* poll_listener_queued
1575
* Returns 0 if no connections are waiting to be accepted
1576
* non-0 if one or more connections are available
1579
poll_listener_queued(LIBSSH2_LISTENER * listener)
1581
return _libssh2_list_first(&listener->queue) ? 1 : 0;
1587
* Poll sockets, channels, and listeners for activity
1590
libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
1592
long timeout_remaining;
1593
unsigned int i, active_fds;
1595
LIBSSH2_SESSION *session = NULL;
1597
struct pollfd *sockets = alloca(sizeof(struct pollfd) * nfds);
1599
struct pollfd sockets[256];
1602
/* systems without alloca use a fixed-size array, this can be fixed if
1603
we really want to, at least if the compiler is a C99 capable one */
1606
/* Setup sockets for polling */
1607
for(i = 0; i < nfds; i++) {
1609
switch(fds[i].type) {
1610
case LIBSSH2_POLLFD_SOCKET:
1611
sockets[i].fd = fds[i].fd.socket;
1612
sockets[i].events = (short)fds[i].events;
1613
sockets[i].revents = 0;
1616
case LIBSSH2_POLLFD_CHANNEL:
1617
sockets[i].fd = fds[i].fd.channel->session->socket_fd;
1618
sockets[i].events = POLLIN;
1619
sockets[i].revents = 0;
1621
session = fds[i].fd.channel->session;
1624
case LIBSSH2_POLLFD_LISTENER:
1625
sockets[i].fd = fds[i].fd.listener->session->socket_fd;
1626
sockets[i].events = POLLIN;
1627
sockets[i].revents = 0;
1629
session = fds[i].fd.listener->session;
1634
_libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
1635
"Invalid descriptor passed to libssh2_poll()");
1639
#elif defined(HAVE_SELECT)
1640
LIBSSH2_SESSION *session = NULL;
1641
libssh2_socket_t maxfd = 0;
1647
for(i = 0; i < nfds; i++) {
1649
switch(fds[i].type) {
1650
case LIBSSH2_POLLFD_SOCKET:
1651
if(fds[i].events & LIBSSH2_POLLFD_POLLIN) {
1652
#if defined(__GNUC__)
1653
#pragma GCC diagnostic push
1654
#pragma GCC diagnostic ignored "-Wsign-conversion"
1656
FD_SET(fds[i].fd.socket, &rfds);
1657
#if defined(__GNUC__)
1658
#pragma GCC diagnostic pop
1660
if(fds[i].fd.socket > maxfd)
1661
maxfd = fds[i].fd.socket;
1663
if(fds[i].events & LIBSSH2_POLLFD_POLLOUT) {
1664
#if defined(__GNUC__)
1665
#pragma GCC diagnostic push
1666
#pragma GCC diagnostic ignored "-Wsign-conversion"
1668
FD_SET(fds[i].fd.socket, &wfds);
1669
#if defined(__GNUC__)
1670
#pragma GCC diagnostic pop
1672
if(fds[i].fd.socket > maxfd)
1673
maxfd = fds[i].fd.socket;
1677
case LIBSSH2_POLLFD_CHANNEL:
1678
#if defined(__GNUC__)
1679
#pragma GCC diagnostic push
1680
#pragma GCC diagnostic ignored "-Wsign-conversion"
1682
FD_SET(fds[i].fd.channel->session->socket_fd, &rfds);
1683
#if defined(__GNUC__)
1684
#pragma GCC diagnostic pop
1686
if(fds[i].fd.channel->session->socket_fd > maxfd)
1687
maxfd = fds[i].fd.channel->session->socket_fd;
1689
session = fds[i].fd.channel->session;
1692
case LIBSSH2_POLLFD_LISTENER:
1693
#if defined(__GNUC__)
1694
#pragma GCC diagnostic push
1695
#pragma GCC diagnostic ignored "-Wsign-conversion"
1697
FD_SET(fds[i].fd.listener->session->socket_fd, &rfds);
1698
#if defined(__GNUC__)
1699
#pragma GCC diagnostic pop
1701
if(fds[i].fd.listener->session->socket_fd > maxfd)
1702
maxfd = fds[i].fd.listener->session->socket_fd;
1704
session = fds[i].fd.listener->session;
1709
_libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
1710
"Invalid descriptor passed to libssh2_poll()");
1715
/* No select() or poll()
1716
* no sockets structure to setup
1720
#endif /* HAVE_POLL or HAVE_SELECT */
1722
timeout_remaining = timeout;
1724
#if defined(HAVE_POLL) || defined(HAVE_SELECT)
1730
for(i = 0; i < nfds; i++) {
1731
if(fds[i].events != fds[i].revents) {
1732
switch(fds[i].type) {
1733
case LIBSSH2_POLLFD_CHANNEL:
1734
if((fds[i].events & LIBSSH2_POLLFD_POLLIN) &&
1735
/* Want to be ready for read */
1736
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) {
1737
/* Not yet known to be ready for read */
1739
libssh2_poll_channel_read(fds[i].fd.channel,
1741
LIBSSH2_POLLFD_POLLIN : 0;
1743
if((fds[i].events & LIBSSH2_POLLFD_POLLEXT) &&
1744
/* Want to be ready for extended read */
1745
((fds[i].revents & LIBSSH2_POLLFD_POLLEXT) == 0)) {
1746
/* Not yet known to be ready for extended read */
1748
libssh2_poll_channel_read(fds[i].fd.channel,
1750
LIBSSH2_POLLFD_POLLEXT : 0;
1752
if((fds[i].events & LIBSSH2_POLLFD_POLLOUT) &&
1753
/* Want to be ready for write */
1754
((fds[i].revents & LIBSSH2_POLLFD_POLLOUT) == 0)) {
1755
/* Not yet known to be ready for write */
1757
poll_channel_write(fds[i].fd. channel) ?
1758
LIBSSH2_POLLFD_POLLOUT : 0;
1760
if(fds[i].fd.channel->remote.close
1761
|| fds[i].fd.channel->local.close) {
1762
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED;
1764
if(fds[i].fd.channel->session->socket_state ==
1765
LIBSSH2_SOCKET_DISCONNECTED) {
1767
LIBSSH2_POLLFD_CHANNEL_CLOSED |
1768
LIBSSH2_POLLFD_SESSION_CLOSED;
1772
case LIBSSH2_POLLFD_LISTENER:
1773
if((fds[i].events & LIBSSH2_POLLFD_POLLIN) &&
1774
/* Want a connection */
1775
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) {
1776
/* No connections known of yet */
1778
poll_listener_queued(fds[i].fd. listener) ?
1779
LIBSSH2_POLLFD_POLLIN : 0;
1781
if(fds[i].fd.listener->session->socket_state ==
1782
LIBSSH2_SOCKET_DISCONNECTED) {
1784
LIBSSH2_POLLFD_LISTENER_CLOSED |
1785
LIBSSH2_POLLFD_SESSION_CLOSED;
1790
if(fds[i].revents) {
1796
/* Don't block on the sockets if we have channels/listeners which
1798
timeout_remaining = 0;
1803
struct timeval tv_begin, tv_end;
1805
gettimeofday(&tv_begin, NULL);
1806
sysret = poll(sockets, nfds, (int)timeout_remaining);
1807
gettimeofday(&tv_end, NULL);
1808
timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000;
1809
timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000;
1813
for(i = 0; i < nfds; i++) {
1814
switch(fds[i].type) {
1815
case LIBSSH2_POLLFD_SOCKET:
1816
fds[i].revents = sockets[i].revents;
1817
sockets[i].revents = 0; /* In case we loop again, be
1819
if(fds[i].revents) {
1823
case LIBSSH2_POLLFD_CHANNEL:
1824
if(sockets[i].events & POLLIN) {
1825
/* Spin session until no data available */
1826
while(_libssh2_transport_read(fds[i].fd.
1830
if(sockets[i].revents & POLLHUP) {
1832
LIBSSH2_POLLFD_CHANNEL_CLOSED |
1833
LIBSSH2_POLLFD_SESSION_CLOSED;
1835
sockets[i].revents = 0;
1837
case LIBSSH2_POLLFD_LISTENER:
1838
if(sockets[i].events & POLLIN) {
1839
/* Spin session until no data available */
1840
while(_libssh2_transport_read(fds[i].fd.
1844
if(sockets[i].revents & POLLHUP) {
1846
LIBSSH2_POLLFD_LISTENER_CLOSED |
1847
LIBSSH2_POLLFD_SESSION_CLOSED;
1849
sockets[i].revents = 0;
1854
#elif defined(HAVE_SELECT)
1855
tv.tv_sec = timeout_remaining / 1000;
1856
#ifdef libssh2_usec_t
1857
tv.tv_usec = (libssh2_usec_t)((timeout_remaining % 1000) * 1000);
1859
tv.tv_usec = (timeout_remaining % 1000) * 1000;
1863
struct timeval tv_begin, tv_end;
1865
gettimeofday(&tv_begin, NULL);
1866
sysret = select((int)(maxfd + 1), &rfds, &wfds, NULL, &tv);
1867
gettimeofday(&tv_end, NULL);
1869
timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000;
1870
timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000;
1874
for(i = 0; i < nfds; i++) {
1875
switch(fds[i].type) {
1876
case LIBSSH2_POLLFD_SOCKET:
1877
#if defined(__GNUC__)
1878
#pragma GCC diagnostic push
1879
#pragma GCC diagnostic ignored "-Wsign-conversion"
1881
if(FD_ISSET(fds[i].fd.socket, &rfds)) {
1882
fds[i].revents |= LIBSSH2_POLLFD_POLLIN;
1884
if(FD_ISSET(fds[i].fd.socket, &wfds)) {
1885
fds[i].revents |= LIBSSH2_POLLFD_POLLOUT;
1887
if(fds[i].revents) {
1890
#if defined(__GNUC__)
1891
#pragma GCC diagnostic pop
1895
case LIBSSH2_POLLFD_CHANNEL:
1896
if(FD_ISSET(fds[i].fd.channel->session->socket_fd,
1898
/* Spin session until no data available */
1899
while(_libssh2_transport_read(fds[i].fd.
1905
case LIBSSH2_POLLFD_LISTENER:
1907
(fds[i].fd.listener->session->socket_fd, &rfds)) {
1908
/* Spin session until no data available */
1909
while(_libssh2_transport_read(fds[i].fd.
1917
#endif /* else no select() or poll() -- timeout (and by extension
1918
* timeout_remaining) will be equal to 0 */
1919
} while((timeout_remaining > 0) && !active_fds);
1925
* libssh2_session_block_directions
1927
* Get blocked direction when a function returns LIBSSH2_ERROR_EAGAIN
1928
* Returns LIBSSH2_SOCKET_BLOCK_INBOUND if recv() blocked
1929
* or LIBSSH2_SOCKET_BLOCK_OUTBOUND if send() blocked
1932
libssh2_session_block_directions(LIBSSH2_SESSION *session)
1934
return session->socket_block_directions;
1937
/* libssh2_session_banner_get
1938
* Get the remote banner (server ID string)
1941
LIBSSH2_API const char *
1942
libssh2_session_banner_get(LIBSSH2_SESSION *session)
1944
/* to avoid a coredump when session is NULL */
1948
if(!session->remote.banner)
1951
return (const char *) session->remote.banner;