Coverage Report

Created: 2025-07-01 07:11

/src/libssh/src/channels.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * channels.c - SSH channel functions
3
 *
4
 * This file is part of the SSH Library
5
 *
6
 * Copyright (c) 2003-2013 by Aris Adamantiadis
7
 * Copyright (c) 2009-2013 by Andreas Schneider <asn@cryptomilk.org>
8
 *
9
 * The SSH Library is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU Lesser General Public License as published by
11
 * the Free Software Foundation; either version 2.1 of the License, or (at your
12
 * option) any later version.
13
 *
14
 * The SSH Library is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
17
 * License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with the SSH Library; see the file COPYING.  If not, write to
21
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22
 * MA 02111-1307, USA.
23
 */
24
25
#include "config.h"
26
27
#include <limits.h>
28
#include <stdio.h>
29
#include <errno.h>
30
#include <time.h>
31
#include <stdbool.h>
32
#include <string.h>
33
#ifdef HAVE_SYS_TIME_H
34
#include <sys/time.h>
35
#endif /* HAVE_SYS_TIME_H */
36
37
#ifndef _WIN32
38
#include <netinet/in.h>
39
#include <arpa/inet.h>
40
#endif
41
42
#include "libssh/priv.h"
43
#include "libssh/ssh2.h"
44
#include "libssh/buffer.h"
45
#include "libssh/packet.h"
46
#include "libssh/socket.h"
47
#include "libssh/channels.h"
48
#include "libssh/session.h"
49
#include "libssh/misc.h"
50
#include "libssh/messages.h"
51
#if WITH_SERVER
52
#include "libssh/server.h"
53
#endif
54
55
/*
56
 * All implementations MUST be able to process packets with an
57
 * uncompressed payload length of 32768 bytes or less and a total packet
58
 * size of 35000 bytes or less.
59
 */
60
0
#define CHANNEL_MAX_PACKET 32768
61
62
/*
63
 * WINDOW_DEFAULT matches the default OpenSSH session window size.
64
 * This controls how much data the peer can send before needing to receive
65
 * a round-trip SSH2_MSG_CHANNEL_WINDOW_ADJUST message that increases the window.
66
 */
67
0
#define WINDOW_DEFAULT (64*CHANNEL_MAX_PACKET)
68
69
/**
70
 * @defgroup libssh_channel The SSH channel functions
71
 * @ingroup libssh
72
 *
73
 * Functions that manage a SSH channel.
74
 *
75
 * @{
76
 */
77
78
static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet);
79
80
/**
81
 * @brief Allocate a new channel.
82
 *
83
 * @param[in]  session  The ssh session to use.
84
 *
85
 * @return              A pointer to a newly allocated channel, NULL on error.
86
 *                      The channel needs to be freed with ssh_channel_free().
87
 *
88
 * @see ssh_channel_free()
89
 */
90
ssh_channel ssh_channel_new(ssh_session session)
91
865
{
92
865
    ssh_channel channel = NULL;
93
94
865
    if (session == NULL) {
95
0
        return NULL;
96
0
    }
97
98
    /* Check if we have an authenticated session */
99
865
    if (!(session->flags & SSH_SESSION_FLAG_AUTHENTICATED)) {
100
0
        return NULL;
101
0
    }
102
103
865
    channel = calloc(1, sizeof(struct ssh_channel_struct));
104
865
    if (channel == NULL) {
105
0
        ssh_set_error_oom(session);
106
0
        return NULL;
107
0
    }
108
109
865
    channel->stdout_buffer = ssh_buffer_new();
110
865
    if (channel->stdout_buffer == NULL) {
111
0
        ssh_set_error_oom(session);
112
0
        SAFE_FREE(channel);
113
0
        return NULL;
114
0
    }
115
116
865
    channel->stderr_buffer = ssh_buffer_new();
117
865
    if (channel->stderr_buffer == NULL) {
118
0
        ssh_set_error_oom(session);
119
0
        SSH_BUFFER_FREE(channel->stdout_buffer);
120
0
        SAFE_FREE(channel);
121
0
        return NULL;
122
0
    }
123
124
865
    channel->session = session;
125
865
    channel->exit.code = (uint32_t)-1;
126
865
    channel->flags = SSH_CHANNEL_FLAG_NOT_BOUND;
127
128
865
    if (session->channels == NULL) {
129
830
        session->channels = ssh_list_new();
130
830
        if (session->channels == NULL) {
131
0
            ssh_set_error_oom(session);
132
0
            SSH_BUFFER_FREE(channel->stdout_buffer);
133
0
            SSH_BUFFER_FREE(channel->stderr_buffer);
134
0
            SAFE_FREE(channel);
135
0
            return NULL;
136
0
        }
137
830
    }
138
139
865
    ssh_list_prepend(session->channels, channel);
140
141
    /* Set states explicitly */
142
865
    channel->state = SSH_CHANNEL_STATE_NOT_OPEN;
143
865
    channel->request_state = SSH_CHANNEL_REQ_STATE_NONE;
144
145
865
    return channel;
146
865
}
147
148
/**
149
 * @internal
150
 *
151
 * @brief Create a new channel identifier.
152
 *
153
 * @param[in]  session  The SSH session to use.
154
 *
155
 * @return              The new channel identifier.
156
 */
157
uint32_t ssh_channel_new_id(ssh_session session)
158
865
{
159
865
    return ++(session->maxchannel);
160
865
}
161
162
/**
163
 * @internal
164
 *
165
 * @brief Handle a SSH_PACKET_CHANNEL_OPEN_CONFIRMATION packet.
166
 *
167
 * Constructs the channel object.
168
 */
169
SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf)
170
66
{
171
66
    uint32_t channelid = 0;
172
66
    ssh_channel channel = NULL;
173
66
    int rc;
174
66
    (void)type;
175
66
    (void)user;
176
177
66
    SSH_LOG(SSH_LOG_PACKET, "Received SSH2_MSG_CHANNEL_OPEN_CONFIRMATION");
178
179
66
    rc = ssh_buffer_unpack(packet, "d", &channelid);
180
66
    if (rc != SSH_OK)
181
12
        goto error;
182
54
    channel = ssh_channel_from_local(session, channelid);
183
54
    if (channel == NULL) {
184
52
        ssh_set_error(session,
185
52
                      SSH_FATAL,
186
52
                      "Unknown channel id %" PRIu32,
187
52
                      (uint32_t)channelid);
188
        /* TODO: Set error marking in channel object */
189
190
52
        return SSH_PACKET_USED;
191
52
    }
192
193
2
    rc = ssh_buffer_unpack(packet,
194
2
                           "ddd",
195
2
                           &channel->remote_channel,
196
2
                           &channel->remote_window,
197
2
                           &channel->remote_maxpacket);
198
2
    if (rc != SSH_OK)
199
1
        goto error;
200
201
1
    SSH_LOG(SSH_LOG_DEBUG,
202
1
            "Received a CHANNEL_OPEN_CONFIRMATION for channel %" PRIu32
203
1
            ":%" PRIu32,
204
1
            channel->local_channel,
205
1
            channel->remote_channel);
206
207
1
    if (channel->state != SSH_CHANNEL_STATE_OPENING) {
208
1
        SSH_LOG(SSH_LOG_RARE,
209
1
                "SSH2_MSG_CHANNEL_OPEN_CONFIRMATION received in incorrect "
210
1
                "channel state %d",
211
1
                channel->state);
212
1
        goto error;
213
1
    }
214
215
0
    SSH_LOG(SSH_LOG_DEBUG,
216
0
            "Remote window : %" PRIu32 ", maxpacket : %" PRIu32,
217
0
            channel->remote_window,
218
0
            channel->remote_maxpacket);
219
220
0
    channel->state = SSH_CHANNEL_STATE_OPEN;
221
0
    channel->flags &= ~SSH_CHANNEL_FLAG_NOT_BOUND;
222
223
0
    ssh_callbacks_execute_list(channel->callbacks,
224
0
                               ssh_channel_callbacks,
225
0
                               channel_open_response_function,
226
0
                               channel->session,
227
0
                               channel,
228
0
                               true /* is_success */);
229
230
0
    return SSH_PACKET_USED;
231
232
14
error:
233
14
    ssh_set_error(session, SSH_FATAL, "Invalid packet");
234
14
    return SSH_PACKET_USED;
235
1
}
236
237
/**
238
 * @internal
239
 *
240
 * @brief Handle a SSH_CHANNEL_OPEN_FAILURE and set the state of the channel.
241
 */
242
SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail)
243
23
{
244
23
    ssh_channel channel = NULL;
245
23
    char *error = NULL;
246
23
    uint32_t code;
247
23
    int rc;
248
23
    (void)user;
249
23
    (void)type;
250
251
23
    channel = channel_from_msg(session, packet);
252
23
    if (channel == NULL) {
253
16
        SSH_LOG(SSH_LOG_RARE, "Invalid channel in packet");
254
16
        return SSH_PACKET_USED;
255
16
    }
256
257
7
    rc = ssh_buffer_unpack(packet, "ds", &code, &error);
258
7
    if (rc != SSH_OK) {
259
4
        ssh_set_error(session, SSH_FATAL, "Invalid packet");
260
4
        return SSH_PACKET_USED;
261
4
    }
262
263
3
    if (channel->state != SSH_CHANNEL_STATE_OPENING) {
264
3
        SSH_LOG(SSH_LOG_RARE,
265
3
                "SSH2_MSG_CHANNEL_OPEN_FAILURE received in incorrect channel "
266
3
                "state %d",
267
3
                channel->state);
268
3
        SAFE_FREE(error);
269
3
        goto error;
270
3
    }
271
272
0
    ssh_set_error(session,
273
0
                  SSH_REQUEST_DENIED,
274
0
                  "Channel opening failure: channel %" PRIu32 " error (%" PRIu32
275
0
                  ") %s",
276
0
                  channel->local_channel,
277
0
                  code,
278
0
                  error);
279
0
    SAFE_FREE(error);
280
0
    channel->state = SSH_CHANNEL_STATE_OPEN_DENIED;
281
282
0
    ssh_callbacks_execute_list(channel->callbacks,
283
0
                               ssh_channel_callbacks,
284
0
                               channel_open_response_function,
285
0
                               channel->session,
286
0
                               channel,
287
0
                               false /* is_success */);
288
289
0
    return SSH_PACKET_USED;
290
291
3
error:
292
3
  ssh_set_error(session, SSH_FATAL, "Invalid packet");
293
3
  return SSH_PACKET_USED;
294
3
}
295
296
static int ssh_channel_open_termination(void *c)
297
0
{
298
0
  ssh_channel channel = (ssh_channel) c;
299
0
  if (channel->state != SSH_CHANNEL_STATE_OPENING ||
300
0
      channel->session->session_state == SSH_SESSION_STATE_ERROR)
301
0
    return 1;
302
0
  else
303
0
    return 0;
304
0
}
305
306
/**
307
 * @internal
308
 *
309
 * @brief Open a channel by sending a SSH_OPEN_CHANNEL message and
310
 *        wait for the reply.
311
 *
312
 * @param[in]  channel  The current channel.
313
 *
314
 * @param[in]  type   A C string describing the kind of channel (e.g. "exec").
315
 *
316
 * @param[in]  window   The receiving window of the channel. The window is the
317
 *                      maximum size of data that can stay in buffers and
318
 *                      network.
319
 *
320
 * @param[in]  maxpacket The maximum packet size allowed (like MTU).
321
 *
322
 * @param[in]  payload   The buffer containing additional payload for the query.
323
 *
324
 * @return             SSH_OK if successful; SSH_ERROR otherwise.
325
 */
326
static int
327
channel_open(ssh_channel channel,
328
             const char *type,
329
             uint32_t window,
330
             uint32_t maxpacket,
331
             ssh_buffer payload)
332
0
{
333
0
    ssh_session session = channel->session;
334
0
    int err = SSH_ERROR;
335
0
    int rc;
336
337
0
    switch (channel->state) {
338
0
    case SSH_CHANNEL_STATE_NOT_OPEN:
339
0
        break;
340
0
    case SSH_CHANNEL_STATE_OPENING:
341
0
        goto pending;
342
0
    case SSH_CHANNEL_STATE_OPEN:
343
0
    case SSH_CHANNEL_STATE_CLOSED:
344
0
    case SSH_CHANNEL_STATE_OPEN_DENIED:
345
0
        goto end;
346
0
    default:
347
0
        ssh_set_error(session, SSH_FATAL, "Bad state in channel_open: %d",
348
0
                      channel->state);
349
0
    }
350
351
0
    channel->local_channel = ssh_channel_new_id(session);
352
0
    channel->local_maxpacket = maxpacket;
353
0
    channel->local_window = window;
354
355
0
    SSH_LOG(SSH_LOG_DEBUG,
356
0
            "Creating a channel %" PRIu32 " with %" PRIu32 " window and %" PRIu32 " max packet",
357
0
            channel->local_channel, window, maxpacket);
358
359
0
    rc = ssh_buffer_pack(session->out_buffer,
360
0
                         "bsddd",
361
0
                         SSH2_MSG_CHANNEL_OPEN,
362
0
                         type,
363
0
                         channel->local_channel,
364
0
                         channel->local_window,
365
0
                         channel->local_maxpacket);
366
0
    if (rc != SSH_OK) {
367
0
        ssh_set_error_oom(session);
368
0
        return err;
369
0
    }
370
371
0
    if (payload != NULL) {
372
0
        if (ssh_buffer_add_buffer(session->out_buffer, payload) < 0) {
373
0
            ssh_set_error_oom(session);
374
375
0
            return err;
376
0
        }
377
0
    }
378
0
    channel->state = SSH_CHANNEL_STATE_OPENING;
379
0
    if (ssh_packet_send(session) == SSH_ERROR) {
380
0
        return err;
381
0
    }
382
383
0
    SSH_LOG(SSH_LOG_PACKET,
384
0
            "Sent a SSH_MSG_CHANNEL_OPEN type %s for channel %" PRIu32,
385
0
            type, channel->local_channel);
386
387
0
pending:
388
    /* wait until channel is opened by server */
389
0
    err = ssh_handle_packets_termination(session,
390
0
                                         SSH_TIMEOUT_DEFAULT,
391
0
                                         ssh_channel_open_termination,
392
0
                                         channel);
393
394
0
    if (session->session_state == SSH_SESSION_STATE_ERROR) {
395
0
        err = SSH_ERROR;
396
0
    }
397
398
0
end:
399
    /* This needs to pass the SSH_AGAIN from the above,
400
     * but needs to catch failed channel states */
401
0
    if (channel->state == SSH_CHANNEL_STATE_OPEN) {
402
0
        err = SSH_OK;
403
0
    } else if (err != SSH_AGAIN) {
404
        /* Messages were handled correctly, but the channel state is invalid */
405
0
        err = SSH_ERROR;
406
0
    }
407
408
0
    return err;
409
0
}
410
411
/* return channel with corresponding local id, or NULL if not found */
412
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id)
413
951
{
414
951
    struct ssh_iterator *it = NULL;
415
951
    ssh_channel channel = NULL;
416
417
1.11k
    for (it = ssh_list_get_iterator(session->channels); it != NULL;
418
951
         it = it->next) {
419
921
        channel = ssh_iterator_value(ssh_channel, it);
420
921
        if (channel == NULL) {
421
0
            continue;
422
0
        }
423
921
        if (channel->local_channel == id) {
424
757
            return channel;
425
757
        }
426
921
    }
427
428
194
    return NULL;
429
951
}
430
431
/**
432
 * @internal
433
 * @brief grows the local window and sends a packet to the other party
434
 * @param session SSH session
435
 * @param channel SSH channel
436
 * @return            SSH_OK if successful; SSH_ERROR otherwise.
437
 */
438
static int grow_window(ssh_session session,
439
                       ssh_channel channel)
440
0
{
441
0
  uint32_t used;
442
0
  uint32_t increment;
443
0
  int rc;
444
445
  /* Calculate the increment taking into account what the peer may still send
446
   * (local_window) and what we've already buffered (stdout_buffer and
447
   * stderr_buffer).
448
  */
449
0
  used = channel->local_window;
450
0
  if (channel->stdout_buffer != NULL) {
451
0
    used += ssh_buffer_get_len(channel->stdout_buffer);
452
0
  }
453
0
  if (channel->stderr_buffer != NULL) {
454
0
    used += ssh_buffer_get_len(channel->stderr_buffer);
455
0
  }
456
  /* Avoid a negative increment in case the peer sent more than the window allowed */
457
0
  increment = WINDOW_DEFAULT > used ? WINDOW_DEFAULT - used : 0;
458
  /* Don't grow until we can request at least half a window */
459
0
  if (increment < (WINDOW_DEFAULT / 2)) {
460
0
    SSH_LOG(SSH_LOG_DEBUG,
461
0
        "growing window (channel %" PRIu32 ":%" PRIu32 ") to %" PRIu32 " bytes : not needed (%" PRIu32 " bytes)",
462
0
        channel->local_channel, channel->remote_channel, WINDOW_DEFAULT,
463
0
        channel->local_window);
464
465
0
    return SSH_OK;
466
0
  }
467
468
0
  rc = ssh_buffer_pack(session->out_buffer,
469
0
                       "bdd",
470
0
                       SSH2_MSG_CHANNEL_WINDOW_ADJUST,
471
0
                       channel->remote_channel,
472
0
                       increment);
473
0
  if (rc != SSH_OK) {
474
0
    ssh_set_error_oom(session);
475
0
    goto error;
476
0
  }
477
478
0
  if (ssh_packet_send(session) == SSH_ERROR) {
479
0
    goto error;
480
0
  }
481
482
0
  SSH_LOG(SSH_LOG_DEBUG,
483
0
      "growing window (channel %" PRIu32 ":%" PRIu32 ") by %" PRIu32 " bytes",
484
0
      channel->local_channel,
485
0
      channel->remote_channel,
486
0
      increment);
487
488
0
  channel->local_window += increment;
489
490
0
  return SSH_OK;
491
0
error:
492
0
  ssh_buffer_reinit(session->out_buffer);
493
494
0
  return SSH_ERROR;
495
0
}
496
497
/**
498
 * @internal
499
 *
500
 * @brief Parse a channel-related packet to resolve it to a ssh_channel.
501
 *
502
 * @param[in]  session  The current SSH session.
503
 *
504
 * @param[in]  packet   The buffer to parse packet from. The read pointer will
505
 *                      be moved after the call.
506
 *
507
 * @return              The related ssh_channel, or NULL if the channel is
508
 *                      unknown or the packet is invalid.
509
 */
510
static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet)
511
1.14k
{
512
1.14k
    ssh_channel channel = NULL;
513
1.14k
    uint32_t chan;
514
1.14k
    int rc;
515
516
1.14k
    rc = ssh_buffer_unpack(packet, "d", &chan);
517
1.14k
    if (rc != SSH_OK) {
518
251
        ssh_set_error(session,
519
251
                      SSH_FATAL,
520
251
                      "Getting channel from message: short read");
521
251
        return NULL;
522
251
    }
523
524
897
    channel = ssh_channel_from_local(session, chan);
525
897
    if (channel == NULL) {
526
142
        ssh_set_error(session,
527
142
                      SSH_FATAL,
528
142
                      "Server specified invalid channel %" PRIu32,
529
142
                      (uint32_t)chan);
530
142
    }
531
532
897
    return channel;
533
1.14k
}
534
535
SSH_PACKET_CALLBACK(channel_rcv_change_window)
536
50
{
537
50
    ssh_channel channel = NULL;
538
50
    uint32_t bytes;
539
50
    int rc;
540
50
    bool was_empty;
541
542
50
    (void)user;
543
50
    (void)type;
544
545
50
    channel = channel_from_msg(session, packet);
546
50
    if (channel == NULL) {
547
5
        SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
548
5
    }
549
550
50
    rc = ssh_buffer_unpack(packet, "d", &bytes);
551
50
    if (channel == NULL || rc != SSH_OK) {
552
6
        SSH_LOG(SSH_LOG_PACKET,
553
6
                "Error getting a window adjust message: invalid packet");
554
555
6
        return SSH_PACKET_USED;
556
6
    }
557
558
44
    SSH_LOG(SSH_LOG_DEBUG,
559
44
            "Adding %" PRIu32 " bytes to channel (%" PRIu32 ":%" PRIu32
560
44
            ") (from %" PRIu32 " bytes)",
561
44
            bytes,
562
44
            channel->local_channel,
563
44
            channel->remote_channel,
564
44
            channel->remote_window);
565
566
44
    was_empty = channel->remote_window == 0;
567
568
44
    channel->remote_window += bytes;
569
570
    /* Writing to the channel is non-blocking until the receive window is empty.
571
     * When the receive window becomes non-zero again, call
572
     * channel_write_wontblock_function. */
573
44
    if (was_empty && bytes > 0) {
574
1
        ssh_callbacks_execute_list(channel->callbacks,
575
1
                                   ssh_channel_callbacks,
576
1
                                   channel_write_wontblock_function,
577
1
                                   session,
578
1
                                   channel,
579
1
                                   channel->remote_window);
580
1
    }
581
582
44
    return SSH_PACKET_USED;
583
50
}
584
585
/* is_stderr is set to 1 if the data are extended, ie stderr */
586
SSH_PACKET_CALLBACK(channel_rcv_data)
587
89
{
588
89
    ssh_channel channel = NULL;
589
89
    ssh_string str = NULL;
590
89
    ssh_buffer buf = NULL;
591
89
    void *data = NULL;
592
89
    uint32_t len;
593
89
    int extended, is_stderr = 0;
594
89
    int rest;
595
596
89
    (void)user;
597
598
89
    if (type == SSH2_MSG_CHANNEL_DATA) {
599
24
        extended = 0;
600
65
    } else { /* SSH_MSG_CHANNEL_EXTENDED_DATA */
601
65
        extended = 1;
602
65
    }
603
604
89
    channel = channel_from_msg(session, packet);
605
89
    if (channel == NULL) {
606
42
        SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
607
608
42
        return SSH_PACKET_USED;
609
42
    }
610
611
47
    if (extended) {
612
28
        uint32_t data_type_code, rc;
613
28
        rc = ssh_buffer_get_u32(packet, &data_type_code);
614
28
        if (rc != sizeof(uint32_t)) {
615
1
            SSH_LOG(SSH_LOG_PACKET,
616
1
                    "Failed to read data type code: rc = %" PRIu32, rc);
617
618
1
            return SSH_PACKET_USED;
619
1
        }
620
27
        is_stderr = 1;
621
27
        data_type_code = ntohl(data_type_code);
622
27
        if (data_type_code != SSH2_EXTENDED_DATA_STDERR) {
623
24
            SSH_LOG(SSH_LOG_PACKET, "Invalid data type code %" PRIu32 "!",
624
24
                    data_type_code);
625
24
        }
626
27
    }
627
628
46
    str = ssh_buffer_get_ssh_string(packet);
629
46
    if (str == NULL) {
630
26
        SSH_LOG(SSH_LOG_PACKET, "Invalid data packet!");
631
632
26
        return SSH_PACKET_USED;
633
26
    }
634
    /* STRING_SIZE_MAX < UINT32_MAX */
635
20
    len = (uint32_t)ssh_string_len(str);
636
637
20
    SSH_LOG(SSH_LOG_PACKET,
638
20
            "Channel receiving %" PRIu32 " bytes data%s (local win=%" PRIu32
639
20
            " remote win=%" PRIu32 ")",
640
20
            len,
641
20
            is_stderr ? " in stderr"  : "",
642
20
            channel->local_window,
643
20
            channel->remote_window);
644
645
20
    if (len > channel->local_window) {
646
0
        SSH_LOG(SSH_LOG_RARE,
647
0
                "Data packet too big for our window(%" PRIu32 " vs %" PRIu32 ")",
648
0
                len,
649
0
                channel->local_window);
650
651
0
        SSH_STRING_FREE(str);
652
653
0
        ssh_set_error(session, SSH_FATAL, "Window exceeded");
654
655
0
        return SSH_PACKET_USED;
656
0
    }
657
658
20
    data = ssh_string_data(str);
659
20
    if (channel_default_bufferize(channel, data, len, is_stderr) < 0) {
660
0
        SSH_STRING_FREE(str);
661
662
0
        return SSH_PACKET_USED;
663
0
    }
664
665
20
    channel->local_window -= len;
666
667
20
    SSH_LOG(SSH_LOG_PACKET,
668
20
            "Channel windows are now (local win=%" PRIu32 " remote win=%" PRIu32 ")",
669
20
            channel->local_window,
670
20
            channel->remote_window);
671
672
20
    SSH_STRING_FREE(str);
673
674
20
    if (is_stderr) {
675
5
        buf = channel->stderr_buffer;
676
15
    } else {
677
15
        buf = channel->stdout_buffer;
678
15
    }
679
680
20
    ssh_callbacks_iterate(channel->callbacks,
681
20
                          ssh_channel_callbacks,
682
20
                          channel_data_function) {
683
0
        if (ssh_buffer_get(buf) == NULL) {
684
0
            break;
685
0
        }
686
0
        rest = ssh_callbacks_iterate_exec(channel_data_function,
687
0
                                          channel->session,
688
0
                                          channel,
689
0
                                          ssh_buffer_get(buf),
690
0
                                          ssh_buffer_get_len(buf),
691
0
                                          is_stderr);
692
0
        if (rest > 0) {
693
0
            int rc;
694
0
            if (channel->counter != NULL) {
695
0
                channel->counter->in_bytes += rest;
696
0
            }
697
0
            ssh_buffer_pass_bytes(buf, rest);
698
699
0
            rc = grow_window(session, channel);
700
0
            if (rc == SSH_ERROR) {
701
0
              return -1;
702
0
            }
703
0
        }
704
0
    }
705
20
    ssh_callbacks_iterate_end();
706
707
20
    return SSH_PACKET_USED;
708
20
}
709
710
SSH_PACKET_CALLBACK(channel_rcv_eof)
711
204
{
712
204
    ssh_channel channel = NULL;
713
204
    (void)user;
714
204
    (void)type;
715
716
204
    channel = channel_from_msg(session, packet);
717
204
    if (channel == NULL) {
718
203
        SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
719
720
203
        return SSH_PACKET_USED;
721
203
    }
722
723
1
    SSH_LOG(SSH_LOG_PACKET,
724
1
            "Received eof on channel (%" PRIu32 ":%" PRIu32 ")",
725
1
            channel->local_channel,
726
1
            channel->remote_channel);
727
    /* channel->remote_window = 0; */
728
1
    channel->remote_eof = 1;
729
730
1
    ssh_callbacks_execute_list(channel->callbacks,
731
1
                               ssh_channel_callbacks,
732
1
                               channel_eof_function,
733
1
                               channel->session,
734
1
                               channel);
735
736
1
    return SSH_PACKET_USED;
737
204
}
738
739
static bool ssh_channel_has_unread_data(ssh_channel channel)
740
1
{
741
1
    if (channel == NULL) {
742
0
        return false;
743
0
    }
744
745
1
    if ((channel->stdout_buffer &&
746
1
         ssh_buffer_get_len(channel->stdout_buffer) > 0) ||
747
1
        (channel->stderr_buffer &&
748
1
         ssh_buffer_get_len(channel->stderr_buffer) > 0))
749
0
    {
750
0
        return true;
751
0
    }
752
753
1
    return false;
754
1
}
755
756
SSH_PACKET_CALLBACK(channel_rcv_close)
757
7
{
758
7
    ssh_channel channel = NULL;
759
7
    (void)user;
760
7
    (void)type;
761
762
7
    channel = channel_from_msg(session,packet);
763
7
    if (channel == NULL) {
764
6
        SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
765
766
6
        return SSH_PACKET_USED;
767
6
    }
768
769
1
    SSH_LOG(SSH_LOG_PACKET,
770
1
        "Received close on channel (%" PRIu32 ":%" PRIu32 ")",
771
1
        channel->local_channel,
772
1
        channel->remote_channel);
773
774
1
    if (!ssh_channel_has_unread_data(channel)) {
775
1
        channel->state = SSH_CHANNEL_STATE_CLOSED;
776
1
    } else {
777
0
        channel->delayed_close = 1;
778
0
    }
779
780
1
    if (channel->remote_eof == 0) {
781
1
        SSH_LOG(SSH_LOG_PACKET,
782
1
            "Remote host not polite enough to send an eof before close");
783
1
    }
784
    /*
785
    * The remote eof doesn't break things if there was still data into read
786
    * buffer because the eof is ignored until the buffer is empty.
787
    */
788
1
    channel->remote_eof = 1;
789
790
1
    ssh_callbacks_execute_list(channel->callbacks,
791
1
                               ssh_channel_callbacks,
792
1
                               channel_close_function,
793
1
                               channel->session,
794
1
                               channel);
795
796
1
    channel->flags |= SSH_CHANNEL_FLAG_CLOSED_REMOTE;
797
1
    if(channel->flags & SSH_CHANNEL_FLAG_FREED_LOCAL)
798
0
        ssh_channel_do_free(channel);
799
800
1
    return SSH_PACKET_USED;
801
7
}
802
803
SSH_PACKET_CALLBACK(channel_rcv_request)
804
672
{
805
672
    ssh_channel channel = NULL;
806
672
    char *request = NULL;
807
672
    uint8_t want_reply;
808
672
    int rc;
809
672
    (void)user;
810
672
    (void)type;
811
812
672
    channel = channel_from_msg(session, packet);
813
672
    if (channel == NULL) {
814
26
        SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
815
26
        return SSH_PACKET_USED;
816
26
    }
817
818
646
    rc = ssh_buffer_unpack(packet, "sb", &request, &want_reply);
819
646
    if (rc != SSH_OK) {
820
6
        SSH_LOG(SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST");
821
6
        return SSH_PACKET_USED;
822
6
    }
823
824
640
    if (strcmp(request, "exit-status") == 0) {
825
2
        SAFE_FREE(request);
826
2
        rc = ssh_buffer_unpack(packet, "d", &channel->exit.code);
827
2
        if (rc != SSH_OK) {
828
1
            SSH_LOG(SSH_LOG_PACKET, "Invalid exit-status packet");
829
1
            return SSH_PACKET_USED;
830
1
        }
831
1
        channel->exit.status = true;
832
833
1
        SSH_LOG(SSH_LOG_PACKET,
834
1
                "received exit-status %u",
835
1
                channel->exit.code);
836
837
1
        ssh_callbacks_execute_list(channel->callbacks,
838
1
                                   ssh_channel_callbacks,
839
1
                                   channel_exit_status_function,
840
1
                                   channel->session,
841
1
                                   channel,
842
1
                                   channel->exit.code);
843
844
1
        return SSH_PACKET_USED;
845
2
    }
846
847
638
    if (strcmp(request, "signal") == 0) {
848
2
        char *sig = NULL;
849
850
2
        SAFE_FREE(request);
851
2
        SSH_LOG(SSH_LOG_PACKET, "received signal");
852
853
2
        rc = ssh_buffer_unpack(packet, "s", &sig);
854
2
        if (rc != SSH_OK) {
855
1
            SSH_LOG(SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST");
856
1
            return SSH_PACKET_USED;
857
1
        }
858
859
1
        SSH_LOG(SSH_LOG_PACKET, "Remote connection sent a signal SIG %s", sig);
860
1
        ssh_callbacks_execute_list(channel->callbacks,
861
1
                                   ssh_channel_callbacks,
862
1
                                   channel_signal_function,
863
1
                                   channel->session,
864
1
                                   channel,
865
1
                                   sig);
866
1
        SAFE_FREE(sig);
867
868
1
        return SSH_PACKET_USED;
869
2
    }
870
871
636
    if (strcmp(request, "exit-signal") == 0) {
872
8
        const char *core = "(core dumped)";
873
8
        char *sig = NULL;
874
8
        char *errmsg = NULL;
875
8
        char *lang = NULL;
876
8
        uint8_t core_dumped;
877
878
8
        SAFE_FREE(request);
879
880
8
        rc = ssh_buffer_unpack(packet,
881
8
                               "sbss",
882
8
                               &sig,         /* signal name */
883
8
                               &core_dumped, /* core dumped */
884
8
                               &errmsg,      /* error message */
885
8
                               &lang);
886
8
        if (rc != SSH_OK) {
887
3
            SSH_LOG(SSH_LOG_PACKET, "Invalid MSG_CHANNEL_REQUEST");
888
3
            return SSH_PACKET_USED;
889
3
        }
890
891
5
        if (core_dumped == 0) {
892
3
            core = "";
893
3
        }
894
895
5
        SSH_LOG(SSH_LOG_PACKET,
896
5
                "Remote connection closed by signal SIG %s %s",
897
5
                sig,
898
5
                core);
899
5
        ssh_callbacks_execute_list(channel->callbacks,
900
5
                                   ssh_channel_callbacks,
901
5
                                   channel_exit_signal_function,
902
5
                                   channel->session,
903
5
                                   channel,
904
5
                                   sig,
905
5
                                   core_dumped,
906
5
                                   errmsg,
907
5
                                   lang);
908
909
5
        channel->exit.core_dumped = core_dumped;
910
5
        if (sig != NULL) {
911
5
            SAFE_FREE(channel->exit.signal);
912
5
            channel->exit.signal = sig;
913
5
        }
914
5
        channel->exit.status = true;
915
916
5
        SAFE_FREE(lang);
917
5
        SAFE_FREE(errmsg);
918
919
5
        return SSH_PACKET_USED;
920
8
    }
921
628
    if (strcmp(request, "keepalive@openssh.com") == 0) {
922
0
        SAFE_FREE(request);
923
0
        SSH_LOG(SSH_LOG_DEBUG, "Responding to Openssh's keepalive");
924
925
0
        rc = ssh_buffer_pack(session->out_buffer,
926
0
                             "bd",
927
0
                             SSH2_MSG_CHANNEL_FAILURE,
928
0
                             channel->remote_channel);
929
0
        if (rc != SSH_OK) {
930
0
            return SSH_PACKET_USED;
931
0
        }
932
0
        ssh_packet_send(session);
933
934
0
        return SSH_PACKET_USED;
935
0
    }
936
937
628
    if (strcmp(request, "auth-agent-req@openssh.com") == 0) {
938
0
        int status;
939
940
0
        SAFE_FREE(request);
941
0
        SSH_LOG(SSH_LOG_DEBUG, "Received an auth-agent-req request");
942
943
0
        status = SSH2_MSG_CHANNEL_FAILURE;
944
0
        ssh_callbacks_iterate (channel->callbacks,
945
0
                               ssh_channel_callbacks,
946
0
                               channel_auth_agent_req_function) {
947
0
            ssh_callbacks_iterate_exec(channel_auth_agent_req_function,
948
0
                                       channel->session,
949
0
                                       channel);
950
            /* in lieu of a return value, if the callback exists it's supported
951
             */
952
0
            status = SSH2_MSG_CHANNEL_SUCCESS;
953
0
            break;
954
0
        }
955
0
        ssh_callbacks_iterate_end();
956
957
0
        if (want_reply) {
958
0
            rc = ssh_buffer_pack(session->out_buffer,
959
0
                                 "bd",
960
0
                                 status,
961
0
                                 channel->remote_channel);
962
0
            if (rc != SSH_OK) {
963
0
                return SSH_PACKET_USED;
964
0
            }
965
0
            ssh_packet_send(session);
966
0
        }
967
968
0
        return SSH_PACKET_USED;
969
0
    }
970
628
#ifdef WITH_SERVER
971
    /* If we are here, that means we have a request that is not in the
972
     * understood client requests. That means we need to create a ssh message to
973
     * be passed to the user code handling ssh messages
974
     */
975
628
    ssh_message_handle_channel_request(session,
976
628
                                       channel,
977
628
                                       packet,
978
628
                                       request,
979
628
                                       want_reply);
980
#else
981
    SSH_LOG(SSH_LOG_DEBUG, "Unhandled channel request %s", request);
982
#endif
983
984
628
    SAFE_FREE(request);
985
986
628
    return SSH_PACKET_USED;
987
628
}
988
989
/*
990
 * When data has been received from the ssh server, it can be applied to the
991
 * known user function, with help of the callback, or inserted here
992
 *
993
 * FIXME is the window changed?
994
 */
995
int channel_default_bufferize(ssh_channel channel,
996
                              void *data, uint32_t len,
997
                              bool is_stderr)
998
20
{
999
20
    ssh_session session = NULL;
1000
1001
20
    if (channel == NULL) {
1002
0
        return -1;
1003
0
    }
1004
1005
20
    session = channel->session;
1006
1007
20
    if (data == NULL) {
1008
0
        ssh_set_error_invalid(session);
1009
0
        return -1;
1010
0
    }
1011
1012
20
    SSH_LOG(SSH_LOG_PACKET,
1013
20
            "placing %" PRIu32 " bytes into channel buffer (%s)",
1014
20
            len,
1015
20
            is_stderr ? "stderr" : "stdout");
1016
20
    if (!is_stderr) {
1017
        /* stdout */
1018
15
        if (channel->stdout_buffer == NULL) {
1019
0
            channel->stdout_buffer = ssh_buffer_new();
1020
0
            if (channel->stdout_buffer == NULL) {
1021
0
                ssh_set_error_oom(session);
1022
0
                return -1;
1023
0
            }
1024
0
        }
1025
1026
15
        if (ssh_buffer_add_data(channel->stdout_buffer, data, len) < 0) {
1027
0
            ssh_set_error_oom(session);
1028
0
            SSH_BUFFER_FREE(channel->stdout_buffer);
1029
0
            channel->stdout_buffer = NULL;
1030
0
            return -1;
1031
0
        }
1032
15
    } else {
1033
        /* stderr */
1034
5
        if (channel->stderr_buffer == NULL) {
1035
0
            channel->stderr_buffer = ssh_buffer_new();
1036
0
            if (channel->stderr_buffer == NULL) {
1037
0
                ssh_set_error_oom(session);
1038
0
                return -1;
1039
0
            }
1040
0
        }
1041
1042
5
        if (ssh_buffer_add_data(channel->stderr_buffer, data, len) < 0) {
1043
0
            ssh_set_error_oom(session);
1044
0
            SSH_BUFFER_FREE(channel->stderr_buffer);
1045
0
            channel->stderr_buffer = NULL;
1046
0
            return -1;
1047
0
        }
1048
5
    }
1049
1050
20
    return 0;
1051
20
}
1052
1053
/**
1054
 * @brief Open a session channel (suited for a shell, not TCP forwarding).
1055
 *
1056
 * @param[in]  channel  An allocated channel.
1057
 *
1058
 * @return              SSH_OK on success,
1059
 *                      SSH_ERROR if an error occurred,
1060
 *                      SSH_AGAIN if in nonblocking mode and call has
1061
 *                      to be done again.
1062
 *
1063
 * @see ssh_channel_open_forward()
1064
 * @see ssh_channel_request_env()
1065
 * @see ssh_channel_request_shell()
1066
 * @see ssh_channel_request_exec()
1067
 */
1068
int ssh_channel_open_session(ssh_channel channel)
1069
0
{
1070
0
  if (channel == NULL) {
1071
0
      return SSH_ERROR;
1072
0
  }
1073
1074
0
  return channel_open(channel,
1075
0
                      "session",
1076
0
                      WINDOW_DEFAULT,
1077
0
                      CHANNEL_MAX_PACKET,
1078
0
                      NULL);
1079
0
}
1080
1081
/**
1082
 * @brief Open an agent authentication forwarding channel. This type of channel
1083
 * can be opened by a server towards a client in order to provide SSH-Agent services
1084
 * to the server-side process. This channel can only be opened if the client
1085
 * claimed support by sending a channel request beforehand.
1086
 *
1087
 * @param[in]  channel  An allocated channel.
1088
 *
1089
 * @return              SSH_OK on success,
1090
 *                      SSH_ERROR if an error occurred,
1091
 *                      SSH_AGAIN if in nonblocking mode and call has
1092
 *                      to be done again.
1093
 *
1094
 * @see ssh_channel_open_forward()
1095
 */
1096
int ssh_channel_open_auth_agent(ssh_channel channel)
1097
0
{
1098
0
  if (channel == NULL) {
1099
0
      return SSH_ERROR;
1100
0
  }
1101
1102
0
  return channel_open(channel,
1103
0
                      "auth-agent@openssh.com",
1104
0
                      WINDOW_DEFAULT,
1105
0
                      CHANNEL_MAX_PACKET,
1106
0
                      NULL);
1107
0
}
1108
1109
1110
/**
1111
 * @brief Open a TCP/IP forwarding channel.
1112
 *
1113
 * @param[in]  channel  An allocated channel.
1114
 *
1115
 * @param[in]  remotehost The remote host to connected (host name or IP).
1116
 *
1117
 * @param[in]  remoteport The remote port.
1118
 *
1119
 * @param[in]  sourcehost The numeric IP address of the machine from where the
1120
 *                        connection request originates. This is mostly for
1121
 *                        logging purposes.
1122
 *
1123
 * @param[in]  localport  The port on the host from where the connection
1124
 *                        originated. This is mostly for logging purposes.
1125
 *
1126
 * @return              SSH_OK on success,
1127
 *                      SSH_ERROR if an error occurred,
1128
 *                      SSH_AGAIN if in nonblocking mode and call has
1129
 *                      to be done again.
1130
 *
1131
 * @warning This function does not bind the local port and does not automatically
1132
 *          forward the content of a socket to the channel. You still have to
1133
 *          use ssh_channel_read and ssh_channel_write for this.
1134
 */
1135
int ssh_channel_open_forward(ssh_channel channel, const char *remotehost,
1136
    int remoteport, const char *sourcehost, int localport)
1137
0
{
1138
0
    ssh_session session = NULL;
1139
0
    ssh_buffer payload = NULL;
1140
0
    ssh_string str = NULL;
1141
0
    int rc = SSH_ERROR;
1142
1143
0
    if (channel == NULL) {
1144
0
        return rc;
1145
0
    }
1146
1147
0
    session = channel->session;
1148
1149
0
    if (remotehost == NULL || sourcehost == NULL) {
1150
0
        ssh_set_error_invalid(session);
1151
0
        return rc;
1152
0
    }
1153
1154
0
    payload = ssh_buffer_new();
1155
0
    if (payload == NULL) {
1156
0
        ssh_set_error_oom(session);
1157
0
        goto error;
1158
0
    }
1159
1160
0
    rc = ssh_buffer_pack(payload,
1161
0
                         "sdsd",
1162
0
                         remotehost,
1163
0
                         remoteport,
1164
0
                         sourcehost,
1165
0
                         localport);
1166
0
    if (rc != SSH_OK) {
1167
0
        ssh_set_error_oom(session);
1168
0
        goto error;
1169
0
    }
1170
1171
0
    rc = channel_open(channel,
1172
0
                      "direct-tcpip",
1173
0
                      WINDOW_DEFAULT,
1174
0
                      CHANNEL_MAX_PACKET,
1175
0
                      payload);
1176
1177
0
error:
1178
0
    SSH_BUFFER_FREE(payload);
1179
0
    SSH_STRING_FREE(str);
1180
1181
0
    return rc;
1182
0
}
1183
1184
/**
1185
 * @brief Open a TCP/IP - UNIX domain socket forwarding channel.
1186
 *
1187
 * @param[in]  channel  An allocated channel.
1188
 *
1189
 * @param[in]  remotepath   The UNIX socket path on the remote machine
1190
 *
1191
 * @param[in]  sourcehost   The numeric IP address of the machine from where the
1192
 *                          connection request originates. This is mostly for
1193
 *                          logging purposes.
1194
 *
1195
 * @param[in]  localport    The port on the host from where the connection
1196
 *                          originated. This is mostly for logging purposes.
1197
 *
1198
 * @return              SSH_OK on success,
1199
 *                      SSH_ERROR if an error occurred,
1200
 *                      SSH_AGAIN if in nonblocking mode and call has
1201
 *                      to be done again.
1202
 *
1203
 * @warning This function does not bind the local port and does not
1204
 *          automatically forward the content of a socket to the channel.
1205
 *          You still have to use ssh_channel_read and ssh_channel_write for this.
1206
 * @warning Requires support of OpenSSH for UNIX domain socket forwarding.
1207
  */
1208
int ssh_channel_open_forward_unix(ssh_channel channel,
1209
                                  const char *remotepath,
1210
                                  const char *sourcehost,
1211
                                  int localport)
1212
0
{
1213
0
    ssh_session session = NULL;
1214
0
    ssh_buffer payload = NULL;
1215
0
    ssh_string str = NULL;
1216
0
    int rc = SSH_ERROR;
1217
0
    int version;
1218
1219
0
    if (channel == NULL) {
1220
0
        return rc;
1221
0
    }
1222
1223
0
    session = channel->session;
1224
1225
0
    version = ssh_get_openssh_version(session);
1226
0
    if (version == 0) {
1227
0
        ssh_set_error(session,
1228
0
                      SSH_REQUEST_DENIED,
1229
0
                      "We're not connected to an OpenSSH server!");
1230
0
        return SSH_ERROR;
1231
0
    }
1232
1233
0
    if (remotepath == NULL || sourcehost == NULL) {
1234
0
        ssh_set_error_invalid(session);
1235
0
        return rc;
1236
0
    }
1237
1238
0
    payload = ssh_buffer_new();
1239
0
    if (payload == NULL) {
1240
0
        ssh_set_error_oom(session);
1241
0
        goto error;
1242
0
    }
1243
1244
0
    rc = ssh_buffer_pack(payload,
1245
0
                         "ssd",
1246
0
                         remotepath,
1247
0
                         sourcehost,
1248
0
                         localport);
1249
0
    if (rc != SSH_OK) {
1250
0
        ssh_set_error_oom(session);
1251
0
        goto error;
1252
0
    }
1253
1254
0
    rc = channel_open(channel,
1255
0
                      "direct-streamlocal@openssh.com",
1256
0
                      WINDOW_DEFAULT,
1257
0
                      CHANNEL_MAX_PACKET,
1258
0
                      payload);
1259
1260
0
error:
1261
0
    SSH_BUFFER_FREE(payload);
1262
0
    SSH_STRING_FREE(str);
1263
1264
0
    return rc;
1265
0
}
1266
1267
/**
1268
 * @brief Close and free a channel.
1269
 *
1270
 * @param[in]  channel  The channel to free.
1271
 *
1272
 * @warning Any data unread on this channel will be lost.
1273
 */
1274
void ssh_channel_free(ssh_channel channel)
1275
3.57k
{
1276
3.57k
    ssh_session session = NULL;
1277
1278
3.57k
    if (channel == NULL) {
1279
3.57k
        return;
1280
3.57k
    }
1281
1282
0
    session = channel->session;
1283
0
    if (session->alive) {
1284
0
        bool send_close = false;
1285
1286
0
        switch (channel->state) {
1287
0
        case SSH_CHANNEL_STATE_OPEN:
1288
0
            send_close = true;
1289
0
            break;
1290
0
        case SSH_CHANNEL_STATE_CLOSED:
1291
0
            if (channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE) {
1292
0
                send_close = true;
1293
0
            }
1294
0
            if (channel->flags & SSH_CHANNEL_FLAG_CLOSED_LOCAL) {
1295
0
                send_close = false;
1296
0
            }
1297
0
            break;
1298
0
        default:
1299
0
            send_close = false;
1300
0
            break;
1301
0
        }
1302
1303
0
        if (send_close) {
1304
0
            ssh_channel_close(channel);
1305
0
        }
1306
0
    }
1307
0
    channel->flags |= SSH_CHANNEL_FLAG_FREED_LOCAL;
1308
1309
0
    if (channel->callbacks != NULL) {
1310
0
        ssh_list_free(channel->callbacks);
1311
0
        channel->callbacks = NULL;
1312
0
    }
1313
1314
    /* The idea behind the flags is the following : it is well possible
1315
     * that a client closes a channel that still exists on the server side.
1316
     * We definitively close the channel when we receive a close message *and*
1317
     * the user closed it.
1318
     */
1319
0
    if ((channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE) ||
1320
0
        (channel->flags & SSH_CHANNEL_FLAG_NOT_BOUND)) {
1321
0
        ssh_channel_do_free(channel);
1322
0
    }
1323
0
}
1324
1325
/**
1326
 * @internal
1327
 * @brief Effectively free a channel, without caring about flags
1328
 */
1329
1330
void ssh_channel_do_free(ssh_channel channel)
1331
865
{
1332
865
    struct ssh_iterator *it = NULL;
1333
865
    ssh_session session = channel->session;
1334
1335
865
    it = ssh_list_find(session->channels, channel);
1336
865
    if (it != NULL) {
1337
865
        ssh_list_remove(session->channels, it);
1338
865
    }
1339
1340
865
    SSH_BUFFER_FREE(channel->stdout_buffer);
1341
865
    SSH_BUFFER_FREE(channel->stderr_buffer);
1342
1343
865
    if (channel->callbacks != NULL) {
1344
0
        ssh_list_free(channel->callbacks);
1345
0
        channel->callbacks = NULL;
1346
0
    }
1347
865
    SAFE_FREE(channel->exit.signal);
1348
1349
865
    channel->session = NULL;
1350
865
    SAFE_FREE(channel);
1351
865
}
1352
1353
/**
1354
 * @brief Send an end of file on the channel.
1355
 *
1356
 * This doesn't close the channel. You may still read from it but not write.
1357
 *
1358
 * @param[in]  channel  The channel to send the eof to.
1359
 *
1360
 * @return              SSH_OK on success, SSH_ERROR if an error occurred.
1361
 *
1362
 * Example:
1363
@code
1364
   rc = ssh_channel_send_eof(channel);
1365
   if (rc == SSH_ERROR) {
1366
       return -1;
1367
   }
1368
   while(!ssh_channel_is_eof(channel)) {
1369
       rc = ssh_channel_read(channel, buf, sizeof(buf), 0);
1370
       if (rc == SSH_ERROR) {
1371
           return -1;
1372
       }
1373
   }
1374
   ssh_channel_close(channel);
1375
@endcode
1376
 *
1377
 * @see ssh_channel_close()
1378
 * @see ssh_channel_free()
1379
 * @see ssh_channel_is_eof()
1380
 */
1381
int ssh_channel_send_eof(ssh_channel channel)
1382
0
{
1383
0
    ssh_session session = NULL;
1384
0
    int rc = SSH_ERROR;
1385
0
    int err;
1386
1387
0
    if (channel == NULL || channel->session == NULL) {
1388
0
        return rc;
1389
0
    }
1390
1391
    /* If the EOF has already been sent we're done here. */
1392
0
    if (channel->local_eof != 0) {
1393
0
        return SSH_OK;
1394
0
    }
1395
1396
0
    session = channel->session;
1397
1398
0
    err = ssh_buffer_pack(session->out_buffer,
1399
0
                          "bd",
1400
0
                          SSH2_MSG_CHANNEL_EOF,
1401
0
                          channel->remote_channel);
1402
0
    if (err != SSH_OK) {
1403
0
        ssh_set_error_oom(session);
1404
0
        goto error;
1405
0
    }
1406
1407
0
    rc = ssh_packet_send(session);
1408
0
    SSH_LOG(SSH_LOG_PACKET,
1409
0
        "Sent a EOF on client channel (%" PRIu32 ":%" PRIu32 ")",
1410
0
        channel->local_channel,
1411
0
        channel->remote_channel);
1412
0
    if (rc != SSH_OK) {
1413
0
        goto error;
1414
0
    }
1415
1416
0
    rc = ssh_channel_flush(channel);
1417
0
    if (rc == SSH_ERROR) {
1418
0
        goto error;
1419
0
    }
1420
0
    channel->local_eof = 1;
1421
1422
0
    return rc;
1423
0
error:
1424
0
    ssh_buffer_reinit(session->out_buffer);
1425
1426
0
    return rc;
1427
0
}
1428
1429
/**
1430
 * @brief Close a channel.
1431
 *
1432
 * This sends an end of file and then closes the channel. You won't be able
1433
 * to recover any data the server was going to send or was in buffers.
1434
 *
1435
 * @param[in]  channel  The channel to close.
1436
 *
1437
 * @return              SSH_OK on success, SSH_ERROR if an error occurred.
1438
 *
1439
 * @see ssh_channel_free()
1440
 * @see ssh_channel_is_eof()
1441
 */
1442
int ssh_channel_close(ssh_channel channel)
1443
0
{
1444
0
    ssh_session session = NULL;
1445
0
    int rc = 0;
1446
1447
0
    if(channel == NULL) {
1448
0
        return SSH_ERROR;
1449
0
    }
1450
1451
    /* If the channel close has already been sent we're done here. */
1452
0
    if (channel->flags & SSH_CHANNEL_FLAG_CLOSED_LOCAL) {
1453
0
        return SSH_OK;
1454
0
    }
1455
1456
0
    session = channel->session;
1457
1458
0
    rc = ssh_channel_send_eof(channel);
1459
0
    if (rc != SSH_OK) {
1460
0
        return rc;
1461
0
    }
1462
1463
0
    rc = ssh_buffer_pack(session->out_buffer,
1464
0
                         "bd",
1465
0
                         SSH2_MSG_CHANNEL_CLOSE,
1466
0
                         channel->remote_channel);
1467
0
    if (rc != SSH_OK) {
1468
0
        ssh_set_error_oom(session);
1469
0
        goto error;
1470
0
    }
1471
1472
0
    rc = ssh_packet_send(session);
1473
0
    SSH_LOG(SSH_LOG_PACKET,
1474
0
            "Sent a close on client channel (%" PRIu32 ":%" PRIu32 ")",
1475
0
            channel->local_channel,
1476
0
            channel->remote_channel);
1477
1478
0
    if (rc == SSH_OK) {
1479
0
        channel->state = SSH_CHANNEL_STATE_CLOSED;
1480
0
        channel->flags |= SSH_CHANNEL_FLAG_CLOSED_LOCAL;
1481
0
    }
1482
1483
0
    rc = ssh_channel_flush(channel);
1484
0
    if(rc == SSH_ERROR) {
1485
0
        goto error;
1486
0
    }
1487
1488
0
    return rc;
1489
0
error:
1490
0
    ssh_buffer_reinit(session->out_buffer);
1491
1492
0
    return rc;
1493
0
}
1494
1495
/* this termination function waits for a window growing condition */
1496
static int ssh_channel_waitwindow_termination(void *c)
1497
0
{
1498
0
  ssh_channel channel = (ssh_channel) c;
1499
0
  if (channel->remote_window > 0 ||
1500
0
      channel->session->session_state == SSH_SESSION_STATE_ERROR ||
1501
0
      channel->state == SSH_CHANNEL_STATE_CLOSED)
1502
0
    return 1;
1503
0
  else
1504
0
    return 0;
1505
0
}
1506
1507
/* This termination function waits until the session is not in blocked status
1508
 * anymore, e.g. because of a key re-exchange.
1509
 */
1510
static int ssh_waitsession_unblocked(void *s)
1511
0
{
1512
0
    ssh_session session = (ssh_session)s;
1513
0
    switch (session->session_state){
1514
0
        case SSH_SESSION_STATE_DH:
1515
0
        case SSH_SESSION_STATE_INITIAL_KEX:
1516
0
        case SSH_SESSION_STATE_KEXINIT_RECEIVED:
1517
0
            return 0;
1518
0
        default:
1519
0
            return 1;
1520
0
    }
1521
0
}
1522
/**
1523
 * @internal
1524
 * @brief Flushes a channel (and its session) until the output buffer
1525
 *        is empty, or timeout elapsed.
1526
 * @param channel SSH channel
1527
 * @return  SSH_OK On success,
1528
 *          SSH_ERROR On error.
1529
 *          SSH_AGAIN Timeout elapsed (or in nonblocking mode).
1530
 */
1531
int ssh_channel_flush(ssh_channel channel)
1532
0
{
1533
0
    return ssh_blocking_flush(channel->session, SSH_TIMEOUT_DEFAULT);
1534
0
}
1535
1536
static int channel_write_common(ssh_channel channel,
1537
                                const void *data,
1538
                                uint32_t len, int is_stderr)
1539
0
{
1540
0
    ssh_session session = NULL;
1541
0
    uint32_t origlen = len;
1542
0
    uint32_t effectivelen;
1543
0
    int rc;
1544
1545
0
    if (channel == NULL) {
1546
0
        return -1;
1547
0
    }
1548
0
    session = channel->session;
1549
0
    if (data == NULL) {
1550
0
        ssh_set_error_invalid(session);
1551
0
        return -1;
1552
0
    }
1553
1554
0
    if (len > INT_MAX) {
1555
0
        SSH_LOG(SSH_LOG_TRACE,
1556
0
                "Length (%" PRIu32 ") is bigger than INT_MAX",
1557
0
                len);
1558
0
        return SSH_ERROR;
1559
0
    }
1560
1561
0
    if (channel->local_eof) {
1562
0
        ssh_set_error(session,
1563
0
                      SSH_REQUEST_DENIED,
1564
0
                      "Can't write to channel %" PRIu32 ":%" PRIu32
1565
0
                      " after EOF was sent",
1566
0
                      channel->local_channel,
1567
0
                      channel->remote_channel);
1568
0
        return -1;
1569
0
    }
1570
1571
0
    if (channel->state != SSH_CHANNEL_STATE_OPEN ||
1572
0
        channel->delayed_close != 0) {
1573
0
        ssh_set_error(session, SSH_REQUEST_DENIED, "Remote channel is closed");
1574
1575
0
        return -1;
1576
0
    }
1577
1578
0
    if (session->session_state == SSH_SESSION_STATE_ERROR) {
1579
0
        return SSH_ERROR;
1580
0
    }
1581
1582
0
    if (ssh_waitsession_unblocked(session) == 0) {
1583
0
        rc = ssh_handle_packets_termination(session,
1584
0
                                            SSH_TIMEOUT_DEFAULT,
1585
0
                                            ssh_waitsession_unblocked,
1586
0
                                            session);
1587
0
        if (rc == SSH_ERROR || !ssh_waitsession_unblocked(session))
1588
0
            goto out;
1589
0
    }
1590
0
    while (len > 0) {
1591
0
        if (channel->remote_window < len) {
1592
0
            SSH_LOG(SSH_LOG_DEBUG,
1593
0
                    "Remote window is %" PRIu32
1594
0
                    " bytes. going to write %" PRIu32 " bytes",
1595
0
                    channel->remote_window,
1596
0
                    len);
1597
            /* When the window is zero, wait for it to grow */
1598
0
            if (channel->remote_window == 0) {
1599
                /* nothing can be written */
1600
0
                SSH_LOG(SSH_LOG_DEBUG, "Wait for a growing window message...");
1601
0
                rc = ssh_handle_packets_termination(
1602
0
                    session,
1603
0
                    SSH_TIMEOUT_DEFAULT,
1604
0
                    ssh_channel_waitwindow_termination,
1605
0
                    channel);
1606
0
                if (rc == SSH_ERROR ||
1607
0
                    !ssh_channel_waitwindow_termination(channel) ||
1608
0
                    session->session_state == SSH_SESSION_STATE_ERROR ||
1609
0
                    channel->state == SSH_CHANNEL_STATE_CLOSED)
1610
0
                    goto out;
1611
0
                continue;
1612
0
            }
1613
            /* When the window is non-zero, accept data up to the window size */
1614
0
            effectivelen = MIN(len, channel->remote_window);
1615
0
        } else {
1616
0
            effectivelen = len;
1617
0
        }
1618
1619
        /*
1620
         * Like OpenSSH, don't subtract bytes for the header fields
1621
         * and allow to send a payload of remote_maxpacket length.
1622
         */
1623
0
        effectivelen = MIN(effectivelen, channel->remote_maxpacket);
1624
1625
0
        rc = ssh_buffer_pack(session->out_buffer,
1626
0
                             "bd",
1627
0
                             is_stderr ? SSH2_MSG_CHANNEL_EXTENDED_DATA
1628
0
                                       : SSH2_MSG_CHANNEL_DATA,
1629
0
                             channel->remote_channel);
1630
0
        if (rc != SSH_OK) {
1631
0
            ssh_set_error_oom(session);
1632
0
            goto error;
1633
0
        }
1634
1635
        /* stderr message has an extra field */
1636
0
        if (is_stderr) {
1637
0
            rc = ssh_buffer_pack(session->out_buffer,
1638
0
                                 "d",
1639
0
                                 SSH2_EXTENDED_DATA_STDERR);
1640
0
            if (rc != SSH_OK) {
1641
0
                ssh_set_error_oom(session);
1642
0
                goto error;
1643
0
            }
1644
0
        }
1645
1646
        /* append payload data */
1647
0
        rc = ssh_buffer_pack(session->out_buffer,
1648
0
                             "dP",
1649
0
                             effectivelen,
1650
0
                             (size_t)effectivelen,
1651
0
                             data);
1652
0
        if (rc != SSH_OK) {
1653
0
            ssh_set_error_oom(session);
1654
0
            goto error;
1655
0
        }
1656
1657
0
        rc = ssh_packet_send(session);
1658
0
        if (rc == SSH_ERROR) {
1659
0
            return SSH_ERROR;
1660
0
        }
1661
1662
0
        SSH_LOG(SSH_LOG_PACKET,
1663
0
                "ssh_channel_write wrote %" PRIu32 " bytes",
1664
0
                effectivelen);
1665
1666
0
        channel->remote_window -= effectivelen;
1667
0
        len -= effectivelen;
1668
0
        data = ((uint8_t *)data + effectivelen);
1669
0
        if (channel->counter != NULL) {
1670
0
            channel->counter->out_bytes += effectivelen;
1671
0
        }
1672
0
    }
1673
1674
    /* it's a good idea to flush the socket now */
1675
0
    rc = ssh_channel_flush(channel);
1676
0
    if (rc == SSH_ERROR) {
1677
0
        goto error;
1678
0
    }
1679
1680
0
out:
1681
0
    return (int)(origlen - len);
1682
1683
0
error:
1684
0
    ssh_buffer_reinit(session->out_buffer);
1685
1686
0
    return SSH_ERROR;
1687
0
}
1688
1689
/**
1690
 * @brief Get the remote window size.
1691
 *
1692
 * This is the maximum amount of bytes the remote side expects us to send
1693
 * before growing the window again.
1694
 *
1695
 * @param[in] channel The channel to query.
1696
 *
1697
 * @return            The remote window size
1698
 *
1699
 * @warning A nonzero return value does not guarantee the socket is ready
1700
 *          to send that much data. Buffering may happen in the local SSH
1701
 *          packet buffer, so beware of really big window sizes.
1702
 *
1703
 * @warning A zero return value means ssh_channel_write (default settings)
1704
 *          will block until the window grows back.
1705
 */
1706
uint32_t ssh_channel_window_size(ssh_channel channel)
1707
0
{
1708
0
    return channel->remote_window;
1709
0
}
1710
1711
/**
1712
 * @brief Blocking write on a channel.
1713
 *
1714
 * @param[in]  channel  The channel to write to.
1715
 *
1716
 * @param[in]  data     A pointer to the data to write.
1717
 *
1718
 * @param[in]  len      The length of the buffer to write to.
1719
 *
1720
 * @return              The number of bytes written, SSH_ERROR on error.
1721
 *
1722
 * @see ssh_channel_read()
1723
 */
1724
int ssh_channel_write(ssh_channel channel, const void *data, uint32_t len)
1725
0
{
1726
0
    return channel_write_common(channel, data, len, 0);
1727
0
}
1728
1729
/**
1730
 * @brief Check if the channel is open or not.
1731
 *
1732
 * @param[in]  channel  The channel to check.
1733
 *
1734
 * @return              0 if channel is closed, nonzero otherwise.
1735
 *
1736
 * @see ssh_channel_is_closed()
1737
 */
1738
int ssh_channel_is_open(ssh_channel channel)
1739
0
{
1740
0
    if (channel == NULL) {
1741
0
        return 0;
1742
0
    }
1743
0
    return (channel->state == SSH_CHANNEL_STATE_OPEN && channel->session->alive != 0);
1744
0
}
1745
1746
/**
1747
 * @brief Check if the channel is closed or not.
1748
 *
1749
 * @param[in]  channel  The channel to check.
1750
 *
1751
 * @return              0 if channel is opened, nonzero otherwise.
1752
 *
1753
 * @see ssh_channel_is_open()
1754
 */
1755
int ssh_channel_is_closed(ssh_channel channel)
1756
0
{
1757
0
    if (channel == NULL || channel->session == NULL) {
1758
0
        return SSH_ERROR;
1759
0
    }
1760
0
    return (channel->state != SSH_CHANNEL_STATE_OPEN || channel->session->alive == 0);
1761
0
}
1762
1763
/**
1764
 * @brief Check if remote has sent an EOF.
1765
 *
1766
 * @param[in]  channel  The channel to check.
1767
 *
1768
 * @return              0 if there is no EOF, nonzero otherwise.
1769
 */
1770
int ssh_channel_is_eof(ssh_channel channel)
1771
0
{
1772
0
    if (channel == NULL) {
1773
0
        return SSH_ERROR;
1774
0
    }
1775
0
    if (ssh_channel_has_unread_data(channel)) {
1776
0
        return 0;
1777
0
    }
1778
1779
0
    return (channel->remote_eof != 0);
1780
0
}
1781
1782
/**
1783
 * @brief Put the channel into blocking or nonblocking mode.
1784
 *
1785
 * @param[in]  channel  The channel to use.
1786
 *
1787
 * @param[in]  blocking A boolean for blocking or nonblocking.
1788
 *
1789
 * @warning    A side-effect of this is to put the whole session
1790
 *             in non-blocking mode.
1791
 * @see ssh_set_blocking()
1792
 */
1793
void ssh_channel_set_blocking(ssh_channel channel, int blocking)
1794
0
{
1795
0
    if (channel == NULL) {
1796
0
        return;
1797
0
    }
1798
0
    ssh_set_blocking(channel->session, blocking);
1799
0
}
1800
1801
/**
1802
 * @internal
1803
 *
1804
 * @brief handle a SSH_CHANNEL_SUCCESS packet and set the channel state.
1805
 */
1806
SSH_PACKET_CALLBACK(ssh_packet_channel_success)
1807
83
{
1808
83
    ssh_channel channel = NULL;
1809
83
    (void)type;
1810
83
    (void)user;
1811
1812
83
    channel = channel_from_msg(session, packet);
1813
83
    if (channel == NULL) {
1814
76
        SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
1815
76
        return SSH_PACKET_USED;
1816
76
    }
1817
1818
7
    SSH_LOG(SSH_LOG_PACKET,
1819
7
            "Received SSH_CHANNEL_SUCCESS on channel (%" PRIu32 ":%" PRIu32 ")",
1820
7
            channel->local_channel,
1821
7
            channel->remote_channel);
1822
7
    if (channel->request_state != SSH_CHANNEL_REQ_STATE_PENDING) {
1823
7
        SSH_LOG(SSH_LOG_RARE,
1824
7
                "SSH_CHANNEL_SUCCESS received in incorrect state %d",
1825
7
                channel->request_state);
1826
7
    } else {
1827
0
        channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED;
1828
1829
0
        ssh_callbacks_execute_list(channel->callbacks,
1830
0
                                   ssh_channel_callbacks,
1831
0
                                   channel_request_response_function,
1832
0
                                   channel->session,
1833
0
                                   channel);
1834
0
    }
1835
1836
7
    return SSH_PACKET_USED;
1837
83
}
1838
1839
/**
1840
 * @internal
1841
 *
1842
 * @brief Handle a SSH_CHANNEL_FAILURE packet and set the channel state.
1843
 */
1844
SSH_PACKET_CALLBACK(ssh_packet_channel_failure)
1845
20
{
1846
20
    ssh_channel channel = NULL;
1847
20
    (void)type;
1848
20
    (void)user;
1849
1850
20
    channel = channel_from_msg(session, packet);
1851
20
    if (channel == NULL) {
1852
19
        SSH_LOG(SSH_LOG_FUNCTIONS, "%s", ssh_get_error(session));
1853
1854
19
        return SSH_PACKET_USED;
1855
19
    }
1856
1857
1
    SSH_LOG(SSH_LOG_PACKET,
1858
1
            "Received SSH_CHANNEL_FAILURE on channel (%" PRIu32 ":%" PRIu32 ")",
1859
1
            channel->local_channel,
1860
1
            channel->remote_channel);
1861
1
    if (channel->request_state != SSH_CHANNEL_REQ_STATE_PENDING) {
1862
1
        SSH_LOG(SSH_LOG_RARE,
1863
1
                "SSH_CHANNEL_FAILURE received in incorrect state %d",
1864
1
                channel->request_state);
1865
1
    } else {
1866
0
        channel->request_state = SSH_CHANNEL_REQ_STATE_DENIED;
1867
1868
0
        ssh_callbacks_execute_list(channel->callbacks,
1869
0
                                   ssh_channel_callbacks,
1870
0
                                   channel_request_response_function,
1871
0
                                   channel->session,
1872
0
                                   channel);
1873
0
    }
1874
1875
1
    return SSH_PACKET_USED;
1876
20
}
1877
1878
static int ssh_channel_request_termination(void *c)
1879
0
{
1880
0
  ssh_channel channel = (ssh_channel)c;
1881
0
  if(channel->request_state != SSH_CHANNEL_REQ_STATE_PENDING ||
1882
0
      channel->session->session_state == SSH_SESSION_STATE_ERROR)
1883
0
    return 1;
1884
0
  else
1885
0
    return 0;
1886
0
}
1887
1888
static int channel_request(ssh_channel channel, const char *request,
1889
    ssh_buffer buffer, int reply)
1890
0
{
1891
0
  ssh_session session = channel->session;
1892
0
  int rc = SSH_ERROR;
1893
0
  int ret;
1894
1895
0
  switch(channel->request_state){
1896
0
  case SSH_CHANNEL_REQ_STATE_NONE:
1897
0
    break;
1898
0
  default:
1899
0
    goto pending;
1900
0
  }
1901
1902
0
  ret = ssh_buffer_pack(session->out_buffer,
1903
0
                        "bdsb",
1904
0
                        SSH2_MSG_CHANNEL_REQUEST,
1905
0
                        channel->remote_channel,
1906
0
                        request,
1907
0
                        reply == 0 ? 0 : 1);
1908
0
  if (ret != SSH_OK) {
1909
0
    ssh_set_error_oom(session);
1910
0
    goto error;
1911
0
  }
1912
1913
0
  if (buffer != NULL) {
1914
0
    if (ssh_buffer_add_data(session->out_buffer, ssh_buffer_get(buffer),
1915
0
        ssh_buffer_get_len(buffer)) < 0) {
1916
0
      ssh_set_error_oom(session);
1917
0
      goto error;
1918
0
    }
1919
0
  }
1920
0
  channel->request_state = SSH_CHANNEL_REQ_STATE_PENDING;
1921
0
  if (ssh_packet_send(session) == SSH_ERROR) {
1922
0
    return rc;
1923
0
  }
1924
1925
0
  SSH_LOG(SSH_LOG_PACKET,
1926
0
      "Sent a SSH_MSG_CHANNEL_REQUEST %s", request);
1927
0
  if (reply == 0) {
1928
0
    channel->request_state = SSH_CHANNEL_REQ_STATE_NONE;
1929
0
    return SSH_OK;
1930
0
  }
1931
0
pending:
1932
0
  rc = ssh_handle_packets_termination(session,
1933
0
                                      SSH_TIMEOUT_DEFAULT,
1934
0
                                      ssh_channel_request_termination,
1935
0
                                      channel);
1936
1937
0
  if(session->session_state == SSH_SESSION_STATE_ERROR || rc == SSH_ERROR) {
1938
0
      channel->request_state = SSH_CHANNEL_REQ_STATE_ERROR;
1939
0
  }
1940
  /* we received something */
1941
0
  switch (channel->request_state){
1942
0
    case SSH_CHANNEL_REQ_STATE_ERROR:
1943
0
      rc=SSH_ERROR;
1944
0
      break;
1945
0
    case SSH_CHANNEL_REQ_STATE_DENIED:
1946
0
      ssh_set_error(session, SSH_REQUEST_DENIED,
1947
0
          "Channel request %s failed", request);
1948
0
      rc=SSH_ERROR;
1949
0
      break;
1950
0
    case SSH_CHANNEL_REQ_STATE_ACCEPTED:
1951
0
      SSH_LOG(SSH_LOG_DEBUG,
1952
0
          "Channel request %s success",request);
1953
0
      rc=SSH_OK;
1954
0
      break;
1955
0
    case SSH_CHANNEL_REQ_STATE_PENDING:
1956
0
      rc = SSH_AGAIN;
1957
0
      return rc;
1958
0
    case SSH_CHANNEL_REQ_STATE_NONE:
1959
      /* Never reached */
1960
0
      ssh_set_error(session, SSH_FATAL, "Invalid state in channel_request()");
1961
0
      rc=SSH_ERROR;
1962
0
      break;
1963
0
  }
1964
0
  channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
1965
1966
0
  return rc;
1967
0
error:
1968
0
  ssh_buffer_reinit(session->out_buffer);
1969
1970
0
  return rc;
1971
0
}
1972
1973
/**
1974
 * @brief Request a pty with a specific type and size.
1975
 *
1976
 * @param[in]  channel  The channel to send the request.
1977
 *
1978
 * @param[in]  terminal The terminal type ("vt100, xterm,...").
1979
 *
1980
 * @param[in]  col      The number of columns.
1981
 *
1982
 * @param[in]  row      The number of rows.
1983
 *
1984
 * @param[in]  modes    Encoded SSH terminal modes for the PTY
1985
 *
1986
 * @param[in]  modes_len Number of bytes in 'modes'
1987
 *
1988
 * @return              SSH_OK on success,
1989
 *                      SSH_ERROR if an error occurred,
1990
 *                      SSH_AGAIN if in nonblocking mode and call has
1991
 *                      to be done again.
1992
 */
1993
int ssh_channel_request_pty_size_modes(ssh_channel channel, const char *terminal,
1994
    int col, int row, const unsigned char* modes, size_t modes_len)
1995
0
{
1996
0
    ssh_session session = NULL;
1997
0
    ssh_buffer buffer = NULL;
1998
0
    int rc = SSH_ERROR;
1999
2000
0
    if (channel == NULL) {
2001
0
        return SSH_ERROR;
2002
0
    }
2003
0
    session = channel->session;
2004
2005
0
    if (terminal == NULL) {
2006
0
        ssh_set_error_invalid(channel->session);
2007
0
        return rc;
2008
0
    }
2009
2010
0
    switch (channel->request_state) {
2011
0
    case SSH_CHANNEL_REQ_STATE_NONE:
2012
0
        break;
2013
0
    default:
2014
0
        goto pending;
2015
0
    }
2016
2017
0
    buffer = ssh_buffer_new();
2018
0
    if (buffer == NULL) {
2019
0
        ssh_set_error_oom(session);
2020
0
        goto error;
2021
0
    }
2022
2023
0
    rc = ssh_buffer_pack(buffer,
2024
0
                         "sdddddP",
2025
0
                         terminal,
2026
0
                         col,
2027
0
                         row,
2028
0
                         0, /* pix */
2029
0
                         0, /* pix */
2030
0
                         (uint32_t)modes_len,
2031
0
                         (size_t)modes_len,
2032
0
                         modes);
2033
2034
0
    if (rc != SSH_OK) {
2035
0
        ssh_set_error_oom(session);
2036
0
        goto error;
2037
0
    }
2038
0
pending:
2039
0
    rc = channel_request(channel, "pty-req", buffer, 1);
2040
0
error:
2041
0
    SSH_BUFFER_FREE(buffer);
2042
2043
0
    return rc;
2044
0
}
2045
2046
int ssh_channel_request_pty_size(ssh_channel channel, const char *terminal,
2047
    int col, int row)
2048
0
{
2049
    /* use modes from the current TTY */
2050
0
    unsigned char modes_buf[SSH_TTY_MODES_MAX_BUFSIZE];
2051
0
    int rc = encode_current_tty_opts(modes_buf, sizeof(modes_buf));
2052
0
    if (rc < 0) {
2053
0
        return rc;
2054
0
    }
2055
0
    return ssh_channel_request_pty_size_modes(channel,
2056
0
                                              terminal,
2057
0
                                              col,
2058
0
                                              row,
2059
0
                                              modes_buf,
2060
0
                                              (size_t)rc);
2061
0
}
2062
2063
/**
2064
 * @brief Request a PTY.
2065
 *
2066
 * @param[in]  channel  The channel to send the request.
2067
 *
2068
 * @return              SSH_OK on success,
2069
 *                      SSH_ERROR if an error occurred,
2070
 *                      SSH_AGAIN if in nonblocking mode and call has
2071
 *                      to be done again.
2072
 *
2073
 * @see ssh_channel_request_pty_size()
2074
 */
2075
int ssh_channel_request_pty(ssh_channel channel)
2076
0
{
2077
0
  return ssh_channel_request_pty_size(channel, "xterm", 80, 24);
2078
0
}
2079
2080
/**
2081
 * @brief Change the size of the terminal associated to a channel.
2082
 *
2083
 * @param[in]  channel  The channel to change the size.
2084
 *
2085
 * @param[in]  cols     The new number of columns.
2086
 *
2087
 * @param[in]  rows     The new number of rows.
2088
 *
2089
 * @return              SSH_OK on success, SSH_ERROR if an error occurred.
2090
 *
2091
 * @warning Do not call it from a signal handler if you are not sure any other
2092
 *          libssh function using the same channel/session is running at the
2093
 *          same time (not 100% threadsafe).
2094
 */
2095
int ssh_channel_change_pty_size(ssh_channel channel, int cols, int rows)
2096
0
{
2097
0
  ssh_session session = channel->session;
2098
0
  ssh_buffer buffer = NULL;
2099
0
  int rc = SSH_ERROR;
2100
2101
0
  buffer = ssh_buffer_new();
2102
0
  if (buffer == NULL) {
2103
0
    ssh_set_error_oom(session);
2104
0
    goto error;
2105
0
  }
2106
2107
0
  rc = ssh_buffer_pack(buffer,
2108
0
                       "dddd",
2109
0
                       cols,
2110
0
                       rows,
2111
0
                       0, /* pix */
2112
0
                       0 /* pix */);
2113
0
  if (rc != SSH_OK) {
2114
0
    ssh_set_error_oom(session);
2115
0
    goto error;
2116
0
  }
2117
2118
0
  rc = channel_request(channel, "window-change", buffer, 0);
2119
0
error:
2120
0
  SSH_BUFFER_FREE(buffer);
2121
2122
0
  return rc;
2123
0
}
2124
2125
/**
2126
 * @brief Request a shell.
2127
 *
2128
 * @param[in]  channel  The channel to send the request.
2129
 *
2130
 * @return              SSH_OK on success,
2131
 *                      SSH_ERROR if an error occurred,
2132
 *                      SSH_AGAIN if in nonblocking mode and call has
2133
 *                      to be done again.
2134
 */
2135
int ssh_channel_request_shell(ssh_channel channel)
2136
0
{
2137
0
    if (channel == NULL) {
2138
0
        return SSH_ERROR;
2139
0
    }
2140
2141
0
    return channel_request(channel, "shell", NULL, 1);
2142
0
}
2143
2144
/**
2145
 * @brief Request a subsystem (for example "sftp").
2146
 *
2147
 * @param[in]  channel  The channel to send the request.
2148
 *
2149
 * @param[in]  subsys   The subsystem to request (for example "sftp").
2150
 *
2151
 * @return              SSH_OK on success,
2152
 *                      SSH_ERROR if an error occurred,
2153
 *                      SSH_AGAIN if in nonblocking mode and call has
2154
 *                      to be done again.
2155
 *
2156
 * @warning You normally don't have to call it for sftp, see sftp_new().
2157
 */
2158
int ssh_channel_request_subsystem(ssh_channel channel, const char *subsys)
2159
0
{
2160
0
  ssh_buffer buffer = NULL;
2161
0
  int rc = SSH_ERROR;
2162
2163
0
  if(channel == NULL) {
2164
0
      return SSH_ERROR;
2165
0
  }
2166
0
  if(subsys == NULL) {
2167
0
      ssh_set_error_invalid(channel->session);
2168
0
      return rc;
2169
0
  }
2170
0
  switch(channel->request_state){
2171
0
  case SSH_CHANNEL_REQ_STATE_NONE:
2172
0
    break;
2173
0
  default:
2174
0
    goto pending;
2175
0
  }
2176
2177
0
  buffer = ssh_buffer_new();
2178
0
  if (buffer == NULL) {
2179
0
    ssh_set_error_oom(channel->session);
2180
0
    goto error;
2181
0
  }
2182
2183
0
  rc = ssh_buffer_pack(buffer, "s", subsys);
2184
0
  if (rc != SSH_OK) {
2185
0
    ssh_set_error_oom(channel->session);
2186
0
    goto error;
2187
0
  }
2188
0
pending:
2189
0
  rc = channel_request(channel, "subsystem", buffer, 1);
2190
0
error:
2191
0
  SSH_BUFFER_FREE(buffer);
2192
2193
0
  return rc;
2194
0
}
2195
2196
/**
2197
 * @brief Request sftp subsystem on the channel
2198
 *
2199
 * @param[in]  channel The channel to request the sftp subsystem.
2200
 *
2201
 * @return              SSH_OK on success,
2202
 *                      SSH_ERROR if an error occurred,
2203
 *                      SSH_AGAIN if in nonblocking mode and call has
2204
 *                      to be done again.
2205
 *
2206
 * @note You should use sftp_new() which does this for you.
2207
 */
2208
int ssh_channel_request_sftp( ssh_channel channel)
2209
0
{
2210
0
    if(channel == NULL) {
2211
0
        return SSH_ERROR;
2212
0
    }
2213
0
    return ssh_channel_request_subsystem(channel, "sftp");
2214
0
}
2215
2216
static char *generate_cookie(void)
2217
0
{
2218
0
  static const char *hex = "0123456789abcdef";
2219
0
  char s[36];
2220
0
  unsigned char rnd[16];
2221
0
  int ok;
2222
0
  int i;
2223
2224
0
  ok = ssh_get_random(rnd, sizeof(rnd), 0);
2225
0
  if (!ok) {
2226
0
      return NULL;
2227
0
  }
2228
2229
0
  for (i = 0; i < 16; i++) {
2230
0
    s[i*2] = hex[rnd[i] & 0x0f];
2231
0
    s[i*2+1] = hex[rnd[i] >> 4];
2232
0
  }
2233
0
  s[32] = '\0';
2234
0
  return strdup(s);
2235
0
}
2236
2237
/**
2238
 * @brief Sends the "x11-req" channel request over an existing session channel.
2239
 *
2240
 * This will enable redirecting the display of the remote X11 applications to
2241
 * local X server over a secure tunnel.
2242
 *
2243
 * @param[in]  channel  An existing session channel where the remote X11
2244
 *                      applications are going to be executed.
2245
 *
2246
 * @param[in]  single_connection A boolean to mark only one X11 app will be
2247
 *                               redirected.
2248
 *
2249
 * @param[in]  protocol A x11 authentication protocol. Pass NULL to use the
2250
 *                      default value MIT-MAGIC-COOKIE-1.
2251
 *
2252
 * @param[in]  cookie   A x11 authentication cookie. Pass NULL to generate
2253
 *                      a random cookie.
2254
 *
2255
 * @param[in] screen_number The screen number.
2256
 *
2257
 * @return              SSH_OK on success,
2258
 *                      SSH_ERROR if an error occurred,
2259
 *                      SSH_AGAIN if in nonblocking mode and call has
2260
 *                      to be done again.
2261
 */
2262
int ssh_channel_request_x11(ssh_channel channel, int single_connection, const char *protocol,
2263
    const char *cookie, int screen_number)
2264
0
{
2265
0
  ssh_buffer buffer = NULL;
2266
0
  char *c = NULL;
2267
0
  int rc = SSH_ERROR;
2268
2269
0
  if(channel == NULL) {
2270
0
      return SSH_ERROR;
2271
0
  }
2272
0
  switch(channel->request_state){
2273
0
  case SSH_CHANNEL_REQ_STATE_NONE:
2274
0
    break;
2275
0
  default:
2276
0
    goto pending;
2277
0
  }
2278
2279
0
  buffer = ssh_buffer_new();
2280
0
  if (buffer == NULL) {
2281
0
    ssh_set_error_oom(channel->session);
2282
0
    goto error;
2283
0
  }
2284
2285
0
  if (cookie == NULL) {
2286
0
    c = generate_cookie();
2287
0
    if (c == NULL) {
2288
0
      ssh_set_error_oom(channel->session);
2289
0
      goto error;
2290
0
    }
2291
0
  }
2292
2293
0
  rc = ssh_buffer_pack(buffer,
2294
0
                       "bssd",
2295
0
                       single_connection == 0 ? 0 : 1,
2296
0
                       protocol ? protocol : "MIT-MAGIC-COOKIE-1",
2297
0
                       cookie ? cookie : c,
2298
0
                       screen_number);
2299
0
  if (c != NULL){
2300
0
      SAFE_FREE(c);
2301
0
  }
2302
0
  if (rc != SSH_OK) {
2303
0
    ssh_set_error_oom(channel->session);
2304
0
    goto error;
2305
0
  }
2306
0
pending:
2307
0
  rc = channel_request(channel, "x11-req", buffer, 1);
2308
2309
0
error:
2310
0
  SSH_BUFFER_FREE(buffer);
2311
0
  return rc;
2312
0
}
2313
2314
static ssh_channel ssh_channel_accept(ssh_session session, int channeltype,
2315
    int timeout_ms, int *destination_port, char **originator, int *originator_port)
2316
0
{
2317
0
#ifndef _WIN32
2318
0
  static const struct timespec ts = {
2319
0
    .tv_sec = 0,
2320
0
    .tv_nsec = 50000000 /* 50ms */
2321
0
  };
2322
0
#endif
2323
0
  ssh_message msg = NULL;
2324
0
  ssh_channel channel = NULL;
2325
0
  struct ssh_iterator *iterator = NULL;
2326
0
  int t;
2327
2328
  /*
2329
   * We sleep for 50 ms in ssh_handle_packets() and later sleep for
2330
   * 50 ms. So we need to decrement by 100 ms.
2331
   */
2332
0
  for (t = timeout_ms; t >= 0; t -= 100) {
2333
0
    if (timeout_ms == 0) {
2334
0
        ssh_handle_packets(session, 0);
2335
0
    } else {
2336
0
        ssh_handle_packets(session, 50);
2337
0
    }
2338
2339
0
    if (session->ssh_message_list) {
2340
0
      iterator = ssh_list_get_iterator(session->ssh_message_list);
2341
0
      while (iterator) {
2342
0
        msg = (ssh_message)iterator->data;
2343
0
        if (ssh_message_type(msg) == SSH_REQUEST_CHANNEL_OPEN &&
2344
0
            ssh_message_subtype(msg) == channeltype) {
2345
0
          ssh_list_remove(session->ssh_message_list, iterator);
2346
0
          channel = ssh_message_channel_request_open_reply_accept(msg);
2347
0
          if(destination_port) {
2348
0
            *destination_port=msg->channel_request_open.destination_port;
2349
0
          }
2350
0
          if(originator) {
2351
0
            *originator=strdup(msg->channel_request_open.originator);
2352
0
          }
2353
0
          if(originator_port) {
2354
0
            *originator_port=msg->channel_request_open.originator_port;
2355
0
          }
2356
2357
0
          ssh_message_free(msg);
2358
0
          return channel;
2359
0
        }
2360
0
        iterator = iterator->next;
2361
0
      }
2362
0
    }
2363
0
    if(t>0){
2364
#ifdef _WIN32
2365
      Sleep(50); /* 50ms */
2366
#else
2367
0
      nanosleep(&ts, NULL);
2368
0
#endif
2369
0
    }
2370
0
  }
2371
2372
0
  ssh_set_error(session, SSH_NO_ERROR, "No channel request of this type from server");
2373
0
  return NULL;
2374
0
}
2375
2376
/**
2377
 * @brief Accept an X11 forwarding channel.
2378
 *
2379
 * @param[in]  channel  An x11-enabled session channel.
2380
 *
2381
 * @param[in]  timeout_ms Timeout in milliseconds.
2382
 *
2383
 * @return              A newly created channel, or NULL if no X11 request from
2384
 *                      the server.
2385
 */
2386
ssh_channel ssh_channel_accept_x11(ssh_channel channel, int timeout_ms)
2387
0
{
2388
0
    return ssh_channel_accept(channel->session, SSH_CHANNEL_X11, timeout_ms, NULL, NULL, NULL);
2389
0
}
2390
2391
/**
2392
 * @brief Send an "auth-agent-req" channel request over an existing session channel.
2393
 *
2394
 * This client-side request will enable forwarding the agent over an secure tunnel.
2395
 * When the server is ready to open one authentication agent channel, an
2396
 * ssh_channel_open_request_auth_agent_callback event will be generated.
2397
 *
2398
 * @param[in]  channel  The channel to send signal.
2399
 *
2400
 * @return              SSH_OK on success, SSH_ERROR if an error occurred
2401
 */
2402
0
int ssh_channel_request_auth_agent(ssh_channel channel) {
2403
0
  if (channel == NULL) {
2404
0
    return SSH_ERROR;
2405
0
  }
2406
2407
0
  return channel_request(channel, "auth-agent-req@openssh.com", NULL, 0);
2408
0
}
2409
2410
/**
2411
 * @internal
2412
 *
2413
 * @brief Handle a SSH_REQUEST_SUCCESS packet normally sent after a global
2414
 * request.
2415
 */
2416
3
SSH_PACKET_CALLBACK(ssh_request_success){
2417
3
  (void)type;
2418
3
  (void)user;
2419
3
  (void)packet;
2420
2421
3
  SSH_LOG(SSH_LOG_PACKET,
2422
3
      "Received SSH_REQUEST_SUCCESS");
2423
3
  if(session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING){
2424
3
    SSH_LOG(SSH_LOG_RARE, "SSH_REQUEST_SUCCESS received in incorrect state %d",
2425
3
        session->global_req_state);
2426
3
  } else {
2427
0
    session->global_req_state=SSH_CHANNEL_REQ_STATE_ACCEPTED;
2428
0
  }
2429
2430
3
  return SSH_PACKET_USED;
2431
3
}
2432
2433
/**
2434
 * @internal
2435
 *
2436
 * @brief Handle a SSH_REQUEST_DENIED packet normally sent after a global
2437
 * request.
2438
 */
2439
6
SSH_PACKET_CALLBACK(ssh_request_denied){
2440
6
  (void)type;
2441
6
  (void)user;
2442
6
  (void)packet;
2443
2444
6
  SSH_LOG(SSH_LOG_PACKET,
2445
6
      "Received SSH_REQUEST_FAILURE");
2446
6
  if(session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING){
2447
6
    SSH_LOG(SSH_LOG_RARE, "SSH_REQUEST_DENIED received in incorrect state %d",
2448
6
        session->global_req_state);
2449
6
  } else {
2450
0
    session->global_req_state=SSH_CHANNEL_REQ_STATE_DENIED;
2451
0
  }
2452
2453
6
  return SSH_PACKET_USED;
2454
2455
6
}
2456
2457
static int ssh_global_request_termination(void *s)
2458
0
{
2459
0
  ssh_session session = (ssh_session) s;
2460
0
  if (session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING ||
2461
0
      session->session_state == SSH_SESSION_STATE_ERROR)
2462
0
    return 1;
2463
0
  else
2464
0
    return 0;
2465
0
}
2466
2467
/**
2468
 * @internal
2469
 *
2470
 * @brief Send a global request (needed for forward listening) and wait for the
2471
 * result.
2472
 *
2473
 * @param[in]  session  The SSH session handle.
2474
 *
2475
 * @param[in]  request  The type of request (defined in RFC).
2476
 *
2477
 * @param[in]  buffer   Additional data to put in packet.
2478
 *
2479
 * @param[in]  reply    Set if you expect a reply from server.
2480
 *
2481
 * @return              SSH_OK on success,
2482
 *                      SSH_ERROR if an error occurred,
2483
 *                      SSH_AGAIN if in nonblocking mode and call has
2484
 *                      to be done again.
2485
 */
2486
int ssh_global_request(ssh_session session,
2487
                       const char *request,
2488
                       ssh_buffer buffer,
2489
                       int reply)
2490
0
{
2491
0
  int rc;
2492
2493
0
  switch (session->global_req_state) {
2494
0
  case SSH_CHANNEL_REQ_STATE_NONE:
2495
0
    break;
2496
0
  default:
2497
0
    goto pending;
2498
0
  }
2499
2500
0
  rc = ssh_buffer_pack(session->out_buffer,
2501
0
                       "bsb",
2502
0
                       SSH2_MSG_GLOBAL_REQUEST,
2503
0
                       request,
2504
0
                       reply == 0 ? 0 : 1);
2505
0
  if (rc != SSH_OK){
2506
0
      ssh_set_error_oom(session);
2507
0
      rc = SSH_ERROR;
2508
0
      goto error;
2509
0
  }
2510
2511
0
  if (buffer != NULL) {
2512
0
      rc = ssh_buffer_add_data(session->out_buffer,
2513
0
                           ssh_buffer_get(buffer),
2514
0
                           ssh_buffer_get_len(buffer));
2515
0
      if (rc < 0) {
2516
0
          ssh_set_error_oom(session);
2517
0
          rc = SSH_ERROR;
2518
0
          goto error;
2519
0
      }
2520
0
  }
2521
2522
0
  session->global_req_state = SSH_CHANNEL_REQ_STATE_PENDING;
2523
0
  rc = ssh_packet_send(session);
2524
0
  if (rc == SSH_ERROR) {
2525
0
      return rc;
2526
0
  }
2527
2528
0
  SSH_LOG(SSH_LOG_PACKET,
2529
0
      "Sent a SSH_MSG_GLOBAL_REQUEST %s", request);
2530
2531
0
  if (reply == 0) {
2532
0
      session->global_req_state = SSH_CHANNEL_REQ_STATE_NONE;
2533
2534
0
      return SSH_OK;
2535
0
  }
2536
0
pending:
2537
0
  rc = ssh_handle_packets_termination(session,
2538
0
                                      SSH_TIMEOUT_DEFAULT,
2539
0
                                      ssh_global_request_termination,
2540
0
                                      session);
2541
2542
0
  if(rc==SSH_ERROR || session->session_state == SSH_SESSION_STATE_ERROR){
2543
0
    session->global_req_state = SSH_CHANNEL_REQ_STATE_ERROR;
2544
0
  }
2545
0
  switch(session->global_req_state){
2546
0
    case SSH_CHANNEL_REQ_STATE_ACCEPTED:
2547
0
      SSH_LOG(SSH_LOG_DEBUG, "Global request %s success",request);
2548
0
      rc=SSH_OK;
2549
0
      break;
2550
0
    case SSH_CHANNEL_REQ_STATE_DENIED:
2551
0
      SSH_LOG(SSH_LOG_PACKET,
2552
0
          "Global request %s failed", request);
2553
0
      ssh_set_error(session, SSH_REQUEST_DENIED,
2554
0
          "Global request %s failed", request);
2555
0
      rc=SSH_ERROR;
2556
0
      break;
2557
0
    case SSH_CHANNEL_REQ_STATE_ERROR:
2558
0
    case SSH_CHANNEL_REQ_STATE_NONE:
2559
0
      rc = SSH_ERROR;
2560
0
      break;
2561
0
    case SSH_CHANNEL_REQ_STATE_PENDING:
2562
0
      return SSH_AGAIN;
2563
0
  }
2564
0
  session->global_req_state = SSH_CHANNEL_REQ_STATE_NONE;
2565
2566
0
  return rc;
2567
0
error:
2568
0
  ssh_buffer_reinit(session->out_buffer);
2569
2570
0
  return rc;
2571
0
}
2572
2573
/**
2574
 * @brief Sends the "tcpip-forward" global request to ask the server to begin
2575
 *        listening for inbound connections.
2576
 *
2577
 * @param[in]  session  The ssh session to send the request.
2578
 *
2579
 * @param[in]  address  The address to bind to on the server. Pass NULL to bind
2580
 *                      to all available addresses on all protocol families
2581
 *                      supported by the server.
2582
 *
2583
 * @param[in]  port     The port to bind to on the server. Pass 0 to ask the
2584
 *                      server to allocate the next available unprivileged port
2585
 *                      number
2586
 *
2587
 * @param[in]  bound_port The pointer to get actual bound port. Pass NULL to
2588
 *                        ignore.
2589
 *
2590
 * @return              SSH_OK on success,
2591
 *                      SSH_ERROR if an error occurred,
2592
 *                      SSH_AGAIN if in nonblocking mode and call has
2593
 *                      to be done again.
2594
 **/
2595
int ssh_channel_listen_forward(ssh_session session,
2596
                               const char *address,
2597
                               int port,
2598
                               int *bound_port)
2599
0
{
2600
0
  ssh_buffer buffer = NULL;
2601
0
  int rc = SSH_ERROR;
2602
2603
0
  if(session->global_req_state != SSH_CHANNEL_REQ_STATE_NONE)
2604
0
    goto pending;
2605
2606
0
  buffer = ssh_buffer_new();
2607
0
  if (buffer == NULL) {
2608
0
    ssh_set_error_oom(session);
2609
0
    goto error;
2610
0
  }
2611
2612
0
  rc = ssh_buffer_pack(buffer,
2613
0
                       "sd",
2614
0
                       address ? address : "",
2615
0
                       port);
2616
0
  if (rc != SSH_OK){
2617
0
    ssh_set_error_oom(session);
2618
0
    goto error;
2619
0
  }
2620
0
pending:
2621
0
  rc = ssh_global_request(session, "tcpip-forward", buffer, 1);
2622
2623
  /* TODO: FIXME no guarantee the last packet we received contains
2624
   * that info */
2625
0
  if (rc == SSH_OK && port == 0 && bound_port != NULL) {
2626
0
    rc = ssh_buffer_unpack(session->in_buffer, "d", bound_port);
2627
0
    if (rc != SSH_OK)
2628
0
        *bound_port = 0;
2629
0
  }
2630
2631
0
error:
2632
0
  SSH_BUFFER_FREE(buffer);
2633
0
  return rc;
2634
0
}
2635
2636
/* DEPRECATED */
2637
int ssh_forward_listen(ssh_session session, const char *address, int port, int *bound_port)
2638
0
{
2639
0
  return ssh_channel_listen_forward(session, address, port, bound_port);
2640
0
}
2641
2642
/* DEPRECATED */
2643
ssh_channel ssh_forward_accept(ssh_session session, int timeout_ms)
2644
0
{
2645
0
    return ssh_channel_accept(session, SSH_CHANNEL_FORWARDED_TCPIP, timeout_ms, NULL, NULL, NULL);
2646
0
}
2647
2648
/**
2649
 * @brief Accept an incoming TCP/IP forwarding channel and get some information
2650
 * about incoming connection
2651
 *
2652
 * @param[in]  session    The ssh session to use.
2653
 *
2654
 * @param[in]  timeout_ms A timeout in milliseconds.
2655
 *
2656
 * @param[in]  destination_port A pointer to destination port or NULL.
2657
 *
2658
 * @return Newly created channel, or NULL if no incoming channel request from
2659
 *         the server
2660
 */
2661
0
ssh_channel ssh_channel_accept_forward(ssh_session session, int timeout_ms, int* destination_port) {
2662
0
  return ssh_channel_accept(session, SSH_CHANNEL_FORWARDED_TCPIP, timeout_ms, destination_port, NULL, NULL);
2663
0
}
2664
2665
/**
2666
 * @brief Accept an incoming TCP/IP forwarding channel and get information
2667
 * about incoming connection
2668
 *
2669
 * @param[in]  session    The ssh session to use.
2670
 *
2671
 * @param[in]  timeout_ms A timeout in milliseconds.
2672
 *
2673
 * @param[out]  destination_port A pointer to destination port or NULL.
2674
 *
2675
 * @param[out]  originator A pointer to a pointer to a string of originator host or NULL.
2676
 *              That the caller is responsible for to ssh_string_free_char().
2677
 *
2678
 * @param[out]  originator_port A pointer to originator port or NULL.
2679
 *
2680
 * @return Newly created channel, or NULL if no incoming channel request from
2681
 *         the server
2682
 *
2683
 * @see ssh_string_free_char()
2684
 */
2685
0
ssh_channel ssh_channel_open_forward_port(ssh_session session, int timeout_ms, int *destination_port, char **originator, int *originator_port) {
2686
0
  return ssh_channel_accept(session, SSH_CHANNEL_FORWARDED_TCPIP, timeout_ms, destination_port, originator, originator_port);
2687
0
}
2688
2689
/**
2690
 * @brief Sends the "cancel-tcpip-forward" global request to ask the server to
2691
 *        cancel the tcpip-forward request.
2692
 *
2693
 * @param[in]  session  The ssh session to send the request.
2694
 *
2695
 * @param[in]  address  The bound address on the server.
2696
 *
2697
 * @param[in]  port     The bound port on the server.
2698
 *
2699
 * @return              SSH_OK on success,
2700
 *                      SSH_ERROR if an error occurred,
2701
 *                      SSH_AGAIN if in nonblocking mode and call has
2702
 *                      to be done again.
2703
 */
2704
int ssh_channel_cancel_forward(ssh_session session,
2705
                               const char *address,
2706
                               int port)
2707
0
{
2708
0
  ssh_buffer buffer = NULL;
2709
0
  int rc = SSH_ERROR;
2710
2711
0
  if(session->global_req_state != SSH_CHANNEL_REQ_STATE_NONE)
2712
0
    goto pending;
2713
2714
0
  buffer = ssh_buffer_new();
2715
0
  if (buffer == NULL) {
2716
0
    ssh_set_error_oom(session);
2717
0
    goto error;
2718
0
  }
2719
2720
0
  rc = ssh_buffer_pack(buffer, "sd",
2721
0
                       address ? address : "",
2722
0
                       port);
2723
0
  if (rc != SSH_OK){
2724
0
      ssh_set_error_oom(session);
2725
0
      goto error;
2726
0
  }
2727
0
pending:
2728
0
  rc = ssh_global_request(session, "cancel-tcpip-forward", buffer, 1);
2729
2730
0
error:
2731
0
  SSH_BUFFER_FREE(buffer);
2732
0
  return rc;
2733
0
}
2734
2735
/* DEPRECATED */
2736
int ssh_forward_cancel(ssh_session session, const char *address, int port)
2737
0
{
2738
0
    return ssh_channel_cancel_forward(session, address, port);
2739
0
}
2740
2741
/**
2742
 * @brief Set environment variables.
2743
 *
2744
 * @param[in]  channel  The channel to set the environment variables.
2745
 *
2746
 * @param[in]  name     The name of the variable.
2747
 *
2748
 * @param[in]  value    The value to set.
2749
 *
2750
 * @return              SSH_OK on success,
2751
 *                      SSH_ERROR if an error occurred,
2752
 *                      SSH_AGAIN if in nonblocking mode and call has
2753
 *                      to be done again.
2754
 * @warning Some environment variables may be refused by security reasons.
2755
 */
2756
int ssh_channel_request_env(ssh_channel channel, const char *name, const char *value)
2757
0
{
2758
0
  ssh_buffer buffer = NULL;
2759
0
  int rc = SSH_ERROR;
2760
2761
0
  if(channel == NULL) {
2762
0
      return SSH_ERROR;
2763
0
  }
2764
0
  if(name == NULL || value == NULL) {
2765
0
      ssh_set_error_invalid(channel->session);
2766
0
      return rc;
2767
0
  }
2768
0
  switch(channel->request_state){
2769
0
  case SSH_CHANNEL_REQ_STATE_NONE:
2770
0
    break;
2771
0
  default:
2772
0
    goto pending;
2773
0
  }
2774
0
  buffer = ssh_buffer_new();
2775
0
  if (buffer == NULL) {
2776
0
    ssh_set_error_oom(channel->session);
2777
0
    goto error;
2778
0
  }
2779
2780
0
  rc = ssh_buffer_pack(buffer,
2781
0
                       "ss",
2782
0
                       name,
2783
0
                       value);
2784
0
  if (rc != SSH_OK){
2785
0
    ssh_set_error_oom(channel->session);
2786
0
    goto error;
2787
0
  }
2788
0
pending:
2789
0
  rc = channel_request(channel, "env", buffer,1);
2790
0
error:
2791
0
  SSH_BUFFER_FREE(buffer);
2792
2793
0
  return rc;
2794
0
}
2795
2796
/**
2797
 * @brief Run a shell command without an interactive shell.
2798
 *
2799
 * This is similar to 'sh -c command'.
2800
 *
2801
 * @param[in]  channel  The channel to execute the command.
2802
 *
2803
 * @param[in]  cmd      The command to execute
2804
 *                      (e.g. "ls ~/ -al | grep -i reports").
2805
 *
2806
 * @return              SSH_OK on success,
2807
 *                      SSH_ERROR if an error occurred,
2808
 *                      SSH_AGAIN if in nonblocking mode and call has
2809
 *                      to be done again.
2810
 *
2811
 * Example:
2812
@code
2813
   rc = ssh_channel_request_exec(channel, "ps aux");
2814
   if (rc > 0) {
2815
       return -1;
2816
   }
2817
2818
   while ((rc = ssh_channel_read(channel, buffer, sizeof(buffer), 0)) > 0) {
2819
       if (fwrite(buffer, 1, rc, stdout) != (unsigned int) rc) {
2820
           return -1;
2821
       }
2822
   }
2823
@endcode
2824
 *
2825
 * @warning In a single channel, only ONE command can be executed!
2826
 * If you want to executed multiple commands, allocate separate channels for
2827
 * them or consider opening interactive shell.
2828
 * Attempting to run multiple consecutive commands in one channel will fail.
2829
 * See RFC 4254 Section 6.5.
2830
 *
2831
 * @see ssh_channel_request_shell()
2832
 */
2833
int ssh_channel_request_exec(ssh_channel channel, const char *cmd)
2834
0
{
2835
0
  ssh_buffer buffer = NULL;
2836
0
  int rc = SSH_ERROR;
2837
2838
0
  if(channel == NULL) {
2839
0
      return SSH_ERROR;
2840
0
  }
2841
0
  if(cmd == NULL) {
2842
0
      ssh_set_error_invalid(channel->session);
2843
0
      return rc;
2844
0
  }
2845
2846
0
  switch(channel->request_state){
2847
0
  case SSH_CHANNEL_REQ_STATE_NONE:
2848
0
    break;
2849
0
  default:
2850
0
    goto pending;
2851
0
  }
2852
0
  buffer = ssh_buffer_new();
2853
0
  if (buffer == NULL) {
2854
0
    ssh_set_error_oom(channel->session);
2855
0
    goto error;
2856
0
  }
2857
2858
0
  rc = ssh_buffer_pack(buffer, "s", cmd);
2859
2860
0
  if (rc != SSH_OK) {
2861
0
    ssh_set_error_oom(channel->session);
2862
0
    goto error;
2863
0
  }
2864
0
pending:
2865
0
  rc = channel_request(channel, "exec", buffer, 1);
2866
0
error:
2867
0
  SSH_BUFFER_FREE(buffer);
2868
0
  return rc;
2869
0
}
2870
2871
2872
/**
2873
 * @brief Send a signal to remote process (as described in RFC 4254, section 6.9).
2874
 *
2875
 * Sends a signal 'sig' to the remote process.
2876
 * Note, that remote system may not support signals concept.
2877
 * In such a case this request will be silently ignored.
2878
 *
2879
 * @param[in]  channel  The channel to send signal.
2880
 *
2881
 * @param[in]  sig      The signal to send (without SIG prefix)
2882
 *                      \n\n
2883
 *                      SIGABRT  -> ABRT \n
2884
 *                      SIGALRM  -> ALRM \n
2885
 *                      SIGFPE   -> FPE  \n
2886
 *                      SIGHUP   -> HUP  \n
2887
 *                      SIGILL   -> ILL  \n
2888
 *                      SIGINT   -> INT  \n
2889
 *                      SIGKILL  -> KILL \n
2890
 *                      SIGPIPE  -> PIPE \n
2891
 *                      SIGQUIT  -> QUIT \n
2892
 *                      SIGSEGV  -> SEGV \n
2893
 *                      SIGTERM  -> TERM \n
2894
 *                      SIGUSR1  -> USR1 \n
2895
 *                      SIGUSR2  -> USR2 \n
2896
 *
2897
 * @return              SSH_OK on success, SSH_ERROR if an error occurred.
2898
 */
2899
int ssh_channel_request_send_signal(ssh_channel channel, const char *sig)
2900
0
{
2901
0
  ssh_buffer buffer = NULL;
2902
0
  int rc = SSH_ERROR;
2903
2904
0
  if (channel == NULL) {
2905
0
      return SSH_ERROR;
2906
0
  }
2907
0
  if (sig == NULL) {
2908
0
      ssh_set_error_invalid(channel->session);
2909
0
      return rc;
2910
0
  }
2911
2912
0
  buffer = ssh_buffer_new();
2913
0
  if (buffer == NULL) {
2914
0
    ssh_set_error_oom(channel->session);
2915
0
    goto error;
2916
0
  }
2917
2918
0
  rc = ssh_buffer_pack(buffer, "s", sig);
2919
0
  if (rc != SSH_OK) {
2920
0
    ssh_set_error_oom(channel->session);
2921
0
    goto error;
2922
0
  }
2923
2924
0
  rc = channel_request(channel, "signal", buffer, 0);
2925
0
error:
2926
0
  SSH_BUFFER_FREE(buffer);
2927
0
  return rc;
2928
0
}
2929
2930
2931
/**
2932
 * @brief Send a break signal to the server (as described in RFC 4335).
2933
 *
2934
 * Sends a break signal to the remote process.
2935
 * Note, that remote system may not support breaks.
2936
 * In such a case this request will be silently ignored.
2937
 *
2938
 * @param[in]  channel  The channel to send the break to.
2939
 *
2940
 * @param[in]  length   The break-length in milliseconds to send.
2941
 *
2942
 * @return              SSH_OK on success, SSH_ERROR if an error occurred
2943
 */
2944
int ssh_channel_request_send_break(ssh_channel channel, uint32_t length)
2945
0
{
2946
0
    ssh_buffer buffer = NULL;
2947
0
    int rc = SSH_ERROR;
2948
2949
0
    if (channel == NULL) {
2950
0
        return SSH_ERROR;
2951
0
    }
2952
2953
0
    buffer = ssh_buffer_new();
2954
0
    if (buffer == NULL) {
2955
0
        ssh_set_error_oom(channel->session);
2956
0
        goto error;
2957
0
    }
2958
2959
0
    rc = ssh_buffer_pack(buffer, "d", length);
2960
0
    if (rc != SSH_OK) {
2961
0
        ssh_set_error_oom(channel->session);
2962
0
        goto error;
2963
0
    }
2964
2965
0
    rc = channel_request(channel, "break", buffer, 0);
2966
2967
0
error:
2968
0
    SSH_BUFFER_FREE(buffer);
2969
0
    return rc;
2970
0
}
2971
2972
/**
2973
 * @brief Read data from a channel into a buffer.
2974
 *
2975
 * @param[in]  channel  The channel to read from.
2976
 *
2977
 * @param[out]  buffer   The buffer which will get the data.
2978
 *
2979
 * @param[in]  count    The count of bytes to be read. If it is bigger than 0,
2980
 *                      the exact size will be read, else (bytes=0) it will
2981
 *                      return once anything is available.
2982
 *
2983
 * @param is_stderr     A boolean value to mark reading from the stderr stream.
2984
 *
2985
 * @return              The number of bytes read, 0 on end of file, SSH_AGAIN on
2986
 *                      timeout and SSH_ERROR on error.
2987
 * @deprecated          Please use ssh_channel_read instead
2988
 * @warning             This function doesn't work in nonblocking/timeout mode
2989
 * @see ssh_channel_read
2990
 */
2991
int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
2992
    int is_stderr)
2993
0
{
2994
0
    ssh_session session = NULL;
2995
0
    char *buffer_tmp = NULL;
2996
0
    int r;
2997
0
    uint32_t total = 0;
2998
2999
0
    if (channel == NULL) {
3000
0
        return SSH_ERROR;
3001
0
    }
3002
0
    session = channel->session;
3003
3004
0
    if (buffer == NULL) {
3005
0
        ssh_set_error_invalid(channel->session);
3006
0
        return SSH_ERROR;
3007
0
    }
3008
3009
0
    ssh_buffer_reinit(buffer);
3010
0
    if (count == 0) {
3011
0
        do {
3012
0
            r = ssh_channel_poll(channel, is_stderr);
3013
0
            if (r < 0) {
3014
0
                return r;
3015
0
            }
3016
0
            if (r > 0) {
3017
0
                count = r;
3018
0
                buffer_tmp = ssh_buffer_allocate(buffer, count);
3019
0
                if (buffer_tmp == NULL) {
3020
0
                    ssh_set_error_oom(session);
3021
0
                    return SSH_ERROR;
3022
0
                }
3023
0
                r = ssh_channel_read(channel, buffer_tmp, r, is_stderr);
3024
0
                if (r < 0) {
3025
0
                    ssh_buffer_pass_bytes_end(buffer, count);
3026
0
                    return r;
3027
0
                }
3028
                /* Rollback the unused space */
3029
0
                ssh_buffer_pass_bytes_end(buffer, count - r);
3030
3031
0
                return r;
3032
0
            }
3033
0
            if (ssh_channel_is_eof(channel)) {
3034
0
                return 0;
3035
0
            }
3036
0
            ssh_handle_packets(channel->session, SSH_TIMEOUT_INFINITE);
3037
0
        } while (r == 0);
3038
0
    }
3039
3040
0
    buffer_tmp = ssh_buffer_allocate(buffer, count);
3041
0
    if (buffer_tmp == NULL) {
3042
0
        ssh_set_error_oom(session);
3043
0
        return SSH_ERROR;
3044
0
    }
3045
0
    while (total < count) {
3046
0
        r = ssh_channel_read(channel, buffer_tmp, count - total, is_stderr);
3047
0
        if (r < 0) {
3048
0
            ssh_buffer_pass_bytes_end(buffer, count);
3049
0
            return r;
3050
0
        }
3051
0
        if (r == 0) {
3052
            /* Rollback the unused space */
3053
0
            ssh_buffer_pass_bytes_end(buffer, count - total);
3054
0
            return total;
3055
0
        }
3056
0
        total += r;
3057
0
    }
3058
3059
0
    return total;
3060
0
}
3061
3062
struct ssh_channel_read_termination_struct {
3063
  ssh_channel channel;
3064
  ssh_buffer buffer;
3065
};
3066
3067
static int ssh_channel_read_termination(void *s)
3068
0
{
3069
0
  struct ssh_channel_read_termination_struct *ctx = s;
3070
0
  if (ssh_buffer_get_len(ctx->buffer) >= 1 ||
3071
0
      ctx->channel->remote_eof ||
3072
0
      ctx->channel->session->session_state == SSH_SESSION_STATE_ERROR)
3073
0
    return 1;
3074
0
  else
3075
0
    return 0;
3076
0
}
3077
3078
/**
3079
 * @brief Reads data from a channel.
3080
 *
3081
 * @param[in]  channel  The channel to read from.
3082
 *
3083
 * @param[out] dest     The destination buffer which will get the data.
3084
 *
3085
 * @param[in]  count    The count of bytes to be read.
3086
 *
3087
 * @param[in]  is_stderr A boolean value to mark reading from the stderr flow.
3088
 *
3089
 * @return              The number of bytes read, 0 on end of file, SSH_AGAIN on
3090
 *                      timeout and SSH_ERROR on error.
3091
 *
3092
 * @warning This function may return less than count bytes of data, and won't
3093
 *          block until count bytes have been read.
3094
 */
3095
int ssh_channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr)
3096
0
{
3097
0
    return ssh_channel_read_timeout(channel,
3098
0
                                    dest,
3099
0
                                    count,
3100
0
                                    is_stderr,
3101
0
                                    SSH_TIMEOUT_DEFAULT);
3102
0
}
3103
3104
/**
3105
 * @brief Reads data from a channel.
3106
 *
3107
 * @param[in]  channel     The channel to read from.
3108
 *
3109
 * @param[out] dest        The destination buffer which will get the data.
3110
 *
3111
 * @param[in]  count       The count of bytes to be read.
3112
 *
3113
 * @param[in]  is_stderr   A boolean value to mark reading from the stderr flow.
3114
 *
3115
 * @param[in]  timeout_ms  A timeout in milliseconds. A value of -1 means
3116
 *                         infinite timeout.
3117
 *
3118
 * @return              The number of bytes read, 0 on end of file, SSH_AGAIN on
3119
 *                      timeout, SSH_ERROR on error.
3120
 *
3121
 * @warning This function may return less than count bytes of data, and won't
3122
 *          block until count bytes have been read.
3123
 */
3124
int ssh_channel_read_timeout(ssh_channel channel,
3125
                             void *dest,
3126
                             uint32_t count,
3127
                             int is_stderr,
3128
                             int timeout_ms)
3129
0
{
3130
0
    ssh_session session = NULL;
3131
0
    ssh_buffer stdbuf = NULL;
3132
0
    uint32_t len;
3133
0
    struct ssh_channel_read_termination_struct ctx;
3134
0
    int rc;
3135
3136
0
    if (channel == NULL) {
3137
0
        return SSH_ERROR;
3138
0
    }
3139
0
    if (dest == NULL) {
3140
0
        ssh_set_error_invalid(channel->session);
3141
0
        return SSH_ERROR;
3142
0
    }
3143
3144
0
    session = channel->session;
3145
0
    stdbuf = channel->stdout_buffer;
3146
3147
0
    if (count == 0) {
3148
0
        return 0;
3149
0
    }
3150
3151
0
    if (is_stderr) {
3152
0
        stdbuf = channel->stderr_buffer;
3153
0
    }
3154
3155
0
    SSH_LOG(SSH_LOG_PACKET,
3156
0
            "Read (%" PRIu32 ") buffered : %" PRIu32 " bytes. Window: %" PRIu32,
3157
0
            count,
3158
0
            ssh_buffer_get_len(stdbuf),
3159
0
            channel->local_window);
3160
3161
    /* block reading until at least one byte has been read
3162
     * and ignore the trivial case count=0
3163
     */
3164
0
    ctx.channel = channel;
3165
0
    ctx.buffer = stdbuf;
3166
3167
0
    if (timeout_ms < SSH_TIMEOUT_DEFAULT) {
3168
0
        timeout_ms = SSH_TIMEOUT_INFINITE;
3169
0
    }
3170
3171
0
    rc = ssh_handle_packets_termination(session,
3172
0
                                        timeout_ms,
3173
0
                                        ssh_channel_read_termination,
3174
0
                                        &ctx);
3175
0
    if (rc == SSH_ERROR || rc == SSH_AGAIN) {
3176
0
        return rc;
3177
0
    }
3178
3179
    /*
3180
     * If the channel is closed or in an error state, reading from it is an
3181
     * error
3182
     */
3183
0
    if (session->session_state == SSH_SESSION_STATE_ERROR) {
3184
0
        return SSH_ERROR;
3185
0
    }
3186
    /* If the server closed the channel properly, there is nothing to do */
3187
0
    if (channel->remote_eof && ssh_buffer_get_len(stdbuf) == 0) {
3188
0
        return 0;
3189
0
    }
3190
0
    if (channel->state == SSH_CHANNEL_STATE_CLOSED) {
3191
0
        ssh_set_error(session, SSH_FATAL, "Remote channel is closed.");
3192
0
        return SSH_ERROR;
3193
0
    }
3194
0
    len = ssh_buffer_get_len(stdbuf);
3195
    /* Read count bytes if len is greater, everything otherwise */
3196
0
    len = (len > count ? count : len);
3197
0
    memcpy(dest, ssh_buffer_get(stdbuf), len);
3198
0
    ssh_buffer_pass_bytes(stdbuf, len);
3199
0
    if (channel->counter != NULL) {
3200
0
        channel->counter->in_bytes += len;
3201
0
    }
3202
    /* Try completing the delayed_close */
3203
0
    if (channel->delayed_close && !ssh_channel_has_unread_data(channel)) {
3204
0
        channel->state = SSH_CHANNEL_STATE_CLOSED;
3205
0
    }
3206
3207
0
    rc = grow_window(session, channel);
3208
0
    if (rc == SSH_ERROR) {
3209
0
        return -1;
3210
0
    }
3211
3212
0
    return len;
3213
0
}
3214
3215
/**
3216
 * @brief Do a nonblocking read on the channel.
3217
 *
3218
 * A nonblocking read on the specified channel. it will return <= count bytes of
3219
 * data read atomically. It will also trigger any callbacks set on the channel.
3220
 *
3221
 * @param[in]  channel  The channel to read from.
3222
 *
3223
 * @param[out] dest     A pointer to a destination buffer.
3224
 *
3225
 * @param[in]  count    The count of bytes of data to be read.
3226
 *
3227
 * @param[in]  is_stderr A boolean to select the stderr stream.
3228
 *
3229
 * @return              The number of bytes read, SSH_AGAIN if nothing is
3230
 * available, SSH_ERROR on error, and SSH_EOF if the channel is EOF.
3231
 *
3232
 * @see ssh_channel_is_eof()
3233
 */
3234
int ssh_channel_read_nonblocking(ssh_channel channel,
3235
                                 void *dest,
3236
                                 uint32_t count,
3237
                                 int is_stderr)
3238
0
{
3239
0
    ssh_session session = NULL;
3240
0
    uint32_t to_read;
3241
0
    int rc;
3242
0
    int blocking;
3243
3244
0
    if(channel == NULL) {
3245
0
        return SSH_ERROR;
3246
0
    }
3247
0
    if(dest == NULL) {
3248
0
        ssh_set_error_invalid(channel->session);
3249
0
        return SSH_ERROR;
3250
0
    }
3251
3252
0
    session = channel->session;
3253
3254
0
    rc = ssh_channel_poll(channel, is_stderr);
3255
3256
0
    if (rc <= 0) {
3257
0
        if (session->session_state == SSH_SESSION_STATE_ERROR){
3258
0
            return SSH_ERROR;
3259
0
        }
3260
3261
0
        return rc; /* may be an error code */
3262
0
    }
3263
3264
0
    to_read = (unsigned int)rc;
3265
3266
0
    if (to_read > count) {
3267
0
        to_read = count;
3268
0
    }
3269
0
    blocking = ssh_is_blocking(session);
3270
0
    ssh_set_blocking(session, 0);
3271
0
    rc = ssh_channel_read(channel, dest, to_read, is_stderr);
3272
0
    ssh_set_blocking(session,blocking);
3273
3274
0
    return rc;
3275
0
}
3276
3277
/**
3278
 * @brief Polls a channel for data to read.
3279
 *
3280
 * If callbacks are set on the channel, they will be called.
3281
 *
3282
 * @param[in]  channel  The channel to poll.
3283
 *
3284
 * @param[in]  is_stderr A boolean to select the stderr stream.
3285
 *
3286
 * @return              The number of bytes available for reading, 0 if nothing
3287
 *                      is available or SSH_ERROR on error.
3288
 *                      When a channel is freed the function returns
3289
 *                      SSH_ERROR immediately.
3290
 *
3291
 * @warning When the channel is in EOF state, the function returns SSH_EOF.
3292
 *
3293
 * @see ssh_channel_is_eof()
3294
 */
3295
int ssh_channel_poll(ssh_channel channel, int is_stderr)
3296
0
{
3297
0
  ssh_buffer stdbuf;
3298
3299
0
  if ((channel == NULL) || (channel->flags & SSH_CHANNEL_FLAG_FREED_LOCAL)) {
3300
0
      return SSH_ERROR;
3301
0
  }
3302
3303
0
  stdbuf = channel->stdout_buffer;
3304
3305
0
  if (is_stderr) {
3306
0
    stdbuf = channel->stderr_buffer;
3307
0
  }
3308
3309
0
  if (channel->remote_eof == 0) {
3310
0
    if (channel->session->session_state == SSH_SESSION_STATE_ERROR){
3311
0
      return SSH_ERROR;
3312
0
    }
3313
0
    if (ssh_handle_packets(channel->session, SSH_TIMEOUT_NONBLOCKING)==SSH_ERROR) {
3314
0
      return SSH_ERROR;
3315
0
    }
3316
0
  }
3317
3318
0
  if (ssh_buffer_get_len(stdbuf) > 0){
3319
0
    return ssh_buffer_get_len(stdbuf);
3320
0
  }
3321
3322
0
  if (channel->remote_eof) {
3323
0
    return SSH_EOF;
3324
0
  }
3325
3326
0
  return ssh_buffer_get_len(stdbuf);
3327
0
}
3328
3329
/**
3330
 * @brief Polls a channel for data to read, waiting for a certain timeout.
3331
 *
3332
 * @param[in]  channel   The channel to poll.
3333
 * @param[in]  timeout   Set an upper limit on the time for which this function
3334
 *                       will block, in milliseconds. Specifying a negative value
3335
 *                       means an infinite timeout. This parameter is passed to
3336
 *                       the poll() function.
3337
 * @param[in]  is_stderr A boolean to select the stderr stream.
3338
 *
3339
 * @return              The number of bytes available for reading,
3340
 *                      0 if nothing is available (timeout elapsed),
3341
 *                      SSH_EOF on end of file,
3342
 *                      SSH_ERROR on error.
3343
 *
3344
 * @warning When the channel is in EOF state, the function returns SSH_EOF.
3345
 *          When a channel is freed the function returns SSH_ERROR immediately.
3346
 *
3347
 * @see ssh_channel_is_eof()
3348
 */
3349
int ssh_channel_poll_timeout(ssh_channel channel, int timeout, int is_stderr)
3350
0
{
3351
0
    ssh_session session = NULL;
3352
0
    ssh_buffer stdbuf = NULL;
3353
0
    struct ssh_channel_read_termination_struct ctx;
3354
0
    size_t len;
3355
0
    int rc;
3356
3357
0
    if ((channel == NULL) || (channel->flags & SSH_CHANNEL_FLAG_FREED_LOCAL)) {
3358
0
        return SSH_ERROR;
3359
0
    }
3360
3361
0
    session = channel->session;
3362
0
    stdbuf = channel->stdout_buffer;
3363
3364
0
    if (is_stderr) {
3365
0
        stdbuf = channel->stderr_buffer;
3366
0
    }
3367
0
    ctx.buffer = stdbuf;
3368
0
    ctx.channel = channel;
3369
0
    rc = ssh_handle_packets_termination(channel->session,
3370
0
                                        timeout,
3371
0
                                        ssh_channel_read_termination,
3372
0
                                        &ctx);
3373
0
    if (rc == SSH_ERROR ||
3374
0
        session->session_state == SSH_SESSION_STATE_ERROR) {
3375
0
        rc = SSH_ERROR;
3376
0
        goto out;
3377
0
    } else if (rc == SSH_AGAIN) {
3378
        /* If the above timeout expired, it is ok and we do not need to
3379
         * attempt to check the read buffer. The calling functions do not
3380
         * expect us to return SSH_AGAIN either here. */
3381
0
        rc = SSH_OK;
3382
0
        goto out;
3383
0
    }
3384
0
    len = ssh_buffer_get_len(stdbuf);
3385
0
    if (len > 0) {
3386
0
        if (len > INT_MAX) {
3387
0
            rc = SSH_ERROR;
3388
0
        } else {
3389
0
            rc = (int)len;
3390
0
        }
3391
0
        goto out;
3392
0
    }
3393
0
    if (channel->remote_eof) {
3394
0
        rc = SSH_EOF;
3395
0
    }
3396
3397
0
out:
3398
0
    return rc;
3399
0
}
3400
3401
/**
3402
 * @brief Recover the session in which belongs a channel.
3403
 *
3404
 * @param[in]  channel  The channel to recover the session from.
3405
 *
3406
 * @return              The session pointer.
3407
 */
3408
ssh_session ssh_channel_get_session(ssh_channel channel)
3409
0
{
3410
0
  if (channel == NULL) {
3411
0
      return NULL;
3412
0
  }
3413
3414
0
  return channel->session;
3415
0
}
3416
3417
static int ssh_channel_exit_status_termination(void *c)
3418
0
{
3419
0
    ssh_channel channel = c;
3420
0
    if (channel->exit.status ||
3421
        /* When a channel is closed, no exit status message can
3422
         * come anymore */
3423
0
        (channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE) ||
3424
0
        channel->session->session_state == SSH_SESSION_STATE_ERROR)
3425
0
    {
3426
0
        return 1;
3427
0
    }
3428
0
    return 0;
3429
0
}
3430
3431
/**
3432
 * @brief Get the exit state of the channel (error code from the executed
3433
 *        instruction or signal).
3434
 *
3435
 * @param[in]  channel  The channel to get the status from.
3436
 *
3437
 * @param[out] pexit_code   A pointer to an uint32_t to store the exit status.
3438
 *
3439
 * @param[out] pexit_signal A pointer to store the exit signal as a string.
3440
 *                         The signal is without the SIG prefix, e.g. "TERM" or
3441
 *                         "KILL"). The caller has to free the memory.
3442
 *
3443
 * @param[out] pcore_dumped A pointer to store a boolean value if it dumped a
3444
 *                          core.
3445
 *
3446
 * @return              SSH_OK on success, SSH_AGAIN if we don't have a status
3447
 *                      or an SSH error.
3448
 * @warning             This function may block until a timeout (or never)
3449
 *                      if the other side is not willing to close the channel.
3450
 *                      When a channel is freed the function returns
3451
 *                      SSH_ERROR immediately.
3452
 *
3453
 * If you're looking for an async handling of this register a callback for the
3454
 * exit status!
3455
 *
3456
 * @see ssh_channel_exit_status_callback
3457
 * @see ssh_channel_exit_signal_callback
3458
 */
3459
int ssh_channel_get_exit_state(ssh_channel channel,
3460
                               uint32_t *pexit_code,
3461
                               char **pexit_signal,
3462
                               int *pcore_dumped)
3463
0
{
3464
0
    ssh_session session = NULL;
3465
0
    int rc;
3466
3467
0
    if ((channel == NULL) || (channel->flags & SSH_CHANNEL_FLAG_FREED_LOCAL)) {
3468
0
        return SSH_ERROR;
3469
0
    }
3470
0
    session = channel->session;
3471
3472
0
    rc = ssh_handle_packets_termination(channel->session,
3473
0
                                        SSH_TIMEOUT_DEFAULT,
3474
0
                                        ssh_channel_exit_status_termination,
3475
0
                                        channel);
3476
0
    if (rc == SSH_ERROR || channel->session->session_state ==
3477
0
        SSH_SESSION_STATE_ERROR) {
3478
0
        return SSH_ERROR;
3479
0
    }
3480
3481
    /* If we don't have any kind of exit state, return SSH_AGAIN */
3482
0
    if (!channel->exit.status) {
3483
0
        return SSH_AGAIN;
3484
0
    }
3485
3486
0
    if (pexit_code != NULL) {
3487
0
        *pexit_code = channel->exit.code;
3488
0
    }
3489
3490
0
    if (pexit_signal != NULL) {
3491
0
        *pexit_signal = NULL;
3492
0
        if (channel->exit.signal != NULL) {
3493
0
            *pexit_signal = strdup(channel->exit.signal);
3494
0
            if (pexit_signal == NULL) {
3495
0
                ssh_set_error_oom(session);
3496
0
                return SSH_ERROR;
3497
0
            }
3498
0
        }
3499
0
    }
3500
3501
0
    if (pcore_dumped != NULL) {
3502
0
        *pcore_dumped = channel->exit.core_dumped;
3503
0
    }
3504
3505
0
    return SSH_OK;
3506
0
}
3507
3508
/**
3509
 * @brief Get the exit status of the channel (error code from the executed
3510
 *        instruction).
3511
 *
3512
 * @param[in]  channel  The channel to get the status from.
3513
 *
3514
 * @return              The exit status, -1 if no exit status has been returned
3515
 *                      (yet), or SSH_ERROR on error.
3516
 * @warning             This function may block until a timeout (or never)
3517
 *                      if the other side is not willing to close the channel.
3518
 *                      When a channel is freed the function returns
3519
 *                      SSH_ERROR immediately.
3520
 *
3521
 * If you're looking for an async handling of this register a callback for the
3522
 * exit status.
3523
 *
3524
 * @see ssh_channel_exit_status_callback
3525
 * @deprecated Please use ssh_channel_exit_state()
3526
 */
3527
int ssh_channel_get_exit_status(ssh_channel channel)
3528
0
{
3529
0
    uint32_t exit_status = (uint32_t)-1;
3530
0
    int rc;
3531
3532
0
    rc = ssh_channel_get_exit_state(channel, &exit_status, NULL, NULL);
3533
0
    if (rc != SSH_OK) {
3534
0
        return SSH_ERROR;
3535
0
    }
3536
3537
0
    return exit_status;
3538
0
}
3539
3540
/*
3541
 * This function acts as a meta select.
3542
 *
3543
 * First, channels are analyzed to seek potential can-write or can-read ones,
3544
 * then if no channel has been elected, it goes in a loop with the posix
3545
 * select(2).
3546
 * This is made in two parts: protocol select and network select. The protocol
3547
 * select does not use the network functions at all
3548
 */
3549
static int
3550
channel_protocol_select(ssh_channel *rchans, ssh_channel *wchans,
3551
                        ssh_channel *echans, ssh_channel *rout,
3552
                        ssh_channel *wout, ssh_channel *eout)
3553
0
{
3554
0
    ssh_channel chan = NULL;
3555
0
    int i;
3556
0
    int j = 0;
3557
3558
0
    for (i = 0; rchans[i] != NULL; i++) {
3559
0
        chan = rchans[i];
3560
3561
0
        while (ssh_channel_is_open(chan) &&
3562
0
               ssh_socket_data_available(chan->session->socket)) {
3563
0
            ssh_handle_packets(chan->session, SSH_TIMEOUT_NONBLOCKING);
3564
0
        }
3565
3566
0
        if ((chan->stdout_buffer &&
3567
0
             ssh_buffer_get_len(chan->stdout_buffer) > 0) ||
3568
0
            (chan->stderr_buffer &&
3569
0
             ssh_buffer_get_len(chan->stderr_buffer) > 0) ||
3570
0
            chan->remote_eof) {
3571
0
            rout[j] = chan;
3572
0
            j++;
3573
0
        }
3574
0
    }
3575
0
    rout[j] = NULL;
3576
3577
0
    j = 0;
3578
0
    for (i = 0; wchans[i] != NULL; i++) {
3579
0
        chan = wchans[i];
3580
        /* It's not our business to seek if the file descriptor is writable */
3581
0
        if (ssh_socket_data_writable(chan->session->socket) &&
3582
0
            ssh_channel_is_open(chan) && (chan->remote_window > 0)) {
3583
0
            wout[j] = chan;
3584
0
            j++;
3585
0
        }
3586
0
    }
3587
0
    wout[j] = NULL;
3588
3589
0
    j = 0;
3590
0
    for (i = 0; echans[i] != NULL; i++) {
3591
0
        chan = echans[i];
3592
3593
0
        if (!ssh_socket_is_open(chan->session->socket) ||
3594
0
            ssh_channel_is_closed(chan)) {
3595
0
            eout[j] = chan;
3596
0
            j++;
3597
0
        }
3598
0
    }
3599
0
    eout[j] = NULL;
3600
3601
0
    return 0;
3602
0
}
3603
3604
/* Just count number of pointers in the array */
3605
static size_t count_ptrs(ssh_channel *ptrs)
3606
0
{
3607
0
  size_t c;
3608
0
  for (c = 0; ptrs[c] != NULL; c++)
3609
0
    ;
3610
3611
0
  return c;
3612
0
}
3613
3614
/**
3615
 * @brief Act like the standard select(2) on channels.
3616
 *
3617
 * The list of pointers are then actualized and will only contain pointers to
3618
 * channels that are respectively readable, writable or have an exception to
3619
 * trap.
3620
 *
3621
 * @param[in]  readchans A NULL pointer or an array of channel pointers,
3622
 *                       terminated by a NULL.
3623
 *
3624
 * @param[in]  writechans A NULL pointer or an array of channel pointers,
3625
 *                        terminated by a NULL.
3626
 *
3627
 * @param[in]  exceptchans A NULL pointer or an array of channel pointers,
3628
 *                         terminated by a NULL.
3629
 *
3630
 * @param[in]  timeout  Timeout as defined by select(2).
3631
 *
3632
 * @return             SSH_OK on a successful operation, SSH_EINTR if the
3633
 *                     select(2) syscall was interrupted, then relaunch the
3634
 *                     function, or SSH_ERROR on error.
3635
 */
3636
int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans,
3637
                       ssh_channel *exceptchans, struct timeval * timeout)
3638
0
{
3639
0
    ssh_channel *rchans = NULL, *wchans = NULL, *echans = NULL;
3640
0
    ssh_channel dummy = NULL;
3641
0
    ssh_event event = NULL;
3642
0
    int rc;
3643
0
    int i;
3644
0
    int tm, tm_base;
3645
0
    int firstround = 1;
3646
0
    struct ssh_timestamp ts;
3647
3648
0
    if (timeout != NULL)
3649
0
        tm_base = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
3650
0
    else
3651
0
        tm_base = SSH_TIMEOUT_INFINITE;
3652
0
    ssh_timestamp_init(&ts);
3653
0
    tm = tm_base;
3654
    /* don't allow NULL pointers */
3655
0
    if (readchans == NULL) {
3656
0
        readchans = &dummy;
3657
0
    }
3658
3659
0
    if (writechans == NULL) {
3660
0
        writechans = &dummy;
3661
0
    }
3662
3663
0
    if (exceptchans == NULL) {
3664
0
        exceptchans = &dummy;
3665
0
    }
3666
3667
0
    if (readchans[0] == NULL && writechans[0] == NULL &&
3668
0
        exceptchans[0] == NULL) {
3669
        /* No channel to poll?? Go away! */
3670
0
        return 0;
3671
0
    }
3672
3673
    /* Prepare the outgoing temporary arrays */
3674
0
    rchans = calloc(count_ptrs(readchans) + 1, sizeof(ssh_channel));
3675
0
    if (rchans == NULL) {
3676
0
        return SSH_ERROR;
3677
0
    }
3678
3679
0
    wchans = calloc(count_ptrs(writechans) + 1, sizeof(ssh_channel));
3680
0
    if (wchans == NULL) {
3681
0
        SAFE_FREE(rchans);
3682
0
        return SSH_ERROR;
3683
0
    }
3684
3685
0
    echans = calloc(count_ptrs(exceptchans) + 1, sizeof(ssh_channel));
3686
0
    if (echans == NULL) {
3687
0
        SAFE_FREE(rchans);
3688
0
        SAFE_FREE(wchans);
3689
0
        return SSH_ERROR;
3690
0
    }
3691
3692
    /*
3693
     * First, try without doing network stuff then, use the ssh_poll
3694
     * infrastructure to poll on all sessions.
3695
     */
3696
0
    do {
3697
0
        channel_protocol_select(readchans,
3698
0
                                writechans,
3699
0
                                exceptchans,
3700
0
                                rchans,
3701
0
                                wchans,
3702
0
                                echans);
3703
0
        if (rchans[0] != NULL || wchans[0] != NULL || echans[0] != NULL) {
3704
            /* At least one channel has an event */
3705
0
            break;
3706
0
        }
3707
        /* Add all channels' sessions right into an event object */
3708
0
        if (event == NULL) {
3709
0
            event = ssh_event_new();
3710
0
            if (event == NULL) {
3711
0
                SAFE_FREE(rchans);
3712
0
                SAFE_FREE(wchans);
3713
0
                SAFE_FREE(echans);
3714
3715
0
                return SSH_ERROR;
3716
0
            }
3717
0
            for (i = 0; readchans[i] != NULL; i++) {
3718
0
                ssh_poll_get_default_ctx(readchans[i]->session);
3719
0
                ssh_event_add_session(event, readchans[i]->session);
3720
0
            }
3721
0
            for (i = 0; writechans[i] != NULL; i++) {
3722
0
                ssh_poll_get_default_ctx(writechans[i]->session);
3723
0
                ssh_event_add_session(event, writechans[i]->session);
3724
0
            }
3725
0
            for (i = 0; exceptchans[i] != NULL; i++) {
3726
0
                ssh_poll_get_default_ctx(exceptchans[i]->session);
3727
0
                ssh_event_add_session(event, exceptchans[i]->session);
3728
0
            }
3729
0
        }
3730
        /* Get out if the timeout has elapsed */
3731
0
        if (!firstround && ssh_timeout_elapsed(&ts, tm_base)) {
3732
0
            break;
3733
0
        }
3734
        /* Here we go */
3735
0
        rc = ssh_event_dopoll(event, tm);
3736
0
        if (rc != SSH_OK) {
3737
0
            SAFE_FREE(rchans);
3738
0
            SAFE_FREE(wchans);
3739
0
            SAFE_FREE(echans);
3740
0
            ssh_event_free(event);
3741
0
            return rc;
3742
0
        }
3743
0
        tm = ssh_timeout_update(&ts, tm_base);
3744
0
        firstround = 0;
3745
0
    } while (1);
3746
3747
0
    if (readchans != &dummy) {
3748
0
        memcpy(readchans,
3749
0
               rchans,
3750
0
               (count_ptrs(rchans) + 1) * sizeof(ssh_channel));
3751
0
    }
3752
0
    if (writechans != &dummy) {
3753
0
        memcpy(writechans,
3754
0
               wchans,
3755
0
               (count_ptrs(wchans) + 1) * sizeof(ssh_channel));
3756
0
    }
3757
0
    if (exceptchans != &dummy) {
3758
0
        memcpy(exceptchans,
3759
0
               echans,
3760
0
               (count_ptrs(echans) + 1) * sizeof(ssh_channel));
3761
0
    }
3762
0
    SAFE_FREE(rchans);
3763
0
    SAFE_FREE(wchans);
3764
0
    SAFE_FREE(echans);
3765
0
    if (event)
3766
0
        ssh_event_free(event);
3767
0
    return 0;
3768
0
}
3769
3770
/**
3771
 * @brief Set the channel data counter.
3772
 *
3773
 * @code
3774
 * struct ssh_counter_struct counter = {
3775
 *     .in_bytes = 0,
3776
 *     .out_bytes = 0,
3777
 *     .in_packets = 0,
3778
 *     .out_packets = 0
3779
 * };
3780
 *
3781
 * ssh_channel_set_counter(channel, &counter);
3782
 * @endcode
3783
 *
3784
 * @param[in] channel The SSH channel.
3785
 *
3786
 * @param[in] counter Counter for bytes handled by the channel.
3787
 */
3788
void ssh_channel_set_counter(ssh_channel channel,
3789
                             ssh_counter counter)
3790
0
{
3791
0
    if (channel != NULL) {
3792
0
        channel->counter = counter;
3793
0
    }
3794
0
}
3795
3796
/**
3797
 * @brief Blocking write on a channel stderr.
3798
 *
3799
 * @param[in]  channel  The channel to write to.
3800
 *
3801
 * @param[in]  data     A pointer to the data to write.
3802
 *
3803
 * @param[in]  len      The length of the buffer to write to.
3804
 *
3805
 * @return              The number of bytes written, SSH_ERROR on error.
3806
 *
3807
 * @see ssh_channel_read()
3808
 */
3809
int ssh_channel_write_stderr(ssh_channel channel, const void *data, uint32_t len)
3810
0
{
3811
0
    return channel_write_common(channel, data, len, 1);
3812
0
}
3813
3814
#if WITH_SERVER
3815
3816
/**
3817
 * @brief Open a TCP/IP reverse forwarding channel.
3818
 *
3819
 * @param[in]  channel  An allocated channel.
3820
 *
3821
 * @param[in]  remotehost The remote host to connected (host name or IP).
3822
 *
3823
 * @param[in]  remoteport The remote port.
3824
 *
3825
 * @param[in]  sourcehost The source host (your local computer). It's optional
3826
 *                        and for logging purpose.
3827
 *
3828
 * @param[in]  localport  The source port (your local computer). It's optional
3829
 *                        and for logging purpose.
3830
 *
3831
 * @return              SSH_OK on success,
3832
 *                      SSH_ERROR if an error occurred,
3833
 *                      SSH_AGAIN if in nonblocking mode and call has
3834
 *                      to be done again.
3835
 *
3836
 * @warning This function does not bind the local port and does not automatically
3837
 *          forward the content of a socket to the channel. You still have to
3838
 *          use ssh_channel_read and ssh_channel_write for this.
3839
 */
3840
int ssh_channel_open_reverse_forward(ssh_channel channel, const char *remotehost,
3841
                                     int remoteport, const char *sourcehost, int localport)
3842
0
{
3843
0
    ssh_session session = NULL;
3844
0
    ssh_buffer payload = NULL;
3845
0
    int rc = SSH_ERROR;
3846
3847
0
    if (channel == NULL) {
3848
0
        return rc;
3849
0
    }
3850
0
    if (remotehost == NULL || sourcehost == NULL) {
3851
0
        ssh_set_error_invalid(channel->session);
3852
0
        return rc;
3853
0
    }
3854
3855
0
    session = channel->session;
3856
3857
0
    if (channel->state != SSH_CHANNEL_STATE_NOT_OPEN)
3858
0
        goto pending;
3859
0
    payload = ssh_buffer_new();
3860
0
    if (payload == NULL) {
3861
0
        ssh_set_error_oom(session);
3862
0
        goto error;
3863
0
    }
3864
0
    rc = ssh_buffer_pack(payload,
3865
0
                         "sdsd",
3866
0
                         remotehost,
3867
0
                         remoteport,
3868
0
                         sourcehost,
3869
0
                         localport);
3870
0
    if (rc != SSH_OK) {
3871
0
        ssh_set_error_oom(session);
3872
0
        goto error;
3873
0
    }
3874
0
pending:
3875
0
    rc = channel_open(channel,
3876
0
                      "forwarded-tcpip",
3877
0
                      WINDOW_DEFAULT,
3878
0
                      CHANNEL_MAX_PACKET,
3879
0
                      payload);
3880
3881
0
error:
3882
0
    SSH_BUFFER_FREE(payload);
3883
3884
0
    return rc;
3885
0
}
3886
3887
/**
3888
 * @brief Open a X11 channel.
3889
 *
3890
 * @param[in]  channel      An allocated channel.
3891
 *
3892
 * @param[in]  orig_addr    The source host (the local server).
3893
 *
3894
 * @param[in]  orig_port    The source port (the local server).
3895
 *
3896
 * @return              SSH_OK on success,
3897
 *                      SSH_ERROR if an error occurred,
3898
 *                      SSH_AGAIN if in nonblocking mode and call has
3899
 *                      to be done again.
3900
 * @warning This function does not bind the local port and does not automatically
3901
 *          forward the content of a socket to the channel. You still have to
3902
 *          use shh_channel_read and ssh_channel_write for this.
3903
 */
3904
int ssh_channel_open_x11(ssh_channel channel,
3905
                         const char *orig_addr, int orig_port)
3906
0
{
3907
0
    ssh_session session = NULL;
3908
0
    ssh_buffer payload = NULL;
3909
0
    int rc = SSH_ERROR;
3910
3911
0
    if (channel == NULL) {
3912
0
        return rc;
3913
0
    }
3914
0
    if (orig_addr == NULL) {
3915
0
        ssh_set_error_invalid(channel->session);
3916
0
        return rc;
3917
0
    }
3918
0
    session = channel->session;
3919
3920
0
    if (channel->state != SSH_CHANNEL_STATE_NOT_OPEN)
3921
0
        goto pending;
3922
3923
0
    payload = ssh_buffer_new();
3924
0
    if (payload == NULL) {
3925
0
        ssh_set_error_oom(session);
3926
0
        goto error;
3927
0
    }
3928
3929
0
    rc = ssh_buffer_pack(payload, "sd", orig_addr, orig_port);
3930
0
    if (rc != SSH_OK) {
3931
0
        ssh_set_error_oom(session);
3932
0
        goto error;
3933
0
    }
3934
0
pending:
3935
0
    rc = channel_open(channel,
3936
0
                      "x11",
3937
0
                      WINDOW_DEFAULT,
3938
0
                      CHANNEL_MAX_PACKET,
3939
0
                      payload);
3940
3941
0
error:
3942
0
    SSH_BUFFER_FREE(payload);
3943
3944
0
    return rc;
3945
0
}
3946
3947
/**
3948
 * @brief Send the exit status to the remote process
3949
 *
3950
 * Sends the exit status to the remote process (as described in RFC 4254,
3951
 * section 6.10).
3952
 *
3953
 * @param[in]  channel  The channel to send exit status.
3954
 *
3955
 * @param[in]  exit_status  The exit status to send
3956
 *
3957
 * @return     SSH_OK on success, SSH_ERROR if an error occurred.
3958
 */
3959
int ssh_channel_request_send_exit_status(ssh_channel channel, int exit_status)
3960
0
{
3961
0
  ssh_buffer buffer = NULL;
3962
0
  int rc = SSH_ERROR;
3963
3964
0
  if(channel == NULL) {
3965
0
      return SSH_ERROR;
3966
0
  }
3967
3968
0
  buffer = ssh_buffer_new();
3969
0
  if (buffer == NULL) {
3970
0
    ssh_set_error_oom(channel->session);
3971
0
    goto error;
3972
0
  }
3973
3974
0
  rc = ssh_buffer_pack(buffer, "d", exit_status);
3975
0
  if (rc != SSH_OK) {
3976
0
    ssh_set_error_oom(channel->session);
3977
0
    goto error;
3978
0
  }
3979
3980
0
  rc = channel_request(channel, "exit-status", buffer, 0);
3981
0
error:
3982
0
  SSH_BUFFER_FREE(buffer);
3983
0
  return rc;
3984
0
}
3985
3986
/**
3987
 * @brief Send an exit signal to remote process (RFC 4254, section 6.10).
3988
 *
3989
 * This sends the exit status of the remote process.
3990
 * Note, that remote system may not support signals concept.
3991
 * In such a case this request will be silently ignored.
3992
 *
3993
 * @param[in]  channel  The channel to send signal.
3994
 *
3995
 * @param[in]  sig      The signal to send (without SIG prefix)
3996
 *                      (e.g. "TERM" or "KILL").
3997
 * @param[in]  core     A boolean to tell if a core was dumped
3998
 * @param[in]  errmsg   A CRLF explanation text about the error condition
3999
 * @param[in]  lang     The language used in the message (format: RFC 3066)
4000
 *
4001
 * @return              SSH_OK on success, SSH_ERROR if an error occurred
4002
 */
4003
int ssh_channel_request_send_exit_signal(ssh_channel channel, const char *sig,
4004
                                         int core, const char *errmsg, const char *lang)
4005
0
{
4006
0
  ssh_buffer buffer = NULL;
4007
0
  int rc = SSH_ERROR;
4008
4009
0
  if(channel == NULL) {
4010
0
      return rc;
4011
0
  }
4012
0
  if(sig == NULL || errmsg == NULL || lang == NULL) {
4013
0
      ssh_set_error_invalid(channel->session);
4014
0
      return rc;
4015
0
  }
4016
4017
0
  buffer = ssh_buffer_new();
4018
0
  if (buffer == NULL) {
4019
0
    ssh_set_error_oom(channel->session);
4020
0
    goto error;
4021
0
  }
4022
4023
0
  rc = ssh_buffer_pack(buffer,
4024
0
                       "sbss",
4025
0
                       sig,
4026
0
                       core ? 1 : 0,
4027
0
                       errmsg,
4028
0
                       lang);
4029
0
  if (rc != SSH_OK) {
4030
0
    ssh_set_error_oom(channel->session);
4031
0
    goto error;
4032
0
  }
4033
4034
0
  rc = channel_request(channel, "exit-signal", buffer, 0);
4035
0
error:
4036
0
  SSH_BUFFER_FREE(buffer);
4037
0
  return rc;
4038
0
}
4039
4040
#endif
4041
4042
/** @} */