1 /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
2  * Copyright (c) 2005,2006 Mikhail Gusarov
3  * Copyright (c) 2009-2014 by Daniel Stenberg
4  * Copyright (c) 2010 Simon Josefsson
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms,
8  * with or without modification, are permitted provided
9  * that the following conditions are met:
10  *
11  *   Redistributions of source code must retain the above
12  *   copyright notice, this list of conditions and the
13  *   following disclaimer.
14  *
15  *   Redistributions in binary form must reproduce the above
16  *   copyright notice, this list of conditions and the following
17  *   disclaimer in the documentation and/or other materials
18  *   provided with the distribution.
19  *
20  *   Neither the name of the copyright holder nor the names
21  *   of any other contributors may be used to endorse or
22  *   promote products derived from this software without
23  *   specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
26  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
27  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
30  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
32  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
35  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
38  * OF SUCH DAMAGE.
39  */
40 
41 #include "libssh2_priv.h"
42 #include <errno.h>
43 #include <fcntl.h>
44 
45 #ifdef HAVE_UNISTD_H
46 #include <unistd.h>
47 #endif
48 
49 #ifdef HAVE_SYS_TIME_H
50 #include <sys/time.h>
51 #endif
52 
53 #ifdef HAVE_INTTYPES_H
54 #include <inttypes.h>
55 #endif
56 
57 /* Needed for struct iovec on some platforms */
58 #ifdef HAVE_SYS_UIO_H
59 #include <sys/uio.h>
60 #endif
61 
62 #include <sys/types.h>
63 
64 #include "transport.h"
65 #include "channel.h"
66 #include "packet.h"
67 
68 /*
69  * libssh2_packet_queue_listener
70  *
71  * Queue a connection request for a listener
72  */
73 static inline int
packet_queue_listener(LIBSSH2_SESSION * session,unsigned char * data,unsigned long datalen,packet_queue_listener_state_t * listen_state)74 packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
75                       unsigned long datalen,
76                       packet_queue_listener_state_t *listen_state)
77 {
78     /*
79      * Look for a matching listener
80      */
81     /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
82     unsigned long packet_len = 17 + (sizeof(FwdNotReq) - 1);
83     unsigned char *p;
84     LIBSSH2_LISTENER *listn = _libssh2_list_first(&session->listeners);
85     char failure_code = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
86     int rc;
87 
88     (void) datalen;
89 
90     if(listen_state->state == libssh2_NB_state_idle) {
91         unsigned char *s = data + (sizeof("forwarded-tcpip") - 1) + 5;
92         listen_state->sender_channel = _libssh2_ntohu32(s);
93         s += 4;
94 
95         listen_state->initial_window_size = _libssh2_ntohu32(s);
96         s += 4;
97         listen_state->packet_size = _libssh2_ntohu32(s);
98         s += 4;
99 
100         listen_state->host_len = _libssh2_ntohu32(s);
101         s += 4;
102         listen_state->host = s;
103         s += listen_state->host_len;
104         listen_state->port = _libssh2_ntohu32(s);
105         s += 4;
106 
107         listen_state->shost_len = _libssh2_ntohu32(s);
108         s += 4;
109         listen_state->shost = s;
110         s += listen_state->shost_len;
111         listen_state->sport = _libssh2_ntohu32(s);
112 
113         _libssh2_debug(session, LIBSSH2_TRACE_CONN,
114                        "Remote received connection from %s:%ld to %s:%ld",
115                        listen_state->shost, listen_state->sport,
116                        listen_state->host, listen_state->port);
117 
118         listen_state->state = libssh2_NB_state_allocated;
119     }
120 
121     if(listen_state->state != libssh2_NB_state_sent) {
122         while(listn) {
123             if((listn->port == (int) listen_state->port) &&
124                 (strlen(listn->host) == listen_state->host_len) &&
125                 (memcmp (listn->host, listen_state->host,
126                          listen_state->host_len) == 0)) {
127                 /* This is our listener */
128                 LIBSSH2_CHANNEL *channel = NULL;
129                 listen_state->channel = NULL;
130 
131                 if(listen_state->state == libssh2_NB_state_allocated) {
132                     if(listn->queue_maxsize &&
133                         (listn->queue_maxsize <= listn->queue_size)) {
134                         /* Queue is full */
135                         failure_code = SSH_OPEN_RESOURCE_SHORTAGE;
136                         _libssh2_debug(session, LIBSSH2_TRACE_CONN,
137                                        "Listener queue full, ignoring");
138                         listen_state->state = libssh2_NB_state_sent;
139                         break;
140                     }
141 
142                     channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL));
143                     if(!channel) {
144                         _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
145                                        "Unable to allocate a channel for "
146                                        "new connection");
147                         failure_code = SSH_OPEN_RESOURCE_SHORTAGE;
148                         listen_state->state = libssh2_NB_state_sent;
149                         break;
150                     }
151                     listen_state->channel = channel;
152 
153                     channel->session = session;
154                     channel->channel_type_len = sizeof("forwarded-tcpip") - 1;
155                     channel->channel_type = LIBSSH2_ALLOC(session,
156                                                           channel->
157                                                           channel_type_len +
158                                                           1);
159                     if(!channel->channel_type) {
160                         _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
161                                        "Unable to allocate a channel for new"
162                                        " connection");
163                         LIBSSH2_FREE(session, channel);
164                         failure_code = SSH_OPEN_RESOURCE_SHORTAGE;
165                         listen_state->state = libssh2_NB_state_sent;
166                         break;
167                     }
168                     memcpy(channel->channel_type, "forwarded-tcpip",
169                            channel->channel_type_len + 1);
170 
171                     channel->remote.id = listen_state->sender_channel;
172                     channel->remote.window_size_initial =
173                         LIBSSH2_CHANNEL_WINDOW_DEFAULT;
174                     channel->remote.window_size =
175                         LIBSSH2_CHANNEL_WINDOW_DEFAULT;
176                     channel->remote.packet_size =
177                         LIBSSH2_CHANNEL_PACKET_DEFAULT;
178 
179                     channel->local.id = _libssh2_channel_nextid(session);
180                     channel->local.window_size_initial =
181                         listen_state->initial_window_size;
182                     channel->local.window_size =
183                         listen_state->initial_window_size;
184                     channel->local.packet_size = listen_state->packet_size;
185 
186                     _libssh2_debug(session, LIBSSH2_TRACE_CONN,
187                                    "Connection queued: channel %lu/%lu "
188                                    "win %lu/%lu packet %lu/%lu",
189                                    channel->local.id, channel->remote.id,
190                                    channel->local.window_size,
191                                    channel->remote.window_size,
192                                    channel->local.packet_size,
193                                    channel->remote.packet_size);
194 
195                     p = listen_state->packet;
196                     *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION;
197                     _libssh2_store_u32(&p, channel->remote.id);
198                     _libssh2_store_u32(&p, channel->local.id);
199                     _libssh2_store_u32(&p,
200                                        channel->remote.window_size_initial);
201                     _libssh2_store_u32(&p, channel->remote.packet_size);
202 
203                     listen_state->state = libssh2_NB_state_created;
204                 }
205 
206                 if(listen_state->state == libssh2_NB_state_created) {
207                     rc = _libssh2_transport_send(session, listen_state->packet,
208                                                  17, NULL, 0);
209                     if(rc == LIBSSH2_ERROR_EAGAIN)
210                         return rc;
211                     else if(rc) {
212                         listen_state->state = libssh2_NB_state_idle;
213                         return _libssh2_error(session, rc,
214                                               "Unable to send channel "
215                                               "open confirmation");
216                     }
217 
218                     /* Link the channel into the end of the queue list */
219                     if(listen_state->channel) {
220                         _libssh2_list_add(&listn->queue,
221                                           &listen_state->channel->node);
222                         listn->queue_size++;
223                     }
224 
225                     listen_state->state = libssh2_NB_state_idle;
226                     return 0;
227                 }
228             }
229 
230             listn = _libssh2_list_next(&listn->node);
231         }
232 
233         listen_state->state = libssh2_NB_state_sent;
234     }
235 
236     /* We're not listening to you */
237     p = listen_state->packet;
238     *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
239     _libssh2_store_u32(&p, listen_state->sender_channel);
240     _libssh2_store_u32(&p, failure_code);
241     _libssh2_store_str(&p, FwdNotReq, sizeof(FwdNotReq) - 1);
242     _libssh2_htonu32(p, 0);
243 
244     rc = _libssh2_transport_send(session, listen_state->packet,
245                                  packet_len, NULL, 0);
246     if(rc == LIBSSH2_ERROR_EAGAIN) {
247         return rc;
248     }
249     else if(rc) {
250         listen_state->state = libssh2_NB_state_idle;
251         return _libssh2_error(session, rc, "Unable to send open failure");
252 
253     }
254     listen_state->state = libssh2_NB_state_idle;
255     return 0;
256 }
257 
258 /*
259  * packet_x11_open
260  *
261  * Accept a forwarded X11 connection
262  */
263 static inline int
packet_x11_open(LIBSSH2_SESSION * session,unsigned char * data,unsigned long datalen,packet_x11_open_state_t * x11open_state)264 packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
265                 unsigned long datalen,
266                 packet_x11_open_state_t *x11open_state)
267 {
268     int failure_code = SSH_OPEN_CONNECT_FAILED;
269     /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
270     unsigned long packet_len = 17 + (sizeof(X11FwdUnAvil) - 1);
271     unsigned char *p;
272     LIBSSH2_CHANNEL *channel = x11open_state->channel;
273     int rc;
274 
275     (void) datalen;
276 
277     if(x11open_state->state == libssh2_NB_state_idle) {
278         unsigned char *s = data + (sizeof("x11") - 1) + 5;
279         x11open_state->sender_channel = _libssh2_ntohu32(s);
280         s += 4;
281         x11open_state->initial_window_size = _libssh2_ntohu32(s);
282         s += 4;
283         x11open_state->packet_size = _libssh2_ntohu32(s);
284         s += 4;
285         x11open_state->shost_len = _libssh2_ntohu32(s);
286         s += 4;
287         x11open_state->shost = s;
288         s += x11open_state->shost_len;
289         x11open_state->sport = _libssh2_ntohu32(s);
290 
291         _libssh2_debug(session, LIBSSH2_TRACE_CONN,
292                        "X11 Connection Received from %s:%ld on channel %lu",
293                        x11open_state->shost, x11open_state->sport,
294                        x11open_state->sender_channel);
295 
296         x11open_state->state = libssh2_NB_state_allocated;
297     }
298 
299     if(session->x11) {
300         if(x11open_state->state == libssh2_NB_state_allocated) {
301             channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL));
302             if(!channel) {
303                 _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
304                                "allocate a channel for new connection");
305                 failure_code = SSH_OPEN_RESOURCE_SHORTAGE;
306                 goto x11_exit;
307             }
308 
309             channel->session = session;
310             channel->channel_type_len = sizeof("x11") - 1;
311             channel->channel_type = LIBSSH2_ALLOC(session,
312                                                   channel->channel_type_len +
313                                                   1);
314             if(!channel->channel_type) {
315                 _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
316                                "allocate a channel for new connection");
317                 LIBSSH2_FREE(session, channel);
318                 failure_code = SSH_OPEN_RESOURCE_SHORTAGE;
319                 goto x11_exit;
320             }
321             memcpy(channel->channel_type, "x11",
322                    channel->channel_type_len + 1);
323 
324             channel->remote.id = x11open_state->sender_channel;
325             channel->remote.window_size_initial =
326                 LIBSSH2_CHANNEL_WINDOW_DEFAULT;
327             channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT;
328             channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT;
329 
330             channel->local.id = _libssh2_channel_nextid(session);
331             channel->local.window_size_initial =
332                 x11open_state->initial_window_size;
333             channel->local.window_size = x11open_state->initial_window_size;
334             channel->local.packet_size = x11open_state->packet_size;
335 
336             _libssh2_debug(session, LIBSSH2_TRACE_CONN,
337                            "X11 Connection established: channel %lu/%lu "
338                            "win %lu/%lu packet %lu/%lu",
339                            channel->local.id, channel->remote.id,
340                            channel->local.window_size,
341                            channel->remote.window_size,
342                            channel->local.packet_size,
343                            channel->remote.packet_size);
344             p = x11open_state->packet;
345             *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION;
346             _libssh2_store_u32(&p, channel->remote.id);
347             _libssh2_store_u32(&p, channel->local.id);
348             _libssh2_store_u32(&p, channel->remote.window_size_initial);
349             _libssh2_store_u32(&p, channel->remote.packet_size);
350 
351             x11open_state->state = libssh2_NB_state_created;
352         }
353 
354         if(x11open_state->state == libssh2_NB_state_created) {
355             rc = _libssh2_transport_send(session, x11open_state->packet, 17,
356                                          NULL, 0);
357             if(rc == LIBSSH2_ERROR_EAGAIN) {
358                 return rc;
359             }
360             else if(rc) {
361                 x11open_state->state = libssh2_NB_state_idle;
362                 return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
363                                       "Unable to send channel open "
364                                       "confirmation");
365             }
366 
367             /* Link the channel into the session */
368             _libssh2_list_add(&session->channels, &channel->node);
369 
370             /*
371              * Pass control to the callback, they may turn right around and
372              * free the channel, or actually use it
373              */
374             LIBSSH2_X11_OPEN(channel, (char *)x11open_state->shost,
375                              x11open_state->sport);
376 
377             x11open_state->state = libssh2_NB_state_idle;
378             return 0;
379         }
380     }
381     else
382         failure_code = SSH_OPEN_RESOURCE_SHORTAGE;
383     /* fall-trough */
384   x11_exit:
385     p = x11open_state->packet;
386     *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
387     _libssh2_store_u32(&p, x11open_state->sender_channel);
388     _libssh2_store_u32(&p, failure_code);
389     _libssh2_store_str(&p, X11FwdUnAvil, sizeof(X11FwdUnAvil) - 1);
390     _libssh2_htonu32(p, 0);
391 
392     rc = _libssh2_transport_send(session, x11open_state->packet, packet_len,
393                                  NULL, 0);
394     if(rc == LIBSSH2_ERROR_EAGAIN) {
395         return rc;
396     }
397     else if(rc) {
398         x11open_state->state = libssh2_NB_state_idle;
399         return _libssh2_error(session, rc, "Unable to send open failure");
400     }
401     x11open_state->state = libssh2_NB_state_idle;
402     return 0;
403 }
404 
405 /*
406  * _libssh2_packet_add
407  *
408  * Create a new packet and attach it to the brigade. Called from the transport
409  * layer when it has received a packet.
410  *
411  * The input pointer 'data' is pointing to allocated data that this function
412  * is asked to deal with so on failure OR success, it must be freed fine.
413  * The only exception is when the return code is LIBSSH2_ERROR_EAGAIN.
414  *
415  * This function will always be called with 'datalen' greater than zero.
416  */
417 int
_libssh2_packet_add(LIBSSH2_SESSION * session,unsigned char * data,size_t datalen,int macstate)418 _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
419                     size_t datalen, int macstate)
420 {
421     int rc = 0;
422     char *message = NULL;
423     char *language = NULL;
424     size_t message_len = 0;
425     size_t language_len = 0;
426     LIBSSH2_CHANNEL *channelp = NULL;
427     size_t data_head = 0;
428     unsigned char msg = data[0];
429 
430     switch(session->packAdd_state) {
431     case libssh2_NB_state_idle:
432         _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
433                        "Packet type %d received, length=%d",
434                        (int) msg, (int) datalen);
435 
436         if((macstate == LIBSSH2_MAC_INVALID) &&
437             (!session->macerror ||
438              LIBSSH2_MACERROR(session, (char *) data, datalen))) {
439             /* Bad MAC input, but no callback set or non-zero return from the
440                callback */
441 
442             LIBSSH2_FREE(session, data);
443             return _libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC,
444                                   "Invalid MAC received");
445         }
446         session->packAdd_state = libssh2_NB_state_allocated;
447         break;
448     case libssh2_NB_state_jump1:
449         goto libssh2_packet_add_jump_point1;
450     case libssh2_NB_state_jump2:
451         goto libssh2_packet_add_jump_point2;
452     case libssh2_NB_state_jump3:
453         goto libssh2_packet_add_jump_point3;
454     case libssh2_NB_state_jump4:
455         goto libssh2_packet_add_jump_point4;
456     case libssh2_NB_state_jump5:
457         goto libssh2_packet_add_jump_point5;
458     default: /* nothing to do */
459         break;
460     }
461 
462     if(session->packAdd_state == libssh2_NB_state_allocated) {
463         /* A couple exceptions to the packet adding rule: */
464         switch(msg) {
465 
466             /*
467               byte      SSH_MSG_DISCONNECT
468               uint32    reason code
469               string    description in ISO-10646 UTF-8 encoding [RFC3629]
470               string    language tag [RFC3066]
471             */
472 
473         case SSH_MSG_DISCONNECT:
474             if(datalen >= 5) {
475                 size_t reason = _libssh2_ntohu32(data + 1);
476 
477                 if(datalen >= 9) {
478                     message_len = _libssh2_ntohu32(data + 5);
479 
480                     if(message_len < datalen-13) {
481                         /* 9 = packet_type(1) + reason(4) + message_len(4) */
482                         message = (char *) data + 9;
483 
484                         language_len =
485                             _libssh2_ntohu32(data + 9 + message_len);
486                         language = (char *) data + 9 + message_len + 4;
487 
488                         if(language_len > (datalen-13-message_len)) {
489                             /* bad input, clear info */
490                             language = message = NULL;
491                             language_len = message_len = 0;
492                         }
493                     }
494                     else
495                         /* bad size, clear it */
496                         message_len = 0;
497                 }
498                 if(session->ssh_msg_disconnect) {
499                     LIBSSH2_DISCONNECT(session, reason, message,
500                                        message_len, language, language_len);
501                 }
502                 _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
503                                "Disconnect(%d): %s(%s)", reason,
504                                message, language);
505             }
506 
507             LIBSSH2_FREE(session, data);
508             session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
509             session->packAdd_state = libssh2_NB_state_idle;
510             return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
511                                   "socket disconnect");
512             /*
513               byte      SSH_MSG_IGNORE
514               string    data
515             */
516 
517         case SSH_MSG_IGNORE:
518             if(datalen >= 2) {
519                 if(session->ssh_msg_ignore) {
520                     LIBSSH2_IGNORE(session, (char *) data + 1, datalen - 1);
521                 }
522             }
523             else if(session->ssh_msg_ignore) {
524                 LIBSSH2_IGNORE(session, "", 0);
525             }
526             LIBSSH2_FREE(session, data);
527             session->packAdd_state = libssh2_NB_state_idle;
528             return 0;
529 
530             /*
531               byte      SSH_MSG_DEBUG
532               boolean   always_display
533               string    message in ISO-10646 UTF-8 encoding [RFC3629]
534               string    language tag [RFC3066]
535             */
536 
537         case SSH_MSG_DEBUG:
538             if(datalen >= 2) {
539                 int always_display = data[1];
540 
541                 if(datalen >= 6) {
542                     message_len = _libssh2_ntohu32(data + 2);
543 
544                     if(message_len <= (datalen - 10)) {
545                         /* 6 = packet_type(1) + display(1) + message_len(4) */
546                         message = (char *) data + 6;
547                         language_len = _libssh2_ntohu32(data + 6 +
548                                                         message_len);
549 
550                         if(language_len <= (datalen - 10 - message_len))
551                             language = (char *) data + 10 + message_len;
552                     }
553                 }
554 
555                 if(session->ssh_msg_debug) {
556                     LIBSSH2_DEBUG(session, always_display, message,
557                                   message_len, language, language_len);
558                 }
559             }
560             /*
561              * _libssh2_debug will actually truncate this for us so
562              * that it's not an inordinate about of data
563              */
564             _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
565                            "Debug Packet: %s", message);
566             LIBSSH2_FREE(session, data);
567             session->packAdd_state = libssh2_NB_state_idle;
568             return 0;
569 
570             /*
571               byte      SSH_MSG_GLOBAL_REQUEST
572               string    request name in US-ASCII only
573               boolean   want reply
574               ....      request-specific data follows
575             */
576 
577         case SSH_MSG_GLOBAL_REQUEST:
578             if(datalen >= 5) {
579                 uint32_t len = 0;
580                 unsigned char want_reply = 0;
581                 len = _libssh2_ntohu32(data + 1);
582                 if(datalen >= (6 + len)) {
583                     want_reply = data[5 + len];
584                     _libssh2_debug(session,
585                                    LIBSSH2_TRACE_CONN,
586                                    "Received global request type %.*s (wr %X)",
587                                    len, data + 5, want_reply);
588                 }
589 
590 
591                 if(want_reply) {
592                     static const unsigned char packet =
593                         SSH_MSG_REQUEST_FAILURE;
594                   libssh2_packet_add_jump_point5:
595                     session->packAdd_state = libssh2_NB_state_jump5;
596                     rc = _libssh2_transport_send(session, &packet, 1, NULL, 0);
597                     if(rc == LIBSSH2_ERROR_EAGAIN)
598                         return rc;
599                 }
600             }
601             LIBSSH2_FREE(session, data);
602             session->packAdd_state = libssh2_NB_state_idle;
603             return 0;
604 
605             /*
606               byte      SSH_MSG_CHANNEL_EXTENDED_DATA
607               uint32    recipient channel
608               uint32    data_type_code
609               string    data
610             */
611 
612         case SSH_MSG_CHANNEL_EXTENDED_DATA:
613             /* streamid(4) */
614             data_head += 4;
615 
616             /* fall-through */
617 
618             /*
619               byte      SSH_MSG_CHANNEL_DATA
620               uint32    recipient channel
621               string    data
622             */
623 
624         case SSH_MSG_CHANNEL_DATA:
625             /* packet_type(1) + channelno(4) + datalen(4) */
626             data_head += 9;
627 
628             if(datalen >= data_head)
629                 channelp =
630                     _libssh2_channel_locate(session,
631                                             _libssh2_ntohu32(data + 1));
632 
633             if(!channelp) {
634                 _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN,
635                                "Packet received for unknown channel");
636                 LIBSSH2_FREE(session, data);
637                 session->packAdd_state = libssh2_NB_state_idle;
638                 return 0;
639             }
640 #ifdef LIBSSH2DEBUG
641             {
642                 uint32_t stream_id = 0;
643                 if(msg == SSH_MSG_CHANNEL_EXTENDED_DATA)
644                     stream_id = _libssh2_ntohu32(data + 5);
645 
646                 _libssh2_debug(session, LIBSSH2_TRACE_CONN,
647                                "%d bytes packet_add() for %lu/%lu/%lu",
648                                (int) (datalen - data_head),
649                                channelp->local.id,
650                                channelp->remote.id,
651                                stream_id);
652             }
653 #endif
654             if((channelp->remote.extended_data_ignore_mode ==
655                  LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) &&
656                 (msg == SSH_MSG_CHANNEL_EXTENDED_DATA)) {
657                 /* Pretend we didn't receive this */
658                 LIBSSH2_FREE(session, data);
659 
660                 _libssh2_debug(session, LIBSSH2_TRACE_CONN,
661                                "Ignoring extended data and refunding %d bytes",
662                                (int) (datalen - 13));
663                 if(channelp->read_avail + datalen - data_head >=
664                     channelp->remote.window_size)
665                     datalen = channelp->remote.window_size -
666                         channelp->read_avail + data_head;
667 
668                 channelp->remote.window_size -= datalen - data_head;
669                 _libssh2_debug(session, LIBSSH2_TRACE_CONN,
670                                "shrinking window size by %lu bytes to %lu, "
671                                "read_avail %lu",
672                                datalen - data_head,
673                                channelp->remote.window_size,
674                                channelp->read_avail);
675 
676                 session->packAdd_channelp = channelp;
677 
678                 /* Adjust the window based on the block we just freed */
679               libssh2_packet_add_jump_point1:
680                 session->packAdd_state = libssh2_NB_state_jump1;
681                 rc = _libssh2_channel_receive_window_adjust(session->
682                                                             packAdd_channelp,
683                                                             datalen - 13,
684                                                             1, NULL);
685                 if(rc == LIBSSH2_ERROR_EAGAIN)
686                     return rc;
687 
688                 session->packAdd_state = libssh2_NB_state_idle;
689                 return 0;
690             }
691 
692             /*
693              * REMEMBER! remote means remote as source of data,
694              * NOT remote window!
695              */
696             if(channelp->remote.packet_size < (datalen - data_head)) {
697                 /*
698                  * Spec says we MAY ignore bytes sent beyond
699                  * packet_size
700                  */
701                 _libssh2_error(session,
702                                LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED,
703                                "Packet contains more data than we offered"
704                                " to receive, truncating");
705                 datalen = channelp->remote.packet_size + data_head;
706             }
707             if(channelp->remote.window_size <= channelp->read_avail) {
708                 /*
709                  * Spec says we MAY ignore bytes sent beyond
710                  * window_size
711                  */
712                 _libssh2_error(session,
713                                LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
714                                "The current receive window is full,"
715                                " data ignored");
716                 LIBSSH2_FREE(session, data);
717                 session->packAdd_state = libssh2_NB_state_idle;
718                 return 0;
719             }
720             /* Reset EOF status */
721             channelp->remote.eof = 0;
722 
723             if(channelp->read_avail + datalen - data_head >
724                 channelp->remote.window_size) {
725                 _libssh2_error(session,
726                                LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
727                                "Remote sent more data than current "
728                                "window allows, truncating");
729                 datalen = channelp->remote.window_size -
730                     channelp->read_avail + data_head;
731             }
732 
733             /* Update the read_avail counter. The window size will be
734              * updated once the data is actually read from the queue
735              * from an upper layer */
736             channelp->read_avail += datalen - data_head;
737 
738             _libssh2_debug(session, LIBSSH2_TRACE_CONN,
739                            "increasing read_avail by %lu bytes to %lu/%lu",
740                            (long)(datalen - data_head),
741                            (long)channelp->read_avail,
742                            (long)channelp->remote.window_size);
743 
744             break;
745 
746             /*
747               byte      SSH_MSG_CHANNEL_EOF
748               uint32    recipient channel
749             */
750 
751         case SSH_MSG_CHANNEL_EOF:
752             if(datalen >= 5)
753                 channelp =
754                     _libssh2_channel_locate(session,
755                                             _libssh2_ntohu32(data + 1));
756             if(!channelp)
757                 /* We may have freed already, just quietly ignore this... */
758                 ;
759             else {
760                 _libssh2_debug(session,
761                                LIBSSH2_TRACE_CONN,
762                                "EOF received for channel %lu/%lu",
763                                channelp->local.id,
764                                channelp->remote.id);
765                 channelp->remote.eof = 1;
766             }
767             LIBSSH2_FREE(session, data);
768             session->packAdd_state = libssh2_NB_state_idle;
769             return 0;
770 
771             /*
772               byte      SSH_MSG_CHANNEL_REQUEST
773               uint32    recipient channel
774               string    request type in US-ASCII characters only
775               boolean   want reply
776               ....      type-specific data follows
777             */
778 
779         case SSH_MSG_CHANNEL_REQUEST:
780             if(datalen >= 9) {
781                 uint32_t channel = _libssh2_ntohu32(data + 1);
782                 uint32_t len = _libssh2_ntohu32(data + 5);
783                 unsigned char want_reply = 1;
784 
785                 if((len + 9) < datalen)
786                     want_reply = data[len + 9];
787 
788                 _libssh2_debug(session,
789                                LIBSSH2_TRACE_CONN,
790                                "Channel %d received request type %.*s (wr %X)",
791                                channel, len, data + 9, want_reply);
792 
793                 if(len == sizeof("exit-status") - 1
794                     && (sizeof("exit-status") - 1 + 9) <= datalen
795                     && !memcmp("exit-status", data + 9,
796                                sizeof("exit-status") - 1)) {
797 
798                     /* we've got "exit-status" packet. Set the session value */
799                     if(datalen >= 20)
800                         channelp =
801                             _libssh2_channel_locate(session, channel);
802 
803                     if(channelp && (sizeof("exit-status") + 13) <= datalen) {
804                         channelp->exit_status =
805                             _libssh2_ntohu32(data + 9 + sizeof("exit-status"));
806                         _libssh2_debug(session, LIBSSH2_TRACE_CONN,
807                                        "Exit status %lu received for "
808                                        "channel %lu/%lu",
809                                        channelp->exit_status,
810                                        channelp->local.id,
811                                        channelp->remote.id);
812                     }
813 
814                 }
815                 else if(len == sizeof("exit-signal") - 1
816                          && (sizeof("exit-signal") - 1 + 9) <= datalen
817                          && !memcmp("exit-signal", data + 9,
818                                     sizeof("exit-signal") - 1)) {
819                     /* command terminated due to signal */
820                     if(datalen >= 20)
821                         channelp = _libssh2_channel_locate(session, channel);
822 
823                     if(channelp && (sizeof("exit-signal") + 13) <= datalen) {
824                         /* set signal name (without SIG prefix) */
825                         uint32_t namelen =
826                             _libssh2_ntohu32(data + 9 + sizeof("exit-signal"));
827 
828                         if(namelen <= UINT_MAX - 1) {
829                             channelp->exit_signal =
830                                 LIBSSH2_ALLOC(session, namelen + 1);
831                         }
832                         else {
833                             channelp->exit_signal = NULL;
834                         }
835 
836                         if(!channelp->exit_signal)
837                             rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
838                                                 "memory for signal name");
839                         else if((sizeof("exit-signal") + 13 + namelen <=
840                                  datalen)) {
841                             memcpy(channelp->exit_signal,
842                                    data + 13 + sizeof("exit-signal"), namelen);
843                             channelp->exit_signal[namelen] = '\0';
844                             /* TODO: save error message and language tag */
845                             _libssh2_debug(session, LIBSSH2_TRACE_CONN,
846                                            "Exit signal %s received for "
847                                            "channel %lu/%lu",
848                                            channelp->exit_signal,
849                                            channelp->local.id,
850                                            channelp->remote.id);
851                         }
852                     }
853                 }
854 
855 
856                 if(want_reply) {
857                     unsigned char packet[5];
858                   libssh2_packet_add_jump_point4:
859                     session->packAdd_state = libssh2_NB_state_jump4;
860                     packet[0] = SSH_MSG_CHANNEL_FAILURE;
861                     memcpy(&packet[1], data + 1, 4);
862                     rc = _libssh2_transport_send(session, packet, 5, NULL, 0);
863                     if(rc == LIBSSH2_ERROR_EAGAIN)
864                         return rc;
865                 }
866             }
867             LIBSSH2_FREE(session, data);
868             session->packAdd_state = libssh2_NB_state_idle;
869             return rc;
870 
871             /*
872               byte      SSH_MSG_CHANNEL_CLOSE
873               uint32    recipient channel
874             */
875 
876         case SSH_MSG_CHANNEL_CLOSE:
877             if(datalen >= 5)
878                 channelp =
879                     _libssh2_channel_locate(session,
880                                             _libssh2_ntohu32(data + 1));
881             if(!channelp) {
882                 /* We may have freed already, just quietly ignore this... */
883                 LIBSSH2_FREE(session, data);
884                 session->packAdd_state = libssh2_NB_state_idle;
885                 return 0;
886             }
887             _libssh2_debug(session, LIBSSH2_TRACE_CONN,
888                            "Close received for channel %lu/%lu",
889                            channelp->local.id,
890                            channelp->remote.id);
891 
892             channelp->remote.close = 1;
893             channelp->remote.eof = 1;
894 
895             LIBSSH2_FREE(session, data);
896             session->packAdd_state = libssh2_NB_state_idle;
897             return 0;
898 
899             /*
900               byte      SSH_MSG_CHANNEL_OPEN
901               string    "session"
902               uint32    sender channel
903               uint32    initial window size
904               uint32    maximum packet size
905             */
906 
907         case SSH_MSG_CHANNEL_OPEN:
908             if(datalen < 17)
909                 ;
910             else if((datalen >= (sizeof("forwarded-tcpip") + 4)) &&
911                      ((sizeof("forwarded-tcpip") - 1) ==
912                       _libssh2_ntohu32(data + 1))
913                      &&
914                      (memcmp(data + 5, "forwarded-tcpip",
915                              sizeof("forwarded-tcpip") - 1) == 0)) {
916 
917                 /* init the state struct */
918                 memset(&session->packAdd_Qlstn_state, 0,
919                        sizeof(session->packAdd_Qlstn_state));
920 
921               libssh2_packet_add_jump_point2:
922                 session->packAdd_state = libssh2_NB_state_jump2;
923                 rc = packet_queue_listener(session, data, datalen,
924                                            &session->packAdd_Qlstn_state);
925             }
926             else if((datalen >= (sizeof("x11") + 4)) &&
927                      ((sizeof("x11") - 1) == _libssh2_ntohu32(data + 1)) &&
928                      (memcmp(data + 5, "x11", sizeof("x11") - 1) == 0)) {
929 
930                 /* init the state struct */
931                 memset(&session->packAdd_x11open_state, 0,
932                        sizeof(session->packAdd_x11open_state));
933 
934               libssh2_packet_add_jump_point3:
935                 session->packAdd_state = libssh2_NB_state_jump3;
936                 rc = packet_x11_open(session, data, datalen,
937                                      &session->packAdd_x11open_state);
938             }
939             if(rc == LIBSSH2_ERROR_EAGAIN)
940                 return rc;
941 
942             LIBSSH2_FREE(session, data);
943             session->packAdd_state = libssh2_NB_state_idle;
944             return rc;
945 
946             /*
947               byte      SSH_MSG_CHANNEL_WINDOW_ADJUST
948               uint32    recipient channel
949               uint32    bytes to add
950             */
951         case SSH_MSG_CHANNEL_WINDOW_ADJUST:
952             if(datalen < 9)
953                 ;
954             else {
955                 uint32_t bytestoadd = _libssh2_ntohu32(data + 5);
956                 channelp =
957                     _libssh2_channel_locate(session,
958                                             _libssh2_ntohu32(data + 1));
959                 if(channelp) {
960                     channelp->local.window_size += bytestoadd;
961 
962                     _libssh2_debug(session, LIBSSH2_TRACE_CONN,
963                                    "Window adjust for channel %lu/%lu, "
964                                    "adding %lu bytes, new window_size=%lu",
965                                    channelp->local.id,
966                                    channelp->remote.id,
967                                    bytestoadd,
968                                    channelp->local.window_size);
969                 }
970             }
971             LIBSSH2_FREE(session, data);
972             session->packAdd_state = libssh2_NB_state_idle;
973             return 0;
974         default:
975             break;
976         }
977 
978         session->packAdd_state = libssh2_NB_state_sent;
979     }
980 
981     if(session->packAdd_state == libssh2_NB_state_sent) {
982         LIBSSH2_PACKET *packetp =
983             LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
984         if(!packetp) {
985             _libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
986                            "memory for packet");
987             LIBSSH2_FREE(session, data);
988             session->packAdd_state = libssh2_NB_state_idle;
989             return LIBSSH2_ERROR_ALLOC;
990         }
991         packetp->data = data;
992         packetp->data_len = datalen;
993         packetp->data_head = data_head;
994 
995         _libssh2_list_add(&session->packets, &packetp->node);
996 
997         session->packAdd_state = libssh2_NB_state_sent1;
998     }
999 
1000     if((msg == SSH_MSG_KEXINIT &&
1001          !(session->state & LIBSSH2_STATE_EXCHANGING_KEYS)) ||
1002         (session->packAdd_state == libssh2_NB_state_sent2)) {
1003         if(session->packAdd_state == libssh2_NB_state_sent1) {
1004             /*
1005              * Remote wants new keys
1006              * Well, it's already in the brigade,
1007              * let's just call back into ourselves
1008              */
1009             _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Renegotiating Keys");
1010 
1011             session->packAdd_state = libssh2_NB_state_sent2;
1012         }
1013 
1014         /*
1015          * The KEXINIT message has been added to the queue.  The packAdd and
1016          * readPack states need to be reset because _libssh2_kex_exchange
1017          * (eventually) calls upon _libssh2_transport_read to read the rest of
1018          * the key exchange conversation.
1019          */
1020         session->readPack_state = libssh2_NB_state_idle;
1021         session->packet.total_num = 0;
1022         session->packAdd_state = libssh2_NB_state_idle;
1023         session->fullpacket_state = libssh2_NB_state_idle;
1024 
1025         memset(&session->startup_key_state, 0, sizeof(key_exchange_state_t));
1026 
1027         /*
1028          * If there was a key reexchange failure, let's just hope we didn't
1029          * send NEWKEYS yet, otherwise remote will drop us like a rock
1030          */
1031         rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
1032         if(rc == LIBSSH2_ERROR_EAGAIN)
1033             return rc;
1034     }
1035 
1036     session->packAdd_state = libssh2_NB_state_idle;
1037     return 0;
1038 }
1039 
1040 /*
1041  * _libssh2_packet_ask
1042  *
1043  * Scan the brigade for a matching packet type, optionally poll the socket for
1044  * a packet first
1045  */
1046 int
_libssh2_packet_ask(LIBSSH2_SESSION * session,unsigned char packet_type,unsigned char ** data,size_t * data_len,int match_ofs,const unsigned char * match_buf,size_t match_len)1047 _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
1048                     unsigned char **data, size_t *data_len,
1049                     int match_ofs, const unsigned char *match_buf,
1050                     size_t match_len)
1051 {
1052     LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
1053 
1054     _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
1055                    "Looking for packet of type: %d", (int) packet_type);
1056 
1057     while(packet) {
1058         if(packet->data[0] == packet_type
1059             && (packet->data_len >= (match_ofs + match_len))
1060             && (!match_buf ||
1061                 (memcmp(packet->data + match_ofs, match_buf,
1062                         match_len) == 0))) {
1063             *data = packet->data;
1064             *data_len = packet->data_len;
1065 
1066             /* unlink struct from session->packets */
1067             _libssh2_list_remove(&packet->node);
1068 
1069             LIBSSH2_FREE(session, packet);
1070 
1071             return 0;
1072         }
1073         packet = _libssh2_list_next(&packet->node);
1074     }
1075     return -1;
1076 }
1077 
1078 /*
1079  * libssh2_packet_askv
1080  *
1081  * Scan for any of a list of packet types in the brigade, optionally poll the
1082  * socket for a packet first
1083  */
1084 int
_libssh2_packet_askv(LIBSSH2_SESSION * session,const unsigned char * packet_types,unsigned char ** data,size_t * data_len,int match_ofs,const unsigned char * match_buf,size_t match_len)1085 _libssh2_packet_askv(LIBSSH2_SESSION * session,
1086                      const unsigned char *packet_types,
1087                      unsigned char **data, size_t *data_len,
1088                      int match_ofs,
1089                      const unsigned char *match_buf,
1090                      size_t match_len)
1091 {
1092     int i, packet_types_len = strlen((char *) packet_types);
1093 
1094     for(i = 0; i < packet_types_len; i++) {
1095         if(0 == _libssh2_packet_ask(session, packet_types[i], data,
1096                                      data_len, match_ofs,
1097                                      match_buf, match_len)) {
1098             return 0;
1099         }
1100     }
1101 
1102     return -1;
1103 }
1104 
1105 /*
1106  * _libssh2_packet_require
1107  *
1108  * Loops _libssh2_transport_read() until the packet requested is available
1109  * SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause a bailout
1110  *
1111  * Returns negative on error
1112  * Returns 0 when it has taken care of the requested packet.
1113  */
1114 int
_libssh2_packet_require(LIBSSH2_SESSION * session,unsigned char packet_type,unsigned char ** data,size_t * data_len,int match_ofs,const unsigned char * match_buf,size_t match_len,packet_require_state_t * state)1115 _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
1116                         unsigned char **data, size_t *data_len,
1117                         int match_ofs,
1118                         const unsigned char *match_buf,
1119                         size_t match_len,
1120                         packet_require_state_t *state)
1121 {
1122     if(state->start == 0) {
1123         if(_libssh2_packet_ask(session, packet_type, data, data_len,
1124                                 match_ofs, match_buf,
1125                                 match_len) == 0) {
1126             /* A packet was available in the packet brigade */
1127             return 0;
1128         }
1129 
1130         state->start = time(NULL);
1131     }
1132 
1133     while(session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
1134         int ret = _libssh2_transport_read(session);
1135         if(ret == LIBSSH2_ERROR_EAGAIN)
1136             return ret;
1137         else if(ret < 0) {
1138             state->start = 0;
1139             /* an error which is not just because of blocking */
1140             return ret;
1141         }
1142         else if(ret == packet_type) {
1143             /* Be lazy, let packet_ask pull it out of the brigade */
1144             ret = _libssh2_packet_ask(session, packet_type, data, data_len,
1145                                       match_ofs, match_buf, match_len);
1146             state->start = 0;
1147             return ret;
1148         }
1149         else if(ret == 0) {
1150             /* nothing available, wait until data arrives or we time out */
1151             long left = LIBSSH2_READ_TIMEOUT - (long)(time(NULL) -
1152                                                       state->start);
1153 
1154             if(left <= 0) {
1155                 state->start = 0;
1156                 return LIBSSH2_ERROR_TIMEOUT;
1157             }
1158             return -1; /* no packet available yet */
1159         }
1160     }
1161 
1162     /* Only reached if the socket died */
1163     return LIBSSH2_ERROR_SOCKET_DISCONNECT;
1164 }
1165 
1166 /*
1167  * _libssh2_packet_burn
1168  *
1169  * Loops _libssh2_transport_read() until any packet is available and promptly
1170  * discards it.
1171  * Used during KEX exchange to discard badly guessed KEX_INIT packets
1172  */
1173 int
_libssh2_packet_burn(LIBSSH2_SESSION * session,libssh2_nonblocking_states * state)1174 _libssh2_packet_burn(LIBSSH2_SESSION * session,
1175                      libssh2_nonblocking_states * state)
1176 {
1177     unsigned char *data;
1178     size_t data_len;
1179     unsigned char i, all_packets[255];
1180     int ret;
1181 
1182     if(*state == libssh2_NB_state_idle) {
1183         for(i = 1; i < 255; i++) {
1184             all_packets[i - 1] = i;
1185         }
1186         all_packets[254] = 0;
1187 
1188         if(_libssh2_packet_askv(session, all_packets, &data, &data_len, 0,
1189                                  NULL, 0) == 0) {
1190             i = data[0];
1191             /* A packet was available in the packet brigade, burn it */
1192             LIBSSH2_FREE(session, data);
1193             return i;
1194         }
1195 
1196         _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
1197                        "Blocking until packet becomes available to burn");
1198         *state = libssh2_NB_state_created;
1199     }
1200 
1201     while(session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
1202         ret = _libssh2_transport_read(session);
1203         if(ret == LIBSSH2_ERROR_EAGAIN) {
1204             return ret;
1205         }
1206         else if(ret < 0) {
1207             *state = libssh2_NB_state_idle;
1208             return ret;
1209         }
1210         else if(ret == 0) {
1211             /* FIXME: this might busyloop */
1212             continue;
1213         }
1214 
1215         /* Be lazy, let packet_ask pull it out of the brigade */
1216         if(0 ==
1217             _libssh2_packet_ask(session, (unsigned char)ret,
1218                                          &data, &data_len, 0, NULL, 0)) {
1219             /* Smoke 'em if you got 'em */
1220             LIBSSH2_FREE(session, data);
1221             *state = libssh2_NB_state_idle;
1222             return ret;
1223         }
1224     }
1225 
1226     /* Only reached if the socket died */
1227     return LIBSSH2_ERROR_SOCKET_DISCONNECT;
1228 }
1229 
1230 /*
1231  * _libssh2_packet_requirev
1232  *
1233  * Loops _libssh2_transport_read() until one of a list of packet types
1234  * requested is available. SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause
1235  * a bailout. packet_types is a null terminated list of packet_type numbers
1236  */
1237 
1238 int
_libssh2_packet_requirev(LIBSSH2_SESSION * session,const unsigned char * packet_types,unsigned char ** data,size_t * data_len,int match_ofs,const unsigned char * match_buf,size_t match_len,packet_requirev_state_t * state)1239 _libssh2_packet_requirev(LIBSSH2_SESSION *session,
1240                          const unsigned char *packet_types,
1241                          unsigned char **data, size_t *data_len,
1242                          int match_ofs,
1243                          const unsigned char *match_buf, size_t match_len,
1244                          packet_requirev_state_t * state)
1245 {
1246     if(_libssh2_packet_askv(session, packet_types, data, data_len, match_ofs,
1247                              match_buf, match_len) == 0) {
1248         /* One of the packets listed was available in the packet brigade */
1249         state->start = 0;
1250         return 0;
1251     }
1252 
1253     if(state->start == 0) {
1254         state->start = time(NULL);
1255     }
1256 
1257     while(session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) {
1258         int ret = _libssh2_transport_read(session);
1259         if((ret < 0) && (ret != LIBSSH2_ERROR_EAGAIN)) {
1260             state->start = 0;
1261             return ret;
1262         }
1263         if(ret <= 0) {
1264             long left = LIBSSH2_READ_TIMEOUT -
1265                 (long)(time(NULL) - state->start);
1266 
1267             if(left <= 0) {
1268                 state->start = 0;
1269                 return LIBSSH2_ERROR_TIMEOUT;
1270             }
1271             else if(ret == LIBSSH2_ERROR_EAGAIN) {
1272                 return ret;
1273             }
1274         }
1275 
1276         if(strchr((char *) packet_types, ret)) {
1277             /* Be lazy, let packet_ask pull it out of the brigade */
1278             return _libssh2_packet_askv(session, packet_types, data,
1279                                         data_len, match_ofs, match_buf,
1280                                         match_len);
1281         }
1282     }
1283 
1284     /* Only reached if the socket died */
1285     state->start = 0;
1286     return LIBSSH2_ERROR_SOCKET_DISCONNECT;
1287 }
1288 
1289