dropbear: update to 2015.67
[tomato.git] / release / src-rt-6.x.4708 / router / dropbear / common-channel.c
blob049658d929e407383920398b24ebb086c893107c
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:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
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. */
25 /* Handle the multiplexed channels, such as sessions, x11, agent connections */
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 "ssh.h"
36 #include "listener.h"
37 #include "runopts.h"
39 static void send_msg_channel_open_failure(unsigned int remotechan, int reason,
40 const unsigned char *text, const unsigned char *lang);
41 static void send_msg_channel_open_confirmation(struct Channel* channel,
42 unsigned int recvwindow,
43 unsigned int recvmaxpacket);
44 static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf);
45 static void send_msg_channel_window_adjust(struct Channel *channel,
46 unsigned int incr);
47 static void send_msg_channel_data(struct Channel *channel, int isextended);
48 static void send_msg_channel_eof(struct Channel *channel);
49 static void send_msg_channel_close(struct Channel *channel);
50 static void remove_channel(struct Channel *channel);
51 static void check_in_progress(struct Channel *channel);
52 static unsigned int write_pending(struct Channel * channel);
53 static void check_close(struct Channel *channel);
54 static void close_chan_fd(struct Channel *channel, int fd, int how);
56 #define FD_UNINIT (-2)
57 #define FD_CLOSED (-1)
59 #define ERRFD_IS_READ(channel) ((channel)->extrabuf == NULL)
60 #define ERRFD_IS_WRITE(channel) (!ERRFD_IS_READ(channel))
62 /* allow space for:
63 * 1 byte byte SSH_MSG_CHANNEL_DATA
64 * 4 bytes uint32 recipient channel
65 * 4 bytes string data
67 #define RECV_MAX_CHANNEL_DATA_LEN (RECV_MAX_PAYLOAD_LEN-(1+4+4))
69 /* Initialise all the channels */
70 void chaninitialise(const struct ChanType *chantypes[]) {
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;
78 ses.chantypes = chantypes;
80 #ifdef USING_LISTENERS
81 listeners_initialise();
82 #endif
86 /* Clean up channels, freeing allocated memory */
87 void chancleanup() {
89 unsigned int i;
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]);
98 m_free(ses.channels);
99 TRACE(("leave chancleanup"))
102 static void
103 chan_initwritebuf(struct Channel *channel)
105 dropbear_assert(channel->writebuf->size == 0 && channel->recvwindow == 0);
106 cbuf_free(channel->writebuf);
107 channel->writebuf = cbuf_new(opts.recv_window);
108 channel->recvwindow = opts.recv_window;
111 /* Create a new channel entry, send a reply confirm or failure */
112 /* If remotechan, transwindow and transmaxpacket are not know (for a new
113 * outgoing connection, with them to be filled on confirmation), they should
114 * all be set to 0 */
115 static struct Channel* newchannel(unsigned int remotechan,
116 const struct ChanType *type,
117 unsigned int transwindow, unsigned int transmaxpacket) {
119 struct Channel * newchan;
120 unsigned int i, j;
122 TRACE(("enter newchannel"))
124 /* first see if we can use existing channels */
125 for (i = 0; i < ses.chansize; i++) {
126 if (ses.channels[i] == NULL) {
127 break;
131 /* otherwise extend the list */
132 if (i == ses.chansize) {
133 if (ses.chansize >= MAX_CHANNELS) {
134 TRACE(("leave newchannel: max chans reached"))
135 return NULL;
138 /* extend the channels */
139 ses.channels = (struct Channel**)m_realloc(ses.channels,
140 (ses.chansize+CHAN_EXTEND_SIZE)*sizeof(struct Channel*));
142 ses.chansize += CHAN_EXTEND_SIZE;
144 /* set the new channels to null */
145 for (j = i; j < ses.chansize; j++) {
146 ses.channels[j] = NULL;
151 newchan = (struct Channel*)m_malloc(sizeof(struct Channel));
152 newchan->type = type;
153 newchan->index = i;
154 newchan->sent_close = newchan->recv_close = 0;
155 newchan->sent_eof = newchan->recv_eof = 0;
156 newchan->close_handler_done = 0;
158 newchan->remotechan = remotechan;
159 newchan->transwindow = transwindow;
160 newchan->transmaxpacket = transmaxpacket;
162 newchan->typedata = NULL;
163 newchan->writefd = FD_UNINIT;
164 newchan->readfd = FD_UNINIT;
165 newchan->errfd = FD_CLOSED; /* this isn't always set to start with */
166 newchan->initconn = 0;
167 newchan->await_open = 0;
168 newchan->flushing = 0;
170 newchan->writebuf = cbuf_new(0); /* resized later by chan_initwritebuf */
171 newchan->recvwindow = 0;
173 newchan->extrabuf = NULL; /* The user code can set it up */
174 newchan->recvdonelen = 0;
175 newchan->recvmaxpacket = RECV_MAX_CHANNEL_DATA_LEN;
177 newchan->prio = DROPBEAR_CHANNEL_PRIO_EARLY; /* inithandler sets it */
179 ses.channels[i] = newchan;
180 ses.chancount++;
182 TRACE(("leave newchannel"))
184 return newchan;
187 /* Returns the channel structure corresponding to the channel in the current
188 * data packet (ses.payload must be positioned appropriately).
189 * A valid channel is always returns, it will fail fatally with an unknown
190 * channel */
191 static struct Channel* getchannel_msg(const char* kind) {
193 unsigned int chan;
195 chan = buf_getint(ses.payload);
196 if (chan >= ses.chansize || ses.channels[chan] == NULL) {
197 if (kind) {
198 dropbear_exit("%s for unknown channel %d", kind, chan);
199 } else {
200 dropbear_exit("Unknown channel %d", chan);
203 return ses.channels[chan];
206 struct Channel* getchannel() {
207 return getchannel_msg(NULL);
210 /* Iterate through the channels, performing IO if available */
211 void channelio(fd_set *readfds, fd_set *writefds) {
213 /* Listeners such as TCP, X11, agent-auth */
214 struct Channel *channel;
215 unsigned int i;
217 /* foreach channel */
218 for (i = 0; i < ses.chansize; i++) {
219 /* Close checking only needs to occur for channels that had IO events */
220 int do_check_close = 0;
222 channel = ses.channels[i];
223 if (channel == NULL) {
224 /* only process in-use channels */
225 continue;
228 /* read data and send it over the wire */
229 if (channel->readfd >= 0 && FD_ISSET(channel->readfd, readfds)) {
230 TRACE(("send normal readfd"))
231 send_msg_channel_data(channel, 0);
232 do_check_close = 1;
235 /* read stderr data and send it over the wire */
236 if (ERRFD_IS_READ(channel) && channel->errfd >= 0
237 && FD_ISSET(channel->errfd, readfds)) {
238 TRACE(("send normal errfd"))
239 send_msg_channel_data(channel, 1);
240 do_check_close = 1;
243 /* write to program/pipe stdin */
244 if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) {
245 if (channel->initconn) {
246 /* XXX should this go somewhere cleaner? */
247 check_in_progress(channel);
248 continue; /* Important not to use the channel after
249 check_in_progress(), as it may be NULL */
251 writechannel(channel, channel->writefd, channel->writebuf);
252 do_check_close = 1;
255 /* stderr for client mode */
256 if (ERRFD_IS_WRITE(channel)
257 && channel->errfd >= 0 && FD_ISSET(channel->errfd, writefds)) {
258 writechannel(channel, channel->errfd, channel->extrabuf);
259 do_check_close = 1;
262 if (ses.channel_signal_pending) {
263 /* SIGCHLD can change channel state for server sessions */
264 do_check_close = 1;
265 ses.channel_signal_pending = 0;
268 /* handle any channel closing etc */
269 if (do_check_close) {
270 check_close(channel);
274 #ifdef USING_LISTENERS
275 handle_listeners(readfds);
276 #endif
280 /* Returns true if there is data remaining to be written to stdin or
281 * stderr of a channel's endpoint. */
282 static unsigned int write_pending(struct Channel * channel) {
284 if (channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0) {
285 return 1;
286 } else if (channel->errfd >= 0 && channel->extrabuf &&
287 cbuf_getused(channel->extrabuf) > 0) {
288 return 1;
290 return 0;
294 /* EOF/close handling */
295 static void check_close(struct Channel *channel) {
296 int close_allowed = 0;
298 TRACE2(("check_close: writefd %d, readfd %d, errfd %d, sent_close %d, recv_close %d",
299 channel->writefd, channel->readfd,
300 channel->errfd, channel->sent_close, channel->recv_close))
301 TRACE2(("writebuf size %d extrabuf size %d",
302 channel->writebuf ? cbuf_getused(channel->writebuf) : 0,
303 channel->extrabuf ? cbuf_getused(channel->extrabuf) : 0))
305 if (!channel->flushing
306 && !channel->close_handler_done
307 && channel->type->check_close
308 && channel->type->check_close(channel))
310 channel->flushing = 1;
313 /* if a type-specific check_close is defined we will only exit
314 once that has been triggered. this is only used for a server "session"
315 channel, to ensure that the shell has exited (and the exit status
316 retrieved) before we close things up. */
317 if (!channel->type->check_close
318 || channel->close_handler_done
319 || channel->type->check_close(channel)) {
320 close_allowed = 1;
323 if (channel->recv_close && !write_pending(channel) && close_allowed) {
324 if (!channel->sent_close) {
325 TRACE(("Sending MSG_CHANNEL_CLOSE in response to same."))
326 send_msg_channel_close(channel);
328 remove_channel(channel);
329 return;
332 if ((channel->recv_eof && !write_pending(channel))
333 /* have a server "session" and child has exited */
334 || (channel->type->check_close && close_allowed)) {
335 close_chan_fd(channel, channel->writefd, SHUT_WR);
338 /* Special handling for flushing read data after an exit. We
339 read regardless of whether the select FD was set,
340 and if there isn't data available, the channel will get closed. */
341 if (channel->flushing) {
342 TRACE(("might send data, flushing"))
343 if (channel->readfd >= 0 && channel->transwindow > 0) {
344 TRACE(("send data readfd"))
345 send_msg_channel_data(channel, 0);
347 if (ERRFD_IS_READ(channel) && channel->errfd >= 0
348 && channel->transwindow > 0) {
349 TRACE(("send data errfd"))
350 send_msg_channel_data(channel, 1);
354 /* If we're not going to send any more data, send EOF */
355 if (!channel->sent_eof
356 && channel->readfd == FD_CLOSED
357 && (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED)) {
358 send_msg_channel_eof(channel);
361 /* And if we can't receive any more data from them either, close up */
362 if (channel->readfd == FD_CLOSED
363 && channel->writefd == FD_CLOSED
364 && (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED)
365 && !channel->sent_close
366 && close_allowed
367 && !write_pending(channel)) {
368 TRACE(("sending close, readfd is closed"))
369 send_msg_channel_close(channel);
373 /* Check whether a deferred (EINPROGRESS) connect() was successful, and
374 * if so, set up the channel properly. Otherwise, the channel is cleaned up, so
375 * it is important that the channel reference isn't used after a call to this
376 * function */
377 static void check_in_progress(struct Channel *channel) {
379 int val;
380 socklen_t vallen = sizeof(val);
382 TRACE(("enter check_in_progress"))
384 if (getsockopt(channel->writefd, SOL_SOCKET, SO_ERROR, &val, &vallen)
385 || val != 0) {
386 send_msg_channel_open_failure(channel->remotechan,
387 SSH_OPEN_CONNECT_FAILED, "", "");
388 close(channel->writefd);
389 remove_channel(channel);
390 TRACE(("leave check_in_progress: fail"))
391 } else {
392 chan_initwritebuf(channel);
393 send_msg_channel_open_confirmation(channel, channel->recvwindow,
394 channel->recvmaxpacket);
395 channel->readfd = channel->writefd;
396 channel->initconn = 0;
397 TRACE(("leave check_in_progress: success"))
402 /* Send the close message and set the channel as closed */
403 static void send_msg_channel_close(struct Channel *channel) {
405 TRACE(("enter send_msg_channel_close %p", channel))
406 if (channel->type->closehandler
407 && !channel->close_handler_done) {
408 channel->type->closehandler(channel);
409 channel->close_handler_done = 1;
412 CHECKCLEARTOWRITE();
414 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_CLOSE);
415 buf_putint(ses.writepayload, channel->remotechan);
417 encrypt_packet();
419 channel->sent_eof = 1;
420 channel->sent_close = 1;
421 close_chan_fd(channel, channel->readfd, SHUT_RD);
422 close_chan_fd(channel, channel->errfd, SHUT_RDWR);
423 close_chan_fd(channel, channel->writefd, SHUT_WR);
424 TRACE(("leave send_msg_channel_close"))
427 /* call this when trans/eof channels are closed */
428 static void send_msg_channel_eof(struct Channel *channel) {
430 TRACE(("enter send_msg_channel_eof"))
431 CHECKCLEARTOWRITE();
433 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_EOF);
434 buf_putint(ses.writepayload, channel->remotechan);
436 encrypt_packet();
438 channel->sent_eof = 1;
440 TRACE(("leave send_msg_channel_eof"))
443 /* Called to write data out to the local side of the channel.
444 * Only called when we know we can write to a channel, writes as much as
445 * possible */
446 static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) {
448 int len, maxlen;
450 TRACE(("enter writechannel fd %d", fd))
452 maxlen = cbuf_readlen(cbuf);
454 /* Write the data out */
455 len = write(fd, cbuf_readptr(cbuf, maxlen), maxlen);
456 if (len <= 0) {
457 TRACE(("errno %d len %d", errno, len))
458 if (len < 0 && errno != EINTR) {
459 close_chan_fd(channel, fd, SHUT_WR);
461 TRACE(("leave writechannel: len <= 0"))
462 return;
464 TRACE(("writechannel wrote %d", len))
466 cbuf_incrread(cbuf, len);
467 channel->recvdonelen += len;
469 /* Window adjust handling */
470 if (channel->recvdonelen >= RECV_WINDOWEXTEND) {
471 /* Set it back to max window */
472 send_msg_channel_window_adjust(channel, channel->recvdonelen);
473 channel->recvwindow += channel->recvdonelen;
474 channel->recvdonelen = 0;
477 dropbear_assert(channel->recvwindow <= opts.recv_window);
478 dropbear_assert(channel->recvwindow <= cbuf_getavail(channel->writebuf));
479 dropbear_assert(channel->extrabuf == NULL ||
480 channel->recvwindow <= cbuf_getavail(channel->extrabuf));
482 TRACE(("leave writechannel"))
485 /* Set the file descriptors for the main select in session.c
486 * This avoid channels which don't have any window available, are closed, etc*/
487 void setchannelfds(fd_set *readfds, fd_set *writefds) {
489 unsigned int i;
490 struct Channel * channel;
492 for (i = 0; i < ses.chansize; i++) {
494 channel = ses.channels[i];
495 if (channel == NULL) {
496 continue;
499 /* Stuff to put over the wire.
500 Avoid queueing data to send if we're in the middle of a
501 key re-exchange (!dataallowed), but still read from the
502 FD if there's the possibility of "~."" to kill an
503 interactive session (the read_mangler) */
504 if (channel->transwindow > 0
505 && (ses.dataallowed || channel->read_mangler)) {
507 if (channel->readfd >= 0) {
508 FD_SET(channel->readfd, readfds);
511 if (ERRFD_IS_READ(channel) && channel->errfd >= 0) {
512 FD_SET(channel->errfd, readfds);
516 /* Stuff from the wire */
517 if (channel->initconn
518 ||(channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0)) {
519 FD_SET(channel->writefd, writefds);
522 if (ERRFD_IS_WRITE(channel) && channel->errfd >= 0
523 && cbuf_getused(channel->extrabuf) > 0) {
524 FD_SET(channel->errfd, writefds);
527 } /* foreach channel */
529 #ifdef USING_LISTENERS
530 set_listener_fds(readfds);
531 #endif
535 /* handle the channel EOF event, by closing the channel filedescriptor. The
536 * channel isn't closed yet, it is left until the incoming (from the program
537 * etc) FD is also EOF */
538 void recv_msg_channel_eof() {
540 struct Channel * channel;
542 TRACE(("enter recv_msg_channel_eof"))
544 channel = getchannel_msg("EOF");
546 channel->recv_eof = 1;
548 check_close(channel);
549 TRACE(("leave recv_msg_channel_eof"))
553 /* Handle channel closure(), respond in kind and close the channels */
554 void recv_msg_channel_close() {
556 struct Channel * channel;
558 TRACE(("enter recv_msg_channel_close"))
560 channel = getchannel_msg("Close");
562 channel->recv_eof = 1;
563 channel->recv_close = 1;
565 check_close(channel);
566 TRACE(("leave recv_msg_channel_close"))
569 /* Remove a channel entry, this is only executed after both sides have sent
570 * channel close */
571 static void remove_channel(struct Channel * channel) {
573 TRACE(("enter remove_channel"))
574 TRACE(("channel index is %d", channel->index))
576 cbuf_free(channel->writebuf);
577 channel->writebuf = NULL;
579 if (channel->extrabuf) {
580 cbuf_free(channel->extrabuf);
581 channel->extrabuf = NULL;
585 if (IS_DROPBEAR_SERVER || (channel->writefd != STDOUT_FILENO)) {
586 /* close the FDs in case they haven't been done
587 * yet (they might have been shutdown etc) */
588 TRACE(("CLOSE writefd %d", channel->writefd))
589 close(channel->writefd);
590 TRACE(("CLOSE readfd %d", channel->readfd))
591 close(channel->readfd);
592 TRACE(("CLOSE errfd %d", channel->errfd))
593 close(channel->errfd);
596 if (!channel->close_handler_done
597 && channel->type->closehandler) {
598 channel->type->closehandler(channel);
599 channel->close_handler_done = 1;
602 ses.channels[channel->index] = NULL;
603 m_free(channel);
604 ses.chancount--;
606 update_channel_prio();
608 TRACE(("leave remove_channel"))
611 /* Handle channel specific requests, passing off to corresponding handlers
612 * such as chansession or x11fwd */
613 void recv_msg_channel_request() {
615 struct Channel *channel;
617 channel = getchannel();
619 TRACE(("enter recv_msg_channel_request %p", channel))
621 if (channel->sent_close) {
622 TRACE(("leave recv_msg_channel_request: already closed channel"))
623 return;
626 if (channel->type->reqhandler
627 && !channel->close_handler_done) {
628 channel->type->reqhandler(channel);
629 } else {
630 int wantreply;
631 buf_eatstring(ses.payload);
632 wantreply = buf_getbool(ses.payload);
633 if (wantreply) {
634 send_msg_channel_failure(channel);
638 TRACE(("leave recv_msg_channel_request"))
642 /* Reads data from the server's program/shell/etc, and puts it in a
643 * channel_data packet to send.
644 * chan is the remote channel, isextended is 0 if it is normal data, 1
645 * if it is extended data. if it is extended, then the type is in
646 * exttype */
647 static void send_msg_channel_data(struct Channel *channel, int isextended) {
649 int len;
650 size_t maxlen, size_pos;
651 int fd;
653 CHECKCLEARTOWRITE();
655 TRACE(("enter send_msg_channel_data"))
656 dropbear_assert(!channel->sent_close);
658 if (isextended) {
659 fd = channel->errfd;
660 } else {
661 fd = channel->readfd;
663 TRACE(("enter send_msg_channel_data isextended %d fd %d", isextended, fd))
664 dropbear_assert(fd >= 0);
666 maxlen = MIN(channel->transwindow, channel->transmaxpacket);
667 /* -(1+4+4) is SSH_MSG_CHANNEL_DATA, channel number, string length, and
668 * exttype if is extended */
669 maxlen = MIN(maxlen,
670 ses.writepayload->size - 1 - 4 - 4 - (isextended ? 4 : 0));
671 TRACE(("maxlen %zd", maxlen))
672 if (maxlen == 0) {
673 TRACE(("leave send_msg_channel_data: no window"))
674 return;
677 buf_putbyte(ses.writepayload,
678 isextended ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA);
679 buf_putint(ses.writepayload, channel->remotechan);
680 if (isextended) {
681 buf_putint(ses.writepayload, SSH_EXTENDED_DATA_STDERR);
683 /* a dummy size first ...*/
684 size_pos = ses.writepayload->pos;
685 buf_putint(ses.writepayload, 0);
687 /* read the data */
688 len = read(fd, buf_getwriteptr(ses.writepayload, maxlen), maxlen);
690 if (len <= 0) {
691 if (len == 0 || errno != EINTR) {
692 /* This will also get hit in the case of EAGAIN. The only
693 time we expect to receive EAGAIN is when we're flushing a FD,
694 in which case it can be treated the same as EOF */
695 close_chan_fd(channel, fd, SHUT_RD);
697 buf_setpos(ses.writepayload, 0);
698 buf_setlen(ses.writepayload, 0);
699 TRACE(("leave send_msg_channel_data: len %d read err %d or EOF for fd %d",
700 len, errno, fd))
701 return;
704 if (channel->read_mangler) {
705 channel->read_mangler(channel, buf_getwriteptr(ses.writepayload, len), &len);
706 if (len == 0) {
707 buf_setpos(ses.writepayload, 0);
708 buf_setlen(ses.writepayload, 0);
709 return;
713 TRACE(("send_msg_channel_data: len %d fd %d", len, fd))
714 buf_incrwritepos(ses.writepayload, len);
715 /* ... real size here */
716 buf_setpos(ses.writepayload, size_pos);
717 buf_putint(ses.writepayload, len);
719 channel->transwindow -= len;
721 encrypt_packet();
723 /* If we receive less data than we requested when flushing, we've
724 reached the equivalent of EOF */
725 if (channel->flushing && len < (ssize_t)maxlen)
727 TRACE(("closing from channel, flushing out."))
728 close_chan_fd(channel, fd, SHUT_RD);
730 TRACE(("leave send_msg_channel_data"))
733 /* We receive channel data */
734 void recv_msg_channel_data() {
736 struct Channel *channel;
738 channel = getchannel();
740 common_recv_msg_channel_data(channel, channel->writefd, channel->writebuf);
743 /* Shared for data and stderr data - when we receive data, put it in a buffer
744 * for writing to the local file descriptor */
745 void common_recv_msg_channel_data(struct Channel *channel, int fd,
746 circbuffer * cbuf) {
748 unsigned int datalen;
749 unsigned int maxdata;
750 unsigned int buflen;
751 unsigned int len;
753 TRACE(("enter recv_msg_channel_data"))
755 if (channel->recv_eof) {
756 dropbear_exit("Received data after eof");
759 if (fd < 0 || !cbuf) {
760 /* If we have encountered failed write, the far side might still
761 * be sending data without having yet received our close notification.
762 * We just drop the data. */
763 return;
766 datalen = buf_getint(ses.payload);
767 TRACE(("length %d", datalen))
769 maxdata = cbuf_getavail(cbuf);
771 /* Whilst the spec says we "MAY ignore data past the end" this could
772 * lead to corrupted file transfers etc (chunks missed etc). It's better to
773 * just die horribly */
774 if (datalen > maxdata) {
775 dropbear_exit("Oversized packet");
778 /* We may have to run throught twice, if the buffer wraps around. Can't
779 * just "leave it for next time" like with writechannel, since this
780 * is payload data */
781 len = datalen;
782 while (len > 0) {
783 buflen = cbuf_writelen(cbuf);
784 buflen = MIN(buflen, len);
786 memcpy(cbuf_writeptr(cbuf, buflen),
787 buf_getptr(ses.payload, buflen), buflen);
788 cbuf_incrwrite(cbuf, buflen);
789 buf_incrpos(ses.payload, buflen);
790 len -= buflen;
793 dropbear_assert(channel->recvwindow >= datalen);
794 channel->recvwindow -= datalen;
795 dropbear_assert(channel->recvwindow <= opts.recv_window);
797 TRACE(("leave recv_msg_channel_data"))
800 /* Increment the outgoing data window for a channel - the remote end limits
801 * the amount of data which may be transmitted, this window is decremented
802 * as data is sent, and incremented upon receiving window-adjust messages */
803 void recv_msg_channel_window_adjust() {
805 struct Channel * channel;
806 unsigned int incr;
808 channel = getchannel();
810 incr = buf_getint(ses.payload);
811 TRACE(("received window increment %d", incr))
812 incr = MIN(incr, TRANS_MAX_WIN_INCR);
814 channel->transwindow += incr;
815 channel->transwindow = MIN(channel->transwindow, TRANS_MAX_WINDOW);
819 /* Increment the incoming data window for a channel, and let the remote
820 * end know */
821 static void send_msg_channel_window_adjust(struct Channel* channel,
822 unsigned int incr) {
824 TRACE(("sending window adjust %d", incr))
825 CHECKCLEARTOWRITE();
827 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_WINDOW_ADJUST);
828 buf_putint(ses.writepayload, channel->remotechan);
829 buf_putint(ses.writepayload, incr);
831 encrypt_packet();
834 /* Handle a new channel request, performing any channel-type-specific setup */
835 void recv_msg_channel_open() {
837 unsigned char *type;
838 unsigned int typelen;
839 unsigned int remotechan, transwindow, transmaxpacket;
840 struct Channel *channel;
841 const struct ChanType **cp;
842 const struct ChanType *chantype;
843 unsigned int errtype = SSH_OPEN_UNKNOWN_CHANNEL_TYPE;
844 int ret;
847 TRACE(("enter recv_msg_channel_open"))
849 /* get the packet contents */
850 type = buf_getstring(ses.payload, &typelen);
852 remotechan = buf_getint(ses.payload);
853 transwindow = buf_getint(ses.payload);
854 transwindow = MIN(transwindow, TRANS_MAX_WINDOW);
855 transmaxpacket = buf_getint(ses.payload);
856 transmaxpacket = MIN(transmaxpacket, TRANS_MAX_PAYLOAD_LEN);
858 /* figure what type of packet it is */
859 if (typelen > MAX_NAME_LEN) {
860 goto failure;
863 /* Get the channel type. Client and server style invokation will set up a
864 * different list for ses.chantypes at startup. We just iterate through
865 * this list and find the matching name */
866 for (cp = &ses.chantypes[0], chantype = (*cp);
867 chantype != NULL;
868 cp++, chantype = (*cp)) {
869 if (strcmp(type, chantype->name) == 0) {
870 break;
874 if (chantype == NULL) {
875 TRACE(("No matching type for '%s'", type))
876 goto failure;
879 TRACE(("matched type '%s'", type))
881 /* create the channel */
882 channel = newchannel(remotechan, chantype, transwindow, transmaxpacket);
884 if (channel == NULL) {
885 TRACE(("newchannel returned NULL"))
886 goto failure;
889 if (channel->type->inithandler) {
890 ret = channel->type->inithandler(channel);
891 if (ret == SSH_OPEN_IN_PROGRESS) {
892 /* We'll send the confirmation later */
893 goto cleanup;
895 if (ret > 0) {
896 errtype = ret;
897 remove_channel(channel);
898 TRACE(("inithandler returned failure %d", ret))
899 goto failure;
903 if (channel->prio == DROPBEAR_CHANNEL_PRIO_EARLY) {
904 channel->prio = DROPBEAR_CHANNEL_PRIO_BULK;
907 chan_initwritebuf(channel);
909 /* success */
910 send_msg_channel_open_confirmation(channel, channel->recvwindow,
911 channel->recvmaxpacket);
912 goto cleanup;
914 failure:
915 TRACE(("recv_msg_channel_open failure"))
916 send_msg_channel_open_failure(remotechan, errtype, "", "");
918 cleanup:
919 m_free(type);
921 update_channel_prio();
923 TRACE(("leave recv_msg_channel_open"))
926 /* Send a failure message */
927 void send_msg_channel_failure(struct Channel *channel) {
929 TRACE(("enter send_msg_channel_failure"))
930 CHECKCLEARTOWRITE();
932 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_FAILURE);
933 buf_putint(ses.writepayload, channel->remotechan);
935 encrypt_packet();
936 TRACE(("leave send_msg_channel_failure"))
939 /* Send a success message */
940 void send_msg_channel_success(struct Channel *channel) {
942 TRACE(("enter send_msg_channel_success"))
943 CHECKCLEARTOWRITE();
945 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_SUCCESS);
946 buf_putint(ses.writepayload, channel->remotechan);
948 encrypt_packet();
949 TRACE(("leave send_msg_channel_success"))
952 /* Send a channel open failure message, with a corresponding reason
953 * code (usually resource shortage or unknown chan type) */
954 static void send_msg_channel_open_failure(unsigned int remotechan,
955 int reason, const unsigned char *text, const unsigned char *lang) {
957 TRACE(("enter send_msg_channel_open_failure"))
958 CHECKCLEARTOWRITE();
960 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_FAILURE);
961 buf_putint(ses.writepayload, remotechan);
962 buf_putint(ses.writepayload, reason);
963 buf_putstring(ses.writepayload, text, strlen((char*)text));
964 buf_putstring(ses.writepayload, lang, strlen((char*)lang));
966 encrypt_packet();
967 TRACE(("leave send_msg_channel_open_failure"))
970 /* Confirm a channel open, and let the remote end know what number we've
971 * allocated and the receive parameters */
972 static void send_msg_channel_open_confirmation(struct Channel* channel,
973 unsigned int recvwindow,
974 unsigned int recvmaxpacket) {
976 TRACE(("enter send_msg_channel_open_confirmation"))
977 CHECKCLEARTOWRITE();
979 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
980 buf_putint(ses.writepayload, channel->remotechan);
981 buf_putint(ses.writepayload, channel->index);
982 buf_putint(ses.writepayload, recvwindow);
983 buf_putint(ses.writepayload, recvmaxpacket);
985 encrypt_packet();
986 TRACE(("leave send_msg_channel_open_confirmation"))
989 /* close a fd, how is SHUT_RD or SHUT_WR */
990 static void close_chan_fd(struct Channel *channel, int fd, int how) {
992 int closein = 0, closeout = 0;
994 if (channel->type->sepfds) {
995 TRACE(("SHUTDOWN(%d, %d)", fd, how))
996 shutdown(fd, how);
997 if (how == 0) {
998 closeout = 1;
999 } else {
1000 closein = 1;
1002 } else {
1003 TRACE(("CLOSE some fd %d", fd))
1004 close(fd);
1005 closein = closeout = 1;
1008 if (closeout && (fd == channel->readfd)) {
1009 channel->readfd = FD_CLOSED;
1011 if (closeout && ERRFD_IS_READ(channel) && (fd == channel->errfd)) {
1012 channel->errfd = FD_CLOSED;
1015 if (closein && fd == channel->writefd) {
1016 channel->writefd = FD_CLOSED;
1018 if (closein && ERRFD_IS_WRITE(channel) && (fd == channel->errfd)) {
1019 channel->errfd = FD_CLOSED;
1022 /* if we called shutdown on it and all references are gone, then we
1023 * need to close() it to stop it lingering */
1024 if (channel->type->sepfds && channel->readfd == FD_CLOSED
1025 && channel->writefd == FD_CLOSED && channel->errfd == FD_CLOSED) {
1026 TRACE(("CLOSE (finally) of %d", fd))
1027 close(fd);
1032 #if defined(USING_LISTENERS) || defined(DROPBEAR_CLIENT)
1033 /* Create a new channel, and start the open request. This is intended
1034 * for X11, agent, tcp forwarding, and should be filled with channel-specific
1035 * options, with the calling function calling encrypt_packet() after
1036 * completion. It is mandatory for the caller to encrypt_packet() if
1037 * a channel is returned. NULL is returned on failure. */
1038 int send_msg_channel_open_init(int fd, const struct ChanType *type) {
1040 struct Channel* chan;
1042 TRACE(("enter send_msg_channel_open_init()"))
1043 chan = newchannel(0, type, 0, 0);
1044 if (!chan) {
1045 TRACE(("leave send_msg_channel_open_init() - FAILED in newchannel()"))
1046 return DROPBEAR_FAILURE;
1049 /* Outbound opened channels don't make use of in-progress connections,
1050 * we can set it up straight away */
1051 chan_initwritebuf(chan);
1053 /* set fd non-blocking */
1054 setnonblocking(fd);
1056 chan->writefd = chan->readfd = fd;
1057 ses.maxfd = MAX(ses.maxfd, fd);
1059 chan->await_open = 1;
1061 /* now open the channel connection */
1062 CHECKCLEARTOWRITE();
1064 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN);
1065 buf_putstring(ses.writepayload, type->name, strlen(type->name));
1066 buf_putint(ses.writepayload, chan->index);
1067 buf_putint(ses.writepayload, opts.recv_window);
1068 buf_putint(ses.writepayload, RECV_MAX_CHANNEL_DATA_LEN);
1070 TRACE(("leave send_msg_channel_open_init()"))
1071 return DROPBEAR_SUCCESS;
1074 /* Confirmation that our channel open request (for forwardings) was
1075 * successful*/
1076 void recv_msg_channel_open_confirmation() {
1078 struct Channel * channel;
1079 int ret;
1081 TRACE(("enter recv_msg_channel_open_confirmation"))
1083 channel = getchannel();
1085 if (!channel->await_open) {
1086 dropbear_exit("Unexpected channel reply");
1088 channel->await_open = 0;
1090 channel->remotechan = buf_getint(ses.payload);
1091 channel->transwindow = buf_getint(ses.payload);
1092 channel->transmaxpacket = buf_getint(ses.payload);
1094 TRACE(("new chan remote %d local %d",
1095 channel->remotechan, channel->index))
1097 /* Run the inithandler callback */
1098 if (channel->type->inithandler) {
1099 ret = channel->type->inithandler(channel);
1100 if (ret > 0) {
1101 remove_channel(channel);
1102 TRACE(("inithandler returned failure %d", ret))
1103 return;
1107 if (channel->prio == DROPBEAR_CHANNEL_PRIO_EARLY) {
1108 channel->prio = DROPBEAR_CHANNEL_PRIO_BULK;
1110 update_channel_prio();
1112 TRACE(("leave recv_msg_channel_open_confirmation"))
1115 /* Notification that our channel open request failed */
1116 void recv_msg_channel_open_failure() {
1118 struct Channel * channel;
1120 channel = getchannel();
1122 if (!channel->await_open) {
1123 dropbear_exit("Unexpected channel reply");
1125 channel->await_open = 0;
1127 remove_channel(channel);
1129 #endif /* USING_LISTENERS */
1131 void send_msg_request_success() {
1132 CHECKCLEARTOWRITE();
1133 buf_putbyte(ses.writepayload, SSH_MSG_REQUEST_SUCCESS);
1134 encrypt_packet();
1137 void send_msg_request_failure() {
1138 CHECKCLEARTOWRITE();
1139 buf_putbyte(ses.writepayload, SSH_MSG_REQUEST_FAILURE);
1140 encrypt_packet();
1143 struct Channel* get_any_ready_channel() {
1144 if (ses.chancount == 0) {
1145 return NULL;
1147 size_t i;
1148 for (i = 0; i < ses.chansize; i++) {
1149 struct Channel *chan = ses.channels[i];
1150 if (chan
1151 && !(chan->sent_eof || chan->recv_eof)
1152 && !(chan->await_open || chan->initconn)) {
1153 return chan;
1156 return NULL;
1159 void start_send_channel_request(struct Channel *channel,
1160 unsigned char *type) {
1162 CHECKCLEARTOWRITE();
1163 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST);
1164 buf_putint(ses.writepayload, channel->remotechan);
1166 buf_putstring(ses.writepayload, type, strlen(type));