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