1
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
2
* Copyright (C) Mikhail Gusarov <dottedmag@dottedmag.net>
3
* Copyright (C) Daniel Stenberg
6
* Redistribution and use in source and binary forms,
7
* with or without modification, are permitted provided
8
* that the following conditions are met:
10
* Redistributions of source code must retain the above
11
* copyright notice, this list of conditions and the
12
* following disclaimer.
14
* Redistributions in binary form must reproduce the above
15
* copyright notice, this list of conditions and the following
16
* disclaimer in the documentation and/or other materials
17
* provided with the distribution.
19
* Neither the name of the copyright holder nor the names
20
* of any other contributors may be used to endorse or
21
* promote products derived from this software without
22
* specific prior written permission.
24
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
25
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
26
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
34
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
36
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
39
* SPDX-License-Identifier: BSD-3-Clause
42
#include "libssh2_priv.h"
59
* _libssh2_channel_nextid
61
* Determine the next channel ID we can use at our end
64
_libssh2_channel_nextid(LIBSSH2_SESSION * session)
66
uint32_t id = session->next_channel;
67
LIBSSH2_CHANNEL *channel;
69
channel = _libssh2_list_first(&session->channels);
72
if(channel->local.id > id) {
73
id = channel->local.id;
75
channel = _libssh2_list_next(&channel->node);
78
/* This is a shortcut to avoid waiting for close packets on channels we've
79
* forgotten about, This *could* be a problem if we request and close 4
80
* billion or so channels in too rapid succession for the remote end to
81
* respond, but the worst case scenario is that some data meant for
82
* another channel Gets picked up by the new one.... Pretty unlikely all
85
session->next_channel = id + 1;
86
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
87
"Allocated new channel ID#%u", id));
92
* _libssh2_channel_locate
94
* Locate a channel pointer by number
97
_libssh2_channel_locate(LIBSSH2_SESSION *session, uint32_t channel_id)
99
LIBSSH2_CHANNEL *channel;
102
for(channel = _libssh2_list_first(&session->channels);
104
channel = _libssh2_list_next(&channel->node)) {
105
if(channel->local.id == channel_id)
109
/* We didn't find the channel in the session, let's then check its
110
listeners since each listener may have its own set of pending channels
112
for(l = _libssh2_list_first(&session->listeners); l;
113
l = _libssh2_list_next(&l->node)) {
114
for(channel = _libssh2_list_first(&l->queue);
116
channel = _libssh2_list_next(&channel->node)) {
117
if(channel->local.id == channel_id)
126
* _libssh2_channel_open
128
* Establish a generic session channel
131
_libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
132
uint32_t channel_type_len,
133
uint32_t window_size,
134
uint32_t packet_size,
135
const unsigned char *message,
138
static const unsigned char reply_codes[3] = {
139
SSH_MSG_CHANNEL_OPEN_CONFIRMATION,
140
SSH_MSG_CHANNEL_OPEN_FAILURE,
146
if(session->open_state == libssh2_NB_state_idle) {
147
session->open_channel = NULL;
148
session->open_packet = NULL;
149
session->open_data = NULL;
150
/* 17 = packet_type(1) + channel_type_len(4) + sender_channel(4) +
151
* window_size(4) + packet_size(4) */
152
session->open_packet_len = channel_type_len + 17;
153
session->open_local_channel = _libssh2_channel_nextid(session);
155
/* Zero the whole thing out */
156
memset(&session->open_packet_requirev_state, 0,
157
sizeof(session->open_packet_requirev_state));
159
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
160
"Opening Channel - win %d pack %d", window_size,
162
session->open_channel =
163
LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL));
164
if(!session->open_channel) {
165
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
166
"Unable to allocate space for channel data");
169
session->open_channel->channel_type_len = channel_type_len;
170
session->open_channel->channel_type =
171
LIBSSH2_ALLOC(session, channel_type_len);
172
if(!session->open_channel->channel_type) {
173
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
174
"Failed allocating memory for channel type name");
175
LIBSSH2_FREE(session, session->open_channel);
176
session->open_channel = NULL;
179
memcpy(session->open_channel->channel_type, channel_type,
182
/* REMEMBER: local as in locally sourced */
183
session->open_channel->local.id = session->open_local_channel;
184
session->open_channel->remote.window_size = window_size;
185
session->open_channel->remote.window_size_initial = window_size;
186
session->open_channel->remote.packet_size = packet_size;
187
session->open_channel->session = session;
189
_libssh2_list_add(&session->channels,
190
&session->open_channel->node);
192
s = session->open_packet =
193
LIBSSH2_ALLOC(session, session->open_packet_len);
194
if(!session->open_packet) {
195
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
196
"Unable to allocate temporary space for packet");
199
*(s++) = SSH_MSG_CHANNEL_OPEN;
200
_libssh2_store_str(&s, channel_type, channel_type_len);
201
_libssh2_store_u32(&s, session->open_local_channel);
202
_libssh2_store_u32(&s, window_size);
203
_libssh2_store_u32(&s, packet_size);
205
/* Do not copy the message */
207
session->open_state = libssh2_NB_state_created;
210
if(session->open_state == libssh2_NB_state_created) {
211
rc = _libssh2_transport_send(session,
212
session->open_packet,
213
session->open_packet_len,
214
message, message_len);
215
if(rc == LIBSSH2_ERROR_EAGAIN) {
216
_libssh2_error(session, rc,
217
"Would block sending channel-open request");
221
_libssh2_error(session, rc,
222
"Unable to send channel-open request");
226
session->open_state = libssh2_NB_state_sent;
229
if(session->open_state == libssh2_NB_state_sent) {
230
rc = _libssh2_packet_requirev(session, reply_codes,
232
&session->open_data_len, 1,
233
session->open_packet + 5 +
235
&session->open_packet_requirev_state);
236
if(rc == LIBSSH2_ERROR_EAGAIN) {
237
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block");
241
_libssh2_error(session, rc, "Unexpected error");
245
if(session->open_data_len < 1) {
246
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
247
"Unexpected packet size");
251
if(session->open_data[0] == SSH_MSG_CHANNEL_OPEN_CONFIRMATION) {
253
if(session->open_data_len < 17) {
254
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
255
"Unexpected packet size");
259
session->open_channel->remote.id =
260
_libssh2_ntohu32(session->open_data + 5);
261
session->open_channel->local.window_size =
262
_libssh2_ntohu32(session->open_data + 9);
263
session->open_channel->local.window_size_initial =
264
_libssh2_ntohu32(session->open_data + 9);
265
session->open_channel->local.packet_size =
266
_libssh2_ntohu32(session->open_data + 13);
267
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
268
"Connection Established - ID: %u/%u win: %u/%u"
270
session->open_channel->local.id,
271
session->open_channel->remote.id,
272
session->open_channel->local.window_size,
273
session->open_channel->remote.window_size,
274
session->open_channel->local.packet_size,
275
session->open_channel->remote.packet_size));
276
LIBSSH2_FREE(session, session->open_packet);
277
session->open_packet = NULL;
278
LIBSSH2_FREE(session, session->open_data);
279
session->open_data = NULL;
281
session->open_state = libssh2_NB_state_idle;
282
return session->open_channel;
285
if(session->open_data[0] == SSH_MSG_CHANNEL_OPEN_FAILURE) {
286
unsigned int reason_code =
287
_libssh2_ntohu32(session->open_data + 5);
288
switch(reason_code) {
289
case SSH_OPEN_ADMINISTRATIVELY_PROHIBITED:
290
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
291
"Channel open failure "
292
"(administratively prohibited)");
294
case SSH_OPEN_CONNECT_FAILED:
295
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
296
"Channel open failure (connect failed)");
298
case SSH_OPEN_UNKNOWN_CHANNELTYPE:
299
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
300
"Channel open failure (unknown channel type)");
302
case SSH_OPEN_RESOURCE_SHORTAGE:
303
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
304
"Channel open failure (resource shortage)");
307
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
308
"Channel open failure");
315
if(session->open_data) {
316
LIBSSH2_FREE(session, session->open_data);
317
session->open_data = NULL;
319
if(session->open_packet) {
320
LIBSSH2_FREE(session, session->open_packet);
321
session->open_packet = NULL;
323
if(session->open_channel) {
324
unsigned char channel_id[4];
325
LIBSSH2_FREE(session, session->open_channel->channel_type);
327
_libssh2_list_remove(&session->open_channel->node);
329
/* Clear out packets meant for this channel */
330
_libssh2_htonu32(channel_id, session->open_channel->local.id);
331
while((_libssh2_packet_ask(session, SSH_MSG_CHANNEL_DATA,
333
&session->open_data_len, 1,
336
(_libssh2_packet_ask(session, SSH_MSG_CHANNEL_EXTENDED_DATA,
338
&session->open_data_len, 1,
339
channel_id, 4) >= 0)) {
340
LIBSSH2_FREE(session, session->open_data);
341
session->open_data = NULL;
344
LIBSSH2_FREE(session, session->open_channel);
345
session->open_channel = NULL;
348
session->open_state = libssh2_NB_state_idle;
353
* libssh2_channel_open_ex
355
* Establish a generic session channel
357
LIBSSH2_API LIBSSH2_CHANNEL *
358
libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *type,
359
unsigned int type_len,
360
unsigned int window_size, unsigned int packet_size,
361
const char *msg, unsigned int msg_len)
363
LIBSSH2_CHANNEL *ptr;
368
BLOCK_ADJUST_ERRNO(ptr, session,
369
_libssh2_channel_open(session, type, type_len,
370
window_size, packet_size,
371
(unsigned char *)msg,
377
* libssh2_channel_direct_tcpip_ex
379
* Tunnel TCP/IP connect through the SSH session to direct host/port
381
static LIBSSH2_CHANNEL *
382
channel_direct_tcpip(LIBSSH2_SESSION * session, const char *host,
383
int port, const char *shost, int sport)
385
LIBSSH2_CHANNEL *channel;
388
if(session->direct_state == libssh2_NB_state_idle) {
389
session->direct_host_len = strlen(host);
390
session->direct_shost_len = strlen(shost);
391
/* host_len(4) + port(4) + shost_len(4) + sport(4) */
392
session->direct_message_len =
393
session->direct_host_len + session->direct_shost_len + 16;
395
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
396
"Requesting direct-tcpip session from %s:%d to %s:%d",
397
shost, sport, host, port));
399
s = session->direct_message =
400
LIBSSH2_ALLOC(session, session->direct_message_len);
401
if(!session->direct_message) {
402
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
403
"Unable to allocate memory for "
404
"direct-tcpip connection");
407
_libssh2_store_str(&s, host, session->direct_host_len);
408
_libssh2_store_u32(&s, port);
409
_libssh2_store_str(&s, shost, session->direct_shost_len);
410
_libssh2_store_u32(&s, sport);
414
_libssh2_channel_open(session, "direct-tcpip",
415
sizeof("direct-tcpip") - 1,
416
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
417
LIBSSH2_CHANNEL_PACKET_DEFAULT,
418
session->direct_message,
419
session->direct_message_len);
422
libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
423
/* The error code is still set to LIBSSH2_ERROR_EAGAIN, set our state
424
to created to avoid re-creating the package on next invoke */
425
session->direct_state = libssh2_NB_state_created;
428
/* by default we set (keep?) idle state... */
429
session->direct_state = libssh2_NB_state_idle;
431
LIBSSH2_FREE(session, session->direct_message);
432
session->direct_message = NULL;
438
* libssh2_channel_direct_tcpip_ex
440
* Tunnel TCP/IP connect through the SSH session to direct host/port
442
LIBSSH2_API LIBSSH2_CHANNEL *
443
libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host,
444
int port, const char *shost, int sport)
446
LIBSSH2_CHANNEL *ptr;
451
BLOCK_ADJUST_ERRNO(ptr, session,
452
channel_direct_tcpip(session, host, port,
458
* libssh2_channel_direct_streamlocal_ex
460
* Tunnel TCP/IP connect through the SSH session to direct UNIX socket
462
static LIBSSH2_CHANNEL *
463
channel_direct_streamlocal(LIBSSH2_SESSION * session, const char *socket_path,
464
const char *shost, int sport)
466
LIBSSH2_CHANNEL *channel;
469
if(session->direct_state == libssh2_NB_state_idle) {
470
session->direct_host_len = strlen(socket_path);
471
session->direct_shost_len = strlen(shost);
472
session->direct_message_len =
473
session->direct_host_len + session->direct_shost_len + 12;
475
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
476
"Requesting direct-streamlocal session to %s",
479
s = session->direct_message =
480
LIBSSH2_ALLOC(session, session->direct_message_len);
481
if(!session->direct_message) {
482
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
483
"Unable to allocate memory for direct-streamlocal connection");
486
_libssh2_store_str(&s, socket_path, session->direct_host_len);
487
_libssh2_store_str(&s, shost, session->direct_shost_len);
488
_libssh2_store_u32(&s, sport);
492
_libssh2_channel_open(session, "direct-streamlocal@openssh.com",
493
sizeof("direct-streamlocal@openssh.com") - 1,
494
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
495
LIBSSH2_CHANNEL_PACKET_DEFAULT,
496
session->direct_message,
497
session->direct_message_len);
500
libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
501
/* The error code is still set to LIBSSH2_ERROR_EAGAIN, set our state
502
to created to avoid re-creating the package on next invoke */
503
session->direct_state = libssh2_NB_state_created;
506
/* by default we set (keep?) idle state... */
507
session->direct_state = libssh2_NB_state_idle;
509
LIBSSH2_FREE(session, session->direct_message);
510
session->direct_message = NULL;
516
* libssh2_channel_direct_streamlocal_ex
518
* Tunnel TCP/IP connect through the SSH session to direct UNIX socket
520
LIBSSH2_API LIBSSH2_CHANNEL *
521
libssh2_channel_direct_streamlocal_ex(LIBSSH2_SESSION * session,
522
const char *socket_path,
523
const char *shost, int sport)
525
LIBSSH2_CHANNEL *ptr;
530
BLOCK_ADJUST_ERRNO(ptr, session,
531
channel_direct_streamlocal(session,
532
socket_path, shost, sport));
537
* channel_forward_listen
539
* Bind a port on the remote host and listen for connections
541
static LIBSSH2_LISTENER *
542
channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
543
int port, int *bound_port, int queue_maxsize)
546
static const unsigned char reply_codes[3] =
547
{ SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE, 0 };
553
if(session->fwdLstn_state == libssh2_NB_state_idle) {
554
session->fwdLstn_host_len = (uint32_t)strlen(host);
555
/* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4)
557
session->fwdLstn_packet_len =
558
session->fwdLstn_host_len +
559
(uint32_t)(sizeof("tcpip-forward") - 1) + 14;
561
/* Zero the whole thing out */
562
memset(&session->fwdLstn_packet_requirev_state, 0,
563
sizeof(session->fwdLstn_packet_requirev_state));
565
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
566
"Requesting tcpip-forward session for %s:%d", host,
569
s = session->fwdLstn_packet =
570
LIBSSH2_ALLOC(session, session->fwdLstn_packet_len);
571
if(!session->fwdLstn_packet) {
572
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
573
"Unable to allocate memory for setenv packet");
577
*(s++) = SSH_MSG_GLOBAL_REQUEST;
578
_libssh2_store_str(&s, "tcpip-forward", sizeof("tcpip-forward") - 1);
579
*(s++) = 0x01; /* want_reply */
581
_libssh2_store_str(&s, host, session->fwdLstn_host_len);
582
_libssh2_store_u32(&s, port);
584
session->fwdLstn_state = libssh2_NB_state_created;
587
if(session->fwdLstn_state == libssh2_NB_state_created) {
588
rc = _libssh2_transport_send(session,
589
session->fwdLstn_packet,
590
session->fwdLstn_packet_len,
592
if(rc == LIBSSH2_ERROR_EAGAIN) {
593
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
594
"Would block sending global-request packet for "
595
"forward listen request");
599
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
600
"Unable to send global-request packet for forward "
602
LIBSSH2_FREE(session, session->fwdLstn_packet);
603
session->fwdLstn_packet = NULL;
604
session->fwdLstn_state = libssh2_NB_state_idle;
607
LIBSSH2_FREE(session, session->fwdLstn_packet);
608
session->fwdLstn_packet = NULL;
610
session->fwdLstn_state = libssh2_NB_state_sent;
613
if(session->fwdLstn_state == libssh2_NB_state_sent) {
616
rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len,
618
&session->fwdLstn_packet_requirev_state);
619
if(rc == LIBSSH2_ERROR_EAGAIN) {
620
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block");
623
else if(rc || (data_len < 1)) {
624
_libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unknown");
625
session->fwdLstn_state = libssh2_NB_state_idle;
629
if(data[0] == SSH_MSG_REQUEST_SUCCESS) {
630
LIBSSH2_LISTENER *listener;
632
listener = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_LISTENER));
634
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
635
"Unable to allocate memory for listener queue");
638
LIBSSH2_ALLOC(session, session->fwdLstn_host_len + 1);
639
if(!listener->host) {
640
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
641
"Unable to allocate memory "
642
"for listener queue");
643
LIBSSH2_FREE(session, listener);
647
listener->session = session;
648
memcpy(listener->host, host, session->fwdLstn_host_len);
649
listener->host[session->fwdLstn_host_len] = 0;
650
if(data_len >= 5 && !port) {
651
listener->port = _libssh2_ntohu32(data + 1);
652
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
653
"Dynamic tcpip-forward port "
658
listener->port = port;
660
listener->queue_size = 0;
661
listener->queue_maxsize = queue_maxsize;
663
/* append this to the parent's list of listeners */
664
_libssh2_list_add(&session->listeners, &listener->node);
667
*bound_port = listener->port;
672
LIBSSH2_FREE(session, data);
673
session->fwdLstn_state = libssh2_NB_state_idle;
676
else if(data[0] == SSH_MSG_REQUEST_FAILURE) {
677
LIBSSH2_FREE(session, data);
678
_libssh2_error(session, LIBSSH2_ERROR_REQUEST_DENIED,
679
"Unable to complete request for forward-listen");
680
session->fwdLstn_state = libssh2_NB_state_idle;
685
session->fwdLstn_state = libssh2_NB_state_idle;
691
* libssh2_channel_forward_listen_ex
693
* Bind a port on the remote host and listen for connections
695
LIBSSH2_API LIBSSH2_LISTENER *
696
libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host,
697
int port, int *bound_port, int queue_maxsize)
699
LIBSSH2_LISTENER *ptr;
704
BLOCK_ADJUST_ERRNO(ptr, session,
705
channel_forward_listen(session, host, port, bound_port,
711
* _libssh2_channel_forward_cancel
713
* Stop listening on a remote port and free the listener
714
* Toss out any pending (un-accept()ed) connections
716
* Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error
718
int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
720
LIBSSH2_SESSION *session = listener->session;
721
LIBSSH2_CHANNEL *queued;
722
unsigned char *packet, *s;
723
size_t host_len = strlen(listener->host);
724
/* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) +
727
host_len + 14 + sizeof("cancel-tcpip-forward") - 1;
731
if(listener->chanFwdCncl_state == libssh2_NB_state_idle) {
732
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
733
"Cancelling tcpip-forward session for %s:%d",
734
listener->host, listener->port));
736
s = packet = LIBSSH2_ALLOC(session, packet_len);
738
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
739
"Unable to allocate memory for setenv packet");
740
return LIBSSH2_ERROR_ALLOC;
743
*(s++) = SSH_MSG_GLOBAL_REQUEST;
744
_libssh2_store_str(&s, "cancel-tcpip-forward",
745
sizeof("cancel-tcpip-forward") - 1);
746
*(s++) = 0x00; /* want_reply */
748
_libssh2_store_str(&s, listener->host, host_len);
749
_libssh2_store_u32(&s, listener->port);
751
listener->chanFwdCncl_state = libssh2_NB_state_created;
754
packet = listener->chanFwdCncl_data;
757
if(listener->chanFwdCncl_state == libssh2_NB_state_created) {
758
rc = _libssh2_transport_send(session, packet, packet_len, NULL, 0);
759
if(rc == LIBSSH2_ERROR_EAGAIN) {
760
_libssh2_error(session, rc,
761
"Would block sending forward request");
762
listener->chanFwdCncl_data = packet;
766
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
767
"Unable to send global-request packet for forward "
769
/* set the state to something we don't check for, for the
770
unfortunate situation where we get an EAGAIN further down
771
when trying to bail out due to errors! */
772
listener->chanFwdCncl_state = libssh2_NB_state_sent;
773
retcode = LIBSSH2_ERROR_SOCKET_SEND;
775
LIBSSH2_FREE(session, packet);
777
listener->chanFwdCncl_state = libssh2_NB_state_sent;
780
queued = _libssh2_list_first(&listener->queue);
782
LIBSSH2_CHANNEL *next = _libssh2_list_next(&queued->node);
784
rc = _libssh2_channel_free(queued);
785
if(rc == LIBSSH2_ERROR_EAGAIN) {
790
LIBSSH2_FREE(session, listener->host);
792
/* remove this entry from the parent's list of listeners */
793
_libssh2_list_remove(&listener->node);
795
LIBSSH2_FREE(session, listener);
801
* libssh2_channel_forward_cancel
803
* Stop listening on a remote port and free the listener
804
* Toss out any pending (un-accept()ed) connections
806
* Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error
809
libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
814
return LIBSSH2_ERROR_BAD_USE;
816
BLOCK_ADJUST(rc, listener->session,
817
_libssh2_channel_forward_cancel(listener));
822
* channel_forward_accept
824
* Accept a connection
826
static LIBSSH2_CHANNEL *
827
channel_forward_accept(LIBSSH2_LISTENER *listener)
832
rc = _libssh2_transport_read(listener->session);
835
if(_libssh2_list_first(&listener->queue)) {
836
LIBSSH2_CHANNEL *channel = _libssh2_list_first(&listener->queue);
838
/* detach channel from listener's queue */
839
_libssh2_list_remove(&channel->node);
841
listener->queue_size--;
843
/* add channel to session's channel list */
844
_libssh2_list_add(&channel->session->channels, &channel->node);
849
if(rc == LIBSSH2_ERROR_EAGAIN) {
850
_libssh2_error(listener->session, LIBSSH2_ERROR_EAGAIN,
851
"Would block waiting for packet");
854
_libssh2_error(listener->session, LIBSSH2_ERROR_CHANNEL_UNKNOWN,
855
"Channel not found");
860
* libssh2_channel_forward_accept
862
* Accept a connection
864
LIBSSH2_API LIBSSH2_CHANNEL *
865
libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener)
867
LIBSSH2_CHANNEL *ptr;
872
BLOCK_ADJUST_ERRNO(ptr, listener->session,
873
channel_forward_accept(listener));
881
* Set an environment variable prior to requesting a shell/program/subsystem
883
static int channel_setenv(LIBSSH2_CHANNEL *channel,
884
const char *varname, unsigned int varname_len,
885
const char *value, unsigned int value_len)
887
LIBSSH2_SESSION *session = channel->session;
888
unsigned char *s, *data;
889
static const unsigned char reply_codes[3] =
890
{ SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
894
if(channel->setenv_state == libssh2_NB_state_idle) {
895
/* 21 = packet_type(1) + channel_id(4) + request_len(4) +
896
* request(3)"env" + want_reply(1) + varname_len(4) + value_len(4) */
897
channel->setenv_packet_len = varname_len + value_len + 21;
899
/* Zero the whole thing out */
900
memset(&channel->setenv_packet_requirev_state, 0,
901
sizeof(channel->setenv_packet_requirev_state));
903
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
904
"Setting remote environment variable: %s=%s on "
906
varname, value, channel->local.id, channel->remote.id));
908
s = channel->setenv_packet =
909
LIBSSH2_ALLOC(session, channel->setenv_packet_len);
910
if(!channel->setenv_packet) {
911
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
912
"Unable to allocate memory "
913
"for setenv packet");
916
*(s++) = SSH_MSG_CHANNEL_REQUEST;
917
_libssh2_store_u32(&s, channel->remote.id);
918
_libssh2_store_str(&s, "env", sizeof("env") - 1);
920
_libssh2_store_str(&s, varname, varname_len);
921
_libssh2_store_str(&s, value, value_len);
923
channel->setenv_state = libssh2_NB_state_created;
926
if(channel->setenv_state == libssh2_NB_state_created) {
927
rc = _libssh2_transport_send(session,
928
channel->setenv_packet,
929
channel->setenv_packet_len,
931
if(rc == LIBSSH2_ERROR_EAGAIN) {
932
_libssh2_error(session, rc,
933
"Would block sending setenv request");
937
LIBSSH2_FREE(session, channel->setenv_packet);
938
channel->setenv_packet = NULL;
939
channel->setenv_state = libssh2_NB_state_idle;
940
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
941
"Unable to send channel-request packet for "
944
LIBSSH2_FREE(session, channel->setenv_packet);
945
channel->setenv_packet = NULL;
947
_libssh2_htonu32(channel->setenv_local_channel, channel->local.id);
949
channel->setenv_state = libssh2_NB_state_sent;
952
if(channel->setenv_state == libssh2_NB_state_sent) {
953
rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len,
954
1, channel->setenv_local_channel, 4,
956
setenv_packet_requirev_state);
957
if(rc == LIBSSH2_ERROR_EAGAIN) {
961
channel->setenv_state = libssh2_NB_state_idle;
962
return _libssh2_error(session, rc,
963
"Failed getting response for "
966
else if(data_len < 1) {
967
channel->setenv_state = libssh2_NB_state_idle;
968
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
969
"Unexpected packet size");
972
if(data[0] == SSH_MSG_CHANNEL_SUCCESS) {
973
LIBSSH2_FREE(session, data);
974
channel->setenv_state = libssh2_NB_state_idle;
978
LIBSSH2_FREE(session, data);
981
channel->setenv_state = libssh2_NB_state_idle;
982
return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
983
"Unable to complete request for channel-setenv");
987
* libssh2_channel_setenv_ex
989
* Set an environment variable prior to requesting a shell/program/subsystem
992
libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel,
993
const char *varname, unsigned int varname_len,
994
const char *value, unsigned int value_len)
999
return LIBSSH2_ERROR_BAD_USE;
1001
BLOCK_ADJUST(rc, channel->session,
1002
channel_setenv(channel, varname, varname_len,
1008
* channel_request_pty
1009
* Duh... Request a PTY
1011
static int channel_request_pty(LIBSSH2_CHANNEL *channel,
1012
const char *term, unsigned int term_len,
1013
const char *modes, unsigned int modes_len,
1014
int width, int height,
1015
int width_px, int height_px)
1017
LIBSSH2_SESSION *session = channel->session;
1019
static const unsigned char reply_codes[3] =
1020
{ SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
1023
if(channel->reqPTY_state == libssh2_NB_state_idle) {
1024
/* 41 = packet_type(1) + channel(4) + pty_req_len(4) + "pty_req"(7) +
1025
* want_reply(1) + term_len(4) + width(4) + height(4) + width_px(4) +
1026
* height_px(4) + modes_len(4) */
1027
if(term_len + modes_len > 256) {
1028
return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
1029
"term + mode lengths too large");
1032
channel->reqPTY_packet_len = term_len + modes_len + 41;
1034
/* Zero the whole thing out */
1035
memset(&channel->reqPTY_packet_requirev_state, 0,
1036
sizeof(channel->reqPTY_packet_requirev_state));
1038
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
1039
"Allocating tty on channel %u/%u", channel->local.id,
1040
channel->remote.id));
1042
s = channel->reqPTY_packet;
1044
*(s++) = SSH_MSG_CHANNEL_REQUEST;
1045
_libssh2_store_u32(&s, channel->remote.id);
1046
_libssh2_store_str(&s, (char *)"pty-req", sizeof("pty-req") - 1);
1050
_libssh2_store_str(&s, term, term_len);
1051
_libssh2_store_u32(&s, width);
1052
_libssh2_store_u32(&s, height);
1053
_libssh2_store_u32(&s, width_px);
1054
_libssh2_store_u32(&s, height_px);
1055
_libssh2_store_str(&s, modes, modes_len);
1057
channel->reqPTY_state = libssh2_NB_state_created;
1060
if(channel->reqPTY_state == libssh2_NB_state_created) {
1061
rc = _libssh2_transport_send(session, channel->reqPTY_packet,
1062
channel->reqPTY_packet_len,
1064
if(rc == LIBSSH2_ERROR_EAGAIN) {
1065
_libssh2_error(session, rc,
1066
"Would block sending pty request");
1070
channel->reqPTY_state = libssh2_NB_state_idle;
1071
return _libssh2_error(session, rc,
1072
"Unable to send pty-request packet");
1074
_libssh2_htonu32(channel->reqPTY_local_channel, channel->local.id);
1076
channel->reqPTY_state = libssh2_NB_state_sent;
1079
if(channel->reqPTY_state == libssh2_NB_state_sent) {
1080
unsigned char *data;
1083
rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len,
1084
1, channel->reqPTY_local_channel, 4,
1085
&channel->reqPTY_packet_requirev_state);
1086
if(rc == LIBSSH2_ERROR_EAGAIN) {
1089
else if(rc || data_len < 1) {
1090
channel->reqPTY_state = libssh2_NB_state_idle;
1091
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1092
"Failed to require the PTY package");
1097
LIBSSH2_FREE(session, data);
1098
channel->reqPTY_state = libssh2_NB_state_idle;
1100
if(code == SSH_MSG_CHANNEL_SUCCESS)
1104
return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
1105
"Unable to complete request for "
1106
"channel request-pty");
1110
* channel_request_auth_agent
1111
* The actual re-entrant method which requests an auth agent.
1113
static int channel_request_auth_agent(LIBSSH2_CHANNEL *channel,
1114
const char *request_str,
1115
int request_str_len)
1117
LIBSSH2_SESSION *session = channel->session;
1119
static const unsigned char reply_codes[3] =
1120
{ SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
1123
if(channel->req_auth_agent_state == libssh2_NB_state_idle) {
1124
/* Only valid options are "auth-agent-req" and
1125
* "auth-agent-req_at_openssh.com" so we make sure it is not
1126
* actually longer than the longest possible. */
1127
if(request_str_len > 26) {
1128
return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
1129
"request_str length too large");
1133
* Length: 24 or 36 = packet_type(1) + channel(4) + req_len(4) +
1134
* request_str (variable) + want_reply (1) */
1135
channel->req_auth_agent_packet_len = 10 + request_str_len;
1137
/* Zero out the requireev state to reset */
1138
memset(&channel->req_auth_agent_requirev_state, 0,
1139
sizeof(channel->req_auth_agent_requirev_state));
1141
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
1142
"Requesting auth agent on channel %u/%u",
1143
channel->local.id, channel->remote.id));
1146
* byte SSH_MSG_CHANNEL_REQUEST
1147
* uint32 recipient channel
1148
* string "auth-agent-req"
1149
* boolean want reply
1151
s = channel->req_auth_agent_packet;
1152
*(s++) = SSH_MSG_CHANNEL_REQUEST;
1153
_libssh2_store_u32(&s, channel->remote.id);
1154
_libssh2_store_str(&s, (char *)request_str, request_str_len);
1157
channel->req_auth_agent_state = libssh2_NB_state_created;
1160
if(channel->req_auth_agent_state == libssh2_NB_state_created) {
1161
/* Send the packet, we can use sizeof() on the packet because it
1162
* is always completely filled; there are no variable length fields. */
1163
rc = _libssh2_transport_send(session, channel->req_auth_agent_packet,
1164
channel->req_auth_agent_packet_len,
1167
if(rc == LIBSSH2_ERROR_EAGAIN) {
1168
_libssh2_error(session, rc,
1169
"Would block sending auth-agent request");
1173
channel->req_auth_agent_state = libssh2_NB_state_idle;
1174
return _libssh2_error(session, rc,
1175
"Unable to send auth-agent request");
1177
_libssh2_htonu32(channel->req_auth_agent_local_channel,
1179
channel->req_auth_agent_state = libssh2_NB_state_sent;
1182
if(channel->req_auth_agent_state == libssh2_NB_state_sent) {
1183
unsigned char *data;
1187
rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len,
1188
1, channel->req_auth_agent_local_channel,
1190
&channel->req_auth_agent_requirev_state);
1191
if(rc == LIBSSH2_ERROR_EAGAIN) {
1195
channel->req_auth_agent_state = libssh2_NB_state_idle;
1196
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1197
"Failed to request auth-agent");
1202
LIBSSH2_FREE(session, data);
1203
channel->req_auth_agent_state = libssh2_NB_state_idle;
1205
if(code == SSH_MSG_CHANNEL_SUCCESS)
1209
return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
1210
"Unable to complete request for auth-agent");
1214
* libssh2_channel_request_auth_agent
1216
* Requests that agent forwarding be enabled for the session. The
1217
* request must be sent over a specific channel, which starts the agent
1218
* listener on the remote side. Once the channel is closed, the agent
1219
* listener continues to exist.
1222
libssh2_channel_request_auth_agent(LIBSSH2_CHANNEL *channel)
1227
return LIBSSH2_ERROR_BAD_USE;
1229
rc = LIBSSH2_ERROR_CHANNEL_UNKNOWN;
1231
/* The current RFC draft for agent forwarding says you're supposed to
1232
* send "auth-agent-req," but most SSH servers out there right now
1233
* actually expect "auth-agent-req@openssh.com", so we try that
1235
if(channel->req_auth_agent_try_state == libssh2_NB_state_idle) {
1236
BLOCK_ADJUST(rc, channel->session,
1237
channel_request_auth_agent(channel,
1238
"auth-agent-req@openssh.com",
1241
/* If we failed (but not with EAGAIN), then we move onto
1242
* the next step to try another request type. */
1243
if(rc != LIBSSH2_ERROR_NONE &&
1244
rc != LIBSSH2_ERROR_EAGAIN)
1245
channel->req_auth_agent_try_state = libssh2_NB_state_sent;
1248
if(channel->req_auth_agent_try_state == libssh2_NB_state_sent) {
1249
BLOCK_ADJUST(rc, channel->session,
1250
channel_request_auth_agent(channel,
1251
"auth-agent-req", 14));
1253
/* If we failed without an EAGAIN, then move on with this
1255
if(rc != LIBSSH2_ERROR_NONE &&
1256
rc != LIBSSH2_ERROR_EAGAIN)
1257
channel->req_auth_agent_try_state = libssh2_NB_state_sent1;
1260
/* If things are good, reset the try state. */
1261
if(rc == LIBSSH2_ERROR_NONE)
1262
channel->req_auth_agent_try_state = libssh2_NB_state_idle;
1268
* libssh2_channel_request_pty_ex
1269
* Duh... Request a PTY
1272
libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term,
1273
unsigned int term_len, const char *modes,
1274
unsigned int modes_len, int width, int height,
1275
int width_px, int height_px)
1280
return LIBSSH2_ERROR_BAD_USE;
1282
BLOCK_ADJUST(rc, channel->session,
1283
channel_request_pty(channel, term, term_len, modes,
1284
modes_len, width, height,
1285
width_px, height_px));
1290
channel_request_pty_size(LIBSSH2_CHANNEL * channel, int width,
1291
int height, int width_px, int height_px)
1293
LIBSSH2_SESSION *session = channel->session;
1296
int retcode = LIBSSH2_ERROR_PROTO;
1298
if(channel->reqPTY_state == libssh2_NB_state_idle) {
1299
channel->reqPTY_packet_len = 39;
1301
/* Zero the whole thing out */
1302
memset(&channel->reqPTY_packet_requirev_state, 0,
1303
sizeof(channel->reqPTY_packet_requirev_state));
1305
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
1306
"changing tty size on channel %u/%u",
1308
channel->remote.id));
1310
s = channel->reqPTY_packet;
1312
*(s++) = SSH_MSG_CHANNEL_REQUEST;
1313
_libssh2_store_u32(&s, channel->remote.id);
1314
_libssh2_store_str(&s, (char *)"window-change",
1315
sizeof("window-change") - 1);
1316
*(s++) = 0x00; /* Don't reply */
1317
_libssh2_store_u32(&s, width);
1318
_libssh2_store_u32(&s, height);
1319
_libssh2_store_u32(&s, width_px);
1320
_libssh2_store_u32(&s, height_px);
1322
channel->reqPTY_state = libssh2_NB_state_created;
1325
if(channel->reqPTY_state == libssh2_NB_state_created) {
1326
rc = _libssh2_transport_send(session, channel->reqPTY_packet,
1327
channel->reqPTY_packet_len,
1329
if(rc == LIBSSH2_ERROR_EAGAIN) {
1330
_libssh2_error(session, rc,
1331
"Would block sending window-change request");
1335
channel->reqPTY_state = libssh2_NB_state_idle;
1336
return _libssh2_error(session, rc,
1337
"Unable to send window-change packet");
1339
_libssh2_htonu32(channel->reqPTY_local_channel, channel->local.id);
1340
retcode = LIBSSH2_ERROR_NONE;
1343
channel->reqPTY_state = libssh2_NB_state_idle;
1348
libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel, int width,
1349
int height, int width_px, int height_px)
1354
return LIBSSH2_ERROR_BAD_USE;
1356
BLOCK_ADJUST(rc, channel->session,
1357
channel_request_pty_size(channel, width, height, width_px,
1362
/* Keep this an even number */
1363
#define LIBSSH2_X11_RANDOM_COOKIE_LEN 32
1367
* Request X11 forwarding
1370
channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection,
1371
const char *auth_proto, const char *auth_cookie,
1374
LIBSSH2_SESSION *session = channel->session;
1376
static const unsigned char reply_codes[3] =
1377
{ SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
1379
auth_proto ? strlen(auth_proto) : (sizeof("MIT-MAGIC-COOKIE-1") - 1);
1381
auth_cookie ? strlen(auth_cookie) : LIBSSH2_X11_RANDOM_COOKIE_LEN;
1384
if(channel->reqX11_state == libssh2_NB_state_idle) {
1385
/* 30 = packet_type(1) + channel(4) + x11_req_len(4) + "x11-req"(7) +
1386
* want_reply(1) + single_cnx(1) + proto_len(4) + cookie_len(4) +
1388
channel->reqX11_packet_len = proto_len + cookie_len + 30;
1390
/* Zero the whole thing out */
1391
memset(&channel->reqX11_packet_requirev_state, 0,
1392
sizeof(channel->reqX11_packet_requirev_state));
1394
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
1395
"Requesting x11-req for channel %u/%u: single=%d "
1396
"proto=%s cookie=%s screen=%d",
1397
channel->local.id, channel->remote.id,
1399
auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1",
1400
auth_cookie ? auth_cookie : "<random>", screen_number));
1402
s = channel->reqX11_packet =
1403
LIBSSH2_ALLOC(session, channel->reqX11_packet_len);
1404
if(!channel->reqX11_packet) {
1405
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
1406
"Unable to allocate memory for pty-request");
1409
*(s++) = SSH_MSG_CHANNEL_REQUEST;
1410
_libssh2_store_u32(&s, channel->remote.id);
1411
_libssh2_store_str(&s, "x11-req", sizeof("x11-req") - 1);
1413
*(s++) = 0x01; /* want_reply */
1414
*(s++) = single_connection ? 0x01 : 0x00;
1416
_libssh2_store_str(&s, auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1",
1419
_libssh2_store_u32(&s, (uint32_t)cookie_len);
1421
memcpy(s, auth_cookie, cookie_len);
1425
/* note: the extra +1 below is necessary since the sprintf()
1426
loop will always write 3 bytes so the last one will write
1427
the trailing zero at the LIBSSH2_X11_RANDOM_COOKIE_LEN/2
1429
unsigned char buffer[(LIBSSH2_X11_RANDOM_COOKIE_LEN / 2) + 1];
1431
if(_libssh2_random(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2)) {
1432
return _libssh2_error(session, LIBSSH2_ERROR_RANDGEN,
1433
"Unable to get random bytes "
1434
"for x11-req cookie");
1436
for(i = 0; i < (LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); i++) {
1437
snprintf((char *)&s[i*2], 3, "%02X", buffer[i]);
1442
_libssh2_store_u32(&s, screen_number);
1443
channel->reqX11_state = libssh2_NB_state_created;
1446
if(channel->reqX11_state == libssh2_NB_state_created) {
1447
rc = _libssh2_transport_send(session, channel->reqX11_packet,
1448
channel->reqX11_packet_len,
1450
if(rc == LIBSSH2_ERROR_EAGAIN) {
1451
_libssh2_error(session, rc,
1452
"Would block sending X11-req packet");
1456
LIBSSH2_FREE(session, channel->reqX11_packet);
1457
channel->reqX11_packet = NULL;
1458
channel->reqX11_state = libssh2_NB_state_idle;
1459
return _libssh2_error(session, rc,
1460
"Unable to send x11-req packet");
1462
LIBSSH2_FREE(session, channel->reqX11_packet);
1463
channel->reqX11_packet = NULL;
1465
_libssh2_htonu32(channel->reqX11_local_channel, channel->local.id);
1467
channel->reqX11_state = libssh2_NB_state_sent;
1470
if(channel->reqX11_state == libssh2_NB_state_sent) {
1472
unsigned char *data;
1475
rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len,
1476
1, channel->reqX11_local_channel, 4,
1477
&channel->reqX11_packet_requirev_state);
1478
if(rc == LIBSSH2_ERROR_EAGAIN) {
1481
else if(rc || data_len < 1) {
1482
channel->reqX11_state = libssh2_NB_state_idle;
1483
return _libssh2_error(session, rc,
1484
"waiting for x11-req response packet");
1488
LIBSSH2_FREE(session, data);
1489
channel->reqX11_state = libssh2_NB_state_idle;
1491
if(code == SSH_MSG_CHANNEL_SUCCESS)
1495
return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
1496
"Unable to complete request for channel x11-req");
1500
* libssh2_channel_x11_req_ex
1501
* Request X11 forwarding
1504
libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection,
1505
const char *auth_proto, const char *auth_cookie,
1511
return LIBSSH2_ERROR_BAD_USE;
1513
BLOCK_ADJUST(rc, channel->session,
1514
channel_x11_req(channel, single_connection, auth_proto,
1515
auth_cookie, screen_number));
1521
* _libssh2_channel_process_startup
1523
* Primitive for libssh2_channel_(shell|exec|subsystem)
1526
_libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
1527
const char *request, size_t request_len,
1528
const char *message, size_t message_len)
1530
LIBSSH2_SESSION *session = channel->session;
1532
static const unsigned char reply_codes[3] =
1533
{ SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
1536
if(channel->process_state == libssh2_NB_state_end) {
1537
return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
1538
"Channel can not be reused");
1541
if(channel->process_state == libssh2_NB_state_idle) {
1542
/* 10 = packet_type(1) + channel(4) + request_len(4) + want_reply(1) */
1543
channel->process_packet_len = request_len + 10;
1545
/* Zero the whole thing out */
1546
memset(&channel->process_packet_requirev_state, 0,
1547
sizeof(channel->process_packet_requirev_state));
1550
channel->process_packet_len += + 4;
1552
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
1553
"starting request(%s) on channel %u/%u, message=%s",
1554
request, channel->local.id, channel->remote.id,
1555
message ? message : "<null>"));
1556
s = channel->process_packet =
1557
LIBSSH2_ALLOC(session, channel->process_packet_len);
1558
if(!channel->process_packet)
1559
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
1560
"Unable to allocate memory "
1561
"for channel-process request");
1563
*(s++) = SSH_MSG_CHANNEL_REQUEST;
1564
_libssh2_store_u32(&s, channel->remote.id);
1565
_libssh2_store_str(&s, request, request_len);
1569
_libssh2_store_u32(&s, (uint32_t)message_len);
1571
channel->process_state = libssh2_NB_state_created;
1574
if(channel->process_state == libssh2_NB_state_created) {
1575
rc = _libssh2_transport_send(session,
1576
channel->process_packet,
1577
channel->process_packet_len,
1578
(unsigned char *)message, message_len);
1579
if(rc == LIBSSH2_ERROR_EAGAIN) {
1580
_libssh2_error(session, rc,
1581
"Would block sending channel request");
1585
LIBSSH2_FREE(session, channel->process_packet);
1586
channel->process_packet = NULL;
1587
channel->process_state = libssh2_NB_state_end;
1588
return _libssh2_error(session, rc,
1589
"Unable to send channel request");
1591
LIBSSH2_FREE(session, channel->process_packet);
1592
channel->process_packet = NULL;
1594
_libssh2_htonu32(channel->process_local_channel, channel->local.id);
1596
channel->process_state = libssh2_NB_state_sent;
1599
if(channel->process_state == libssh2_NB_state_sent) {
1600
unsigned char *data;
1603
rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len,
1604
1, channel->process_local_channel, 4,
1605
&channel->process_packet_requirev_state);
1606
if(rc == LIBSSH2_ERROR_EAGAIN) {
1609
else if(rc || data_len < 1) {
1610
channel->process_state = libssh2_NB_state_end;
1611
return _libssh2_error(session, rc,
1612
"Failed waiting for channel success");
1616
LIBSSH2_FREE(session, data);
1617
channel->process_state = libssh2_NB_state_end;
1619
if(code == SSH_MSG_CHANNEL_SUCCESS)
1623
return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
1624
"Unable to complete request for "
1625
"channel-process-startup");
1629
* libssh2_channel_process_startup
1631
* Primitive for libssh2_channel_(shell|exec|subsystem)
1634
libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
1635
const char *req, unsigned int req_len,
1636
const char *msg, unsigned int msg_len)
1641
return LIBSSH2_ERROR_BAD_USE;
1643
BLOCK_ADJUST(rc, channel->session,
1644
_libssh2_channel_process_startup(channel, req, req_len,
1651
* libssh2_channel_set_blocking
1653
* Set a channel's BEHAVIOR blocking on or off. The socket will remain non-
1657
libssh2_channel_set_blocking(LIBSSH2_CHANNEL * channel, int blocking)
1660
(void)_libssh2_session_set_blocking(channel->session, blocking);
1664
* _libssh2_channel_flush
1666
* Flush data from one (or all) stream
1667
* Returns number of bytes flushed, or negative on failure
1670
_libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
1672
if(channel->flush_state == libssh2_NB_state_idle) {
1673
LIBSSH2_PACKET *packet =
1674
_libssh2_list_first(&channel->session->packets);
1675
channel->flush_refund_bytes = 0;
1676
channel->flush_flush_bytes = 0;
1679
unsigned char packet_type;
1680
LIBSSH2_PACKET *next = _libssh2_list_next(&packet->node);
1682
if(packet->data_len < 1) {
1684
_libssh2_debug((channel->session, LIBSSH2_TRACE_ERROR,
1685
"Unexpected packet length"));
1689
packet_type = packet->data[0];
1691
if(((packet_type == SSH_MSG_CHANNEL_DATA)
1692
|| (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA))
1693
&& ((packet->data_len >= 5)
1694
&& (_libssh2_ntohu32(packet->data + 1)
1695
== channel->local.id))) {
1696
/* It's our channel at least */
1697
int packet_stream_id;
1699
if(packet_type == SSH_MSG_CHANNEL_DATA) {
1700
packet_stream_id = 0;
1702
else if(packet->data_len >= 9) {
1703
packet_stream_id = _libssh2_ntohu32(packet->data + 5);
1706
channel->flush_state = libssh2_NB_state_idle;
1707
return _libssh2_error(channel->session,
1708
LIBSSH2_ERROR_PROTO,
1709
"Unexpected packet length");
1712
if((streamid == LIBSSH2_CHANNEL_FLUSH_ALL)
1713
|| ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)
1714
&& ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA)
1715
|| (streamid == packet_stream_id)))
1716
|| ((packet_type == SSH_MSG_CHANNEL_DATA)
1717
&& (streamid == 0))) {
1718
size_t bytes_to_flush = packet->data_len -
1721
_libssh2_debug((channel->session, LIBSSH2_TRACE_CONN,
1722
"Flushing %ld bytes of data from stream "
1723
"%d on channel %u/%u",
1724
(long)bytes_to_flush, packet_stream_id,
1725
channel->local.id, channel->remote.id));
1727
/* It's one of the streams we wanted to flush */
1728
channel->flush_refund_bytes += packet->data_len - 13;
1729
channel->flush_flush_bytes += bytes_to_flush;
1731
LIBSSH2_FREE(channel->session, packet->data);
1733
/* remove this packet from the parent's list */
1734
_libssh2_list_remove(&packet->node);
1735
LIBSSH2_FREE(channel->session, packet);
1741
channel->flush_state = libssh2_NB_state_created;
1744
channel->read_avail -= channel->flush_flush_bytes;
1745
channel->remote.window_size -= (uint32_t)channel->flush_flush_bytes;
1747
if(channel->flush_refund_bytes) {
1749
_libssh2_channel_receive_window_adjust(channel,
1750
(uint32_t)channel->flush_refund_bytes,
1752
if(rc == LIBSSH2_ERROR_EAGAIN)
1756
channel->flush_state = libssh2_NB_state_idle;
1758
return (int)channel->flush_flush_bytes;
1762
* libssh2_channel_flush_ex
1764
* Flush data from one (or all) stream
1765
* Returns number of bytes flushed, or negative on failure
1768
libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int stream)
1773
return LIBSSH2_ERROR_BAD_USE;
1775
BLOCK_ADJUST(rc, channel->session,
1776
_libssh2_channel_flush(channel, stream));
1781
* libssh2_channel_get_exit_status
1783
* Return the channel's program exit status. Note that the actual protocol
1784
* provides the full 32bit this function returns. We cannot abuse it to
1785
* return error values in case of errors so we return a zero if channel is
1789
libssh2_channel_get_exit_status(LIBSSH2_CHANNEL *channel)
1794
return channel->exit_status;
1798
* libssh2_channel_get_exit_signal
1800
* Get exit signal (without leading "SIG"), error message, and language
1801
* tag into newly allocated buffers of indicated length. Caller can
1802
* use NULL pointers to indicate that the value should not be set. The
1803
* *_len variables are set if they are non-NULL even if the
1804
* corresponding string parameter is NULL. Returns LIBSSH2_ERROR_NONE
1805
* on success, or an API error code.
1808
libssh2_channel_get_exit_signal(LIBSSH2_CHANNEL *channel,
1810
size_t *exitsignal_len,
1814
size_t *langtag_len)
1819
LIBSSH2_SESSION *session = channel->session;
1821
if(channel->exit_signal) {
1822
namelen = strlen(channel->exit_signal);
1824
*exitsignal = LIBSSH2_ALLOC(session, namelen + 1);
1826
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
1827
"Unable to allocate memory for signal name");
1829
memcpy(*exitsignal, channel->exit_signal, namelen);
1830
(*exitsignal)[namelen] = '\0';
1833
*exitsignal_len = namelen;
1839
*exitsignal_len = 0;
1842
/* TODO: set error message and language tag */
1857
return LIBSSH2_ERROR_NONE;
1861
* _libssh2_channel_receive_window_adjust
1863
* Adjust the receive window for a channel by adjustment bytes. If the amount
1864
* to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the
1865
* adjustment amount will be queued for a later packet.
1867
* Calls _libssh2_error() !
1870
_libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
1871
uint32_t adjustment,
1872
unsigned char force,
1873
unsigned int *store)
1878
*store = channel->remote.window_size;
1880
if(channel->adjust_state == libssh2_NB_state_idle) {
1882
&& (adjustment + channel->adjust_queue <
1883
LIBSSH2_CHANNEL_MINADJUST)) {
1884
_libssh2_debug((channel->session, LIBSSH2_TRACE_CONN,
1885
"Queueing %u bytes for receive window adjustment "
1886
"for channel %u/%u",
1887
adjustment, channel->local.id, channel->remote.id));
1888
channel->adjust_queue += adjustment;
1892
if(!adjustment && !channel->adjust_queue) {
1896
adjustment += channel->adjust_queue;
1897
channel->adjust_queue = 0;
1899
/* Adjust the window based on the block we just freed */
1900
channel->adjust_adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST;
1901
_libssh2_htonu32(&channel->adjust_adjust[1], channel->remote.id);
1902
_libssh2_htonu32(&channel->adjust_adjust[5], adjustment);
1903
_libssh2_debug((channel->session, LIBSSH2_TRACE_CONN,
1904
"Adjusting window %u bytes for data on "
1906
adjustment, channel->local.id, channel->remote.id));
1908
channel->adjust_state = libssh2_NB_state_created;
1911
rc = _libssh2_transport_send(channel->session, channel->adjust_adjust, 9,
1913
if(rc == LIBSSH2_ERROR_EAGAIN) {
1914
_libssh2_error(channel->session, rc,
1915
"Would block sending window adjust");
1919
channel->adjust_queue = adjustment;
1920
return _libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND,
1921
"Unable to send transfer-window adjustment "
1922
"packet, deferring");
1925
channel->remote.window_size += adjustment;
1928
channel->adjust_state = libssh2_NB_state_idle;
1933
#ifndef LIBSSH2_NO_DEPRECATED
1935
* libssh2_channel_receive_window_adjust (DEPRECATED, DO NOT USE!)
1937
* Adjust the receive window for a channel by adjustment bytes. If the amount
1938
* to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the
1939
* adjustment amount will be queued for a later packet.
1941
* Returns the new size of the receive window (as understood by remote end).
1942
* Note that it might return EAGAIN too which is highly stupid.
1945
LIBSSH2_API unsigned long
1946
libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel,
1948
unsigned char force)
1950
unsigned int window;
1954
return (unsigned long)LIBSSH2_ERROR_BAD_USE;
1956
BLOCK_ADJUST(rc, channel->session,
1957
_libssh2_channel_receive_window_adjust(channel,
1961
/* stupid - but this is how it was made to work before and this is just
1962
kept for backwards compatibility */
1963
return rc ? (unsigned long)rc : window;
1968
* libssh2_channel_receive_window_adjust2
1970
* Adjust the receive window for a channel by adjustment bytes. If the amount
1971
* to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the
1972
* adjustment amount will be queued for a later packet.
1974
* Stores the new size of the receive window in the data 'window' points to.
1976
* Returns the "normal" error code: 0 for success, negative for failure.
1979
libssh2_channel_receive_window_adjust2(LIBSSH2_CHANNEL *channel,
1981
unsigned char force,
1982
unsigned int *window)
1987
return LIBSSH2_ERROR_BAD_USE;
1989
BLOCK_ADJUST(rc, channel->session,
1990
_libssh2_channel_receive_window_adjust(channel,
1997
_libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode)
1999
if(channel->extData2_state == libssh2_NB_state_idle) {
2000
_libssh2_debug((channel->session, LIBSSH2_TRACE_CONN,
2001
"Setting channel %u/%u handle_extended_data"
2003
channel->local.id, channel->remote.id, ignore_mode));
2004
channel->remote.extended_data_ignore_mode = (char)ignore_mode;
2006
channel->extData2_state = libssh2_NB_state_created;
2009
if(channel->extData2_state == libssh2_NB_state_idle) {
2010
if(ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) {
2012
_libssh2_channel_flush(channel,
2013
LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA);
2014
if(LIBSSH2_ERROR_EAGAIN == rc)
2019
channel->extData2_state = libssh2_NB_state_idle;
2024
* libssh2_channel_handle_extended_data2
2028
libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel,
2034
return LIBSSH2_ERROR_BAD_USE;
2036
BLOCK_ADJUST(rc, channel->session, _libssh2_channel_extended_data(channel,
2041
#ifndef LIBSSH2_NO_DEPRECATED
2043
* libssh2_channel_handle_extended_data (DEPRECATED, DO NOT USE!)
2045
* How should extended data look to the calling app? Keep it in separate
2046
* channels[_read() _read_stdder()]? (NORMAL) Merge the extended data to the
2047
* standard data? [everything via _read()]? (MERGE) Ignore it entirely [toss
2048
* out packets as they come in]? (IGNORE)
2051
libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel,
2054
(void)libssh2_channel_handle_extended_data2(channel, ignore_mode);
2060
* _libssh2_channel_read
2062
* Read data from a channel
2064
* It is important to not return 0 until the currently read channel is
2065
* complete. If we read stuff from the wire but it was no payload data to fill
2066
* in the buffer with, we MUST make sure to return LIBSSH2_ERROR_EAGAIN.
2068
* The receive window must be maintained (enlarged) by the user of this
2071
ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
2072
char *buf, size_t buflen)
2074
LIBSSH2_SESSION *session = channel->session;
2076
size_t bytes_read = 0;
2079
LIBSSH2_PACKET *read_packet;
2080
LIBSSH2_PACKET *read_next;
2082
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
2083
"channel_read() wants %ld bytes from channel %u/%u "
2085
(long)buflen, channel->local.id, channel->remote.id,
2088
/* expand the receiving window first if it has become too narrow */
2089
if((channel->read_state == libssh2_NB_state_jump1) ||
2090
(channel->remote.window_size <
2091
channel->remote.window_size_initial / 4 * 3 + buflen)) {
2093
uint32_t adjustment = (uint32_t)(channel->remote.window_size_initial +
2094
buflen - channel->remote.window_size);
2095
if(adjustment < LIBSSH2_CHANNEL_MINADJUST)
2096
adjustment = LIBSSH2_CHANNEL_MINADJUST;
2098
/* the actual window adjusting may not finish so we need to deal with
2099
this special state here */
2100
channel->read_state = libssh2_NB_state_jump1;
2101
rc = _libssh2_channel_receive_window_adjust(channel, adjustment,
2106
channel->read_state = libssh2_NB_state_idle;
2109
/* Process all pending incoming packets. Tests prove that this way
2110
produces faster transfers. */
2112
rc = _libssh2_transport_read(session);
2115
if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN))
2116
return _libssh2_error(session, rc, "transport read");
2118
read_packet = _libssh2_list_first(&session->packets);
2119
while(read_packet && (bytes_read < buflen)) {
2120
/* previously this loop condition also checked for
2121
!channel->remote.close but we cannot let it do this:
2123
We may have a series of packets to read that are still pending even
2124
if a close has been received. Acknowledging the close too early
2125
makes us flush buffers prematurely and loose data.
2128
LIBSSH2_PACKET *readpkt = read_packet;
2130
/* In case packet gets destroyed during this iteration */
2131
read_next = _libssh2_list_next(&readpkt->node);
2133
if(readpkt->data_len < 5) {
2134
read_packet = read_next;
2136
if(readpkt->data_len != 1 ||
2137
readpkt->data[0] != SSH_MSG_REQUEST_FAILURE) {
2138
_libssh2_debug((channel->session, LIBSSH2_TRACE_ERROR,
2139
"Unexpected packet length"));
2145
channel->read_local_id =
2146
_libssh2_ntohu32(readpkt->data + 1);
2149
* Either we asked for a specific extended data stream
2150
* (and data was available),
2151
* or the standard stream (and data was available),
2152
* or the standard stream with extended_data_merge
2153
* enabled and data was available
2156
&& (readpkt->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)
2157
&& (channel->local.id == channel->read_local_id)
2158
&& (readpkt->data_len >= 9)
2159
&& (stream_id == (int) _libssh2_ntohu32(readpkt->data + 5)))
2160
|| (!stream_id && (readpkt->data[0] == SSH_MSG_CHANNEL_DATA)
2161
&& (channel->local.id == channel->read_local_id))
2163
&& (readpkt->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)
2164
&& (channel->local.id == channel->read_local_id)
2165
&& (channel->remote.extended_data_ignore_mode ==
2166
LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) {
2168
/* figure out much more data we want to read */
2169
bytes_want = buflen - bytes_read;
2170
unlink_packet = FALSE;
2172
if(bytes_want >= (readpkt->data_len - readpkt->data_head)) {
2173
/* we want more than this node keeps, so adjust the number and
2174
delete this node after the copy */
2175
bytes_want = readpkt->data_len - readpkt->data_head;
2176
unlink_packet = TRUE;
2179
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
2180
"channel_read() got %ld of data from %u/%u/%d%s",
2181
(long)bytes_want, channel->local.id,
2182
channel->remote.id, stream_id,
2183
unlink_packet?" [ul]":""));
2185
/* copy data from this struct to the target buffer */
2186
memcpy(&buf[bytes_read],
2187
&readpkt->data[readpkt->data_head], bytes_want);
2189
/* advance pointer and counter */
2190
readpkt->data_head += bytes_want;
2191
bytes_read += bytes_want;
2193
/* if drained, remove from list */
2195
/* detach readpkt from session->packets list */
2196
_libssh2_list_remove(&readpkt->node);
2198
LIBSSH2_FREE(session, readpkt->data);
2199
LIBSSH2_FREE(session, readpkt);
2203
/* check the next struct in the chain */
2204
read_packet = read_next;
2208
/* If the channel is already at EOF or even closed, we need to signal
2209
that back. We may have gotten that info while draining the incoming
2210
transport layer until EAGAIN so we must not be fooled by that
2212
if(channel->remote.eof || channel->remote.close)
2214
else if(rc != LIBSSH2_ERROR_EAGAIN)
2217
/* if the transport layer said EAGAIN then we say so as well */
2218
return _libssh2_error(session, rc, "would block");
2221
channel->read_avail -= bytes_read;
2222
channel->remote.window_size -= (uint32_t)bytes_read;
2228
* libssh2_channel_read_ex
2230
* Read data from a channel (blocking or non-blocking depending on set state)
2232
* When this is done non-blocking, it is important to not return 0 until the
2233
* currently read channel is complete. If we read stuff from the wire but it
2234
* was no payload data to fill in the buffer with, we MUST make sure to return
2235
* LIBSSH2_ERROR_EAGAIN.
2237
* This function will first make sure there's a receive window enough to
2238
* receive a full buffer's wort of contents. An application may choose to
2239
* adjust the receive window more to increase transfer performance.
2242
libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf,
2246
unsigned long recv_window;
2249
return LIBSSH2_ERROR_BAD_USE;
2251
recv_window = libssh2_channel_window_read_ex(channel, NULL, NULL);
2253
if(buflen > recv_window) {
2254
BLOCK_ADJUST(rc, channel->session,
2255
_libssh2_channel_receive_window_adjust(channel,
2256
(uint32_t)buflen, 1, NULL));
2259
BLOCK_ADJUST(rc, channel->session,
2260
_libssh2_channel_read(channel, stream_id, buf, buflen));
2265
* _libssh2_channel_packet_data_len
2267
* Return the size of the data block of the current packet, or 0 if there
2271
_libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
2273
LIBSSH2_SESSION *session = channel->session;
2274
LIBSSH2_PACKET *read_packet;
2275
LIBSSH2_PACKET *next_packet;
2276
uint32_t read_local_id;
2278
read_packet = _libssh2_list_first(&session->packets);
2282
while(read_packet) {
2284
next_packet = _libssh2_list_next(&read_packet->node);
2286
if(read_packet->data_len < 5) {
2287
read_packet = next_packet;
2288
_libssh2_debug((channel->session, LIBSSH2_TRACE_ERROR,
2289
"Unexpected packet length"));
2293
read_local_id = _libssh2_ntohu32(read_packet->data + 1);
2296
* Either we asked for a specific extended data stream
2297
* (and data was available),
2298
* or the standard stream (and data was available),
2299
* or the standard stream with extended_data_merge
2300
* enabled and data was available
2303
&& (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)
2304
&& (channel->local.id == read_local_id)
2305
&& (read_packet->data_len >= 9)
2306
&& (stream_id == (int) _libssh2_ntohu32(read_packet->data + 5)))
2309
&& (read_packet->data[0] == SSH_MSG_CHANNEL_DATA)
2310
&& (channel->local.id == read_local_id))
2313
&& (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)
2314
&& (channel->local.id == read_local_id)
2315
&& (channel->remote.extended_data_ignore_mode
2316
== LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) {
2317
return read_packet->data_len - read_packet->data_head;
2320
read_packet = next_packet;
2327
* _libssh2_channel_write
2329
* Send data to a channel. Note that if this returns EAGAIN, the caller must
2330
* call this function again with the SAME input arguments.
2332
* Returns: number of bytes sent, or if it returns a negative number, that is
2336
_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
2337
const unsigned char *buf, size_t buflen)
2340
LIBSSH2_SESSION *session = channel->session;
2341
ssize_t wrote = 0; /* counter for this specific this call */
2343
/* In theory we could split larger buffers into several smaller packets
2344
* but it turns out to be really hard and nasty to do while still offering
2345
* the API/prototype.
2347
* Instead we only deal with the first 32K in this call and for the parent
2348
* function to call it again with the remainder! 32K is a conservative
2349
* limit based on the text in RFC4253 section 6.1.
2354
if(channel->write_state == libssh2_NB_state_idle) {
2355
unsigned char *s = channel->write_packet;
2357
_libssh2_debug((channel->session, LIBSSH2_TRACE_CONN,
2358
"Writing %ld bytes on channel %u/%u, stream #%d",
2359
(long)buflen, channel->local.id, channel->remote.id,
2362
if(channel->local.close)
2363
return _libssh2_error(channel->session,
2364
LIBSSH2_ERROR_CHANNEL_CLOSED,
2365
"We have already closed this channel");
2366
else if(channel->local.eof)
2367
return _libssh2_error(channel->session,
2368
LIBSSH2_ERROR_CHANNEL_EOF_SENT,
2369
"EOF has already been received, "
2370
"data might be ignored");
2372
/* drain the incoming flow first, mostly to make sure we get all
2373
* pending window adjust packets */
2375
rc = _libssh2_transport_read(session);
2378
if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) {
2379
return _libssh2_error(channel->session, rc,
2380
"Failure while draining incoming flow");
2383
if(channel->local.window_size <= 0) {
2384
/* there's no room for data so we stop */
2386
/* Waiting on the socket to be writable would be wrong because we
2387
* would be back here immediately, but a readable socket might
2388
* herald an incoming window adjustment.
2390
session->socket_block_directions = LIBSSH2_SESSION_BLOCK_INBOUND;
2392
return rc == LIBSSH2_ERROR_EAGAIN ? rc : 0;
2395
channel->write_bufwrite = buflen;
2397
*(s++) = stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA :
2398
SSH_MSG_CHANNEL_DATA;
2399
_libssh2_store_u32(&s, channel->remote.id);
2401
_libssh2_store_u32(&s, stream_id);
2403
/* Don't exceed the remote end's limits */
2404
/* REMEMBER local means local as the SOURCE of the data */
2405
if(channel->write_bufwrite > channel->local.window_size) {
2406
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
2407
"Splitting write block due to %u byte "
2408
"window_size on %u/%u/%d",
2409
channel->local.window_size, channel->local.id,
2410
channel->remote.id, stream_id));
2411
channel->write_bufwrite = channel->local.window_size;
2413
if(channel->write_bufwrite > channel->local.packet_size) {
2414
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
2415
"Splitting write block due to %u byte "
2416
"packet_size on %u/%u/%d",
2417
channel->local.packet_size, channel->local.id,
2418
channel->remote.id, stream_id));
2419
channel->write_bufwrite = channel->local.packet_size;
2421
/* store the size here only, the buffer is passed in as-is to
2422
_libssh2_transport_send() */
2423
_libssh2_store_u32(&s, (uint32_t)channel->write_bufwrite);
2424
channel->write_packet_len = s - channel->write_packet;
2426
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
2427
"Sending %ld bytes on channel %u/%u, stream_id=%d",
2428
(long)channel->write_bufwrite, channel->local.id,
2429
channel->remote.id, stream_id));
2431
channel->write_state = libssh2_NB_state_created;
2434
if(channel->write_state == libssh2_NB_state_created) {
2435
rc = _libssh2_transport_send(session, channel->write_packet,
2436
channel->write_packet_len,
2437
buf, channel->write_bufwrite);
2438
if(rc == LIBSSH2_ERROR_EAGAIN) {
2439
return _libssh2_error(session, rc,
2440
"Unable to send channel data");
2443
channel->write_state = libssh2_NB_state_idle;
2444
return _libssh2_error(session, rc,
2445
"Unable to send channel data");
2447
/* Shrink local window size */
2448
channel->local.window_size -= (uint32_t)channel->write_bufwrite;
2450
wrote += channel->write_bufwrite;
2452
/* Since _libssh2_transport_write() succeeded, we must return
2453
now to allow the caller to provide the next chunk of data.
2455
We cannot move on to send the next piece of data that may
2456
already have been provided in this same function call, as we
2457
risk getting EAGAIN for that and we can't return information
2458
both about sent data as well as EAGAIN. So, by returning short
2459
now, the caller will call this function again with new data to
2462
channel->write_state = libssh2_NB_state_idle;
2467
return LIBSSH2_ERROR_INVAL; /* reaching this point is really bad */
2471
* libssh2_channel_write_ex
2473
* Send data to a channel
2476
libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id,
2477
const char *buf, size_t buflen)
2482
return LIBSSH2_ERROR_BAD_USE;
2484
BLOCK_ADJUST(rc, channel->session,
2485
_libssh2_channel_write(channel, stream_id,
2486
(unsigned char *)buf, buflen));
2493
* Send EOF on channel
2495
static int channel_send_eof(LIBSSH2_CHANNEL *channel)
2497
LIBSSH2_SESSION *session = channel->session;
2498
unsigned char packet[5]; /* packet_type(1) + channelno(4) */
2501
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
2502
"Sending EOF on channel %u/%u",
2503
channel->local.id, channel->remote.id));
2504
packet[0] = SSH_MSG_CHANNEL_EOF;
2505
_libssh2_htonu32(packet + 1, channel->remote.id);
2506
rc = _libssh2_transport_send(session, packet, 5, NULL, 0);
2507
if(rc == LIBSSH2_ERROR_EAGAIN) {
2508
_libssh2_error(session, rc,
2509
"Would block sending EOF");
2513
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
2514
"Unable to send EOF on channel");
2516
channel->local.eof = 1;
2522
* libssh2_channel_send_eof
2524
* Send EOF on channel
2527
libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel)
2532
return LIBSSH2_ERROR_BAD_USE;
2534
BLOCK_ADJUST(rc, channel->session, channel_send_eof(channel));
2539
* libssh2_channel_eof
2541
* Read channel's eof status
2544
libssh2_channel_eof(LIBSSH2_CHANNEL * channel)
2546
LIBSSH2_SESSION *session;
2547
LIBSSH2_PACKET *packet;
2548
LIBSSH2_PACKET *next_packet;
2551
return LIBSSH2_ERROR_BAD_USE;
2553
session = channel->session;
2554
packet = _libssh2_list_first(&session->packets);
2558
next_packet = _libssh2_list_next(&packet->node);
2560
if(packet->data_len < 1) {
2561
packet = next_packet;
2562
_libssh2_debug((channel->session, LIBSSH2_TRACE_ERROR,
2563
"Unexpected packet length"));
2567
if(((packet->data[0] == SSH_MSG_CHANNEL_DATA)
2568
|| (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA))
2569
&& ((packet->data_len >= 5)
2570
&& (channel->local.id == _libssh2_ntohu32(packet->data + 1)))) {
2571
/* There's data waiting to be read yet, mask the EOF status */
2574
packet = next_packet;
2577
return channel->remote.eof;
2583
* Awaiting channel EOF
2585
static int channel_wait_eof(LIBSSH2_CHANNEL *channel)
2587
LIBSSH2_SESSION *session = channel->session;
2590
if(channel->wait_eof_state == libssh2_NB_state_idle) {
2591
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
2592
"Awaiting EOF for channel %u/%u", channel->local.id,
2593
channel->remote.id));
2595
channel->wait_eof_state = libssh2_NB_state_created;
2599
* While channel is not eof, read more packets from the network.
2600
* Either the EOF will be set or network timeout will occur.
2603
if(channel->remote.eof) {
2607
if((channel->remote.window_size == channel->read_avail) &&
2608
session->api_block_mode)
2609
return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_WINDOW_FULL,
2610
"Receiving channel window "
2611
"has been exhausted");
2613
rc = _libssh2_transport_read(session);
2614
if(rc == LIBSSH2_ERROR_EAGAIN) {
2618
channel->wait_eof_state = libssh2_NB_state_idle;
2619
return _libssh2_error(session, rc,
2620
"_libssh2_transport_read() bailed out");
2624
channel->wait_eof_state = libssh2_NB_state_idle;
2630
* libssh2_channel_wait_eof
2632
* Awaiting channel EOF
2635
libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel)
2640
return LIBSSH2_ERROR_BAD_USE;
2642
BLOCK_ADJUST(rc, channel->session, channel_wait_eof(channel));
2646
int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
2648
LIBSSH2_SESSION *session = channel->session;
2651
if(channel->local.close) {
2652
/* Already closed, act like we sent another close,
2653
* even though we didn't... shhhhhh */
2654
channel->close_state = libssh2_NB_state_idle;
2658
if(!channel->local.eof) {
2659
rc = channel_send_eof(channel);
2661
if(rc == LIBSSH2_ERROR_EAGAIN) {
2664
_libssh2_error(session, rc,
2665
"Unable to send EOF, but closing channel anyway");
2669
/* ignore if we have received a remote eof or not, as it is now too
2670
late for us to wait for it. Continue closing! */
2672
if(channel->close_state == libssh2_NB_state_idle) {
2673
_libssh2_debug((session, LIBSSH2_TRACE_CONN, "Closing channel %u/%u",
2674
channel->local.id, channel->remote.id));
2676
channel->close_packet[0] = SSH_MSG_CHANNEL_CLOSE;
2677
_libssh2_htonu32(channel->close_packet + 1, channel->remote.id);
2679
channel->close_state = libssh2_NB_state_created;
2682
if(channel->close_state == libssh2_NB_state_created) {
2683
rc = _libssh2_transport_send(session, channel->close_packet, 5,
2685
if(rc == LIBSSH2_ERROR_EAGAIN) {
2686
_libssh2_error(session, rc,
2687
"Would block sending close-channel");
2692
_libssh2_error(session, rc,
2693
"Unable to send close-channel request, "
2694
"but closing anyway");
2695
/* skip waiting for the response and fall through to
2696
LIBSSH2_CHANNEL_CLOSE below */
2700
channel->close_state = libssh2_NB_state_sent;
2703
if(channel->close_state == libssh2_NB_state_sent) {
2704
/* We must wait for the remote SSH_MSG_CHANNEL_CLOSE message */
2706
while(!channel->remote.close && !rc &&
2707
(session->socket_state != LIBSSH2_SOCKET_DISCONNECTED))
2708
rc = _libssh2_transport_read(session);
2711
if(rc != LIBSSH2_ERROR_EAGAIN) {
2712
/* set the local close state first when we're perfectly confirmed to
2713
not do any more EAGAINs */
2714
channel->local.close = 1;
2716
/* We call the callback last in this function to make it keep the local
2717
data as long as EAGAIN is returned. */
2718
if(channel->close_cb) {
2719
LIBSSH2_CHANNEL_CLOSE(session, channel);
2722
channel->close_state = libssh2_NB_state_idle;
2725
/* return 0 or an error */
2726
return rc >= 0 ? 0 : rc;
2730
* libssh2_channel_close
2735
libssh2_channel_close(LIBSSH2_CHANNEL *channel)
2740
return LIBSSH2_ERROR_BAD_USE;
2742
BLOCK_ADJUST(rc, channel->session, _libssh2_channel_close(channel));
2747
* channel_wait_closed
2749
* Awaiting channel close after EOF
2751
static int channel_wait_closed(LIBSSH2_CHANNEL *channel)
2753
LIBSSH2_SESSION *session = channel->session;
2756
if(!channel->remote.eof) {
2757
return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
2758
"libssh2_channel_wait_closed() invoked when "
2759
"channel is not in EOF state");
2762
if(channel->wait_closed_state == libssh2_NB_state_idle) {
2763
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
2764
"Awaiting close of channel %u/%u", channel->local.id,
2765
channel->remote.id));
2767
channel->wait_closed_state = libssh2_NB_state_created;
2771
* While channel is not closed, read more packets from the network.
2772
* Either the channel will be closed or network timeout will occur.
2774
if(!channel->remote.close) {
2776
rc = _libssh2_transport_read(session);
2777
if(channel->remote.close)
2778
/* it is now closed, move on! */
2785
channel->wait_closed_state = libssh2_NB_state_idle;
2791
* libssh2_channel_wait_closed
2793
* Awaiting channel close after EOF
2796
libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel)
2801
return LIBSSH2_ERROR_BAD_USE;
2803
BLOCK_ADJUST(rc, channel->session, channel_wait_closed(channel));
2808
* _libssh2_channel_free
2810
* Make sure a channel is closed, then remove the channel from the session
2811
* and free its resource(s)
2813
* Returns 0 on success, negative on failure
2815
int _libssh2_channel_free(LIBSSH2_CHANNEL *channel)
2817
LIBSSH2_SESSION *session = channel->session;
2818
unsigned char channel_id[4];
2819
unsigned char *data;
2825
if(channel->free_state == libssh2_NB_state_idle) {
2826
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
2827
"Freeing channel %u/%u resources", channel->local.id,
2828
channel->remote.id));
2830
channel->free_state = libssh2_NB_state_created;
2833
/* Allow channel freeing even when the socket has lost its connection */
2834
if(!channel->local.close
2835
&& (session->socket_state == LIBSSH2_SOCKET_CONNECTED)) {
2836
rc = _libssh2_channel_close(channel);
2838
if(rc == LIBSSH2_ERROR_EAGAIN)
2841
/* ignore all other errors as they otherwise risk blocking the channel
2842
free from happening */
2845
channel->free_state = libssh2_NB_state_idle;
2847
if(channel->exit_signal) {
2848
LIBSSH2_FREE(session, channel->exit_signal);
2852
* channel->remote.close *might* not be set yet, Well...
2853
* We've sent the close packet, what more do you want?
2854
* Just let packet_add ignore it when it finally arrives
2857
/* Clear out packets meant for this channel */
2858
_libssh2_htonu32(channel_id, channel->local.id);
2859
while((_libssh2_packet_ask(session, SSH_MSG_CHANNEL_DATA, &data,
2860
&data_len, 1, channel_id, 4) >= 0)
2862
(_libssh2_packet_ask(session, SSH_MSG_CHANNEL_EXTENDED_DATA, &data,
2863
&data_len, 1, channel_id, 4) >= 0)) {
2864
LIBSSH2_FREE(session, data);
2867
/* free "channel_type" */
2868
if(channel->channel_type) {
2869
LIBSSH2_FREE(session, channel->channel_type);
2872
/* Unlink from channel list */
2873
_libssh2_list_remove(&channel->node);
2876
* Make sure all memory used in the state variables are free
2878
if(channel->setenv_packet) {
2879
LIBSSH2_FREE(session, channel->setenv_packet);
2881
if(channel->reqX11_packet) {
2882
LIBSSH2_FREE(session, channel->reqX11_packet);
2884
if(channel->process_packet) {
2885
LIBSSH2_FREE(session, channel->process_packet);
2888
LIBSSH2_FREE(session, channel);
2894
* libssh2_channel_free
2896
* Make sure a channel is closed, then remove the channel from the session
2897
* and free its resource(s)
2899
* Returns 0 on success, negative on failure
2902
libssh2_channel_free(LIBSSH2_CHANNEL *channel)
2907
return LIBSSH2_ERROR_BAD_USE;
2909
BLOCK_ADJUST(rc, channel->session, _libssh2_channel_free(channel));
2913
* libssh2_channel_window_read_ex
2915
* Check the status of the read window. Returns the number of bytes which the
2916
* remote end may send without overflowing the window limit read_avail (if
2917
* passed) will be populated with the number of bytes actually available to be
2918
* read window_size_initial (if passed) will be populated with the
2919
* window_size_initial as defined by the channel_open request
2921
LIBSSH2_API unsigned long
2922
libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel,
2923
/* FIXME: -> size_t */ unsigned long *read_avail,
2924
unsigned long *window_size_initial)
2927
return 0; /* no channel, no window! */
2929
if(window_size_initial) {
2930
*window_size_initial = channel->remote.window_size_initial;
2934
size_t bytes_queued = 0;
2935
LIBSSH2_PACKET *next_packet;
2936
LIBSSH2_PACKET *packet =
2937
_libssh2_list_first(&channel->session->packets);
2940
unsigned char packet_type;
2941
next_packet = _libssh2_list_next(&packet->node);
2943
if(packet->data_len < 1) {
2944
packet = next_packet;
2945
_libssh2_debug((channel->session, LIBSSH2_TRACE_ERROR,
2946
"Unexpected packet length"));
2950
packet_type = packet->data[0];
2952
if(((packet_type == SSH_MSG_CHANNEL_DATA)
2953
|| (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA))
2954
&& ((packet->data_len >= 5)
2955
&& (_libssh2_ntohu32(packet->data + 1) ==
2956
channel->local.id))) {
2957
bytes_queued += packet->data_len - packet->data_head;
2960
packet = next_packet;
2963
*read_avail = (unsigned long)bytes_queued;
2966
return channel->remote.window_size;
2970
* libssh2_channel_window_write_ex
2972
* Check the status of the write window Returns the number of bytes which may
2973
* be safely written on the channel without blocking window_size_initial (if
2974
* passed) will be populated with the size of the initial window as defined by
2975
* the channel_open request
2977
LIBSSH2_API unsigned long
2978
libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel,
2979
unsigned long *window_size_initial)
2982
return 0; /* no channel, no window! */
2984
if(window_size_initial) {
2985
/* For locally initiated channels this is very often 0, so it's not
2986
* *that* useful as information goes */
2987
*window_size_initial = channel->local.window_size_initial;
2990
return channel->local.window_size;
2993
/* A signal can be delivered to the remote process/service using the
2994
following message. Some systems may not implement signals, in which
2995
case they SHOULD ignore this message.
2997
byte SSH_MSG_CHANNEL_REQUEST
2998
uint32 recipient channel
3001
string signal name (without the "SIG" prefix)
3003
'signal name' values will be encoded as discussed in the passage
3004
describing SSH_MSG_CHANNEL_REQUEST messages using "exit-signal" in
3007
static int channel_signal(LIBSSH2_CHANNEL *channel,
3008
const char *signame,
3011
LIBSSH2_SESSION *session = channel->session;
3012
int retcode = LIBSSH2_ERROR_PROTO;
3014
if(channel->sendsignal_state == libssh2_NB_state_idle) {
3017
/* 20 = packet_type(1) + channel(4) +
3018
signal_len + sizeof(signal) - 1 + want_reply(1) +
3019
signame_len_len(4) */
3020
channel->sendsignal_packet_len = 20 + signame_len;
3022
s = channel->sendsignal_packet =
3023
LIBSSH2_ALLOC(session, channel->sendsignal_packet_len);
3024
if(!channel->sendsignal_packet)
3025
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
3026
"Unable to allocate memory for "
3029
*(s++) = SSH_MSG_CHANNEL_REQUEST;
3030
_libssh2_store_u32(&s, channel->remote.id);
3031
_libssh2_store_str(&s, "signal", sizeof("signal") - 1);
3032
*(s++) = 0x00; /* Don't reply */
3033
_libssh2_store_str(&s, signame, signame_len);
3035
channel->sendsignal_state = libssh2_NB_state_created;
3038
if(channel->sendsignal_state == libssh2_NB_state_created) {
3041
rc = _libssh2_transport_send(session, channel->sendsignal_packet,
3042
channel->sendsignal_packet_len,
3044
if(rc == LIBSSH2_ERROR_EAGAIN) {
3045
_libssh2_error(session, rc, "Would block sending signal request");
3049
LIBSSH2_FREE(session, channel->sendsignal_packet);
3050
channel->sendsignal_state = libssh2_NB_state_idle;
3051
return _libssh2_error(session, rc, "Unable to send signal packet");
3053
LIBSSH2_FREE(session, channel->sendsignal_packet);
3054
retcode = LIBSSH2_ERROR_NONE;
3057
channel->sendsignal_state = libssh2_NB_state_idle;
3063
libssh2_channel_signal_ex(LIBSSH2_CHANNEL *channel,
3064
const char *signame,
3070
return LIBSSH2_ERROR_BAD_USE;
3072
BLOCK_ADJUST(rc, channel->session,
3073
channel_signal(channel, signame, signame_len));