Coverage Report

Created: 2023-09-25 06:08

/src/dropbear/src/common-channel.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Dropbear SSH
3
 * 
4
 * Copyright (c) 2002-2004 Matt Johnston
5
 * All rights reserved.
6
 * 
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 * 
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 * 
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
 * SOFTWARE. */
24
25
/* Handle the multiplexed channels, such as sessions, x11, agent connections */
26
27
#include "includes.h"
28
#include "session.h"
29
#include "packet.h"
30
#include "ssh.h"
31
#include "buffer.h"
32
#include "circbuffer.h"
33
#include "dbutil.h"
34
#include "channel.h"
35
#include "listener.h"
36
#include "runopts.h"
37
#include "netio.h"
38
39
static void send_msg_channel_open_failure(unsigned int remotechan, int reason,
40
    const char *text, const char *lang);
41
static void send_msg_channel_open_confirmation(const struct Channel* channel,
42
    unsigned int recvwindow, 
43
    unsigned int recvmaxpacket);
44
static int writechannel(struct Channel* channel, int fd, circbuffer *cbuf,
45
  const unsigned char *moredata, unsigned int *morelen);
46
static void send_msg_channel_window_adjust(const struct Channel *channel,
47
    unsigned int incr);
48
static void send_msg_channel_data(struct Channel *channel, int isextended);
49
static void send_msg_channel_eof(struct Channel *channel);
50
static void send_msg_channel_close(struct Channel *channel);
51
static void remove_channel(struct Channel *channel);
52
static unsigned int write_pending(const struct Channel * channel);
53
static void check_close(struct Channel *channel);
54
static void close_chan_fd(struct Channel *channel, int fd, int how);
55
56
16.0k
#define FD_UNINIT (-2)
57
1.03M
#define FD_CLOSED (-1)
58
59
20.6M
#define ERRFD_IS_READ(channel) ((channel)->extrabuf == NULL)
60
16.2M
#define ERRFD_IS_WRITE(channel) (!ERRFD_IS_READ(channel))
61
62
/* allow space for:
63
 * 1 byte  byte      SSH_MSG_CHANNEL_DATA
64
 * 4 bytes uint32    recipient channel
65
 * 4 bytes string    data
66
 */
67
8.04k
#define RECV_MAX_CHANNEL_DATA_LEN (RECV_MAX_PAYLOAD_LEN-(1+4+4))
68
69
/* Initialise all the channels */
70
1.63k
void chaninitialise(const struct ChanType *chantypes[]) {
71
72
  /* may as well create space for a single channel */
73
1.63k
  ses.channels = (struct Channel**)m_malloc(sizeof(struct Channel*));
74
1.63k
  ses.chansize = 1;
75
1.63k
  ses.channels[0] = NULL;
76
1.63k
  ses.chancount = 0;
77
78
1.63k
  ses.chantypes = chantypes;
79
80
1.63k
#if DROPBEAR_LISTENERS
81
1.63k
  listeners_initialise();
82
1.63k
#endif
83
84
1.63k
}
85
86
/* Clean up channels, freeing allocated memory */
87
1.63k
void chancleanup() {
88
89
1.63k
  unsigned int i;
90
91
1.63k
  TRACE(("enter chancleanup"))
92
8.18k
  for (i = 0; i < ses.chansize; i++) {
93
6.54k
    if (ses.channels[i] != NULL) {
94
5.17k
      TRACE(("channel %d closing", i))
95
5.17k
      remove_channel(ses.channels[i]);
96
5.17k
    }
97
6.54k
  }
98
1.63k
  m_free(ses.channels);
99
1.63k
  TRACE(("leave chancleanup"))
100
1.63k
}
101
102
/* Create a new channel entry, send a reply confirm or failure */
103
/* If remotechan, transwindow and transmaxpacket are not know (for a new
104
 * outgoing connection, with them to be filled on confirmation), they should
105
 * all be set to 0 */
106
static struct Channel* newchannel(unsigned int remotechan, 
107
    const struct ChanType *type, 
108
8.04k
    unsigned int transwindow, unsigned int transmaxpacket) {
109
110
8.04k
  struct Channel * newchan;
111
8.04k
  unsigned int i, j;
112
113
8.04k
  TRACE(("enter newchannel"))
114
  
115
  /* first see if we can use existing channels */
116
189k
  for (i = 0; i < ses.chansize; i++) {
117
187k
    if (ses.channels[i] == NULL) {
118
6.41k
      break;
119
6.41k
    }
120
187k
  }
121
122
  /* otherwise extend the list */
123
8.04k
  if (i == ses.chansize) {
124
1.63k
    if (ses.chansize >= MAX_CHANNELS) {
125
0
      TRACE(("leave newchannel: max chans reached"))
126
0
      return NULL;
127
0
    }
128
129
    /* extend the channels */
130
1.63k
    ses.channels = (struct Channel**)m_realloc(ses.channels,
131
1.63k
        (ses.chansize+CHAN_EXTEND_SIZE)*sizeof(struct Channel*));
132
133
1.63k
    ses.chansize += CHAN_EXTEND_SIZE;
134
135
    /* set the new channels to null */
136
6.54k
    for (j = i; j < ses.chansize; j++) {
137
4.90k
      ses.channels[j] = NULL;
138
4.90k
    }
139
140
1.63k
  }
141
  
142
8.04k
  newchan = (struct Channel*)m_malloc(sizeof(struct Channel));
143
8.04k
  newchan->type = type;
144
8.04k
  newchan->index = i;
145
8.04k
  newchan->sent_close = newchan->recv_close = 0;
146
8.04k
  newchan->sent_eof = newchan->recv_eof = 0;
147
148
8.04k
  newchan->remotechan = remotechan;
149
8.04k
  newchan->transwindow = transwindow;
150
8.04k
  newchan->transmaxpacket = transmaxpacket;
151
  
152
8.04k
  newchan->typedata = NULL;
153
8.04k
  newchan->writefd = FD_UNINIT;
154
8.04k
  newchan->readfd = FD_UNINIT;
155
8.04k
  newchan->errfd = FD_CLOSED; /* this isn't always set to start with */
156
8.04k
  newchan->await_open = 0;
157
158
8.04k
  newchan->writebuf = cbuf_new(opts.recv_window);
159
8.04k
  newchan->recvwindow = opts.recv_window;
160
161
8.04k
  newchan->extrabuf = NULL; /* The user code can set it up */
162
8.04k
  newchan->recvdonelen = 0;
163
8.04k
  newchan->recvmaxpacket = RECV_MAX_CHANNEL_DATA_LEN;
164
165
8.04k
  newchan->prio = DROPBEAR_PRIO_NORMAL;
166
167
8.04k
  ses.channels[i] = newchan;
168
8.04k
  ses.chancount++;
169
170
8.04k
  TRACE(("leave newchannel"))
171
172
8.04k
  return newchan;
173
8.04k
}
174
175
/* Returns the channel structure corresponding to the channel in the current
176
 * data packet (ses.payload must be positioned appropriately).
177
 * A valid channel is always returns, it will fail fatally with an unknown
178
 * channel */
179
17.0k
static struct Channel* getchannel_msg(const char* kind) {
180
181
17.0k
  unsigned int chan;
182
183
17.0k
  chan = buf_getint(ses.payload);
184
17.0k
  if (chan >= ses.chansize || ses.channels[chan] == NULL) {
185
21
    if (kind) {
186
8
      dropbear_exit("%s for unknown channel %d", kind, chan);
187
13
    } else {
188
13
      dropbear_exit("Unknown channel %d", chan);
189
13
    }
190
21
  }
191
17.0k
  return ses.channels[chan];
192
17.0k
}
193
194
10.9k
struct Channel* getchannel() {
195
10.9k
  return getchannel_msg(NULL);
196
10.9k
}
197
198
/* Iterate through the channels, performing IO if available */
199
501k
void channelio(const fd_set *readfds, const fd_set *writefds) {
200
201
  /* Listeners such as TCP, X11, agent-auth */
202
501k
  struct Channel *channel;
203
501k
  unsigned int i;
204
205
  /* foreach channel */
206
5.04M
  for (i = 0; i < ses.chansize; i++) {
207
    /* Close checking only needs to occur for channels that had IO events */
208
4.54M
    int do_check_close = 0;
209
210
4.54M
    channel = ses.channels[i];
211
4.54M
    if (channel == NULL) {
212
      /* only process in-use channels */
213
490k
      continue;
214
490k
    }
215
216
    /* read data and send it over the wire */
217
4.05M
    if (channel->readfd >= 0 && FD_ISSET(channel->readfd, readfds)) {
218
102k
      TRACE(("send normal readfd"))
219
102k
      send_msg_channel_data(channel, 0);
220
102k
      do_check_close = 1;
221
102k
    }
222
223
    /* read stderr data and send it over the wire */
224
4.05M
    if (ERRFD_IS_READ(channel) && channel->errfd >= 0 
225
4.05M
      && FD_ISSET(channel->errfd, readfds)) {
226
101k
        TRACE(("send normal errfd"))
227
101k
        send_msg_channel_data(channel, 1);
228
101k
      do_check_close = 1;
229
101k
    }
230
231
    /* write to program/pipe stdin */
232
4.05M
    if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) {
233
0
      writechannel(channel, channel->writefd, channel->writebuf, NULL, NULL);
234
0
      do_check_close = 1;
235
0
    }
236
    
237
    /* stderr for client mode */
238
4.05M
    if (ERRFD_IS_WRITE(channel)
239
4.05M
        && channel->errfd >= 0 && FD_ISSET(channel->errfd, writefds)) {
240
0
      writechannel(channel, channel->errfd, channel->extrabuf, NULL, NULL);
241
0
      do_check_close = 1;
242
0
    }
243
244
4.05M
    if (ses.channel_signal_pending) {
245
      /* SIGCHLD can change channel state for server sessions */
246
0
      do_check_close = 1;
247
0
    }
248
  
249
    /* handle any channel closing etc */
250
4.05M
    if (do_check_close) {
251
179k
      check_close(channel);
252
179k
    }
253
4.05M
  }
254
255
501k
#if DROPBEAR_LISTENERS
256
501k
  handle_listeners(readfds);
257
501k
#endif
258
501k
}
259
260
261
/* Returns true if there is data remaining to be written to stdin or
262
 * stderr of a channel's endpoint. */
263
14.7k
static unsigned int write_pending(const struct Channel * channel) {
264
265
14.7k
  if (channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0) {
266
0
    return 1;
267
14.7k
  } else if (channel->errfd >= 0 && channel->extrabuf && 
268
14.7k
      cbuf_getused(channel->extrabuf) > 0) {
269
0
    return 1;
270
0
  }
271
14.7k
  return 0;
272
14.7k
}
273
274
275
/* EOF/close handling */
276
185k
static void check_close(struct Channel *channel) {
277
185k
  int close_allowed = 0;
278
279
185k
  TRACE2(("check_close: writefd %d, readfd %d, errfd %d, sent_close %d, recv_close %d",
280
185k
        channel->writefd, channel->readfd,
281
185k
        channel->errfd, channel->sent_close, channel->recv_close))
282
185k
  TRACE2(("writebuf size %d extrabuf size %d",
283
185k
        channel->writebuf ? cbuf_getused(channel->writebuf) : 0,
284
185k
        channel->extrabuf ? cbuf_getused(channel->extrabuf) : 0))
285
286
  /* if a type-specific check_close is defined we will only exit
287
     once that has been triggered. this is only used for a server "session"
288
     channel, to ensure that the shell has exited (and the exit status
289
     retrieved) before we close things up. */
290
185k
  if (!channel->type->check_close
291
185k
    || channel->sent_close
292
185k
    || channel->type->check_close(channel)) {
293
5.43k
    close_allowed = 1;
294
5.43k
  }
295
296
  /* In flushing mode we close FDs as soon as pipes are empty.
297
  This is used to drain out FDs when the process exits, in the case
298
  where the FD doesn't have EOF - "sleep 10&echo hello" case */
299
185k
  if (channel->flushing) {
300
0
    if (channel->readfd >= 0 && !fd_read_pending(channel->readfd)) {
301
0
      close_chan_fd(channel, channel->readfd, SHUT_RD);
302
0
    }
303
0
    if (ERRFD_IS_READ(channel)
304
0
      && channel->errfd >= 0 && !fd_read_pending(channel->errfd)) {
305
0
      close_chan_fd(channel, channel->errfd, SHUT_RD);
306
0
    }
307
0
  }
308
309
185k
  if (channel->recv_close && !write_pending(channel) && close_allowed) {
310
2.51k
    if (!channel->sent_close) {
311
81
      TRACE(("Sending MSG_CHANNEL_CLOSE in response to same."))
312
81
      send_msg_channel_close(channel);
313
81
    }
314
2.51k
    remove_channel(channel);
315
2.51k
    return;
316
2.51k
  }
317
318
183k
  if ((channel->recv_eof && !write_pending(channel))
319
    /* have a server "session" and child has exited */
320
183k
    || (channel->type->check_close && close_allowed)) {
321
7.97k
    close_chan_fd(channel, channel->writefd, SHUT_WR);
322
7.97k
  }
323
324
  /* If we're not going to send any more data, send EOF */
325
183k
  if (!channel->sent_eof
326
183k
      && channel->readfd == FD_CLOSED 
327
183k
      && (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED)) {
328
2.54k
    send_msg_channel_eof(channel);
329
2.54k
  }
330
331
  /* And if we can't receive any more data from them either, close up */
332
183k
  if (channel->readfd == FD_CLOSED
333
183k
      && channel->writefd == FD_CLOSED
334
183k
      && (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED)
335
183k
      && !channel->sent_close
336
183k
      && close_allowed
337
183k
      && !write_pending(channel)) {
338
2.48k
    TRACE(("sending close, readfd is closed"))
339
2.48k
    send_msg_channel_close(channel);
340
2.48k
  }
341
183k
}
342
343
/* Check whether a deferred (EINPROGRESS) connect() was successful, and
344
 * if so, set up the channel properly. Otherwise, the channel is cleaned up, so
345
 * it is important that the channel reference isn't used after a call to this
346
 * function */
347
100
void channel_connect_done(int result, int sock, void* user_data, const char* errstring) {
348
100
  struct Channel *channel = user_data;
349
350
100
  TRACE(("enter channel_connect_done"))
351
352
100
  if (result == DROPBEAR_SUCCESS)
353
0
  {
354
0
    channel->readfd = channel->writefd = sock;
355
0
    channel->bidir_fd = 1;
356
0
    channel->conn_pending = NULL;
357
0
    send_msg_channel_open_confirmation(channel, channel->recvwindow,
358
0
        channel->recvmaxpacket);
359
0
    TRACE(("leave channel_connect_done: success"))
360
0
  }
361
100
  else
362
100
  {
363
100
    send_msg_channel_open_failure(channel->remotechan,
364
100
        SSH_OPEN_CONNECT_FAILED, errstring, "");
365
100
    remove_channel(channel);
366
100
    TRACE(("leave check_in_progress: fail. internal errstring: %s", errstring))
367
100
  }
368
100
}
369
370
371
/* Send the close message and set the channel as closed */
372
2.56k
static void send_msg_channel_close(struct Channel *channel) {
373
374
2.56k
  TRACE(("enter send_msg_channel_close %p", (void*)channel))
375
2.56k
  if (channel->type->closehandler) {
376
2.56k
    channel->type->closehandler(channel);
377
2.56k
  }
378
  
379
2.56k
  CHECKCLEARTOWRITE();
380
381
2.56k
  buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_CLOSE);
382
2.56k
  buf_putint(ses.writepayload, channel->remotechan);
383
384
2.56k
  encrypt_packet();
385
386
2.56k
  channel->sent_eof = 1;
387
2.56k
  channel->sent_close = 1;
388
2.56k
  close_chan_fd(channel, channel->readfd, SHUT_RD);
389
2.56k
  close_chan_fd(channel, channel->errfd, SHUT_RDWR);
390
2.56k
  close_chan_fd(channel, channel->writefd, SHUT_WR);
391
2.56k
  TRACE(("leave send_msg_channel_close"))
392
2.56k
}
393
394
/* call this when trans/eof channels are closed */
395
2.54k
static void send_msg_channel_eof(struct Channel *channel) {
396
397
2.54k
  TRACE(("enter send_msg_channel_eof"))
398
2.54k
  CHECKCLEARTOWRITE();
399
400
2.54k
  buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_EOF);
401
2.54k
  buf_putint(ses.writepayload, channel->remotechan);
402
403
2.54k
  encrypt_packet();
404
405
2.54k
  channel->sent_eof = 1;
406
407
2.54k
  TRACE(("leave send_msg_channel_eof"))
408
2.54k
}
409
410
#ifndef HAVE_WRITEV
411
static int writechannel_fallback(struct Channel* channel, int fd, circbuffer *cbuf,
412
  const unsigned char *UNUSED(moredata), unsigned int *morelen) {
413
414
  unsigned char *circ_p1, *circ_p2;
415
  unsigned int circ_len1, circ_len2;
416
  ssize_t written;
417
418
  if (morelen) {
419
    /* fallback doesn't consume moredata */
420
    *morelen = 0;
421
  }
422
423
  /* Write the first portion of the circular buffer */
424
  cbuf_readptrs(cbuf, &circ_p1, &circ_len1, &circ_p2, &circ_len2);
425
  written = write(fd, circ_p1, circ_len1);
426
  if (written < 0) {
427
    if (errno != EINTR && errno != EAGAIN) {
428
      TRACE(("channel IO write error fd %d %s", fd, strerror(errno)))
429
      close_chan_fd(channel, fd, SHUT_WR);
430
      return DROPBEAR_FAILURE;
431
    }
432
  } else {
433
    cbuf_incrread(cbuf, written);
434
    channel->recvdonelen += written;
435
  }
436
  return DROPBEAR_SUCCESS;
437
}
438
#endif /* !HAVE_WRITEV */
439
440
#ifdef HAVE_WRITEV
441
static int writechannel_writev(struct Channel* channel, int fd, circbuffer *cbuf,
442
20
  const unsigned char *moredata, unsigned int *morelen) {
443
444
20
  struct iovec iov[3];
445
20
  unsigned char *circ_p1, *circ_p2;
446
20
  unsigned int circ_len1, circ_len2;
447
20
  int io_count = 0;
448
449
20
  ssize_t written;
450
451
20
  cbuf_readptrs(cbuf, &circ_p1, &circ_len1, &circ_p2, &circ_len2);
452
453
20
  if (circ_len1 > 0) {
454
0
    TRACE(("circ1 %d", circ_len1))
455
0
    iov[io_count].iov_base = circ_p1;
456
0
    iov[io_count].iov_len = circ_len1;
457
0
    io_count++;
458
0
  }
459
460
20
  if (circ_len2 > 0) {
461
0
    TRACE(("circ2 %d", circ_len2))
462
0
    iov[io_count].iov_base = circ_p2;
463
0
    iov[io_count].iov_len = circ_len2;
464
0
    io_count++;
465
0
  }
466
467
20
  if (morelen) {
468
20
    assert(moredata);
469
20
    TRACE(("more %d", *morelen))
470
20
    iov[io_count].iov_base = (void*)moredata;
471
20
    iov[io_count].iov_len  = *morelen;
472
20
    io_count++;
473
20
  }
474
475
20
  if (io_count == 0) {
476
    /* writechannel may sometimes be called twice in a main loop iteration.
477
    From common_recv_msg_channel_data() then channelio().
478
    The second call may not have any data to write, so we just return. */
479
0
    TRACE(("leave writechannel, no data"))
480
0
    return DROPBEAR_SUCCESS;
481
0
  }
482
483
20
  if (morelen) {
484
    /* Default return value, none consumed */
485
20
    *morelen = 0;
486
20
  }
487
488
20
  written = writev(fd, iov, io_count);
489
490
20
  if (written < 0) {
491
20
    if (errno != EINTR && errno != EAGAIN) {
492
20
      TRACE(("channel IO write error fd %d %s", fd, strerror(errno)))
493
20
      close_chan_fd(channel, fd, SHUT_WR);
494
20
      return DROPBEAR_FAILURE;
495
20
    }
496
20
  } else {
497
0
    int cbuf_written = MIN(circ_len1+circ_len2, (unsigned int)written);
498
0
    cbuf_incrread(cbuf, cbuf_written);
499
0
    if (morelen) {
500
0
      *morelen = written - cbuf_written;
501
0
    }
502
0
    channel->recvdonelen += written;
503
0
  }
504
0
  return DROPBEAR_SUCCESS;
505
20
}
506
#endif /* HAVE_WRITEV */
507
508
/* Called to write data out to the local side of the channel. 
509
   Writes the circular buffer contents and also the "moredata" buffer
510
   if not null. Will ignore EAGAIN.
511
   Returns DROPBEAR_FAILURE if writing to fd had an error and the channel is being closed, DROPBEAR_SUCCESS otherwise */
512
static int writechannel(struct Channel* channel, int fd, circbuffer *cbuf,
513
20
  const unsigned char *moredata, unsigned int *morelen) {
514
20
  int ret = DROPBEAR_SUCCESS;
515
20
  TRACE(("enter writechannel fd %d", fd))
516
20
#ifdef HAVE_WRITEV
517
20
  ret = writechannel_writev(channel, fd, cbuf, moredata, morelen);
518
#else
519
  ret = writechannel_fallback(channel, fd, cbuf, moredata, morelen);
520
#endif
521
522
  /* Window adjust handling */
523
20
  if (channel->recvdonelen >= RECV_WINDOWEXTEND) {
524
0
    send_msg_channel_window_adjust(channel, channel->recvdonelen);
525
0
    channel->recvwindow += channel->recvdonelen;
526
0
    channel->recvdonelen = 0;
527
0
  }
528
529
20
  dropbear_assert(channel->recvwindow <= opts.recv_window);
530
20
  dropbear_assert(channel->recvwindow <= cbuf_getavail(channel->writebuf));
531
20
  dropbear_assert(channel->extrabuf == NULL ||
532
20
      channel->recvwindow <= cbuf_getavail(channel->extrabuf));
533
  
534
20
  TRACE(("leave writechannel"))
535
20
  return ret;
536
20
}
537
538
539
/* Set the file descriptors for the main select in session.c
540
 * This avoid channels which don't have any window available, are closed, etc*/
541
503k
void setchannelfds(fd_set *readfds, fd_set *writefds, int allow_reads) {
542
  
543
503k
  unsigned int i;
544
503k
  struct Channel * channel;
545
  
546
5.04M
  for (i = 0; i < ses.chansize; i++) {
547
548
4.54M
    channel = ses.channels[i];
549
4.54M
    if (channel == NULL) {
550
491k
      continue;
551
491k
    }
552
553
    /* Stuff to put over the wire. 
554
    Avoid queueing data to send if we're in the middle of a 
555
    key re-exchange (!dataallowed), but still read from the 
556
    FD if there's the possibility of "~."" to kill an 
557
    interactive session (the read_mangler) */
558
4.05M
    if (channel->transwindow > 0
559
4.05M
       && ((ses.dataallowed && allow_reads) || channel->read_mangler)) {
560
561
2.16M
      if (channel->readfd >= 0) {
562
523k
        FD_SET(channel->readfd, readfds);
563
523k
      }
564
      
565
2.16M
      if (ERRFD_IS_READ(channel) && channel->errfd >= 0) {
566
519k
          FD_SET(channel->errfd, readfds);
567
519k
      }
568
2.16M
    }
569
570
    /* Stuff from the wire */
571
4.05M
    if (channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0) {
572
0
        FD_SET(channel->writefd, writefds);
573
0
    }
574
575
4.05M
    if (ERRFD_IS_WRITE(channel) && channel->errfd >= 0 
576
4.05M
        && cbuf_getused(channel->extrabuf) > 0) {
577
0
        FD_SET(channel->errfd, writefds);
578
0
    }
579
580
4.05M
  } /* foreach channel */
581
582
503k
#if DROPBEAR_LISTENERS
583
503k
  set_listener_fds(readfds);
584
503k
#endif
585
586
503k
}
587
588
/* handle the channel EOF event, by closing the channel filedescriptor. The
589
 * channel isn't closed yet, it is left until the incoming (from the program
590
 * etc) FD is also EOF */
591
3.32k
void recv_msg_channel_eof() {
592
593
3.32k
  struct Channel * channel;
594
595
3.32k
  TRACE(("enter recv_msg_channel_eof"))
596
597
3.32k
  channel = getchannel_msg("EOF");
598
599
3.32k
  channel->recv_eof = 1;
600
601
3.32k
  check_close(channel);
602
3.32k
  TRACE(("leave recv_msg_channel_eof"))
603
3.32k
}
604
605
606
/* Handle channel closure(), respond in kind and close the channels */
607
2.77k
void recv_msg_channel_close() {
608
609
2.77k
  struct Channel * channel;
610
611
2.77k
  TRACE(("enter recv_msg_channel_close"))
612
613
2.77k
  channel = getchannel_msg("Close");
614
615
2.77k
  channel->recv_eof = 1;
616
2.77k
  channel->recv_close = 1;
617
618
2.77k
  check_close(channel);
619
2.77k
  TRACE(("leave recv_msg_channel_close"))
620
2.77k
}
621
622
/* Remove a channel entry, this is only executed after both sides have sent
623
 * channel close */
624
8.04k
static void remove_channel(struct Channel * channel) {
625
626
8.04k
  TRACE(("enter remove_channel"))
627
8.04k
  TRACE(("channel index is %d", channel->index))
628
629
8.04k
  cbuf_free(channel->writebuf);
630
8.04k
  channel->writebuf = NULL;
631
632
8.04k
  if (channel->extrabuf) {
633
0
    cbuf_free(channel->extrabuf);
634
0
    channel->extrabuf = NULL;
635
0
  }
636
637
638
8.04k
  if (IS_DROPBEAR_SERVER || (channel->writefd != STDOUT_FILENO)) {
639
    /* close the FDs in case they haven't been done
640
     * yet (they might have been shutdown etc) */
641
8.04k
    TRACE(("CLOSE writefd %d", channel->writefd))
642
8.04k
    m_close(channel->writefd);
643
8.04k
    TRACE(("CLOSE readfd %d", channel->readfd))
644
8.04k
    m_close(channel->readfd);
645
8.04k
    TRACE(("CLOSE errfd %d", channel->errfd))
646
8.04k
    m_close(channel->errfd);
647
8.04k
  }
648
649
8.04k
  if (channel->type->cleanup) {
650
7.68k
    channel->type->cleanup(channel);
651
7.68k
  }
652
653
8.04k
  if (channel->conn_pending) {
654
101
    cancel_connect(channel->conn_pending);
655
101
  }
656
657
8.04k
  ses.channels[channel->index] = NULL;
658
8.04k
  m_free(channel);
659
8.04k
  ses.chancount--;
660
661
8.04k
  update_channel_prio();
662
663
8.04k
  TRACE(("leave remove_channel"))
664
8.04k
}
665
666
/* Handle channel specific requests, passing off to corresponding handlers
667
 * such as chansession or x11fwd */
668
10.2k
void recv_msg_channel_request() {
669
670
10.2k
  struct Channel *channel;
671
672
10.2k
  channel = getchannel();
673
674
10.2k
  TRACE(("enter recv_msg_channel_request %p", (void*)channel))
675
676
10.2k
  if (channel->type->reqhandler) {
677
10.2k
    channel->type->reqhandler(channel);
678
10.2k
  } else {
679
7
    int wantreply;
680
7
    buf_eatstring(ses.payload);
681
7
    wantreply = buf_getbool(ses.payload);
682
7
    if (wantreply) {
683
0
      send_msg_channel_failure(channel);
684
0
    }
685
7
  }
686
687
10.2k
  TRACE(("leave recv_msg_channel_request"))
688
689
10.2k
}
690
691
/* Reads data from the server's program/shell/etc, and puts it in a
692
 * channel_data packet to send.
693
 * chan is the remote channel, isextended is 0 if it is normal data, 1
694
 * if it is extended data. if it is extended, then the type is in
695
 * exttype */
696
203k
static void send_msg_channel_data(struct Channel *channel, int isextended) {
697
698
203k
  int len;
699
203k
  size_t maxlen, size_pos;
700
203k
  int fd;
701
702
203k
  CHECKCLEARTOWRITE();
703
704
203k
  TRACE(("enter send_msg_channel_data"))
705
203k
  dropbear_assert(!channel->sent_close);
706
707
203k
  if (isextended) {
708
101k
    fd = channel->errfd;
709
102k
  } else {
710
102k
    fd = channel->readfd;
711
102k
  }
712
203k
  TRACE(("enter send_msg_channel_data isextended %d fd %d", isextended, fd))
713
203k
  dropbear_assert(fd >= 0);
714
715
203k
  maxlen = MIN(channel->transwindow, channel->transmaxpacket);
716
  /* -(1+4+4) is SSH_MSG_CHANNEL_DATA, channel number, string length, and 
717
   * exttype if is extended */
718
203k
  maxlen = MIN(maxlen, 
719
203k
      ses.writepayload->size - 1 - 4 - 4 - (isextended ? 4 : 0));
720
203k
  TRACE(("maxlen %zd", maxlen))
721
203k
  if (maxlen == 0) {
722
7.15k
    TRACE(("leave send_msg_channel_data: no window"))
723
7.15k
    return;
724
7.15k
  }
725
726
196k
  buf_putbyte(ses.writepayload, 
727
196k
      isextended ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA);
728
196k
  buf_putint(ses.writepayload, channel->remotechan);
729
196k
  if (isextended) {
730
97.4k
    buf_putint(ses.writepayload, SSH_EXTENDED_DATA_STDERR);
731
97.4k
  }
732
  /* a dummy size first ...*/
733
196k
  size_pos = ses.writepayload->pos;
734
196k
  buf_putint(ses.writepayload, 0);
735
736
  /* read the data */
737
196k
  len = read(fd, buf_getwriteptr(ses.writepayload, maxlen), maxlen);
738
739
196k
  if (len <= 0) {
740
567
    if (len == 0 || errno != EINTR) {
741
      /* This will also get hit in the case of EAGAIN. The only
742
      time we expect to receive EAGAIN is when we're flushing a FD,
743
      in which case it can be treated the same as EOF */
744
284
      close_chan_fd(channel, fd, SHUT_RD);
745
284
    }
746
567
    buf_setpos(ses.writepayload, 0);
747
567
    buf_setlen(ses.writepayload, 0);
748
567
    TRACE(("leave send_msg_channel_data: len %d read err %d or EOF for fd %d", 
749
567
          len, errno, fd))
750
567
    return;
751
567
  }
752
753
196k
  if (channel->read_mangler) {
754
0
    channel->read_mangler(channel, buf_getwriteptr(ses.writepayload, len), &len);
755
0
    if (len == 0) {
756
0
      buf_setpos(ses.writepayload, 0);
757
0
      buf_setlen(ses.writepayload, 0);
758
0
      return;
759
0
    }
760
0
  }
761
762
196k
  TRACE(("send_msg_channel_data: len %d fd %d", len, fd))
763
196k
  buf_incrwritepos(ses.writepayload, len);
764
  /* ... real size here */
765
196k
  buf_setpos(ses.writepayload, size_pos);
766
196k
  buf_putint(ses.writepayload, len);
767
768
196k
  channel->transwindow -= len;
769
770
196k
  encrypt_packet();
771
196k
  TRACE(("leave send_msg_channel_data"))
772
196k
}
773
774
/* We receive channel data */
775
150
void recv_msg_channel_data() {
776
777
150
  struct Channel *channel;
778
779
150
  channel = getchannel();
780
781
150
  common_recv_msg_channel_data(channel, channel->writefd, channel->writebuf);
782
150
}
783
784
/* Shared for data and stderr data - when we receive data, put it in a buffer
785
 * for writing to the local file descriptor */
786
void common_recv_msg_channel_data(struct Channel *channel, int fd, 
787
148
    circbuffer * cbuf) {
788
789
148
  unsigned int datalen;
790
148
  unsigned int maxdata;
791
148
  unsigned int buflen;
792
148
  unsigned int len;
793
148
  unsigned int consumed;
794
148
  int res;
795
796
148
  TRACE(("enter recv_msg_channel_data"))
797
798
148
  if (channel->recv_eof) {
799
1
    dropbear_exit("Received data after eof");
800
1
  }
801
802
147
  if (fd < 0 || !cbuf) {
803
    /* If we have encountered failed write, the far side might still
804
     * be sending data without having yet received our close notification.
805
     * We just drop the data. */
806
61
    return;
807
61
  }
808
809
86
  datalen = buf_getint(ses.payload);
810
86
  TRACE(("length %d", datalen))
811
812
86
  maxdata = cbuf_getavail(cbuf);
813
814
  /* Whilst the spec says we "MAY ignore data past the end" this could
815
   * lead to corrupted file transfers etc (chunks missed etc). It's better to
816
   * just die horribly */
817
86
  if (datalen > maxdata) {
818
35
    dropbear_exit("Oversized packet");
819
35
  }
820
821
51
  dropbear_assert(channel->recvwindow >= datalen);
822
51
  channel->recvwindow -= datalen;
823
51
  dropbear_assert(channel->recvwindow <= opts.recv_window);
824
825
  /* Attempt to write the data immediately without having to put it in the circular buffer */
826
51
  consumed = datalen;
827
51
  res = writechannel(channel, fd, cbuf, buf_getptr(ses.payload, datalen), &consumed);
828
829
51
  datalen -= consumed;
830
51
  buf_incrpos(ses.payload, consumed);
831
832
833
  /* We may have to run throught twice, if the buffer wraps around. Can't
834
   * just "leave it for next time" like with writechannel, since this
835
   * is payload data.
836
   * If the writechannel() failed then remaining data is discarded */
837
51
  if (res == DROPBEAR_SUCCESS) {
838
0
    len = datalen;
839
0
    while (len > 0) {
840
0
      buflen = cbuf_writelen(cbuf);
841
0
      buflen = MIN(buflen, len);
842
843
0
      memcpy(cbuf_writeptr(cbuf, buflen), 
844
0
          buf_getptr(ses.payload, buflen), buflen);
845
0
      cbuf_incrwrite(cbuf, buflen);
846
0
      buf_incrpos(ses.payload, buflen);
847
0
      len -= buflen;
848
0
    }
849
0
  }
850
851
51
  TRACE(("leave recv_msg_channel_data"))
852
51
}
853
854
/* Increment the outgoing data window for a channel - the remote end limits
855
 * the amount of data which may be transmitted, this window is decremented
856
 * as data is sent, and incremented upon receiving window-adjust messages */
857
533
void recv_msg_channel_window_adjust() {
858
859
533
  struct Channel * channel;
860
533
  unsigned int incr;
861
  
862
533
  channel = getchannel();
863
  
864
533
  incr = buf_getint(ses.payload);
865
533
  TRACE(("received window increment %d", incr))
866
533
  incr = MIN(incr, TRANS_MAX_WIN_INCR);
867
  
868
533
  channel->transwindow += incr;
869
533
  channel->transwindow = MIN(channel->transwindow, TRANS_MAX_WINDOW);
870
871
533
}
872
873
/* Increment the incoming data window for a channel, and let the remote
874
 * end know */
875
static void send_msg_channel_window_adjust(const struct Channel* channel,
876
0
    unsigned int incr) {
877
878
0
  TRACE(("sending window adjust %d", incr))
879
0
  CHECKCLEARTOWRITE();
880
881
0
  buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_WINDOW_ADJUST);
882
0
  buf_putint(ses.writepayload, channel->remotechan);
883
0
  buf_putint(ses.writepayload, incr);
884
885
0
  encrypt_packet();
886
0
}
887
  
888
/* Handle a new channel request, performing any channel-type-specific setup */
889
8.80k
void recv_msg_channel_open() {
890
891
8.80k
  char *type;
892
8.80k
  unsigned int typelen;
893
8.80k
  unsigned int remotechan, transwindow, transmaxpacket;
894
8.80k
  struct Channel *channel;
895
8.80k
  const struct ChanType **cp;
896
8.80k
  const struct ChanType *chantype;
897
8.80k
  unsigned int errtype = SSH_OPEN_UNKNOWN_CHANNEL_TYPE;
898
8.80k
  int ret;
899
900
901
8.80k
  TRACE(("enter recv_msg_channel_open"))
902
903
  /* get the packet contents */
904
8.80k
  type = buf_getstring(ses.payload, &typelen);
905
906
8.80k
  remotechan = buf_getint(ses.payload);
907
8.80k
  transwindow = buf_getint(ses.payload);
908
8.80k
  transwindow = MIN(transwindow, TRANS_MAX_WINDOW);
909
8.80k
  transmaxpacket = buf_getint(ses.payload);
910
8.80k
  transmaxpacket = MIN(transmaxpacket, TRANS_MAX_PAYLOAD_LEN);
911
912
  /* figure what type of packet it is */
913
8.80k
  if (typelen > MAX_NAME_LEN) {
914
70
    goto failure;
915
70
  }
916
917
  /* Get the channel type. Client and server style invokation will set up a
918
   * different list for ses.chantypes at startup. We just iterate through
919
   * this list and find the matching name */
920
8.73k
  for (cp = &ses.chantypes[0], chantype = (*cp); 
921
10.4k
      chantype != NULL;
922
9.77k
      cp++, chantype = (*cp)) {
923
9.77k
    if (strcmp(type, chantype->name) == 0) {
924
8.04k
      break;
925
8.04k
    }
926
9.77k
  }
927
928
8.73k
  if (chantype == NULL) {
929
682
    TRACE(("No matching type for '%s'", type))
930
682
    goto failure;
931
682
  }
932
933
8.05k
  TRACE(("matched type '%s'", type))
934
935
  /* create the channel */
936
8.05k
  channel = newchannel(remotechan, chantype, transwindow, transmaxpacket);
937
938
8.05k
  if (channel == NULL) {
939
0
    TRACE(("newchannel returned NULL"))
940
0
    errtype = SSH_OPEN_RESOURCE_SHORTAGE;
941
0
    goto failure;
942
0
  }
943
944
8.05k
  if (channel->type->inithandler) {
945
8.04k
    ret = channel->type->inithandler(channel);
946
8.04k
    if (ret == SSH_OPEN_IN_PROGRESS) {
947
      /* We'll send the confirmation later */
948
101
      goto cleanup;
949
101
    }
950
7.94k
    if (ret > 0) {
951
256
      errtype = ret;
952
256
      remove_channel(channel);
953
256
      TRACE(("inithandler returned failure %d", ret))
954
256
      goto failure;
955
256
    }
956
7.94k
  }
957
958
7.69k
  update_channel_prio();
959
960
  /* success */
961
7.69k
  send_msg_channel_open_confirmation(channel, channel->recvwindow,
962
7.69k
      channel->recvmaxpacket);
963
7.69k
  goto cleanup;
964
965
1.00k
failure:
966
1.00k
  TRACE(("recv_msg_channel_open failure"))
967
1.00k
  send_msg_channel_open_failure(remotechan, errtype, "", "");
968
969
8.79k
cleanup:
970
8.79k
  m_free(type);
971
972
8.79k
  TRACE(("leave recv_msg_channel_open"))
973
8.79k
}
974
975
/* Send a failure message */
976
5.05k
void send_msg_channel_failure(const struct Channel *channel) {
977
978
5.05k
  TRACE(("enter send_msg_channel_failure"))
979
980
5.05k
  if (channel->sent_close) {
981
205
    TRACE(("Skipping sending msg_channel_failure for closed channel"))
982
205
    return;
983
205
  }
984
4.84k
  CHECKCLEARTOWRITE();
985
986
4.84k
  buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_FAILURE);
987
4.84k
  buf_putint(ses.writepayload, channel->remotechan);
988
989
4.84k
  encrypt_packet();
990
4.84k
  TRACE(("leave send_msg_channel_failure"))
991
4.84k
}
992
993
/* Send a success message */
994
3.48k
void send_msg_channel_success(const struct Channel *channel) {
995
996
3.48k
  TRACE(("enter send_msg_channel_success"))
997
3.48k
  if (channel->sent_close) {
998
1.62k
    TRACE(("Skipping sending msg_channel_success for closed channel"))
999
1.62k
    return;
1000
1.62k
  }
1001
1.86k
  CHECKCLEARTOWRITE();
1002
1003
1.86k
  buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_SUCCESS);
1004
1.86k
  buf_putint(ses.writepayload, channel->remotechan);
1005
1006
1.86k
  encrypt_packet();
1007
1.86k
  TRACE(("leave send_msg_channel_success"))
1008
1.86k
}
1009
1010
/* Send a channel open failure message, with a corresponding reason
1011
 * code (usually resource shortage or unknown chan type) */
1012
static void send_msg_channel_open_failure(unsigned int remotechan, 
1013
1.10k
    int reason, const char *text, const char *lang) {
1014
1015
1.10k
  TRACE(("enter send_msg_channel_open_failure"))
1016
1.10k
  CHECKCLEARTOWRITE();
1017
  
1018
1.10k
  buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_FAILURE);
1019
1.10k
  buf_putint(ses.writepayload, remotechan);
1020
1.10k
  buf_putint(ses.writepayload, reason);
1021
1.10k
  buf_putstring(ses.writepayload, text, strlen(text));
1022
1.10k
  buf_putstring(ses.writepayload, lang, strlen(lang));
1023
1024
1.10k
  encrypt_packet();
1025
1.10k
  TRACE(("leave send_msg_channel_open_failure"))
1026
1.10k
}
1027
1028
/* Confirm a channel open, and let the remote end know what number we've
1029
 * allocated and the receive parameters */
1030
static void send_msg_channel_open_confirmation(const struct Channel* channel,
1031
    unsigned int recvwindow, 
1032
7.68k
    unsigned int recvmaxpacket) {
1033
1034
7.68k
  TRACE(("enter send_msg_channel_open_confirmation"))
1035
7.68k
  CHECKCLEARTOWRITE();
1036
1037
7.68k
  buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1038
7.68k
  buf_putint(ses.writepayload, channel->remotechan);
1039
7.68k
  buf_putint(ses.writepayload, channel->index);
1040
7.68k
  buf_putint(ses.writepayload, recvwindow);
1041
7.68k
  buf_putint(ses.writepayload, recvmaxpacket);
1042
1043
7.68k
  encrypt_packet();
1044
7.68k
  TRACE(("leave send_msg_channel_open_confirmation"))
1045
7.68k
}
1046
1047
/* close a fd, how is SHUT_RD or SHUT_WR */
1048
15.9k
static void close_chan_fd(struct Channel *channel, int fd, int how) {
1049
1050
15.9k
  int closein = 0, closeout = 0;
1051
1052
15.9k
  if (channel->bidir_fd) {
1053
0
    TRACE(("SHUTDOWN(%d, %d)", fd, how))
1054
0
    shutdown(fd, how);
1055
0
    if (how == 0) {
1056
0
      closeout = 1;
1057
0
    } else {
1058
0
      closein = 1;
1059
0
    }
1060
15.9k
  } else {
1061
15.9k
    TRACE(("CLOSE some fd %d", fd))
1062
15.9k
    m_close(fd);
1063
15.9k
    closein = closeout = 1;
1064
15.9k
  }
1065
1066
15.9k
  if (closeout && (fd == channel->readfd)) {
1067
12.3k
    channel->readfd = FD_CLOSED;
1068
12.3k
  }
1069
15.9k
  if (closeout && ERRFD_IS_READ(channel) && (fd == channel->errfd)) {
1070
8.87k
    channel->errfd = FD_CLOSED;
1071
8.87k
  }
1072
1073
15.9k
  if (closein && fd == channel->writefd) {
1074
15.6k
    channel->writefd = FD_CLOSED;
1075
15.6k
  }
1076
15.9k
  if (closein && ERRFD_IS_WRITE(channel) && (fd == channel->errfd)) {
1077
0
    channel->errfd = FD_CLOSED;
1078
0
  }
1079
1080
  /* if we called shutdown on it and all references are gone, then we 
1081
   * need to close() it to stop it lingering */
1082
15.9k
  if (channel->bidir_fd && channel->readfd == FD_CLOSED 
1083
15.9k
    && channel->writefd == FD_CLOSED && channel->errfd == FD_CLOSED) {
1084
0
    TRACE(("CLOSE (finally) of %d", fd))
1085
0
    m_close(fd);
1086
0
  }
1087
15.9k
}
1088
1089
1090
#if (DROPBEAR_LISTENERS) || (DROPBEAR_CLIENT)
1091
/* Create a new channel, and start the open request. This is intended
1092
 * for X11, agent, tcp forwarding, and should be filled with channel-specific
1093
 * options, with the calling function calling encrypt_packet() after
1094
 * completion. It is mandatory for the caller to encrypt_packet() if
1095
 * a channel is returned. NULL is returned on failure. */
1096
0
int send_msg_channel_open_init(int fd, const struct ChanType *type) {
1097
1098
0
  struct Channel* chan;
1099
1100
0
  TRACE(("enter send_msg_channel_open_init()"))
1101
0
  chan = newchannel(0, type, 0, 0);
1102
0
  if (!chan) {
1103
0
    TRACE(("leave send_msg_channel_open_init() - FAILED in newchannel()"))
1104
0
    return DROPBEAR_FAILURE;
1105
0
  }
1106
1107
  /* Outbound opened channels don't make use of in-progress connections,
1108
   * we can set it up straight away */
1109
1110
  /* set fd non-blocking */
1111
0
  setnonblocking(fd);
1112
1113
0
  chan->writefd = chan->readfd = fd;
1114
0
  ses.maxfd = MAX(ses.maxfd, fd);
1115
0
  chan->bidir_fd = 1;
1116
1117
0
  chan->await_open = 1;
1118
1119
  /* now open the channel connection */
1120
0
  CHECKCLEARTOWRITE();
1121
1122
0
  buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN);
1123
0
  buf_putstring(ses.writepayload, type->name, strlen(type->name));
1124
0
  buf_putint(ses.writepayload, chan->index);
1125
0
  buf_putint(ses.writepayload, opts.recv_window);
1126
0
  buf_putint(ses.writepayload, RECV_MAX_CHANNEL_DATA_LEN);
1127
1128
0
  TRACE(("leave send_msg_channel_open_init()"))
1129
0
  return DROPBEAR_SUCCESS;
1130
0
}
1131
1132
/* Confirmation that our channel open request was 
1133
 * successful*/
1134
0
void recv_msg_channel_open_confirmation() {
1135
1136
0
  struct Channel * channel;
1137
0
  int ret;
1138
1139
0
  TRACE(("enter recv_msg_channel_open_confirmation"))
1140
1141
0
  channel = getchannel();
1142
1143
0
  if (!channel->await_open) {
1144
0
    dropbear_exit("Unexpected channel reply");
1145
0
  }
1146
0
  channel->await_open = 0;
1147
1148
0
  channel->remotechan =  buf_getint(ses.payload);
1149
0
  channel->transwindow = buf_getint(ses.payload);
1150
0
  channel->transmaxpacket = buf_getint(ses.payload);
1151
  
1152
0
  TRACE(("new chan remote %d local %d", 
1153
0
        channel->remotechan, channel->index))
1154
1155
  /* Run the inithandler callback */
1156
0
  if (channel->type->inithandler) {
1157
0
    ret = channel->type->inithandler(channel);
1158
0
    if (ret > 0) {
1159
0
      remove_channel(channel);
1160
0
      TRACE(("inithandler returned failure %d", ret))
1161
0
      return;
1162
0
    }
1163
0
  }
1164
1165
0
  update_channel_prio();
1166
1167
0
  TRACE(("leave recv_msg_channel_open_confirmation"))
1168
0
}
1169
1170
/* Notification that our channel open request failed */
1171
0
void recv_msg_channel_open_failure() {
1172
1173
0
  struct Channel * channel;
1174
1175
0
  channel = getchannel();
1176
1177
0
  if (!channel->await_open) {
1178
0
    dropbear_exit("Unexpected channel reply");
1179
0
  }
1180
0
  channel->await_open = 0;
1181
1182
0
  remove_channel(channel);
1183
0
}
1184
#endif /* DROPBEAR_LISTENERS */
1185
1186
0
void send_msg_request_success() {
1187
0
  CHECKCLEARTOWRITE();
1188
0
  buf_putbyte(ses.writepayload, SSH_MSG_REQUEST_SUCCESS);
1189
0
  encrypt_packet();
1190
0
}
1191
1192
784
void send_msg_request_failure() {
1193
784
  CHECKCLEARTOWRITE();
1194
784
  buf_putbyte(ses.writepayload, SSH_MSG_REQUEST_FAILURE);
1195
784
  encrypt_packet();
1196
784
}
1197
1198
0
struct Channel* get_any_ready_channel() {
1199
0
  size_t i;
1200
0
  if (ses.chancount == 0) {
1201
0
    return NULL;
1202
0
  }
1203
0
  for (i = 0; i < ses.chansize; i++) {
1204
0
    struct Channel *chan = ses.channels[i];
1205
0
    if (chan
1206
0
        && !(chan->sent_eof || chan->recv_eof)
1207
0
        && !(chan->await_open)) {
1208
0
      return chan;
1209
0
    }
1210
0
  }
1211
0
  return NULL;
1212
0
}
1213
1214
void start_send_channel_request(const struct Channel *channel,
1215
0
    const char *type) {
1216
1217
0
  CHECKCLEARTOWRITE();
1218
0
  buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST);
1219
0
  buf_putint(ses.writepayload, channel->remotechan);
1220
1221
0
  buf_putstring(ses.writepayload, type, strlen(type));
1222
1223
0
}