1 /* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
2  * Copyright (c) 2009-2015 by Daniel Stenberg
3  * Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms,
7  * with or without modification, are permitted provided
8  * that the following conditions are met:
9  *
10  *   Redistributions of source code must retain the above
11  *   copyright notice, this list of conditions and the
12  *   following disclaimer.
13  *
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.
18  *
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.
23  *
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
37  * OF SUCH DAMAGE.
38  */
39 
40 #include "libssh2_priv.h"
41 #include <errno.h>
42 #ifdef HAVE_UNISTD_H
43 #include <unistd.h>
44 #endif
45 #include <stdlib.h>
46 #include <fcntl.h>
47 
48 #ifdef HAVE_GETTIMEOFDAY
49 #include <sys/time.h>
50 #endif
51 #ifdef HAVE_ALLOCA_H
52 #include <alloca.h>
53 #endif
54 
55 #include "transport.h"
56 #include "session.h"
57 #include "channel.h"
58 #include "mac.h"
59 #include "misc.h"
60 
61 /* libssh2_default_alloc
62  */
63 static
LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)64 LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
65 {
66     (void) abstract;
67     return malloc(count);
68 }
69 
70 /* libssh2_default_free
71  */
72 static
LIBSSH2_FREE_FUNC(libssh2_default_free)73 LIBSSH2_FREE_FUNC(libssh2_default_free)
74 {
75     (void) abstract;
76     free(ptr);
77 }
78 
79 /* libssh2_default_realloc
80  */
81 static
LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)82 LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
83 {
84     (void) abstract;
85     return realloc(ptr, count);
86 }
87 
88 /*
89  * banner_receive
90  *
91  * Wait for a hello from the remote host
92  * Allocate a buffer and store the banner in session->remote.banner
93  * Returns: 0 on success, LIBSSH2_ERROR_EAGAIN if read would block, negative
94  * on failure
95  */
96 static int
banner_receive(LIBSSH2_SESSION * session)97 banner_receive(LIBSSH2_SESSION * session)
98 {
99     int ret;
100     int banner_len;
101 
102     if(session->banner_TxRx_state == libssh2_NB_state_idle) {
103         banner_len = 0;
104 
105         session->banner_TxRx_state = libssh2_NB_state_created;
106     }
107     else {
108         banner_len = session->banner_TxRx_total_send;
109     }
110 
111     while((banner_len < (int) sizeof(session->banner_TxRx_banner)) &&
112            ((banner_len == 0)
113             || (session->banner_TxRx_banner[banner_len - 1] != '\n'))) {
114         char c = '\0';
115 
116         /* no incoming block yet! */
117         session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;
118 
119         ret = LIBSSH2_RECV(session, &c, 1,
120                             LIBSSH2_SOCKET_RECV_FLAGS(session));
121         if(ret < 0) {
122             if(session->api_block_mode || (ret != -EAGAIN))
123                 /* ignore EAGAIN when non-blocking */
124                 _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
125                                "Error recving %d bytes: %d", 1, -ret);
126         }
127         else
128             _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
129                            "Recved %d bytes banner", ret);
130 
131         if(ret < 0) {
132             if(ret == -EAGAIN) {
133                 session->socket_block_directions =
134                     LIBSSH2_SESSION_BLOCK_INBOUND;
135                 session->banner_TxRx_total_send = banner_len;
136                 return LIBSSH2_ERROR_EAGAIN;
137             }
138 
139             /* Some kinda error */
140             session->banner_TxRx_state = libssh2_NB_state_idle;
141             session->banner_TxRx_total_send = 0;
142             return LIBSSH2_ERROR_SOCKET_RECV;
143         }
144 
145         if(ret == 0) {
146             session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
147             return LIBSSH2_ERROR_SOCKET_DISCONNECT;
148         }
149 
150         if(c == '\0') {
151             /* NULLs are not allowed in SSH banners */
152             session->banner_TxRx_state = libssh2_NB_state_idle;
153             session->banner_TxRx_total_send = 0;
154             return LIBSSH2_ERROR_BANNER_RECV;
155         }
156 
157         session->banner_TxRx_banner[banner_len++] = c;
158     }
159 
160     while(banner_len &&
161            ((session->banner_TxRx_banner[banner_len - 1] == '\n') ||
162             (session->banner_TxRx_banner[banner_len - 1] == '\r'))) {
163         banner_len--;
164     }
165 
166     /* From this point on, we are done here */
167     session->banner_TxRx_state = libssh2_NB_state_idle;
168     session->banner_TxRx_total_send = 0;
169 
170     if(!banner_len)
171         return LIBSSH2_ERROR_BANNER_RECV;
172 
173     if(session->remote.banner)
174         LIBSSH2_FREE(session, session->remote.banner);
175 
176     session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1);
177     if(!session->remote.banner) {
178         return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
179                               "Error allocating space for remote banner");
180     }
181     memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len);
182     session->remote.banner[banner_len] = '\0';
183     _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Received Banner: %s",
184                    session->remote.banner);
185     return LIBSSH2_ERROR_NONE;
186 }
187 
188 /*
189  * banner_send
190  *
191  * Send the default banner, or the one set via libssh2_setopt_string
192  *
193  * Returns LIBSSH2_ERROR_EAGAIN if it would block - and if it does so, you
194  * should call this function again as soon as it is likely that more data can
195  * be sent, and this function should then be called with the same argument set
196  * (same data pointer and same data_len) until zero or failure is returned.
197  */
198 static int
banner_send(LIBSSH2_SESSION * session)199 banner_send(LIBSSH2_SESSION * session)
200 {
201     char *banner = (char *) LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF;
202     int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1;
203     ssize_t ret;
204 #ifdef LIBSSH2DEBUG
205     char banner_dup[256];
206 #endif
207 
208     if(session->banner_TxRx_state == libssh2_NB_state_idle) {
209         if(session->local.banner) {
210             /* setopt_string will have given us our \r\n characters */
211             banner_len = strlen((char *) session->local.banner);
212             banner = (char *) session->local.banner;
213         }
214 #ifdef LIBSSH2DEBUG
215         /* Hack and slash to avoid sending CRLF in debug output */
216         if(banner_len < 256) {
217             memcpy(banner_dup, banner, banner_len - 2);
218             banner_dup[banner_len - 2] = '\0';
219         }
220         else {
221             memcpy(banner_dup, banner, 255);
222             banner[255] = '\0';
223         }
224 
225         _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Sending Banner: %s",
226                        banner_dup);
227 #endif
228 
229         session->banner_TxRx_state = libssh2_NB_state_created;
230     }
231 
232     /* no outgoing block yet! */
233     session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND;
234 
235     ret = LIBSSH2_SEND(session,
236                         banner + session->banner_TxRx_total_send,
237                         banner_len - session->banner_TxRx_total_send,
238                         LIBSSH2_SOCKET_SEND_FLAGS(session));
239     if(ret < 0)
240         _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
241                        "Error sending %d bytes: %d",
242                        banner_len - session->banner_TxRx_total_send, -ret);
243     else
244         _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
245                        "Sent %d/%d bytes at %p+%d", ret,
246                        banner_len - session->banner_TxRx_total_send,
247                        banner, session->banner_TxRx_total_send);
248 
249     if(ret != (banner_len - session->banner_TxRx_total_send)) {
250         if(ret >= 0 || ret == -EAGAIN) {
251             /* the whole packet could not be sent, save the what was */
252             session->socket_block_directions =
253                 LIBSSH2_SESSION_BLOCK_OUTBOUND;
254             if(ret > 0)
255                 session->banner_TxRx_total_send += ret;
256             return LIBSSH2_ERROR_EAGAIN;
257         }
258         session->banner_TxRx_state = libssh2_NB_state_idle;
259         session->banner_TxRx_total_send = 0;
260         return LIBSSH2_ERROR_SOCKET_RECV;
261     }
262 
263     /* Set the state back to idle */
264     session->banner_TxRx_state = libssh2_NB_state_idle;
265     session->banner_TxRx_total_send = 0;
266 
267     return 0;
268 }
269 
270 /*
271  * session_nonblock() sets the given socket to either blocking or
272  * non-blocking mode based on the 'nonblock' boolean argument. This function
273  * is copied from the libcurl sources with permission.
274  */
275 static int
session_nonblock(libssh2_socket_t sockfd,int nonblock)276 session_nonblock(libssh2_socket_t sockfd,   /* operate on this */
277                  int nonblock /* TRUE or FALSE */ )
278 {
279 #undef SETBLOCK
280 #define SETBLOCK 0
281 #ifdef HAVE_O_NONBLOCK
282     /* most recent unix versions */
283     int flags;
284 
285     flags = fcntl(sockfd, F_GETFL, 0);
286     if(nonblock)
287         return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
288     else
289         return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
290 #undef SETBLOCK
291 #define SETBLOCK 1
292 #endif
293 
294 #if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
295     /* older unix versions and VMS*/
296     int flags;
297 
298     flags = nonblock;
299     return ioctl(sockfd, FIONBIO, &flags);
300 #undef SETBLOCK
301 #define SETBLOCK 2
302 #endif
303 
304 #if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
305     /* Windows? */
306     unsigned long flags;
307     flags = nonblock;
308 
309     return ioctlsocket(sockfd, FIONBIO, &flags);
310 #undef SETBLOCK
311 #define SETBLOCK 3
312 #endif
313 
314 #if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
315     /* presumably for Amiga */
316     return IoctlSocket(sockfd, FIONBIO, (long) nonblock);
317 #undef SETBLOCK
318 #define SETBLOCK 4
319 #endif
320 
321 #if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
322     /* BeOS */
323     long b = nonblock ? 1 : 0;
324     return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
325 #undef SETBLOCK
326 #define SETBLOCK 5
327 #endif
328 
329 #ifdef HAVE_DISABLED_NONBLOCKING
330     return 0;                   /* returns success */
331 #undef SETBLOCK
332 #define SETBLOCK 6
333 #endif
334 
335 #if(SETBLOCK == 0)
336 #error "no non-blocking method was found/used/set"
337 #endif
338 }
339 
340 /*
341  * get_socket_nonblocking()
342  *
343  * gets the given blocking or non-blocking state of the socket.
344  */
345 static int
get_socket_nonblocking(int sockfd)346 get_socket_nonblocking(int sockfd)
347 {                               /* operate on this */
348 #undef GETBLOCK
349 #define GETBLOCK 0
350 #ifdef HAVE_O_NONBLOCK
351     /* most recent unix versions */
352     int flags = fcntl(sockfd, F_GETFL, 0);
353 
354     if(flags == -1) {
355         /* Assume blocking on error */
356         return 1;
357     }
358     return (flags & O_NONBLOCK);
359 #undef GETBLOCK
360 #define GETBLOCK 1
361 #endif
362 
363 #if defined(WSAEWOULDBLOCK) && (GETBLOCK == 0)
364     /* Windows? */
365     unsigned int option_value;
366     socklen_t option_len = sizeof(option_value);
367 
368     if(getsockopt
369         (sockfd, SOL_SOCKET, SO_ERROR, (void *) &option_value, &option_len)) {
370         /* Assume blocking on error */
371         return 1;
372     }
373     return (int) option_value;
374 #undef GETBLOCK
375 #define GETBLOCK 2
376 #endif
377 
378 #if defined(HAVE_SO_NONBLOCK) && (GETBLOCK == 0)
379     /* BeOS */
380     long b;
381     if(getsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b))) {
382         /* Assume blocking on error */
383         return 1;
384     }
385     return (int) b;
386 #undef GETBLOCK
387 #define GETBLOCK 5
388 #endif
389 
390 #if defined(SO_STATE) && defined(__VMS) && (GETBLOCK == 0)
391 
392     /* VMS TCP/IP Services */
393 
394     size_t sockstat = 0;
395     int    callstat = 0;
396     size_t size = sizeof(int);
397 
398     callstat = getsockopt(sockfd, SOL_SOCKET, SO_STATE,
399                                   (char *)&sockstat, &size);
400     if(callstat == -1) return 0;
401     if((sockstat&SS_NBIO) != 0) return 1;
402     return 0;
403 
404 #undef GETBLOCK
405 #define GETBLOCK 6
406 #endif
407 
408 #ifdef HAVE_DISABLED_NONBLOCKING
409     return 1;                   /* returns blocking */
410 #undef GETBLOCK
411 #define GETBLOCK 7
412 #endif
413 
414 #if(GETBLOCK == 0)
415 #error "no non-blocking method was found/used/get"
416 #endif
417 }
418 
419 /* libssh2_session_banner_set
420  * Set the local banner to use in the server handshake.
421  */
422 LIBSSH2_API int
libssh2_session_banner_set(LIBSSH2_SESSION * session,const char * banner)423 libssh2_session_banner_set(LIBSSH2_SESSION * session, const char *banner)
424 {
425     size_t banner_len = banner ? strlen(banner) : 0;
426 
427     if(session->local.banner) {
428         LIBSSH2_FREE(session, session->local.banner);
429         session->local.banner = NULL;
430     }
431 
432     if(!banner_len)
433         return 0;
434 
435     session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3);
436     if(!session->local.banner) {
437         return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
438                               "Unable to allocate memory for local banner");
439     }
440 
441     memcpy(session->local.banner, banner, banner_len);
442 
443     /* first zero terminate like this so that the debug output is nice */
444     session->local.banner[banner_len] = '\0';
445     _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting local Banner: %s",
446                    session->local.banner);
447     session->local.banner[banner_len++] = '\r';
448     session->local.banner[banner_len++] = '\n';
449     session->local.banner[banner_len] = '\0';
450 
451     return 0;
452 }
453 
454 /* libssh2_banner_set
455  * Set the local banner. DEPRECATED VERSION
456  */
457 LIBSSH2_API int
libssh2_banner_set(LIBSSH2_SESSION * session,const char * banner)458 libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner)
459 {
460     return libssh2_session_banner_set(session, banner);
461 }
462 
463 /*
464  * libssh2_session_init_ex
465  *
466  * Allocate and initialize a libssh2 session structure. Allows for malloc
467  * callbacks in case the calling program has its own memory manager It's
468  * allowable (but unadvisable) to define some but not all of the malloc
469  * callbacks An additional pointer value may be optionally passed to be sent
470  * to the callbacks (so they know who's asking)
471  */
472 LIBSSH2_API LIBSSH2_SESSION *
libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC ((* my_alloc)),LIBSSH2_FREE_FUNC ((* my_free)),LIBSSH2_REALLOC_FUNC ((* my_realloc)),void * abstract)473 libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
474                         LIBSSH2_FREE_FUNC((*my_free)),
475                         LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract)
476 {
477     LIBSSH2_ALLOC_FUNC((*local_alloc)) = libssh2_default_alloc;
478     LIBSSH2_FREE_FUNC((*local_free)) = libssh2_default_free;
479     LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc;
480     LIBSSH2_SESSION *session;
481 
482     if(my_alloc) {
483         local_alloc = my_alloc;
484     }
485     if(my_free) {
486         local_free = my_free;
487     }
488     if(my_realloc) {
489         local_realloc = my_realloc;
490     }
491 
492     session = local_alloc(sizeof(LIBSSH2_SESSION), &abstract);
493     if(session) {
494         memset(session, 0, sizeof(LIBSSH2_SESSION));
495         session->alloc = local_alloc;
496         session->free = local_free;
497         session->realloc = local_realloc;
498         session->send = _libssh2_send;
499         session->recv = _libssh2_recv;
500         session->abstract = abstract;
501         session->api_timeout = 0; /* timeout-free API by default */
502         session->api_block_mode = 1; /* blocking API by default */
503         _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
504                        "New session resource allocated");
505         _libssh2_init_if_needed();
506     }
507     return session;
508 }
509 
510 /*
511  * libssh2_session_callback_set
512  *
513  * Set (or reset) a callback function
514  * Returns the prior address
515  *
516  * ALERT: this function relies on that we can typecast function pointers
517  * to void pointers, which isn't allowed in ISO C!
518  */
519 #pragma GCC diagnostic push
520 #pragma GCC diagnostic ignored "-Wpedantic"
521 LIBSSH2_API void *
libssh2_session_callback_set(LIBSSH2_SESSION * session,int cbtype,void * callback)522 libssh2_session_callback_set(LIBSSH2_SESSION * session,
523                              int cbtype, void *callback)
524 {
525     void *oldcb;
526 
527     switch(cbtype) {
528     case LIBSSH2_CALLBACK_IGNORE:
529         oldcb = session->ssh_msg_ignore;
530         session->ssh_msg_ignore = callback;
531         return oldcb;
532 
533     case LIBSSH2_CALLBACK_DEBUG:
534         oldcb = session->ssh_msg_debug;
535         session->ssh_msg_debug = callback;
536         return oldcb;
537 
538     case LIBSSH2_CALLBACK_DISCONNECT:
539         oldcb = session->ssh_msg_disconnect;
540         session->ssh_msg_disconnect = callback;
541         return oldcb;
542 
543     case LIBSSH2_CALLBACK_MACERROR:
544         oldcb = session->macerror;
545         session->macerror = callback;
546         return oldcb;
547 
548     case LIBSSH2_CALLBACK_X11:
549         oldcb = session->x11;
550         session->x11 = callback;
551         return oldcb;
552 
553     case LIBSSH2_CALLBACK_SEND:
554         oldcb = session->send;
555         session->send = callback;
556         return oldcb;
557 
558     case LIBSSH2_CALLBACK_RECV:
559         oldcb = session->recv;
560         session->recv = callback;
561         return oldcb;
562     }
563     _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting Callback %d",
564                    cbtype);
565 
566     return NULL;
567 }
568 #pragma GCC diagnostic pop
569 
570 /*
571  * _libssh2_wait_socket()
572  *
573  * Utility function that waits for action on the socket. Returns 0 when ready
574  * to run again or error on timeout.
575  */
_libssh2_wait_socket(LIBSSH2_SESSION * session,time_t start_time)576 int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t start_time)
577 {
578     int rc;
579     int seconds_to_next;
580     int dir;
581     int has_timeout;
582     long ms_to_next = 0;
583     long elapsed_ms;
584 
585     /* since libssh2 often sets EAGAIN internally before this function is
586        called, we can decrease some amount of confusion in user programs by
587        resetting the error code in this function to reduce the risk of EAGAIN
588        being stored as error when a blocking function has returned */
589     session->err_code = LIBSSH2_ERROR_NONE;
590 
591     rc = libssh2_keepalive_send(session, &seconds_to_next);
592     if(rc < 0)
593         return rc;
594 
595     ms_to_next = seconds_to_next * 1000;
596 
597     /* figure out what to wait for */
598     dir = libssh2_session_block_directions(session);
599 
600     if(!dir) {
601         _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
602                        "Nothing to wait for in wait_socket");
603         /* To avoid that we hang below just because there's nothing set to
604            wait for, we timeout on 1 second to also avoid busy-looping
605            during this condition */
606         ms_to_next = 1000;
607     }
608 
609     if(session->api_timeout > 0 &&
610         (seconds_to_next == 0 ||
611          ms_to_next > session->api_timeout)) {
612         time_t now = time(NULL);
613         elapsed_ms = (long)(1000*difftime(now, start_time));
614         if(elapsed_ms > session->api_timeout) {
615             return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
616                                   "API timeout expired");
617         }
618         ms_to_next = (session->api_timeout - elapsed_ms);
619         has_timeout = 1;
620     }
621     else if(ms_to_next > 0) {
622         has_timeout = 1;
623     }
624     else
625         has_timeout = 0;
626 
627 #ifdef HAVE_POLL
628     {
629         struct pollfd sockets[1];
630 
631         sockets[0].fd = session->socket_fd;
632         sockets[0].events = 0;
633         sockets[0].revents = 0;
634 
635         if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
636             sockets[0].events |= POLLIN;
637 
638         if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
639             sockets[0].events |= POLLOUT;
640 
641         rc = poll(sockets, 1, has_timeout?ms_to_next: -1);
642     }
643 #else
644     {
645         fd_set rfd;
646         fd_set wfd;
647         fd_set *writefd = NULL;
648         fd_set *readfd = NULL;
649         struct timeval tv;
650 
651         tv.tv_sec = ms_to_next / 1000;
652         tv.tv_usec = (ms_to_next - tv.tv_sec*1000) * 1000;
653 
654         if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) {
655             FD_ZERO(&rfd);
656             FD_SET(session->socket_fd, &rfd);
657             readfd = &rfd;
658         }
659 
660         if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) {
661             FD_ZERO(&wfd);
662             FD_SET(session->socket_fd, &wfd);
663             writefd = &wfd;
664         }
665 
666         rc = select(session->socket_fd + 1, readfd, writefd, NULL,
667                     has_timeout ? &tv : NULL);
668     }
669 #endif
670     if(rc == 0) {
671         return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
672                               "Timed out waiting on socket");
673     }
674     if(rc < 0) {
675         return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
676                               "Error waiting on socket");
677     }
678 
679     return 0; /* ready to try again */
680 }
681 
682 static int
session_startup(LIBSSH2_SESSION * session,libssh2_socket_t sock)683 session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
684 {
685     int rc;
686 
687     if(session->startup_state == libssh2_NB_state_idle) {
688         _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
689                        "session_startup for socket %d", sock);
690         if(LIBSSH2_INVALID_SOCKET == sock) {
691             /* Did we forget something? */
692             return _libssh2_error(session, LIBSSH2_ERROR_BAD_SOCKET,
693                                   "Bad socket provided");
694         }
695         session->socket_fd = sock;
696 
697         session->socket_prev_blockstate =
698             !get_socket_nonblocking(session->socket_fd);
699 
700         if(session->socket_prev_blockstate) {
701             /* If in blocking state change to non-blocking */
702             rc = session_nonblock(session->socket_fd, 1);
703             if(rc) {
704                 return _libssh2_error(session, rc,
705                                       "Failed changing socket's "
706                                       "blocking state to non-blocking");
707             }
708         }
709 
710         session->startup_state = libssh2_NB_state_created;
711     }
712 
713     if(session->startup_state == libssh2_NB_state_created) {
714         rc = banner_send(session);
715         if(rc == LIBSSH2_ERROR_EAGAIN)
716             return rc;
717         else if(rc) {
718             return _libssh2_error(session, rc,
719                                   "Failed sending banner");
720         }
721         session->startup_state = libssh2_NB_state_sent;
722         session->banner_TxRx_state = libssh2_NB_state_idle;
723     }
724 
725     if(session->startup_state == libssh2_NB_state_sent) {
726         do {
727             rc = banner_receive(session);
728             if(rc == LIBSSH2_ERROR_EAGAIN)
729                 return rc;
730             else if(rc)
731                 return _libssh2_error(session, rc,
732                                       "Failed getting banner");
733         } while(strncmp("SSH-", (char *)session->remote.banner, 4));
734 
735         session->startup_state = libssh2_NB_state_sent1;
736     }
737 
738     if(session->startup_state == libssh2_NB_state_sent1) {
739         rc = _libssh2_kex_exchange(session, 0, &session->startup_key_state);
740         if(rc == LIBSSH2_ERROR_EAGAIN)
741             return rc;
742         else if(rc)
743             return _libssh2_error(session, rc,
744                                   "Unable to exchange encryption keys");
745 
746         session->startup_state = libssh2_NB_state_sent2;
747     }
748 
749     if(session->startup_state == libssh2_NB_state_sent2) {
750         _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
751                        "Requesting userauth service");
752 
753         /* Request the userauth service */
754         session->startup_service[0] = SSH_MSG_SERVICE_REQUEST;
755         _libssh2_htonu32(session->startup_service + 1,
756                          sizeof("ssh-userauth") - 1);
757         memcpy(session->startup_service + 5, "ssh-userauth",
758                sizeof("ssh-userauth") - 1);
759 
760         session->startup_state = libssh2_NB_state_sent3;
761     }
762 
763     if(session->startup_state == libssh2_NB_state_sent3) {
764         rc = _libssh2_transport_send(session, session->startup_service,
765                                      sizeof("ssh-userauth") + 5 - 1,
766                                      NULL, 0);
767         if(rc == LIBSSH2_ERROR_EAGAIN)
768             return rc;
769         else if(rc) {
770             return _libssh2_error(session, rc,
771                                   "Unable to ask for ssh-userauth service");
772         }
773 
774         session->startup_state = libssh2_NB_state_sent4;
775     }
776 
777     if(session->startup_state == libssh2_NB_state_sent4) {
778         rc = _libssh2_packet_require(session, SSH_MSG_SERVICE_ACCEPT,
779                                      &session->startup_data,
780                                      &session->startup_data_len, 0, NULL, 0,
781                                      &session->startup_req_state);
782         if(rc)
783             return rc;
784 
785         if(session->startup_data_len < 5) {
786             return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
787                                   "Unexpected packet length");
788         }
789 
790         session->startup_service_length =
791             _libssh2_ntohu32(session->startup_data + 1);
792 
793 
794         if((session->startup_service_length != (sizeof("ssh-userauth") - 1))
795             || strncmp("ssh-userauth", (char *) session->startup_data + 5,
796                        session->startup_service_length)) {
797             LIBSSH2_FREE(session, session->startup_data);
798             session->startup_data = NULL;
799             return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
800                                   "Invalid response received from server");
801         }
802         LIBSSH2_FREE(session, session->startup_data);
803         session->startup_data = NULL;
804 
805         session->startup_state = libssh2_NB_state_idle;
806 
807         return 0;
808     }
809 
810     /* just for safety return some error */
811     return LIBSSH2_ERROR_INVAL;
812 }
813 
814 /*
815  * libssh2_session_handshake()
816  *
817  * session: LIBSSH2_SESSION struct allocated and owned by the calling program
818  * sock:    *must* be populated with an opened and connected socket.
819  *
820  * Returns: 0 on success, or non-zero on failure
821  */
822 LIBSSH2_API int
libssh2_session_handshake(LIBSSH2_SESSION * session,libssh2_socket_t sock)823 libssh2_session_handshake(LIBSSH2_SESSION *session, libssh2_socket_t sock)
824 {
825     int rc;
826 
827     BLOCK_ADJUST(rc, session, session_startup(session, sock) );
828 
829     return rc;
830 }
831 
832 /*
833  * libssh2_session_startup()
834  *
835  * DEPRECATED. Use libssh2_session_handshake() instead! This function is not
836  * portable enough.
837  *
838  * session: LIBSSH2_SESSION struct allocated and owned by the calling program
839  * sock:    *must* be populated with an opened and connected socket.
840  *
841  * Returns: 0 on success, or non-zero on failure
842  */
843 LIBSSH2_API int
libssh2_session_startup(LIBSSH2_SESSION * session,int sock)844 libssh2_session_startup(LIBSSH2_SESSION *session, int sock)
845 {
846     return libssh2_session_handshake(session, (libssh2_socket_t) sock);
847 }
848 
849 /*
850  * libssh2_session_free
851  *
852  * Frees the memory allocated to the session
853  * Also closes and frees any channels attached to this session
854  */
855 static int
session_free(LIBSSH2_SESSION * session)856 session_free(LIBSSH2_SESSION *session)
857 {
858     int rc;
859     LIBSSH2_PACKET *pkg;
860     LIBSSH2_CHANNEL *ch;
861     LIBSSH2_LISTENER *l;
862     int packets_left = 0;
863 
864     if(session->free_state == libssh2_NB_state_idle) {
865         _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
866                        "Freeing session resource",
867                        session->remote.banner);
868 
869         session->free_state = libssh2_NB_state_created;
870     }
871 
872     if(session->free_state == libssh2_NB_state_created) {
873         while((ch = _libssh2_list_first(&session->channels))) {
874 
875             rc = _libssh2_channel_free(ch);
876             if(rc == LIBSSH2_ERROR_EAGAIN)
877                 return rc;
878         }
879 
880         session->free_state = libssh2_NB_state_sent;
881     }
882 
883     if(session->free_state == libssh2_NB_state_sent) {
884         while((l = _libssh2_list_first(&session->listeners))) {
885             rc = _libssh2_channel_forward_cancel(l);
886             if(rc == LIBSSH2_ERROR_EAGAIN)
887                 return rc;
888         }
889 
890         session->free_state = libssh2_NB_state_sent1;
891     }
892 
893     if(session->state & LIBSSH2_STATE_NEWKEYS) {
894         /* hostkey */
895         if(session->hostkey && session->hostkey->dtor) {
896             session->hostkey->dtor(session, &session->server_hostkey_abstract);
897         }
898 
899         /* Client to Server */
900         /* crypt */
901         if(session->local.crypt && session->local.crypt->dtor) {
902             session->local.crypt->dtor(session,
903                                        &session->local.crypt_abstract);
904         }
905         /* comp */
906         if(session->local.comp && session->local.comp->dtor) {
907             session->local.comp->dtor(session, 1,
908                                       &session->local.comp_abstract);
909         }
910         /* mac */
911         if(session->local.mac && session->local.mac->dtor) {
912             session->local.mac->dtor(session, &session->local.mac_abstract);
913         }
914 
915         /* Server to Client */
916         /* crypt */
917         if(session->remote.crypt && session->remote.crypt->dtor) {
918             session->remote.crypt->dtor(session,
919                                         &session->remote.crypt_abstract);
920         }
921         /* comp */
922         if(session->remote.comp && session->remote.comp->dtor) {
923             session->remote.comp->dtor(session, 0,
924                                        &session->remote.comp_abstract);
925         }
926         /* mac */
927         if(session->remote.mac && session->remote.mac->dtor) {
928             session->remote.mac->dtor(session, &session->remote.mac_abstract);
929         }
930 
931         /* session_id */
932         if(session->session_id) {
933             LIBSSH2_FREE(session, session->session_id);
934         }
935     }
936 
937     /* Free banner(s) */
938     if(session->remote.banner) {
939         LIBSSH2_FREE(session, session->remote.banner);
940     }
941     if(session->local.banner) {
942         LIBSSH2_FREE(session, session->local.banner);
943     }
944 
945     /* Free preference(s) */
946     if(session->kex_prefs) {
947         LIBSSH2_FREE(session, session->kex_prefs);
948     }
949     if(session->hostkey_prefs) {
950         LIBSSH2_FREE(session, session->hostkey_prefs);
951     }
952 
953     if(session->local.kexinit) {
954         LIBSSH2_FREE(session, session->local.kexinit);
955     }
956     if(session->local.crypt_prefs) {
957         LIBSSH2_FREE(session, session->local.crypt_prefs);
958     }
959     if(session->local.mac_prefs) {
960         LIBSSH2_FREE(session, session->local.mac_prefs);
961     }
962     if(session->local.comp_prefs) {
963         LIBSSH2_FREE(session, session->local.comp_prefs);
964     }
965     if(session->local.lang_prefs) {
966         LIBSSH2_FREE(session, session->local.lang_prefs);
967     }
968 
969     if(session->remote.kexinit) {
970         LIBSSH2_FREE(session, session->remote.kexinit);
971     }
972     if(session->remote.crypt_prefs) {
973         LIBSSH2_FREE(session, session->remote.crypt_prefs);
974     }
975     if(session->remote.mac_prefs) {
976         LIBSSH2_FREE(session, session->remote.mac_prefs);
977     }
978     if(session->remote.comp_prefs) {
979         LIBSSH2_FREE(session, session->remote.comp_prefs);
980     }
981     if(session->remote.lang_prefs) {
982         LIBSSH2_FREE(session, session->remote.lang_prefs);
983     }
984 
985     /*
986      * Make sure all memory used in the state variables are free
987      */
988     if(session->kexinit_data) {
989         LIBSSH2_FREE(session, session->kexinit_data);
990     }
991     if(session->startup_data) {
992         LIBSSH2_FREE(session, session->startup_data);
993     }
994     if(session->userauth_list_data) {
995         LIBSSH2_FREE(session, session->userauth_list_data);
996     }
997     if(session->userauth_pswd_data) {
998         LIBSSH2_FREE(session, session->userauth_pswd_data);
999     }
1000     if(session->userauth_pswd_newpw) {
1001         LIBSSH2_FREE(session, session->userauth_pswd_newpw);
1002     }
1003     if(session->userauth_host_packet) {
1004         LIBSSH2_FREE(session, session->userauth_host_packet);
1005     }
1006     if(session->userauth_host_method) {
1007         LIBSSH2_FREE(session, session->userauth_host_method);
1008     }
1009     if(session->userauth_host_data) {
1010         LIBSSH2_FREE(session, session->userauth_host_data);
1011     }
1012     if(session->userauth_pblc_data) {
1013         LIBSSH2_FREE(session, session->userauth_pblc_data);
1014     }
1015     if(session->userauth_pblc_packet) {
1016         LIBSSH2_FREE(session, session->userauth_pblc_packet);
1017     }
1018     if(session->userauth_pblc_method) {
1019         LIBSSH2_FREE(session, session->userauth_pblc_method);
1020     }
1021     if(session->userauth_kybd_data) {
1022         LIBSSH2_FREE(session, session->userauth_kybd_data);
1023     }
1024     if(session->userauth_kybd_packet) {
1025         LIBSSH2_FREE(session, session->userauth_kybd_packet);
1026     }
1027     if(session->userauth_kybd_auth_instruction) {
1028         LIBSSH2_FREE(session, session->userauth_kybd_auth_instruction);
1029     }
1030     if(session->open_packet) {
1031         LIBSSH2_FREE(session, session->open_packet);
1032     }
1033     if(session->open_data) {
1034         LIBSSH2_FREE(session, session->open_data);
1035     }
1036     if(session->direct_message) {
1037         LIBSSH2_FREE(session, session->direct_message);
1038     }
1039     if(session->fwdLstn_packet) {
1040         LIBSSH2_FREE(session, session->fwdLstn_packet);
1041     }
1042     if(session->pkeyInit_data) {
1043         LIBSSH2_FREE(session, session->pkeyInit_data);
1044     }
1045     if(session->scpRecv_command) {
1046         LIBSSH2_FREE(session, session->scpRecv_command);
1047     }
1048     if(session->scpSend_command) {
1049         LIBSSH2_FREE(session, session->scpSend_command);
1050     }
1051     if(session->sftpInit_sftp) {
1052         LIBSSH2_FREE(session, session->sftpInit_sftp);
1053     }
1054 
1055     /* Free payload buffer */
1056     if(session->packet.total_num) {
1057         LIBSSH2_FREE(session, session->packet.payload);
1058     }
1059 
1060     /* Cleanup all remaining packets */
1061     while((pkg = _libssh2_list_first(&session->packets))) {
1062         packets_left++;
1063         _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
1064             "packet left with id %d", pkg->data[0]);
1065         /* unlink the node */
1066         _libssh2_list_remove(&pkg->node);
1067 
1068         /* free */
1069         LIBSSH2_FREE(session, pkg->data);
1070         LIBSSH2_FREE(session, pkg);
1071     }
1072     _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
1073          "Extra packets left %d", packets_left);
1074 
1075     if(session->socket_prev_blockstate) {
1076         /* if the socket was previously blocking, put it back so */
1077         rc = session_nonblock(session->socket_fd, 0);
1078         if(rc) {
1079             _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
1080              "unable to reset socket's blocking state");
1081         }
1082     }
1083 
1084     if(session->server_hostkey) {
1085         LIBSSH2_FREE(session, session->server_hostkey);
1086     }
1087 
1088     /* error string */
1089     if(session->err_msg &&
1090        ((session->err_flags & LIBSSH2_ERR_FLAG_DUP) != 0)) {
1091         LIBSSH2_FREE(session, (char *)session->err_msg);
1092     }
1093 
1094     LIBSSH2_FREE(session, session);
1095 
1096     return 0;
1097 }
1098 
1099 /*
1100  * libssh2_session_free
1101  *
1102  * Frees the memory allocated to the session
1103  * Also closes and frees any channels attached to this session
1104  */
1105 LIBSSH2_API int
libssh2_session_free(LIBSSH2_SESSION * session)1106 libssh2_session_free(LIBSSH2_SESSION * session)
1107 {
1108     int rc;
1109 
1110     BLOCK_ADJUST(rc, session, session_free(session) );
1111 
1112     return rc;
1113 }
1114 
1115 /*
1116  * libssh2_session_disconnect_ex
1117  */
1118 static int
session_disconnect(LIBSSH2_SESSION * session,int reason,const char * description,const char * lang)1119 session_disconnect(LIBSSH2_SESSION *session, int reason,
1120                    const char *description,
1121                    const char *lang)
1122 {
1123     unsigned char *s;
1124     unsigned long descr_len = 0, lang_len = 0;
1125     int rc;
1126 
1127     if(session->disconnect_state == libssh2_NB_state_idle) {
1128         _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
1129                        "Disconnecting: reason=%d, desc=%s, lang=%s", reason,
1130                        description, lang);
1131         if(description)
1132             descr_len = strlen(description);
1133 
1134         if(lang)
1135             lang_len = strlen(lang);
1136 
1137         if(descr_len > 256)
1138             return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
1139                                   "too long description");
1140 
1141         /* 13 = packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */
1142         session->disconnect_data_len = descr_len + lang_len + 13;
1143 
1144         s = session->disconnect_data;
1145 
1146         *(s++) = SSH_MSG_DISCONNECT;
1147         _libssh2_store_u32(&s, reason);
1148         _libssh2_store_str(&s, description, descr_len);
1149         /* store length only, lang is sent separately */
1150         _libssh2_store_u32(&s, lang_len);
1151 
1152         session->disconnect_state = libssh2_NB_state_created;
1153     }
1154 
1155     rc = _libssh2_transport_send(session, session->disconnect_data,
1156                                  session->disconnect_data_len,
1157                                  (unsigned char *)lang, lang_len);
1158     if(rc == LIBSSH2_ERROR_EAGAIN)
1159         return rc;
1160 
1161     session->disconnect_state = libssh2_NB_state_idle;
1162 
1163     return 0;
1164 }
1165 
1166 /*
1167  * libssh2_session_disconnect_ex
1168  */
1169 LIBSSH2_API int
libssh2_session_disconnect_ex(LIBSSH2_SESSION * session,int reason,const char * desc,const char * lang)1170 libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason,
1171                               const char *desc, const char *lang)
1172 {
1173     int rc;
1174     session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
1175     BLOCK_ADJUST(rc, session,
1176                  session_disconnect(session, reason, desc, lang));
1177 
1178     return rc;
1179 }
1180 
1181 /* libssh2_session_methods
1182  *
1183  * Return the currently active methods for method_type
1184  *
1185  * NOTE: Currently lang_cs and lang_sc are ALWAYS set to empty string
1186  * regardless of actual negotiation Strings should NOT be freed
1187  */
1188 LIBSSH2_API const char *
libssh2_session_methods(LIBSSH2_SESSION * session,int method_type)1189 libssh2_session_methods(LIBSSH2_SESSION * session, int method_type)
1190 {
1191     /* All methods have char *name as their first element */
1192     const LIBSSH2_KEX_METHOD *method = NULL;
1193 
1194     switch(method_type) {
1195     case LIBSSH2_METHOD_KEX:
1196         method = session->kex;
1197         break;
1198 
1199     case LIBSSH2_METHOD_HOSTKEY:
1200         method = (LIBSSH2_KEX_METHOD *) session->hostkey;
1201         break;
1202 
1203     case LIBSSH2_METHOD_CRYPT_CS:
1204         method = (LIBSSH2_KEX_METHOD *) session->local.crypt;
1205         break;
1206 
1207     case LIBSSH2_METHOD_CRYPT_SC:
1208         method = (LIBSSH2_KEX_METHOD *) session->remote.crypt;
1209         break;
1210 
1211     case LIBSSH2_METHOD_MAC_CS:
1212         method = (LIBSSH2_KEX_METHOD *) session->local.mac;
1213         break;
1214 
1215     case LIBSSH2_METHOD_MAC_SC:
1216         method = (LIBSSH2_KEX_METHOD *) session->remote.mac;
1217         break;
1218 
1219     case LIBSSH2_METHOD_COMP_CS:
1220         method = (LIBSSH2_KEX_METHOD *) session->local.comp;
1221         break;
1222 
1223     case LIBSSH2_METHOD_COMP_SC:
1224         method = (LIBSSH2_KEX_METHOD *) session->remote.comp;
1225         break;
1226 
1227     case LIBSSH2_METHOD_LANG_CS:
1228         return "";
1229 
1230     case LIBSSH2_METHOD_LANG_SC:
1231         return "";
1232 
1233     default:
1234         _libssh2_error(session, LIBSSH2_ERROR_INVAL,
1235                        "Invalid parameter specified for method_type");
1236         return NULL;
1237     }
1238 
1239     if(!method) {
1240         _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
1241                        "No method negotiated");
1242         return NULL;
1243     }
1244 
1245     return method->name;
1246 }
1247 
1248 /* libssh2_session_abstract
1249  * Retrieve a pointer to the abstract property
1250  */
1251 LIBSSH2_API void **
libssh2_session_abstract(LIBSSH2_SESSION * session)1252 libssh2_session_abstract(LIBSSH2_SESSION * session)
1253 {
1254     return &session->abstract;
1255 }
1256 
1257 /* libssh2_session_last_error
1258  *
1259  * Returns error code and populates an error string into errmsg If want_buf is
1260  * non-zero then the string placed into errmsg must be freed by the calling
1261  * program. Otherwise it is assumed to be owned by libssh2
1262  */
1263 LIBSSH2_API int
libssh2_session_last_error(LIBSSH2_SESSION * session,char ** errmsg,int * errmsg_len,int want_buf)1264 libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg,
1265                            int *errmsg_len, int want_buf)
1266 {
1267     size_t msglen = 0;
1268 
1269     /* No error to report */
1270     if(!session->err_code) {
1271         if(errmsg) {
1272             if(want_buf) {
1273                 *errmsg = LIBSSH2_ALLOC(session, 1);
1274                 if(*errmsg) {
1275                     **errmsg = 0;
1276                 }
1277             }
1278             else {
1279                 *errmsg = (char *) "";
1280             }
1281         }
1282         if(errmsg_len) {
1283             *errmsg_len = 0;
1284         }
1285         return 0;
1286     }
1287 
1288     if(errmsg) {
1289         const char *error = session->err_msg ? session->err_msg : "";
1290 
1291         msglen = strlen(error);
1292 
1293         if(want_buf) {
1294             /* Make a copy so the calling program can own it */
1295             *errmsg = LIBSSH2_ALLOC(session, msglen + 1);
1296             if(*errmsg) {
1297                 memcpy(*errmsg, error, msglen);
1298                 (*errmsg)[msglen] = 0;
1299             }
1300         }
1301         else
1302             *errmsg = (char *)error;
1303     }
1304 
1305     if(errmsg_len) {
1306         *errmsg_len = msglen;
1307     }
1308 
1309     return session->err_code;
1310 }
1311 
1312 /* libssh2_session_last_errno
1313  *
1314  * Returns error code
1315  */
1316 LIBSSH2_API int
libssh2_session_last_errno(LIBSSH2_SESSION * session)1317 libssh2_session_last_errno(LIBSSH2_SESSION * session)
1318 {
1319     return session->err_code;
1320 }
1321 
1322 /* libssh2_session_set_last_error
1323  *
1324  * Sets the internal error code for the session.
1325  *
1326  * This function is available specifically to be used by high level
1327  * language wrappers (i.e. Python or Perl) that may extend the library
1328  * features while still relying on its error reporting mechanism.
1329  */
1330 LIBSSH2_API int
libssh2_session_set_last_error(LIBSSH2_SESSION * session,int errcode,const char * errmsg)1331 libssh2_session_set_last_error(LIBSSH2_SESSION* session,
1332                                int errcode,
1333                                const char *errmsg)
1334 {
1335     return _libssh2_error_flags(session, errcode, errmsg,
1336                                 LIBSSH2_ERR_FLAG_DUP);
1337 }
1338 
1339 /* Libssh2_session_flag
1340  *
1341  * Set/Get session flags
1342  *
1343  * Return error code.
1344  */
1345 LIBSSH2_API int
libssh2_session_flag(LIBSSH2_SESSION * session,int flag,int value)1346 libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value)
1347 {
1348     switch(flag) {
1349     case LIBSSH2_FLAG_SIGPIPE:
1350         session->flag.sigpipe = value;
1351         break;
1352     case LIBSSH2_FLAG_COMPRESS:
1353         session->flag.compress = value;
1354         break;
1355     default:
1356         /* unknown flag */
1357         return LIBSSH2_ERROR_INVAL;
1358     }
1359 
1360     return LIBSSH2_ERROR_NONE;
1361 }
1362 
1363 /* _libssh2_session_set_blocking
1364  *
1365  * Set a session's blocking mode on or off, return the previous status when
1366  * this function is called. Note this function does not alter the state of the
1367  * actual socket involved.
1368  */
1369 int
_libssh2_session_set_blocking(LIBSSH2_SESSION * session,int blocking)1370 _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
1371 {
1372     int bl = session->api_block_mode;
1373     _libssh2_debug(session, LIBSSH2_TRACE_CONN,
1374                    "Setting blocking mode %s", blocking?"ON":"OFF");
1375     session->api_block_mode = blocking;
1376 
1377     return bl;
1378 }
1379 
1380 /* libssh2_session_set_blocking
1381  *
1382  * Set a channel's blocking mode on or off, similar to a socket's
1383  * fcntl(fd, F_SETFL, O_NONBLOCK); type command
1384  */
1385 LIBSSH2_API void
libssh2_session_set_blocking(LIBSSH2_SESSION * session,int blocking)1386 libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking)
1387 {
1388     (void) _libssh2_session_set_blocking(session, blocking);
1389 }
1390 
1391 /* libssh2_session_get_blocking
1392  *
1393  * Returns a session's blocking mode on or off
1394  */
1395 LIBSSH2_API int
libssh2_session_get_blocking(LIBSSH2_SESSION * session)1396 libssh2_session_get_blocking(LIBSSH2_SESSION * session)
1397 {
1398     return session->api_block_mode;
1399 }
1400 
1401 
1402 /* libssh2_session_set_timeout
1403  *
1404  * Set a session's timeout (in msec) for blocking mode,
1405  * or 0 to disable timeouts.
1406  */
1407 LIBSSH2_API void
libssh2_session_set_timeout(LIBSSH2_SESSION * session,long timeout)1408 libssh2_session_set_timeout(LIBSSH2_SESSION * session, long timeout)
1409 {
1410     session->api_timeout = timeout;
1411 }
1412 
1413 /* libssh2_session_get_timeout
1414  *
1415  * Returns a session's timeout, or 0 if disabled
1416  */
1417 LIBSSH2_API long
libssh2_session_get_timeout(LIBSSH2_SESSION * session)1418 libssh2_session_get_timeout(LIBSSH2_SESSION * session)
1419 {
1420     return session->api_timeout;
1421 }
1422 
1423 /*
1424  * libssh2_poll_channel_read
1425  *
1426  * Returns 0 if no data is waiting on channel,
1427  * non-0 if data is available
1428  */
1429 LIBSSH2_API int
libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel,int extended)1430 libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended)
1431 {
1432     LIBSSH2_SESSION *session;
1433     LIBSSH2_PACKET *packet;
1434 
1435     if(!channel)
1436         return LIBSSH2_ERROR_BAD_USE;
1437 
1438     session = channel->session;
1439     packet = _libssh2_list_first(&session->packets);
1440 
1441     while(packet) {
1442         if(packet->data_len < 5) {
1443             return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
1444                                   "Packet too small");
1445         }
1446 
1447         if(channel->local.id == _libssh2_ntohu32(packet->data + 1)) {
1448             if(extended == 1 &&
1449                 (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA
1450                  || packet->data[0] == SSH_MSG_CHANNEL_DATA)) {
1451                 return 1;
1452             }
1453             else if(extended == 0 &&
1454                     packet->data[0] == SSH_MSG_CHANNEL_DATA) {
1455                 return 1;
1456             }
1457             /* else - no data of any type is ready to be read */
1458         }
1459         packet = _libssh2_list_next(&packet->node);
1460     }
1461 
1462     return 0;
1463 }
1464 
1465 /*
1466  * poll_channel_write
1467  *
1468  * Returns 0 if writing to channel would block,
1469  * non-0 if data can be written without blocking
1470  */
1471 static inline int
poll_channel_write(LIBSSH2_CHANNEL * channel)1472 poll_channel_write(LIBSSH2_CHANNEL * channel)
1473 {
1474     return channel->local.window_size ? 1 : 0;
1475 }
1476 
1477 /* poll_listener_queued
1478  *
1479  * Returns 0 if no connections are waiting to be accepted
1480  * non-0 if one or more connections are available
1481  */
1482 static inline int
poll_listener_queued(LIBSSH2_LISTENER * listener)1483 poll_listener_queued(LIBSSH2_LISTENER * listener)
1484 {
1485     return _libssh2_list_first(&listener->queue) ? 1 : 0;
1486 }
1487 
1488 /*
1489  * libssh2_poll
1490  *
1491  * Poll sockets, channels, and listeners for activity
1492  */
1493 LIBSSH2_API int
libssh2_poll(LIBSSH2_POLLFD * fds,unsigned int nfds,long timeout)1494 libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
1495 {
1496     long timeout_remaining;
1497     unsigned int i, active_fds;
1498 #ifdef HAVE_POLL
1499     LIBSSH2_SESSION *session = NULL;
1500 #ifdef HAVE_ALLOCA
1501     struct pollfd *sockets = alloca(sizeof(struct pollfd) * nfds);
1502 #else
1503     struct pollfd sockets[256];
1504 
1505     if(nfds > 256)
1506         /* systems without alloca use a fixed-size array, this can be fixed if
1507            we really want to, at least if the compiler is a C99 capable one */
1508         return -1;
1509 #endif
1510     /* Setup sockets for polling */
1511     for(i = 0; i < nfds; i++) {
1512         fds[i].revents = 0;
1513         switch(fds[i].type) {
1514         case LIBSSH2_POLLFD_SOCKET:
1515             sockets[i].fd = fds[i].fd.socket;
1516             sockets[i].events = fds[i].events;
1517             sockets[i].revents = 0;
1518             break;
1519 
1520         case LIBSSH2_POLLFD_CHANNEL:
1521             sockets[i].fd = fds[i].fd.channel->session->socket_fd;
1522             sockets[i].events = POLLIN;
1523             sockets[i].revents = 0;
1524             if(!session)
1525                 session = fds[i].fd.channel->session;
1526             break;
1527 
1528         case LIBSSH2_POLLFD_LISTENER:
1529             sockets[i].fd = fds[i].fd.listener->session->socket_fd;
1530             sockets[i].events = POLLIN;
1531             sockets[i].revents = 0;
1532             if(!session)
1533                 session = fds[i].fd.listener->session;
1534             break;
1535 
1536         default:
1537             if(session)
1538                 _libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
1539                                "Invalid descriptor passed to libssh2_poll()");
1540             return -1;
1541         }
1542     }
1543 #elif defined(HAVE_SELECT)
1544     LIBSSH2_SESSION *session = NULL;
1545     libssh2_socket_t maxfd = 0;
1546     fd_set rfds, wfds;
1547     struct timeval tv;
1548 
1549     FD_ZERO(&rfds);
1550     FD_ZERO(&wfds);
1551     for(i = 0; i < nfds; i++) {
1552         fds[i].revents = 0;
1553         switch(fds[i].type) {
1554         case LIBSSH2_POLLFD_SOCKET:
1555             if(fds[i].events & LIBSSH2_POLLFD_POLLIN) {
1556                 FD_SET(fds[i].fd.socket, &rfds);
1557                 if(fds[i].fd.socket > maxfd)
1558                     maxfd = fds[i].fd.socket;
1559             }
1560             if(fds[i].events & LIBSSH2_POLLFD_POLLOUT) {
1561                 FD_SET(fds[i].fd.socket, &wfds);
1562                 if(fds[i].fd.socket > maxfd)
1563                     maxfd = fds[i].fd.socket;
1564             }
1565             break;
1566 
1567         case LIBSSH2_POLLFD_CHANNEL:
1568             FD_SET(fds[i].fd.channel->session->socket_fd, &rfds);
1569             if(fds[i].fd.channel->session->socket_fd > maxfd)
1570                 maxfd = fds[i].fd.channel->session->socket_fd;
1571             if(!session)
1572                 session = fds[i].fd.channel->session;
1573             break;
1574 
1575         case LIBSSH2_POLLFD_LISTENER:
1576             FD_SET(fds[i].fd.listener->session->socket_fd, &rfds);
1577             if(fds[i].fd.listener->session->socket_fd > maxfd)
1578                 maxfd = fds[i].fd.listener->session->socket_fd;
1579             if(!session)
1580                 session = fds[i].fd.listener->session;
1581             break;
1582 
1583         default:
1584             if(session)
1585                 _libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
1586                                "Invalid descriptor passed to libssh2_poll()");
1587             return -1;
1588         }
1589     }
1590 #else
1591     /* No select() or poll()
1592      * no sockets structure to setup
1593      */
1594 
1595     timeout = 0;
1596 #endif /* HAVE_POLL or HAVE_SELECT */
1597 
1598     timeout_remaining = timeout;
1599     do {
1600 #if defined(HAVE_POLL) || defined(HAVE_SELECT)
1601         int sysret;
1602 #endif
1603 
1604         active_fds = 0;
1605 
1606         for(i = 0; i < nfds; i++) {
1607             if(fds[i].events != fds[i].revents) {
1608                 switch(fds[i].type) {
1609                 case LIBSSH2_POLLFD_CHANNEL:
1610                     if((fds[i].events & LIBSSH2_POLLFD_POLLIN) &&
1611                         /* Want to be ready for read */
1612                         ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) {
1613                         /* Not yet known to be ready for read */
1614                         fds[i].revents |=
1615                             libssh2_poll_channel_read(fds[i].fd.channel,
1616                                                       0) ?
1617                             LIBSSH2_POLLFD_POLLIN : 0;
1618                     }
1619                     if((fds[i].events & LIBSSH2_POLLFD_POLLEXT) &&
1620                         /* Want to be ready for extended read */
1621                         ((fds[i].revents & LIBSSH2_POLLFD_POLLEXT) == 0)) {
1622                         /* Not yet known to be ready for extended read */
1623                         fds[i].revents |=
1624                             libssh2_poll_channel_read(fds[i].fd.channel,
1625                                                       1) ?
1626                             LIBSSH2_POLLFD_POLLEXT : 0;
1627                     }
1628                     if((fds[i].events & LIBSSH2_POLLFD_POLLOUT) &&
1629                         /* Want to be ready for write */
1630                         ((fds[i].revents & LIBSSH2_POLLFD_POLLOUT) == 0)) {
1631                         /* Not yet known to be ready for write */
1632                         fds[i].revents |=
1633                             poll_channel_write(fds[i].fd. channel) ?
1634                             LIBSSH2_POLLFD_POLLOUT : 0;
1635                     }
1636                     if(fds[i].fd.channel->remote.close
1637                         || fds[i].fd.channel->local.close) {
1638                         fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED;
1639                     }
1640                     if(fds[i].fd.channel->session->socket_state ==
1641                         LIBSSH2_SOCKET_DISCONNECTED) {
1642                         fds[i].revents |=
1643                             LIBSSH2_POLLFD_CHANNEL_CLOSED |
1644                             LIBSSH2_POLLFD_SESSION_CLOSED;
1645                     }
1646                     break;
1647 
1648                 case LIBSSH2_POLLFD_LISTENER:
1649                     if((fds[i].events & LIBSSH2_POLLFD_POLLIN) &&
1650                         /* Want a connection */
1651                         ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) {
1652                         /* No connections known of yet */
1653                         fds[i].revents |=
1654                             poll_listener_queued(fds[i].fd. listener) ?
1655                             LIBSSH2_POLLFD_POLLIN : 0;
1656                     }
1657                     if(fds[i].fd.listener->session->socket_state ==
1658                         LIBSSH2_SOCKET_DISCONNECTED) {
1659                         fds[i].revents |=
1660                             LIBSSH2_POLLFD_LISTENER_CLOSED |
1661                             LIBSSH2_POLLFD_SESSION_CLOSED;
1662                     }
1663                     break;
1664                 }
1665             }
1666             if(fds[i].revents) {
1667                 active_fds++;
1668             }
1669         }
1670 
1671         if(active_fds) {
1672             /* Don't block on the sockets if we have channels/listeners which
1673                are ready */
1674             timeout_remaining = 0;
1675         }
1676 #ifdef HAVE_POLL
1677 
1678 #ifdef HAVE_LIBSSH2_GETTIMEOFDAY
1679         {
1680             struct timeval tv_begin, tv_end;
1681 
1682             _libssh2_gettimeofday((struct timeval *) &tv_begin, NULL);
1683             sysret = poll(sockets, nfds, timeout_remaining);
1684             _libssh2_gettimeofday((struct timeval *) &tv_end, NULL);
1685             timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000;
1686             timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000;
1687         }
1688 #else
1689         /* If the platform doesn't support gettimeofday,
1690          * then just make the call non-blocking and walk away
1691          */
1692         sysret = poll(sockets, nfds, timeout_remaining);
1693         timeout_remaining = 0;
1694 #endif /* HAVE_GETTIMEOFDAY */
1695 
1696         if(sysret > 0) {
1697             for(i = 0; i < nfds; i++) {
1698                 switch(fds[i].type) {
1699                 case LIBSSH2_POLLFD_SOCKET:
1700                     fds[i].revents = sockets[i].revents;
1701                     sockets[i].revents = 0; /* In case we loop again, be
1702                                                nice */
1703                     if(fds[i].revents) {
1704                         active_fds++;
1705                     }
1706                     break;
1707                 case LIBSSH2_POLLFD_CHANNEL:
1708                     if(sockets[i].events & POLLIN) {
1709                         /* Spin session until no data available */
1710                         while(_libssh2_transport_read(fds[i].fd.
1711                                                       channel->session)
1712                               > 0);
1713                     }
1714                     if(sockets[i].revents & POLLHUP) {
1715                         fds[i].revents |=
1716                             LIBSSH2_POLLFD_CHANNEL_CLOSED |
1717                             LIBSSH2_POLLFD_SESSION_CLOSED;
1718                     }
1719                     sockets[i].revents = 0;
1720                     break;
1721                 case LIBSSH2_POLLFD_LISTENER:
1722                     if(sockets[i].events & POLLIN) {
1723                         /* Spin session until no data available */
1724                         while(_libssh2_transport_read(fds[i].fd.
1725                                                       listener->session)
1726                               > 0);
1727                     }
1728                     if(sockets[i].revents & POLLHUP) {
1729                         fds[i].revents |=
1730                             LIBSSH2_POLLFD_LISTENER_CLOSED |
1731                             LIBSSH2_POLLFD_SESSION_CLOSED;
1732                     }
1733                     sockets[i].revents = 0;
1734                     break;
1735                 }
1736             }
1737         }
1738 #elif defined(HAVE_SELECT)
1739         tv.tv_sec = timeout_remaining / 1000;
1740         tv.tv_usec = (timeout_remaining % 1000) * 1000;
1741 #ifdef HAVE_LIBSSH2_GETTIMEOFDAY
1742         {
1743             struct timeval tv_begin, tv_end;
1744 
1745             _libssh2_gettimeofday((struct timeval *) &tv_begin, NULL);
1746             sysret = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
1747             _libssh2_gettimeofday((struct timeval *) &tv_end, NULL);
1748 
1749             timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000;
1750             timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000;
1751         }
1752 #else
1753         /* If the platform doesn't support gettimeofday,
1754          * then just make the call non-blocking and walk away
1755          */
1756         sysret = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
1757         timeout_remaining = 0;
1758 #endif
1759 
1760         if(sysret > 0) {
1761             for(i = 0; i < nfds; i++) {
1762                 switch(fds[i].type) {
1763                 case LIBSSH2_POLLFD_SOCKET:
1764                     if(FD_ISSET(fds[i].fd.socket, &rfds)) {
1765                         fds[i].revents |= LIBSSH2_POLLFD_POLLIN;
1766                     }
1767                     if(FD_ISSET(fds[i].fd.socket, &wfds)) {
1768                         fds[i].revents |= LIBSSH2_POLLFD_POLLOUT;
1769                     }
1770                     if(fds[i].revents) {
1771                         active_fds++;
1772                     }
1773                     break;
1774 
1775                 case LIBSSH2_POLLFD_CHANNEL:
1776                     if(FD_ISSET(fds[i].fd.channel->session->socket_fd,
1777                                 &rfds)) {
1778                         /* Spin session until no data available */
1779                         while(_libssh2_transport_read(fds[i].fd.
1780                                                       channel->session)
1781                               > 0);
1782                     }
1783                     break;
1784 
1785                 case LIBSSH2_POLLFD_LISTENER:
1786                     if(FD_ISSET
1787                         (fds[i].fd.listener->session->socket_fd, &rfds)) {
1788                         /* Spin session until no data available */
1789                         while(_libssh2_transport_read(fds[i].fd.
1790                                                       listener->session)
1791                               > 0);
1792                     }
1793                     break;
1794                 }
1795             }
1796         }
1797 #endif /* else no select() or poll() -- timeout (and by extension
1798         * timeout_remaining) will be equal to 0 */
1799     } while((timeout_remaining > 0) && !active_fds);
1800 
1801     return active_fds;
1802 }
1803 
1804 /*
1805  * libssh2_session_block_directions
1806  *
1807  * Get blocked direction when a function returns LIBSSH2_ERROR_EAGAIN
1808  * Returns LIBSSH2_SOCKET_BLOCK_INBOUND if recv() blocked
1809  * or LIBSSH2_SOCKET_BLOCK_OUTBOUND if send() blocked
1810  */
1811 LIBSSH2_API int
libssh2_session_block_directions(LIBSSH2_SESSION * session)1812 libssh2_session_block_directions(LIBSSH2_SESSION *session)
1813 {
1814     return session->socket_block_directions;
1815 }
1816 
1817 /* libssh2_session_banner_get
1818  * Get the remote banner (server ID string)
1819  */
1820 
1821 LIBSSH2_API const char *
libssh2_session_banner_get(LIBSSH2_SESSION * session)1822 libssh2_session_banner_get(LIBSSH2_SESSION *session)
1823 {
1824     /* to avoid a coredump when session is NULL */
1825     if(NULL == session)
1826         return NULL;
1827 
1828     if(NULL == session->remote.banner)
1829         return NULL;
1830 
1831     return (const char *) session->remote.banner;
1832 }
1833