1 /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
4 * Redistribution and use in source and binary forms,
5 * with or without modification, are permitted provided
6 * that the following conditions are met:
8 * Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the
10 * following disclaimer.
12 * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
17 * Neither the name of the copyright holder nor the names
18 * of any other contributors may be used to endorse or
19 * promote products derived from this software without
20 * specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
34 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
38 #include "libssh2_priv.h"
46 #ifdef HAVE_SYS_TIME_H
50 #ifdef HAVE_INTTYPES_H
54 /* Needed for struct iovec on some platforms */
59 #include <sys/types.h>
61 /* {{{ libssh2_packet_queue_listener
62 * Queue a connection request for a listener
65 libssh2_packet_queue_listener(LIBSSH2_SESSION
* session
, unsigned char *data
,
66 unsigned long datalen
,
67 packet_queue_listener_state_t
* listen_state
)
70 * Look for a matching listener
72 unsigned char *s
= data
+ (sizeof("forwarded-tcpip") - 1) + 5;
73 /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
74 unsigned long packet_len
= 17 + (sizeof(FwdNotReq
) - 1);
76 LIBSSH2_LISTENER
*listen
= session
->listeners
;
77 char failure_code
= 1; /* SSH_OPEN_ADMINISTRATIVELY_PROHIBITED */
82 if (listen_state
->state
== libssh2_NB_state_idle
) {
83 listen_state
->sender_channel
= libssh2_ntohu32(s
);
86 listen_state
->initial_window_size
= libssh2_ntohu32(s
);
88 listen_state
->packet_size
= libssh2_ntohu32(s
);
91 listen_state
->host_len
= libssh2_ntohu32(s
);
93 listen_state
->host
= s
;
94 s
+= listen_state
->host_len
;
95 listen_state
->port
= libssh2_ntohu32(s
);
98 listen_state
->shost_len
= libssh2_ntohu32(s
);
100 listen_state
->shost
= s
;
101 s
+= listen_state
->shost_len
;
102 listen_state
->sport
= libssh2_ntohu32(s
);
105 _libssh2_debug(session
, LIBSSH2_DBG_CONN
,
106 "Remote received connection from %s:%ld to %s:%ld",
107 listen_state
->shost
, listen_state
->sport
,
108 listen_state
->host
, listen_state
->port
);
110 listen_state
->state
= libssh2_NB_state_allocated
;
113 if (listen_state
->state
!= libssh2_NB_state_sent
) {
115 if ((listen
->port
== (int) listen_state
->port
) &&
116 (strlen(listen
->host
) == listen_state
->host_len
) &&
118 (listen
->host
, listen_state
->host
,
119 listen_state
->host_len
) == 0)) {
120 /* This is our listener */
121 LIBSSH2_CHANNEL
*channel
, *last_queued
= listen
->queue
;
123 last_queued
= listen
->queue
;
124 if (listen_state
->state
== libssh2_NB_state_allocated
) {
125 if (listen
->queue_maxsize
&&
126 (listen
->queue_maxsize
<= listen
->queue_size
)) {
128 failure_code
= 4; /* SSH_OPEN_RESOURCE_SHORTAGE */
129 _libssh2_debug(session
, LIBSSH2_DBG_CONN
,
130 "Listener queue full, ignoring");
131 listen_state
->state
= libssh2_NB_state_sent
;
135 channel
= LIBSSH2_ALLOC(session
, sizeof(LIBSSH2_CHANNEL
));
137 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
138 "Unable to allocate a channel for new connection",
140 failure_code
= 4; /* SSH_OPEN_RESOURCE_SHORTAGE */
141 listen_state
->state
= libssh2_NB_state_sent
;
144 memset(channel
, 0, sizeof(LIBSSH2_CHANNEL
));
146 channel
->session
= session
;
147 channel
->channel_type_len
= sizeof("forwarded-tcpip") - 1;
148 channel
->channel_type
= LIBSSH2_ALLOC(session
,
152 if (!channel
->channel_type
) {
153 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
154 "Unable to allocate a channel for new connection",
156 LIBSSH2_FREE(session
, channel
);
157 failure_code
= 4; /* SSH_OPEN_RESOURCE_SHORTAGE */
158 listen_state
->state
= libssh2_NB_state_sent
;
161 memcpy(channel
->channel_type
, "forwarded-tcpip",
162 channel
->channel_type_len
+ 1);
164 channel
->remote
.id
= listen_state
->sender_channel
;
165 channel
->remote
.window_size_initial
=
166 LIBSSH2_CHANNEL_WINDOW_DEFAULT
;
167 channel
->remote
.window_size
=
168 LIBSSH2_CHANNEL_WINDOW_DEFAULT
;
169 channel
->remote
.packet_size
=
170 LIBSSH2_CHANNEL_PACKET_DEFAULT
;
172 channel
->local
.id
= libssh2_channel_nextid(session
);
173 channel
->local
.window_size_initial
=
174 listen_state
->initial_window_size
;
175 channel
->local
.window_size
=
176 listen_state
->initial_window_size
;
177 channel
->local
.packet_size
= listen_state
->packet_size
;
179 _libssh2_debug(session
, LIBSSH2_DBG_CONN
,
180 "Connection queued: channel %lu/%lu win %lu/%lu packet %lu/%lu",
181 channel
->local
.id
, channel
->remote
.id
,
182 channel
->local
.window_size
,
183 channel
->remote
.window_size
,
184 channel
->local
.packet_size
,
185 channel
->remote
.packet_size
);
187 p
= listen_state
->packet
;
188 *(p
++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION
;
189 libssh2_htonu32(p
, channel
->remote
.id
);
191 libssh2_htonu32(p
, channel
->local
.id
);
193 libssh2_htonu32(p
, channel
->remote
.window_size_initial
);
195 libssh2_htonu32(p
, channel
->remote
.packet_size
);
198 listen_state
->state
= libssh2_NB_state_created
;
201 if (listen_state
->state
== libssh2_NB_state_created
) {
202 rc
= libssh2_packet_write(session
, listen_state
->packet
,
204 if (rc
== PACKET_EAGAIN
) {
205 return PACKET_EAGAIN
;
207 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
208 "Unable to send channel open confirmation",
210 listen_state
->state
= libssh2_NB_state_idle
;
214 /* Link the channel into the end of the queue list */
217 listen
->queue
= channel
;
218 listen_state
->state
= libssh2_NB_state_idle
;
222 while (last_queued
->next
) {
223 last_queued
= last_queued
->next
;
226 last_queued
->next
= channel
;
227 channel
->prev
= last_queued
;
229 listen
->queue_size
++;
231 listen_state
->state
= libssh2_NB_state_idle
;
236 listen
= listen
->next
;
239 listen_state
->state
= libssh2_NB_state_sent
;
242 /* We're not listening to you */
244 p
= listen_state
->packet
;
245 *(p
++) = SSH_MSG_CHANNEL_OPEN_FAILURE
;
246 libssh2_htonu32(p
, listen_state
->sender_channel
);
248 libssh2_htonu32(p
, failure_code
);
250 libssh2_htonu32(p
, sizeof(FwdNotReq
) - 1);
252 memcpy(s
, FwdNotReq
, sizeof(FwdNotReq
) - 1);
253 p
+= sizeof(FwdNotReq
) - 1;
254 libssh2_htonu32(p
, 0);
256 rc
= libssh2_packet_write(session
, listen_state
->packet
, packet_len
);
257 if (rc
== PACKET_EAGAIN
) {
258 return PACKET_EAGAIN
;
260 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
261 "Unable to send open failure", 0);
262 listen_state
->state
= libssh2_NB_state_idle
;
265 listen_state
->state
= libssh2_NB_state_idle
;
272 /* {{{ libssh2_packet_x11_open
273 * Accept a forwarded X11 connection
276 libssh2_packet_x11_open(LIBSSH2_SESSION
* session
, unsigned char *data
,
277 unsigned long datalen
,
278 packet_x11_open_state_t
* x11open_state
)
280 int failure_code
= 2; /* SSH_OPEN_CONNECT_FAILED */
281 unsigned char *s
= data
+ (sizeof("x11") - 1) + 5;
282 /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
283 unsigned long packet_len
= 17 + (sizeof(X11FwdUnAvil
) - 1);
285 LIBSSH2_CHANNEL
*channel
;
290 if (x11open_state
->state
== libssh2_NB_state_idle
) {
291 x11open_state
->sender_channel
= libssh2_ntohu32(s
);
293 x11open_state
->initial_window_size
= libssh2_ntohu32(s
);
295 x11open_state
->packet_size
= libssh2_ntohu32(s
);
297 x11open_state
->shost_len
= libssh2_ntohu32(s
);
299 x11open_state
->shost
= s
;
300 s
+= x11open_state
->shost_len
;
301 x11open_state
->sport
= libssh2_ntohu32(s
);
304 _libssh2_debug(session
, LIBSSH2_DBG_CONN
,
305 "X11 Connection Received from %s:%ld on channel %lu",
306 x11open_state
->shost
, x11open_state
->sport
,
307 x11open_state
->sender_channel
);
309 x11open_state
->state
= libssh2_NB_state_allocated
;
313 if (x11open_state
->state
== libssh2_NB_state_allocated
) {
314 channel
= LIBSSH2_ALLOC(session
, sizeof(LIBSSH2_CHANNEL
));
316 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
317 "Unable to allocate a channel for new connection",
319 failure_code
= 4; /* SSH_OPEN_RESOURCE_SHORTAGE */
322 memset(channel
, 0, sizeof(LIBSSH2_CHANNEL
));
324 channel
->session
= session
;
325 channel
->channel_type_len
= sizeof("x11") - 1;
326 channel
->channel_type
= LIBSSH2_ALLOC(session
,
327 channel
->channel_type_len
+
329 if (!channel
->channel_type
) {
330 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
331 "Unable to allocate a channel for new connection",
333 LIBSSH2_FREE(session
, channel
);
334 failure_code
= 4; /* SSH_OPEN_RESOURCE_SHORTAGE */
337 memcpy(channel
->channel_type
, "x11",
338 channel
->channel_type_len
+ 1);
340 channel
->remote
.id
= x11open_state
->sender_channel
;
341 channel
->remote
.window_size_initial
=
342 LIBSSH2_CHANNEL_WINDOW_DEFAULT
;
343 channel
->remote
.window_size
= LIBSSH2_CHANNEL_WINDOW_DEFAULT
;
344 channel
->remote
.packet_size
= LIBSSH2_CHANNEL_PACKET_DEFAULT
;
346 channel
->local
.id
= libssh2_channel_nextid(session
);
347 channel
->local
.window_size_initial
=
348 x11open_state
->initial_window_size
;
349 channel
->local
.window_size
= x11open_state
->initial_window_size
;
350 channel
->local
.packet_size
= x11open_state
->packet_size
;
352 _libssh2_debug(session
, LIBSSH2_DBG_CONN
,
353 "X11 Connection established: channel %lu/%lu win %lu/%lu packet %lu/%lu",
354 channel
->local
.id
, channel
->remote
.id
,
355 channel
->local
.window_size
,
356 channel
->remote
.window_size
,
357 channel
->local
.packet_size
,
358 channel
->remote
.packet_size
);
359 p
= x11open_state
->packet
;
360 *(p
++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION
;
361 libssh2_htonu32(p
, channel
->remote
.id
);
363 libssh2_htonu32(p
, channel
->local
.id
);
365 libssh2_htonu32(p
, channel
->remote
.window_size_initial
);
367 libssh2_htonu32(p
, channel
->remote
.packet_size
);
370 x11open_state
->state
= libssh2_NB_state_created
;
373 if (x11open_state
->state
== libssh2_NB_state_created
) {
374 rc
= libssh2_packet_write(session
, x11open_state
->packet
, 17);
375 if (rc
== PACKET_EAGAIN
) {
376 return PACKET_EAGAIN
;
378 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
379 "Unable to send channel open confirmation", 0);
380 x11open_state
->state
= libssh2_NB_state_idle
;
384 /* Link the channel into the session */
385 if (session
->channels
.tail
) {
386 session
->channels
.tail
->next
= channel
;
387 channel
->prev
= session
->channels
.tail
;
389 session
->channels
.head
= channel
;
390 channel
->prev
= NULL
;
392 channel
->next
= NULL
;
393 session
->channels
.tail
= channel
;
396 * Pass control to the callback, they may turn right around and
397 * free the channel, or actually use it
399 LIBSSH2_X11_OPEN(channel
, (char *) x11open_state
->shost
,
400 x11open_state
->sport
);
402 x11open_state
->state
= libssh2_NB_state_idle
;
406 failure_code
= 4; /* SSH_OPEN_RESOURCE_SHORTAGE */
410 p
= x11open_state
->packet
;
411 *(p
++) = SSH_MSG_CHANNEL_OPEN_FAILURE
;
412 libssh2_htonu32(p
, x11open_state
->sender_channel
);
414 libssh2_htonu32(p
, failure_code
);
416 libssh2_htonu32(p
, sizeof(X11FwdUnAvil
) - 1);
418 memcpy(s
, X11FwdUnAvil
, sizeof(X11FwdUnAvil
) - 1);
419 p
+= sizeof(X11FwdUnAvil
) - 1;
420 libssh2_htonu32(p
, 0);
422 rc
= libssh2_packet_write(session
, x11open_state
->packet
, packet_len
);
423 if (rc
== PACKET_EAGAIN
) {
424 return PACKET_EAGAIN
;
426 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
427 "Unable to send open failure", 0);
428 x11open_state
->state
= libssh2_NB_state_idle
;
431 x11open_state
->state
= libssh2_NB_state_idle
;
437 /* {{{ libssh2_packet_new
438 * Create a new packet and attach it to the brigade
441 libssh2_packet_add(LIBSSH2_SESSION
* session
, unsigned char *data
,
442 size_t datalen
, int macstate
)
446 if (session
->packAdd_state
== libssh2_NB_state_idle
) {
447 session
->packAdd_data_head
= 0;
449 /* Zero the whole thing out */
450 memset(&session
->packAdd_key_state
, 0,
451 sizeof(session
->packAdd_key_state
));
453 /* Zero the whole thing out */
454 memset(&session
->packAdd_Qlstn_state
, 0,
455 sizeof(session
->packAdd_Qlstn_state
));
457 /* Zero the whole thing out */
458 memset(&session
->packAdd_x11open_state
, 0,
459 sizeof(session
->packAdd_x11open_state
));
461 _libssh2_debug(session
, LIBSSH2_DBG_TRANS
,
462 "Packet type %d received, length=%d",
463 (int) data
[0], (int) datalen
);
464 if (macstate
== LIBSSH2_MAC_INVALID
) {
465 if (session
->macerror
) {
466 if (LIBSSH2_MACERROR(session
, (char *) data
, datalen
) == 0) {
467 /* Calling app has given the OK, Process it anyway */
468 macstate
= LIBSSH2_MAC_CONFIRMED
;
470 libssh2_error(session
, LIBSSH2_ERROR_INVALID_MAC
,
471 "Invalid Message Authentication Code received",
473 if (session
->ssh_msg_disconnect
) {
474 LIBSSH2_DISCONNECT(session
, SSH_DISCONNECT_MAC_ERROR
,
475 "Invalid MAC received",
476 sizeof("Invalid MAC received") - 1,
479 LIBSSH2_FREE(session
, data
);
483 libssh2_error(session
, LIBSSH2_ERROR_INVALID_MAC
,
484 "Invalid Message Authentication Code received",
486 if (session
->ssh_msg_disconnect
) {
487 LIBSSH2_DISCONNECT(session
, SSH_DISCONNECT_MAC_ERROR
,
488 "Invalid MAC received",
489 sizeof("Invalid MAC received") - 1,
492 LIBSSH2_FREE(session
, data
);
497 session
->packAdd_state
= libssh2_NB_state_allocated
;
501 * =============================== NOTE ===============================
502 * I know this is very ugly and not a really good use of "goto", but
503 * this case statement would be even uglier to do it any other way
505 if (session
->packAdd_state
== libssh2_NB_state_jump1
) {
506 goto libssh2_packet_add_jump_point1
;
507 } else if (session
->packAdd_state
== libssh2_NB_state_jump2
) {
508 goto libssh2_packet_add_jump_point2
;
509 } else if (session
->packAdd_state
== libssh2_NB_state_jump3
) {
510 goto libssh2_packet_add_jump_point3
;
513 if (session
->packAdd_state
== libssh2_NB_state_allocated
) {
514 /* A couple exceptions to the packet adding rule: */
516 case SSH_MSG_DISCONNECT
:
518 char *message
, *language
;
519 int reason
, message_len
, language_len
;
521 reason
= libssh2_ntohu32(data
+ 1);
522 message_len
= libssh2_ntohu32(data
+ 5);
523 /* 9 = packet_type(1) + reason(4) + message_len(4) */
524 message
= (char *) data
+ 9;
525 language_len
= libssh2_ntohu32(data
+ 9 + message_len
);
527 * This is where we hack on the data a little,
528 * Use the MSB of language_len to to a terminating NULL
529 * (In all liklihood it is already)
530 * Shift the language tag back a byte (In all likelihood
531 * it's zero length anyway)
532 * Store a NULL in the last byte of the packet to terminate
533 * the language string
534 * With the lengths passed this isn't *REALLY* necessary,
537 message
[message_len
] = '\0';
538 language
= (char *) data
+ 9 + message_len
+ 3;
540 memcpy(language
, language
+ 1, language_len
);
542 language
[language_len
] = '\0';
544 if (session
->ssh_msg_disconnect
) {
545 LIBSSH2_DISCONNECT(session
, reason
, message
,
546 message_len
, language
, language_len
);
548 _libssh2_debug(session
, LIBSSH2_DBG_TRANS
,
549 "Disconnect(%d): %s(%s)", reason
,
551 LIBSSH2_FREE(session
, data
);
552 session
->socket_state
= LIBSSH2_SOCKET_DISCONNECTED
;
553 session
->packAdd_state
= libssh2_NB_state_idle
;
559 /* As with disconnect, back it up one and add a trailing NULL */
560 memcpy(data
+ 4, data
+ 5, datalen
- 5);
561 data
[datalen
] = '\0';
562 if (session
->ssh_msg_ignore
) {
563 LIBSSH2_IGNORE(session
, (char *) data
+ 4, datalen
- 5);
565 LIBSSH2_FREE(session
, data
);
566 session
->packAdd_state
= libssh2_NB_state_idle
;
572 int always_display
= data
[0];
573 char *message
, *language
;
574 int message_len
, language_len
;
576 message_len
= libssh2_ntohu32(data
+ 2);
577 /* 6 = packet_type(1) + display(1) + message_len(4) */
578 message
= (char *) data
+ 6;
579 language_len
= libssh2_ntohu32(data
+ 6 + message_len
);
581 * This is where we hack on the data a little,
582 * Use the MSB of language_len to to a terminating NULL
583 * (In all liklihood it is already)
584 * Shift the language tag back a byte (In all likelihood
585 * it's zero length anyway)
586 * Store a NULL in the last byte of the packet to terminate
587 * the language string
588 * With the lengths passed this isn't *REALLY* necessary,
591 message
[message_len
] = '\0';
592 language
= (char *) data
+ 6 + message_len
+ 3;
594 memcpy(language
, language
+ 1, language_len
);
596 language
[language_len
] = '\0';
598 if (session
->ssh_msg_debug
) {
599 LIBSSH2_DEBUG(session
, always_display
, message
,
600 message_len
, language
, language_len
);
603 * _libssh2_debug will actually truncate this for us so
604 * that it's not an inordinate about of data
606 _libssh2_debug(session
, LIBSSH2_DBG_TRANS
,
607 "Debug Packet: %s", message
);
608 LIBSSH2_FREE(session
, data
);
609 session
->packAdd_state
= libssh2_NB_state_idle
;
614 case SSH_MSG_CHANNEL_EXTENDED_DATA
:
616 session
->packAdd_data_head
+= 4;
617 case SSH_MSG_CHANNEL_DATA
:
618 /* packet_type(1) + channelno(4) + datalen(4) */
619 session
->packAdd_data_head
+= 9;
621 session
->packAdd_channel
= libssh2_channel_locate(session
,
625 if (!session
->packAdd_channel
) {
626 libssh2_error(session
, LIBSSH2_ERROR_CHANNEL_UNKNOWN
,
627 "Packet received for unknown channel, ignoring",
629 LIBSSH2_FREE(session
, data
);
630 session
->packAdd_state
= libssh2_NB_state_idle
;
635 unsigned long stream_id
= 0;
637 if (data
[0] == SSH_MSG_CHANNEL_EXTENDED_DATA
) {
638 stream_id
= libssh2_ntohu32(data
+ 5);
641 _libssh2_debug(session
, LIBSSH2_DBG_CONN
,
642 "%d bytes received for channel %lu/%lu stream #%lu",
644 session
->packAdd_data_head
),
645 session
->packAdd_channel
->local
.id
,
646 session
->packAdd_channel
->remote
.id
,
650 if ((session
->packAdd_channel
->remote
.
651 extended_data_ignore_mode
==
652 LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE
)
653 && (data
[0] == SSH_MSG_CHANNEL_EXTENDED_DATA
)) {
654 /* Pretend we didn't receive this */
655 LIBSSH2_FREE(session
, data
);
657 _libssh2_debug(session
, LIBSSH2_DBG_CONN
,
658 "Ignoring extended data and refunding %d bytes",
659 (int) (datalen
- 13));
660 /* Adjust the window based on the block we just freed */
661 libssh2_packet_add_jump_point1
:
662 session
->packAdd_state
= libssh2_NB_state_jump1
;
663 rc
= libssh2_channel_receive_window_adjust(session
->
667 if (rc
== PACKET_EAGAIN
) {
668 return PACKET_EAGAIN
;
670 session
->packAdd_state
= libssh2_NB_state_idle
;
675 * REMEMBER! remote means remote as source of data,
678 if (session
->packAdd_channel
->remote
.packet_size
<
679 (datalen
- session
->packAdd_data_head
)) {
681 * Spec says we MAY ignore bytes sent beyond
684 libssh2_error(session
,
685 LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED
,
686 "Packet contains more data than we offered to receive, truncating",
689 session
->packAdd_channel
->remote
.packet_size
+
690 session
->packAdd_data_head
;
692 if (session
->packAdd_channel
->remote
.window_size
<= 0) {
694 * Spec says we MAY ignore bytes sent beyond
697 libssh2_error(session
,
698 LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED
,
699 "The current receive window is full, data ignored",
701 LIBSSH2_FREE(session
, data
);
702 session
->packAdd_state
= libssh2_NB_state_idle
;
705 /* Reset EOF status */
706 session
->packAdd_channel
->remote
.eof
= 0;
708 if ((datalen
- session
->packAdd_data_head
) >
709 session
->packAdd_channel
->remote
.window_size
) {
710 libssh2_error(session
,
711 LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED
,
712 "Remote sent more data than current window allows, truncating",
715 session
->packAdd_channel
->remote
.window_size
+
716 session
->packAdd_data_head
;
718 /* Now that we've received it, shrink our window */
719 session
->packAdd_channel
->remote
.window_size
-=
720 datalen
- session
->packAdd_data_head
;
725 case SSH_MSG_CHANNEL_EOF
:
727 session
->packAdd_channel
= libssh2_channel_locate(session
,
731 if (!session
->packAdd_channel
) {
732 /* We may have freed already, just quietly ignore this... */
733 LIBSSH2_FREE(session
, data
);
734 session
->packAdd_state
= libssh2_NB_state_idle
;
738 _libssh2_debug(session
,
740 "EOF received for channel %lu/%lu",
741 session
->packAdd_channel
->local
.id
,
742 session
->packAdd_channel
->remote
.id
);
743 session
->packAdd_channel
->remote
.eof
= 1;
745 LIBSSH2_FREE(session
, data
);
746 session
->packAdd_state
= libssh2_NB_state_idle
;
751 case SSH_MSG_CHANNEL_REQUEST
:
753 if (libssh2_ntohu32(data
+ 5) == sizeof("exit-status") - 1
754 && !memcmp("exit-status", data
+ 9,
755 sizeof("exit-status") - 1)) {
757 /* we've got "exit-status" packet. Set the session value */
758 session
->packAdd_channel
=
759 libssh2_channel_locate(session
,
760 libssh2_ntohu32(data
+ 1));
762 if (session
->packAdd_channel
) {
763 session
->packAdd_channel
->exit_status
=
764 libssh2_ntohu32(data
+ 9 + sizeof("exit-status"));
765 _libssh2_debug(session
, LIBSSH2_DBG_CONN
,
766 "Exit status %lu received for channel %lu/%lu",
767 session
->packAdd_channel
->exit_status
,
768 session
->packAdd_channel
->local
.id
,
769 session
->packAdd_channel
->remote
.id
);
772 LIBSSH2_FREE(session
, data
);
773 session
->packAdd_state
= libssh2_NB_state_idle
;
779 case SSH_MSG_CHANNEL_CLOSE
:
781 session
->packAdd_channel
= libssh2_channel_locate(session
,
785 if (!session
->packAdd_channel
) {
786 /* We may have freed already, just quietly ignore this... */
787 LIBSSH2_FREE(session
, data
);
788 session
->packAdd_state
= libssh2_NB_state_idle
;
791 _libssh2_debug(session
, LIBSSH2_DBG_CONN
,
792 "Close received for channel %lu/%lu",
793 session
->packAdd_channel
->local
.id
,
794 session
->packAdd_channel
->remote
.id
);
796 session
->packAdd_channel
->remote
.close
= 1;
797 session
->packAdd_channel
->remote
.eof
= 1;
798 /* TODO: Add a callback for this */
800 LIBSSH2_FREE(session
, data
);
801 session
->packAdd_state
= libssh2_NB_state_idle
;
806 case SSH_MSG_CHANNEL_OPEN
:
807 if ((datalen
>= (sizeof("forwarded-tcpip") + 4)) &&
808 ((sizeof("forwarded-tcpip") - 1) == libssh2_ntohu32(data
+ 1))
811 (data
+ 5, "forwarded-tcpip",
812 sizeof("forwarded-tcpip") - 1) == 0)) {
814 libssh2_packet_add_jump_point2
:
815 session
->packAdd_state
= libssh2_NB_state_jump2
;
816 rc
= libssh2_packet_queue_listener(session
, data
, datalen
,
818 packAdd_Qlstn_state
);
819 if (rc
== PACKET_EAGAIN
) {
820 return PACKET_EAGAIN
;
823 LIBSSH2_FREE(session
, data
);
824 session
->packAdd_state
= libssh2_NB_state_idle
;
827 if ((datalen
>= (sizeof("x11") + 4)) &&
828 ((sizeof("x11") - 1) == libssh2_ntohu32(data
+ 1)) &&
829 (memcmp(data
+ 5, "x11", sizeof("x11") - 1) == 0)) {
831 libssh2_packet_add_jump_point3
:
832 session
->packAdd_state
= libssh2_NB_state_jump3
;
833 rc
= libssh2_packet_x11_open(session
, data
, datalen
,
834 &session
->packAdd_x11open_state
);
835 if (rc
== PACKET_EAGAIN
) {
836 return PACKET_EAGAIN
;
839 LIBSSH2_FREE(session
, data
);
840 session
->packAdd_state
= libssh2_NB_state_idle
;
845 case SSH_MSG_CHANNEL_WINDOW_ADJUST
:
847 unsigned long bytestoadd
= libssh2_ntohu32(data
+ 5);
848 session
->packAdd_channel
= libssh2_channel_locate(session
,
852 if (session
->packAdd_channel
&& bytestoadd
) {
853 session
->packAdd_channel
->local
.window_size
+= bytestoadd
;
855 _libssh2_debug(session
, LIBSSH2_DBG_CONN
,
856 "Window adjust received for channel %lu/%lu, adding %lu bytes, new window_size=%lu",
857 session
->packAdd_channel
->local
.id
,
858 session
->packAdd_channel
->remote
.id
,
860 session
->packAdd_channel
->local
.window_size
);
862 LIBSSH2_FREE(session
, data
);
863 session
->packAdd_state
= libssh2_NB_state_idle
;
869 session
->packAdd_state
= libssh2_NB_state_sent
;
872 if (session
->packAdd_state
== libssh2_NB_state_sent
) {
873 session
->packAdd_packet
=
874 LIBSSH2_ALLOC(session
, sizeof(LIBSSH2_PACKET
));
875 if (!session
->packAdd_packet
) {
876 _libssh2_debug(session
, LIBSSH2_ERROR_ALLOC
,
877 "Unable to allocate memory for LIBSSH2_PACKET");
878 LIBSSH2_FREE(session
, data
);
879 session
->packAdd_state
= libssh2_NB_state_idle
;
882 memset(session
->packAdd_packet
, 0, sizeof(LIBSSH2_PACKET
));
884 session
->packAdd_packet
->data
= data
;
885 session
->packAdd_packet
->data_len
= datalen
;
886 session
->packAdd_packet
->data_head
= session
->packAdd_data_head
;
887 session
->packAdd_packet
->mac
= macstate
;
888 session
->packAdd_packet
->brigade
= &session
->packets
;
889 session
->packAdd_packet
->next
= NULL
;
891 if (session
->packets
.tail
) {
892 session
->packAdd_packet
->prev
= session
->packets
.tail
;
893 session
->packAdd_packet
->prev
->next
= session
->packAdd_packet
;
894 session
->packets
.tail
= session
->packAdd_packet
;
896 session
->packets
.head
= session
->packAdd_packet
;
897 session
->packets
.tail
= session
->packAdd_packet
;
898 session
->packAdd_packet
->prev
= NULL
;
901 session
->packAdd_state
= libssh2_NB_state_sent1
;
904 if ((data
[0] == SSH_MSG_KEXINIT
&&
905 !(session
->state
& LIBSSH2_STATE_EXCHANGING_KEYS
)) ||
906 (session
->packAdd_state
== libssh2_NB_state_sent2
)) {
907 if (session
->packAdd_state
== libssh2_NB_state_sent1
) {
909 * Remote wants new keys
910 * Well, it's already in the brigade,
911 * let's just call back into ourselves
913 _libssh2_debug(session
, LIBSSH2_DBG_TRANS
, "Renegotiating Keys");
915 session
->packAdd_state
= libssh2_NB_state_sent2
;
918 * If there was a key reexchange failure, let's just hope we didn't
919 * send NEWKEYS yet, otherwise remote will drop us like a rock
921 rc
= libssh2_kex_exchange(session
, 1, &session
->packAdd_key_state
);
922 if (rc
== PACKET_EAGAIN
) {
923 return PACKET_EAGAIN
;
927 session
->packAdd_state
= libssh2_NB_state_idle
;
933 /* {{{ libssh2_packet_ask
934 * Scan the brigade for a matching packet type, optionally poll the socket for
938 libssh2_packet_ask_ex(LIBSSH2_SESSION
* session
, unsigned char packet_type
,
939 unsigned char **data
, unsigned long *data_len
,
940 unsigned long match_ofs
, const unsigned char *match_buf
,
941 unsigned long match_len
, int poll_socket
)
943 LIBSSH2_PACKET
*packet
= session
->packets
.head
;
948 * When "poll_socket" is "1" libhss2_packet_read() can return
949 * PACKET_EAGAIN. I am not sure what should happen, but internally
950 * there is only one location that might do so, libssh2_packet_askv_ex()
952 libssh2pack_t rc
= libssh2_packet_read(session
);
953 if ((rc
< 0) && !packet
) {
957 _libssh2_debug(session
, LIBSSH2_DBG_TRANS
,
958 "Looking for packet of type: %d", (int) packet_type
);
961 if (packet
->data
[0] == packet_type
962 && (packet
->data_len
>= (match_ofs
+ match_len
)) && (!match_buf
971 *data
= packet
->data
;
972 *data_len
= packet
->data_len
;
975 packet
->prev
->next
= packet
->next
;
977 session
->packets
.head
= packet
->next
;
981 packet
->next
->prev
= packet
->prev
;
983 session
->packets
.tail
= packet
->prev
;
986 LIBSSH2_FREE(session
, packet
);
990 packet
= packet
->next
;
997 /* {{{ libssh2_packet_askv
998 * Scan for any of a list of packet types in the brigade, optionally poll the
999 * socket for a packet first
1002 libssh2_packet_askv_ex(LIBSSH2_SESSION
* session
,
1003 const unsigned char *packet_types
,
1004 unsigned char **data
, unsigned long *data_len
,
1005 unsigned long match_ofs
,
1006 const unsigned char *match_buf
,
1007 unsigned long match_len
, int poll_socket
)
1009 int i
, packet_types_len
= strlen((char *) packet_types
);
1011 for(i
= 0; i
< packet_types_len
; i
++) {
1014 * When "poll_socket" is "1" libssh2_packet_ask_ex() could
1015 * return PACKET_EAGAIN. Not sure the correct action, I
1016 * think it is right as is.
1018 if (0 == libssh2_packet_ask_ex(session
, packet_types
[i
], data
,
1019 data_len
, match_ofs
, match_buf
,
1020 match_len
, i
? 0 : poll_socket
)) {
1033 * >0 on incoming data
1036 * FIXME: convert to use poll on systems that have it.
1039 libssh2_waitsocket(LIBSSH2_SESSION
* session
, long seconds
)
1041 struct timeval timeout
;
1045 timeout
.tv_sec
= seconds
;
1046 timeout
.tv_usec
= 0;
1050 FD_SET(session
->socket_fd
, &fd
);
1052 rc
= select(session
->socket_fd
+ 1, &fd
, NULL
, NULL
, &timeout
);
1057 /* {{{ libssh2_packet_require
1058 * Loops libssh2_packet_read() until the packet requested is available
1059 * SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause a bailout
1061 * Returns negative on error
1062 * Returns 0 when it has taken care of the requested packet.
1065 libssh2_packet_require_ex(LIBSSH2_SESSION
* session
, unsigned char packet_type
,
1066 unsigned char **data
, unsigned long *data_len
,
1067 unsigned long match_ofs
,
1068 const unsigned char *match_buf
,
1069 unsigned long match_len
,
1070 packet_require_state_t
* state
)
1072 if (state
->start
== 0) {
1073 if (libssh2_packet_ask_ex
1074 (session
, packet_type
, data
, data_len
, match_ofs
, match_buf
,
1075 match_len
, 0) == 0) {
1076 /* A packet was available in the packet brigade */
1080 state
->start
= time(NULL
);
1082 _libssh2_debug(session
, LIBSSH2_DBG_TRANS
,
1083 "May block until packet of type %d becomes available",
1087 while (session
->socket_state
== LIBSSH2_SOCKET_CONNECTED
) {
1088 libssh2pack_t ret
= libssh2_packet_read(session
);
1089 if (ret
== PACKET_EAGAIN
) {
1090 return PACKET_EAGAIN
;
1091 } else if ((ret
== 0) && (!session
->socket_block
)) {
1092 /* If we are in non-blocking and there is no data, return that */
1093 return PACKET_EAGAIN
;
1094 } else if (ret
< 0) {
1096 /* an error which is not just because of blocking */
1098 } else if (ret
== packet_type
) {
1099 /* Be lazy, let packet_ask pull it out of the brigade */
1101 libssh2_packet_ask_ex(session
, packet_type
, data
, data_len
,
1102 match_ofs
, match_buf
, match_len
, 0);
1105 } else if (ret
== 0) {
1106 /* nothing available, wait until data arrives or we time out */
1107 long left
= LIBSSH2_READ_TIMEOUT
- (time(NULL
) - state
->start
);
1109 if ((left
<= 0) || (libssh2_waitsocket(session
, left
) <= 0)) {
1111 return PACKET_TIMEOUT
;
1116 /* Only reached if the socket died */
1122 /* {{{ libssh2_packet_burn
1123 * Loops libssh2_packet_read() until any packet is available and promptly
1125 * Used during KEX exchange to discard badly guessed KEX_INIT packets
1128 libssh2_packet_burn(LIBSSH2_SESSION
* session
,
1129 libssh2_nonblocking_states
* state
)
1131 unsigned char *data
;
1132 unsigned long data_len
;
1133 unsigned char all_packets
[255];
1137 if (*state
== libssh2_NB_state_idle
) {
1138 for(i
= 1; i
< 256; i
++) {
1139 all_packets
[i
- 1] = i
;
1142 if (libssh2_packet_askv_ex
1143 (session
, all_packets
, &data
, &data_len
, 0, NULL
, 0, 0) == 0) {
1145 /* A packet was available in the packet brigade, burn it */
1146 LIBSSH2_FREE(session
, data
);
1150 _libssh2_debug(session
, LIBSSH2_DBG_TRANS
,
1151 "Blocking until packet becomes available to burn");
1152 *state
= libssh2_NB_state_created
;
1155 while (session
->socket_state
== LIBSSH2_SOCKET_CONNECTED
) {
1156 if ((ret
= libssh2_packet_read(session
)) == PACKET_EAGAIN
) {
1157 return PACKET_EAGAIN
;
1158 } else if (ret
< 0) {
1159 *state
= libssh2_NB_state_idle
;
1161 } else if (ret
== 0) {
1162 /* FIXME: this might busyloop */
1166 /* Be lazy, let packet_ask pull it out of the brigade */
1168 libssh2_packet_ask_ex(session
, ret
, &data
, &data_len
, 0, NULL
, 0,
1170 /* Smoke 'em if you got 'em */
1171 LIBSSH2_FREE(session
, data
);
1172 *state
= libssh2_NB_state_idle
;
1177 /* Only reached if the socket died */
1184 * {{{ libssh2_packet_requirev
1186 * Loops libssh2_packet_read() until one of a list of packet types requested is
1188 * SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause a bailout
1189 * packet_types is a null terminated list of packet_type numbers
1193 libssh2_packet_requirev_ex(LIBSSH2_SESSION
* session
,
1194 const unsigned char *packet_types
,
1195 unsigned char **data
, unsigned long *data_len
,
1196 unsigned long match_ofs
,
1197 const unsigned char *match_buf
,
1198 unsigned long match_len
,
1199 packet_requirev_state_t
* state
)
1201 if (libssh2_packet_askv_ex
1202 (session
, packet_types
, data
, data_len
, match_ofs
, match_buf
,
1203 match_len
, 0) == 0) {
1204 /* One of the packets listed was available in the packet
1210 if (state
->start
== 0) {
1211 state
->start
= time(NULL
);
1214 while (session
->socket_state
!= LIBSSH2_SOCKET_DISCONNECTED
) {
1215 int ret
= libssh2_packet_read(session
);
1216 if ((ret
< 0) && (ret
!= PACKET_EAGAIN
)) {
1221 long left
= LIBSSH2_READ_TIMEOUT
- (time(NULL
) - state
->start
);
1223 if ((left
<= 0) || (libssh2_waitsocket(session
, left
) <= 0)) {
1225 return PACKET_TIMEOUT
;
1226 } else if (ret
== PACKET_EAGAIN
) {
1227 return PACKET_EAGAIN
;
1231 if (strchr((char *) packet_types
, ret
)) {
1232 /* Be lazy, let packet_ask pull it out of the brigade */
1233 return libssh2_packet_askv_ex(session
, packet_types
, data
,
1234 data_len
, match_ofs
, match_buf
,
1239 /* Only reached if the socket died */