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