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 "ssh.h"
36 #include "listener.h"
37
38 static void send_msg_channel_open_failure(unsigned int remotechan, int reason,
39 const unsigned char *text, const unsigned char *lang);
40 static void send_msg_channel_open_confirmation(struct Channel* channel,
41 unsigned int recvwindow,
42 unsigned int recvmaxpacket);
43 static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf);
44 static void send_msg_channel_window_adjust(struct Channel *channel,
45 unsigned int incr);
46 static void send_msg_channel_data(struct Channel *channel, int isextended);
47 static void send_msg_channel_eof(struct Channel *channel);
48 static void send_msg_channel_close(struct Channel *channel);
49 static void remove_channel(struct Channel *channel);
50 static void delete_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);
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 /* Initialise all the channels */
chaninitialise(const struct ChanType * chantypes[])63 void chaninitialise(const struct ChanType *chantypes[]) {
64
65 /* may as well create space for a single channel */
66 ses.channels = (struct Channel**)m_malloc(sizeof(struct Channel*));
67 ses.chansize = 1;
68 ses.channels[0] = NULL;
69 ses.chancount = 0;
70
71 ses.chantypes = chantypes;
72
73 #ifdef USING_LISTENERS
74 listeners_initialise();
75 #endif
76
77 }
78
79 /* Clean up channels, freeing allocated memory */
chancleanup()80 void chancleanup() {
81
82 unsigned int i;
83
84 TRACE(("enter chancleanup"))
85 for (i = 0; i < ses.chansize; i++) {
86 if (ses.channels[i] != NULL) {
87 TRACE(("channel %d closing", i))
88 remove_channel(ses.channels[i]);
89 }
90 }
91 m_free(ses.channels);
92 TRACE(("leave chancleanup"))
93 }
94
95 /* Create a new channel entry, send a reply confirm or failure */
96 /* If remotechan, transwindow and transmaxpacket are not know (for a new
97 * outgoing connection, with them to be filled on confirmation), they should
98 * all be set to 0 */
newchannel(unsigned int remotechan,const struct ChanType * type,unsigned int transwindow,unsigned int transmaxpacket)99 struct Channel* newchannel(unsigned int remotechan,
100 const struct ChanType *type,
101 unsigned int transwindow, unsigned int transmaxpacket) {
102
103 struct Channel * newchan;
104 unsigned int i, j;
105
106 TRACE(("enter newchannel"))
107
108 /* first see if we can use existing channels */
109 for (i = 0; i < ses.chansize; i++) {
110 if (ses.channels[i] == NULL) {
111 break;
112 }
113 }
114
115 /* otherwise extend the list */
116 if (i == ses.chansize) {
117 if (ses.chansize >= MAX_CHANNELS) {
118 TRACE(("leave newchannel: max chans reached"))
119 return NULL;
120 }
121
122 /* extend the channels */
123 ses.channels = (struct Channel**)m_realloc(ses.channels,
124 (ses.chansize+CHAN_EXTEND_SIZE)*sizeof(struct Channel*));
125
126 ses.chansize += CHAN_EXTEND_SIZE;
127
128 /* set the new channels to null */
129 for (j = i; j < ses.chansize; j++) {
130 ses.channels[j] = NULL;
131 }
132
133 }
134
135 newchan = (struct Channel*)m_malloc(sizeof(struct Channel));
136 newchan->type = type;
137 newchan->index = i;
138 newchan->sent_close = newchan->recv_close = 0;
139 newchan->sent_eof = newchan->recv_eof = 0;
140
141 newchan->remotechan = remotechan;
142 newchan->transwindow = transwindow;
143 newchan->transmaxpacket = transmaxpacket;
144
145 newchan->typedata = NULL;
146 newchan->writefd = FD_UNINIT;
147 newchan->readfd = FD_UNINIT;
148 newchan->errfd = FD_CLOSED; /* this isn't always set to start with */
149 newchan->initconn = 0;
150 newchan->await_open = 0;
151 newchan->flushing = 0;
152
153 newchan->writebuf = cbuf_new(RECV_MAXWINDOW);
154 newchan->extrabuf = NULL; /* The user code can set it up */
155 newchan->recvwindow = RECV_MAXWINDOW;
156 newchan->recvdonelen = 0;
157 newchan->recvmaxpacket = RECV_MAXPACKET;
158
159 ses.channels[i] = newchan;
160 ses.chancount++;
161
162 TRACE(("leave newchannel"))
163
164 return newchan;
165 }
166
167 /* Returns the channel structure corresponding to the channel in the current
168 * data packet (ses.payload must be positioned appropriately).
169 * A valid channel is always returns, it will fail fatally with an unknown
170 * channel */
getchannel_msg(const char * kind)171 static struct Channel* getchannel_msg(const char* kind) {
172
173 unsigned int chan;
174
175 chan = buf_getint(ses.payload);
176 if (chan >= ses.chansize || ses.channels[chan] == NULL) {
177 if (kind) {
178 dropbear_exit("%s for unknown channel %d", kind, chan);
179 } else {
180 dropbear_exit("Unknown channel %d", chan);
181 }
182 }
183 return ses.channels[chan];
184 }
185
getchannel()186 struct Channel* getchannel() {
187 return getchannel_msg(NULL);
188 }
189
190 /* Iterate through the channels, performing IO if available */
channelio(fd_set * readfds,fd_set * writefds)191 void channelio(fd_set *readfds, fd_set *writefds) {
192
193 struct Channel *channel;
194 unsigned int i;
195
196 /* foreach channel */
197 for (i = 0; i < ses.chansize; i++) {
198
199 channel = ses.channels[i];
200 if (channel == NULL) {
201 /* only process in-use channels */
202 continue;
203 }
204
205 /* read data and send it over the wire */
206 if (channel->readfd >= 0 && FD_ISSET(channel->readfd, readfds)) {
207 TRACE(("send normal readfd"))
208 send_msg_channel_data(channel, 0);
209 }
210
211 /* read stderr data and send it over the wire */
212 if (ERRFD_IS_READ(channel) && channel->errfd >= 0
213 && FD_ISSET(channel->errfd, readfds)) {
214 TRACE(("send normal errfd"))
215 send_msg_channel_data(channel, 1);
216 }
217
218 /* write to program/pipe stdin */
219 if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) {
220 if (channel->initconn) {
221 /* XXX should this go somewhere cleaner? */
222 check_in_progress(channel);
223 continue; /* Important not to use the channel after
224 check_in_progress(), as it may be NULL */
225 }
226 writechannel(channel, channel->writefd, channel->writebuf);
227 }
228
229 /* stderr for client mode */
230 if (ERRFD_IS_WRITE(channel)
231 && channel->errfd >= 0 && FD_ISSET(channel->errfd, writefds)) {
232 writechannel(channel, channel->errfd, channel->extrabuf);
233 }
234
235 /* handle any channel closing etc */
236 check_close(channel);
237
238 }
239
240 /* Listeners such as TCP, X11, agent-auth */
241 #ifdef USING_LISTENERS
242 handle_listeners(readfds);
243 #endif
244 }
245
246
247 /* Returns true if there is data remaining to be written to stdin or
248 * stderr of a channel's endpoint. */
write_pending(struct Channel * channel)249 static unsigned int write_pending(struct Channel * channel) {
250
251 if (channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0) {
252 return 1;
253 } else if (channel->errfd >= 0 && channel->extrabuf &&
254 cbuf_getused(channel->extrabuf) > 0) {
255 return 1;
256 }
257 return 0;
258 }
259
260
261 /* EOF/close handling */
check_close(struct Channel * channel)262 static void check_close(struct Channel *channel) {
263
264 TRACE(("check_close: writefd %d, readfd %d, errfd %d, sent_close %d, recv_close %d",
265 channel->writefd, channel->readfd,
266 channel->errfd, channel->sent_close, channel->recv_close))
267 TRACE(("writebuf size %d extrabuf size %d",
268 cbuf_getused(channel->writebuf),
269 channel->extrabuf ? cbuf_getused(channel->extrabuf) : 0))
270
271 if (!channel->flushing && channel->type->check_close
272 && channel->type->check_close(channel))
273 {
274 channel->flushing = 1;
275 }
276
277 if (channel->recv_close && !write_pending(channel)) {
278 if (!channel->sent_close) {
279 TRACE(("Sending MSG_CHANNEL_CLOSE in response to same."))
280 send_msg_channel_close(channel);
281 }
282 remove_channel(channel);
283 return;
284 }
285
286 if (channel->recv_eof && !write_pending(channel)) {
287 close_chan_fd(channel, channel->writefd, SHUT_WR);
288 }
289
290 /* Special handling for flushing read data after an exit. We
291 read regardless of whether the select FD was set,
292 and if there isn't data available, the channel will get closed. */
293 if (channel->flushing) {
294 TRACE(("might send data, flushing"))
295 if (channel->readfd >= 0 && channel->transwindow > 0) {
296 TRACE(("send data readfd"))
297 send_msg_channel_data(channel, 0);
298 }
299 if (ERRFD_IS_READ(channel) && channel->errfd >= 0
300 && channel->transwindow > 0) {
301 TRACE(("send data errfd"))
302 send_msg_channel_data(channel, 1);
303 }
304 }
305
306 /* If we're not going to send any more data, send EOF */
307 if (!channel->sent_eof
308 && channel->readfd == FD_CLOSED
309 && (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED)) {
310 send_msg_channel_eof(channel);
311 }
312
313 /* And if we can't receive any more data from them either, close up */
314 if (!channel->sent_close
315 && channel->readfd == FD_CLOSED
316 && (ERRFD_IS_WRITE(channel) || channel->errfd == FD_CLOSED)
317 && !write_pending(channel)) {
318 TRACE(("sending close, readfd is closed"))
319 send_msg_channel_close(channel);
320 }
321 }
322
323 /* Check whether a deferred (EINPROGRESS) connect() was successful, and
324 * if so, set up the channel properly. Otherwise, the channel is cleaned up, so
325 * it is important that the channel reference isn't used after a call to this
326 * function */
check_in_progress(struct Channel * channel)327 static void check_in_progress(struct Channel *channel) {
328
329 int val;
330 socklen_t vallen = sizeof(val);
331
332 TRACE(("enter check_in_progress"))
333
334 if (getsockopt(channel->writefd, SOL_SOCKET, SO_ERROR, &val, &vallen)
335 || val != 0) {
336 send_msg_channel_open_failure(channel->remotechan,
337 SSH_OPEN_CONNECT_FAILED, "", "");
338 close(channel->writefd);
339 delete_channel(channel);
340 TRACE(("leave check_in_progress: fail"))
341 } else {
342 send_msg_channel_open_confirmation(channel, channel->recvwindow,
343 channel->recvmaxpacket);
344 channel->readfd = channel->writefd;
345 channel->initconn = 0;
346 TRACE(("leave check_in_progress: success"))
347 }
348 }
349
350
351 /* Send the close message and set the channel as closed */
send_msg_channel_close(struct Channel * channel)352 static void send_msg_channel_close(struct Channel *channel) {
353
354 TRACE(("enter send_msg_channel_close"))
355 if (channel->type->closehandler) {
356 channel->type->closehandler(channel);
357 }
358
359 CHECKCLEARTOWRITE();
360
361 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_CLOSE);
362 buf_putint(ses.writepayload, channel->remotechan);
363
364 encrypt_packet();
365
366 channel->sent_eof = 1;
367 channel->sent_close = 1;
368 close_chan_fd(channel, channel->readfd, SHUT_RD);
369 close_chan_fd(channel, channel->errfd, SHUT_RDWR);
370 close_chan_fd(channel, channel->writefd, SHUT_WR);
371 TRACE(("leave send_msg_channel_close"))
372 }
373
374 /* call this when trans/eof channels are closed */
send_msg_channel_eof(struct Channel * channel)375 static void send_msg_channel_eof(struct Channel *channel) {
376
377 TRACE(("enter send_msg_channel_eof"))
378 CHECKCLEARTOWRITE();
379
380 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_EOF);
381 buf_putint(ses.writepayload, channel->remotechan);
382
383 encrypt_packet();
384
385 channel->sent_eof = 1;
386
387 TRACE(("leave send_msg_channel_eof"))
388 }
389
390 /* Called to write data out to the local side of the channel.
391 * Only called when we know we can write to a channel, writes as much as
392 * possible */
writechannel(struct Channel * channel,int fd,circbuffer * cbuf)393 static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) {
394
395 int len, maxlen;
396
397 TRACE(("enter writechannel fd %d", fd))
398
399 maxlen = cbuf_readlen(cbuf);
400
401 /* Write the data out */
402 len = write(fd, cbuf_readptr(cbuf, maxlen), maxlen);
403 if (len <= 0) {
404 TRACE(("errno %d len %d", errno, len))
405 if (len < 0 && errno != EINTR) {
406 close_chan_fd(channel, fd, SHUT_WR);
407 }
408 TRACE(("leave writechannel: len <= 0"))
409 return;
410 }
411 TRACE(("writechannel wrote %d", len))
412
413 cbuf_incrread(cbuf, len);
414 channel->recvdonelen += len;
415
416 /* Window adjust handling */
417 if (channel->recvdonelen >= RECV_WINDOWEXTEND) {
418 /* Set it back to max window */
419 send_msg_channel_window_adjust(channel, channel->recvdonelen);
420 channel->recvwindow += channel->recvdonelen;
421 channel->recvdonelen = 0;
422 }
423
424 dropbear_assert(channel->recvwindow <= RECV_MAXWINDOW);
425 dropbear_assert(channel->recvwindow <= cbuf_getavail(channel->writebuf));
426 dropbear_assert(channel->extrabuf == NULL ||
427 channel->recvwindow <= cbuf_getavail(channel->extrabuf));
428
429 TRACE(("leave writechannel"))
430 }
431
432 /* Set the file descriptors for the main select in session.c
433 * This avoid channels which don't have any window available, are closed, etc*/
setchannelfds(fd_set * readfds,fd_set * writefds)434 void setchannelfds(fd_set *readfds, fd_set *writefds) {
435
436 unsigned int i;
437 struct Channel * channel;
438
439 for (i = 0; i < ses.chansize; i++) {
440
441 channel = ses.channels[i];
442 if (channel == NULL) {
443 continue;
444 }
445
446 /* Stuff to put over the wire */
447 if (channel->transwindow > 0) {
448
449 if (channel->readfd >= 0) {
450 FD_SET(channel->readfd, readfds);
451 }
452
453 if (ERRFD_IS_READ(channel) && channel->errfd >= 0) {
454 FD_SET(channel->errfd, readfds);
455 }
456 }
457
458 /* Stuff from the wire */
459 if ((channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0 )
460 || channel->initconn) {
461 FD_SET(channel->writefd, writefds);
462 }
463
464 if (ERRFD_IS_WRITE(channel) && channel->errfd >= 0
465 && cbuf_getused(channel->extrabuf) > 0 ) {
466 FD_SET(channel->errfd, writefds);
467 }
468
469 } /* foreach channel */
470
471 #ifdef USING_LISTENERS
472 set_listener_fds(readfds);
473 #endif
474
475 }
476
477 /* handle the channel EOF event, by closing the channel filedescriptor. The
478 * channel isn't closed yet, it is left until the incoming (from the program
479 * etc) FD is also EOF */
recv_msg_channel_eof()480 void recv_msg_channel_eof() {
481
482 struct Channel * channel;
483
484 TRACE(("enter recv_msg_channel_eof"))
485
486 channel = getchannel_msg("EOF");
487
488 channel->recv_eof = 1;
489
490 check_close(channel);
491 TRACE(("leave recv_msg_channel_eof"))
492 }
493
494
495 /* Handle channel closure(), respond in kind and close the channels */
recv_msg_channel_close()496 void recv_msg_channel_close() {
497
498 struct Channel * channel;
499
500 TRACE(("enter recv_msg_channel_close"))
501
502 channel = getchannel_msg("Close");
503
504 channel->recv_eof = 1;
505 channel->recv_close = 1;
506
507 check_close(channel);
508 TRACE(("leave recv_msg_channel_close"))
509 }
510
511 /* Remove a channel entry, this is only executed after both sides have sent
512 * channel close */
remove_channel(struct Channel * channel)513 static void remove_channel(struct Channel * channel) {
514
515 TRACE(("enter remove_channel"))
516 TRACE(("channel index is %d", channel->index))
517
518 cbuf_free(channel->writebuf);
519 channel->writebuf = NULL;
520
521 if (channel->extrabuf) {
522 cbuf_free(channel->extrabuf);
523 channel->extrabuf = NULL;
524 }
525
526
527 /* close the FDs in case they haven't been done
528 * yet (they might have been shutdown etc) */
529 TRACE(("CLOSE writefd %d", channel->writefd))
530 close(channel->writefd);
531 TRACE(("CLOSE readfd %d", channel->readfd))
532 close(channel->readfd);
533 TRACE(("CLOSE errfd %d", channel->errfd))
534 close(channel->errfd);
535
536 channel->typedata = NULL;
537
538 delete_channel(channel);
539
540 TRACE(("leave remove_channel"))
541 }
542
543 /* Remove a channel entry */
delete_channel(struct Channel * channel)544 static void delete_channel(struct Channel *channel) {
545
546 ses.channels[channel->index] = NULL;
547 m_free(channel);
548 ses.chancount--;
549
550 }
551
552
553 /* Handle channel specific requests, passing off to corresponding handlers
554 * such as chansession or x11fwd */
recv_msg_channel_request()555 void recv_msg_channel_request() {
556
557 struct Channel *channel;
558
559 TRACE(("enter recv_msg_channel_request"))
560
561 channel = getchannel();
562
563 if (channel->type->reqhandler) {
564 channel->type->reqhandler(channel);
565 } else {
566 send_msg_channel_failure(channel);
567 }
568
569 TRACE(("leave recv_msg_channel_request"))
570
571 }
572
573 /* Reads data from the server's program/shell/etc, and puts it in a
574 * channel_data packet to send.
575 * chan is the remote channel, isextended is 0 if it is normal data, 1
576 * if it is extended data. if it is extended, then the type is in
577 * exttype */
send_msg_channel_data(struct Channel * channel,int isextended)578 static void send_msg_channel_data(struct Channel *channel, int isextended) {
579
580 int len;
581 size_t maxlen, size_pos;
582 int fd;
583
584 CHECKCLEARTOWRITE();
585
586 TRACE(("enter send_msg_channel_data"))
587 dropbear_assert(!channel->sent_close);
588
589 if (isextended) {
590 fd = channel->errfd;
591 } else {
592 fd = channel->readfd;
593 }
594 TRACE(("enter send_msg_channel_data isextended %d fd %d", isextended, fd))
595 dropbear_assert(fd >= 0);
596
597 maxlen = MIN(channel->transwindow, channel->transmaxpacket);
598 /* -(1+4+4) is SSH_MSG_CHANNEL_DATA, channel number, string length, and
599 * exttype if is extended */
600 maxlen = MIN(maxlen,
601 ses.writepayload->size - 1 - 4 - 4 - (isextended ? 4 : 0));
602 TRACE(("maxlen %d", maxlen))
603 if (maxlen == 0) {
604 TRACE(("leave send_msg_channel_data: no window"))
605 return;
606 }
607
608 buf_putbyte(ses.writepayload,
609 isextended ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA);
610 buf_putint(ses.writepayload, channel->remotechan);
611 if (isextended) {
612 buf_putint(ses.writepayload, SSH_EXTENDED_DATA_STDERR);
613 }
614 /* a dummy size first ...*/
615 size_pos = ses.writepayload->pos;
616 buf_putint(ses.writepayload, 0);
617
618 /* read the data */
619 len = read(fd, buf_getwriteptr(ses.writepayload, maxlen), maxlen);
620 if (len <= 0) {
621 if (len == 0 || errno != EINTR) {
622 /* This will also get hit in the case of EAGAIN. The only
623 time we expect to receive EAGAIN is when we're flushing a FD,
624 in which case it can be treated the same as EOF */
625 close_chan_fd(channel, fd, SHUT_RD);
626 }
627 ses.writepayload->len = ses.writepayload->pos = 0;
628 TRACE(("leave send_msg_channel_data: len %d read err %d or EOF for fd %d",
629 len, errno, fd))
630 return;
631 }
632 buf_incrwritepos(ses.writepayload, len);
633 /* ... real size here */
634 buf_setpos(ses.writepayload, size_pos);
635 buf_putint(ses.writepayload, len);
636
637 channel->transwindow -= len;
638
639 encrypt_packet();
640
641 /* If we receive less data than we requested when flushing, we've
642 reached the equivalent of EOF */
643 if (channel->flushing && len < (ssize_t)maxlen)
644 {
645 TRACE(("closing from channel, flushing out."))
646 close_chan_fd(channel, fd, SHUT_RD);
647 }
648 TRACE(("leave send_msg_channel_data"))
649 }
650
651 /* We receive channel data */
recv_msg_channel_data()652 void recv_msg_channel_data() {
653
654 struct Channel *channel;
655
656 channel = getchannel();
657
658 common_recv_msg_channel_data(channel, channel->writefd, channel->writebuf);
659 }
660
661 /* Shared for data and stderr data - when we receive data, put it in a buffer
662 * for writing to the local file descriptor */
common_recv_msg_channel_data(struct Channel * channel,int fd,circbuffer * cbuf)663 void common_recv_msg_channel_data(struct Channel *channel, int fd,
664 circbuffer * cbuf) {
665
666 unsigned int datalen;
667 unsigned int maxdata;
668 unsigned int buflen;
669 unsigned int len;
670
671 TRACE(("enter recv_msg_channel_data"))
672
673 if (channel->recv_eof) {
674 dropbear_exit("received data after eof");
675 }
676
677 if (fd < 0) {
678 /* If we have encountered failed write, the far side might still
679 * be sending data without having yet received our close notification.
680 * We just drop the data. */
681 return;
682 }
683
684 datalen = buf_getint(ses.payload);
685 TRACE(("length %d", datalen))
686
687 maxdata = cbuf_getavail(cbuf);
688
689 /* Whilst the spec says we "MAY ignore data past the end" this could
690 * lead to corrupted file transfers etc (chunks missed etc). It's better to
691 * just die horribly */
692 if (datalen > maxdata) {
693 dropbear_exit("Oversized packet");
694 }
695
696 /* We may have to run throught twice, if the buffer wraps around. Can't
697 * just "leave it for next time" like with writechannel, since this
698 * is payload data */
699 len = datalen;
700 while (len > 0) {
701 buflen = cbuf_writelen(cbuf);
702 buflen = MIN(buflen, len);
703
704 memcpy(cbuf_writeptr(cbuf, buflen),
705 buf_getptr(ses.payload, buflen), buflen);
706 cbuf_incrwrite(cbuf, buflen);
707 buf_incrpos(ses.payload, buflen);
708 len -= buflen;
709 }
710
711 dropbear_assert(channel->recvwindow >= datalen);
712 channel->recvwindow -= datalen;
713 dropbear_assert(channel->recvwindow <= RECV_MAXWINDOW);
714
715 TRACE(("leave recv_msg_channel_data"))
716 }
717
718 /* Increment the outgoing data window for a channel - the remote end limits
719 * the amount of data which may be transmitted, this window is decremented
720 * as data is sent, and incremented upon receiving window-adjust messages */
recv_msg_channel_window_adjust()721 void recv_msg_channel_window_adjust() {
722
723 struct Channel * channel;
724 unsigned int incr;
725
726 channel = getchannel();
727
728 incr = buf_getint(ses.payload);
729 TRACE(("received window increment %d", incr))
730 incr = MIN(incr, MAX_TRANS_WIN_INCR);
731
732 channel->transwindow += incr;
733 channel->transwindow = MIN(channel->transwindow, MAX_TRANS_WINDOW);
734
735 }
736
737 /* Increment the incoming data window for a channel, and let the remote
738 * end know */
send_msg_channel_window_adjust(struct Channel * channel,unsigned int incr)739 static void send_msg_channel_window_adjust(struct Channel* channel,
740 unsigned int incr) {
741
742 TRACE(("sending window adjust %d", incr))
743 CHECKCLEARTOWRITE();
744
745 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_WINDOW_ADJUST);
746 buf_putint(ses.writepayload, channel->remotechan);
747 buf_putint(ses.writepayload, incr);
748
749 encrypt_packet();
750 }
751
752 /* Handle a new channel request, performing any channel-type-specific setup */
recv_msg_channel_open()753 void recv_msg_channel_open() {
754
755 unsigned char *type;
756 unsigned int typelen;
757 unsigned int remotechan, transwindow, transmaxpacket;
758 struct Channel *channel;
759 const struct ChanType **cp;
760 const struct ChanType *chantype;
761 unsigned int errtype = SSH_OPEN_UNKNOWN_CHANNEL_TYPE;
762 int ret;
763
764
765 TRACE(("enter recv_msg_channel_open"))
766
767 /* get the packet contents */
768 type = buf_getstring(ses.payload, &typelen);
769
770 remotechan = buf_getint(ses.payload);
771 transwindow = buf_getint(ses.payload);
772 transwindow = MIN(transwindow, MAX_TRANS_WINDOW);
773 transmaxpacket = buf_getint(ses.payload);
774 transmaxpacket = MIN(transmaxpacket, MAX_TRANS_PAYLOAD_LEN);
775
776 /* figure what type of packet it is */
777 if (typelen > MAX_NAME_LEN) {
778 goto failure;
779 }
780
781 /* Get the channel type. Client and server style invokation will set up a
782 * different list for ses.chantypes at startup. We just iterate through
783 * this list and find the matching name */
784 for (cp = &ses.chantypes[0], chantype = (*cp);
785 chantype != NULL;
786 cp++, chantype = (*cp)) {
787 if (strcmp(type, chantype->name) == 0) {
788 break;
789 }
790 }
791
792 if (chantype == NULL) {
793 TRACE(("No matching type for '%s'", type))
794 goto failure;
795 }
796
797 TRACE(("matched type '%s'", type))
798
799 /* create the channel */
800 channel = newchannel(remotechan, chantype, transwindow, transmaxpacket);
801
802 if (channel == NULL) {
803 TRACE(("newchannel returned NULL"))
804 goto failure;
805 }
806
807 if (channel->type->inithandler) {
808 ret = channel->type->inithandler(channel);
809 if (ret == SSH_OPEN_IN_PROGRESS) {
810 /* We'll send the confirmation later */
811 goto cleanup;
812 }
813 if (ret > 0) {
814 errtype = ret;
815 delete_channel(channel);
816 TRACE(("inithandler returned failure %d", ret))
817 goto failure;
818 }
819 }
820
821 /* success */
822 send_msg_channel_open_confirmation(channel, channel->recvwindow,
823 channel->recvmaxpacket);
824 goto cleanup;
825
826 failure:
827 TRACE(("recv_msg_channel_open failure"))
828 send_msg_channel_open_failure(remotechan, errtype, "", "");
829
830 cleanup:
831 m_free(type);
832
833 TRACE(("leave recv_msg_channel_open"))
834 }
835
836 /* Send a failure message */
send_msg_channel_failure(struct Channel * channel)837 void send_msg_channel_failure(struct Channel *channel) {
838
839 TRACE(("enter send_msg_channel_failure"))
840 CHECKCLEARTOWRITE();
841
842 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_FAILURE);
843 buf_putint(ses.writepayload, channel->remotechan);
844
845 encrypt_packet();
846 TRACE(("leave send_msg_channel_failure"))
847 }
848
849 /* Send a success message */
send_msg_channel_success(struct Channel * channel)850 void send_msg_channel_success(struct Channel *channel) {
851
852 TRACE(("enter send_msg_channel_success"))
853 CHECKCLEARTOWRITE();
854
855 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_SUCCESS);
856 buf_putint(ses.writepayload, channel->remotechan);
857
858 encrypt_packet();
859 TRACE(("leave send_msg_channel_success"))
860 }
861
862 /* Send a channel open failure message, with a corresponding reason
863 * code (usually resource shortage or unknown chan type) */
send_msg_channel_open_failure(unsigned int remotechan,int reason,const unsigned char * text,const unsigned char * lang)864 static void send_msg_channel_open_failure(unsigned int remotechan,
865 int reason, const unsigned char *text, const unsigned char *lang) {
866
867 TRACE(("enter send_msg_channel_open_failure"))
868 CHECKCLEARTOWRITE();
869
870 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_FAILURE);
871 buf_putint(ses.writepayload, remotechan);
872 buf_putint(ses.writepayload, reason);
873 buf_putstring(ses.writepayload, text, strlen((char*)text));
874 buf_putstring(ses.writepayload, lang, strlen((char*)lang));
875
876 encrypt_packet();
877 TRACE(("leave send_msg_channel_open_failure"))
878 }
879
880 /* Confirm a channel open, and let the remote end know what number we've
881 * allocated and the receive parameters */
send_msg_channel_open_confirmation(struct Channel * channel,unsigned int recvwindow,unsigned int recvmaxpacket)882 static void send_msg_channel_open_confirmation(struct Channel* channel,
883 unsigned int recvwindow,
884 unsigned int recvmaxpacket) {
885
886 TRACE(("enter send_msg_channel_open_confirmation"))
887 CHECKCLEARTOWRITE();
888
889 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
890 buf_putint(ses.writepayload, channel->remotechan);
891 buf_putint(ses.writepayload, channel->index);
892 buf_putint(ses.writepayload, recvwindow);
893 buf_putint(ses.writepayload, recvmaxpacket);
894
895 encrypt_packet();
896 TRACE(("leave send_msg_channel_open_confirmation"))
897 }
898
899 /* close a fd, how is SHUT_RD or SHUT_WR */
close_chan_fd(struct Channel * channel,int fd,int how)900 static void close_chan_fd(struct Channel *channel, int fd, int how) {
901
902 int closein = 0, closeout = 0;
903
904 if (channel->type->sepfds) {
905 TRACE(("SHUTDOWN(%d, %d)", fd, how))
906 shutdown(fd, how);
907 if (how == 0) {
908 closeout = 1;
909 } else {
910 closein = 1;
911 }
912 } else {
913 TRACE(("CLOSE some fd %d", fd))
914 close(fd);
915 closein = closeout = 1;
916 }
917
918 if (closeout && (fd == channel->readfd)) {
919 channel->readfd = FD_CLOSED;
920 }
921 if (closeout && ERRFD_IS_READ(channel) && (fd == channel->errfd)) {
922 channel->errfd = FD_CLOSED;
923 }
924
925 if (closein && fd == channel->writefd) {
926 channel->writefd = FD_CLOSED;
927 }
928 if (closein && ERRFD_IS_WRITE(channel) && (fd == channel->errfd)) {
929 channel->errfd = FD_CLOSED;
930 }
931
932 /* if we called shutdown on it and all references are gone, then we
933 * need to close() it to stop it lingering */
934 if (channel->type->sepfds && channel->readfd == FD_CLOSED
935 && channel->writefd == FD_CLOSED && channel->errfd == FD_CLOSED) {
936 TRACE(("CLOSE (finally) of %d", fd))
937 close(fd);
938 }
939 }
940
941
942 #if defined(USING_LISTENERS) || defined(DROPBEAR_CLIENT)
943 /* Create a new channel, and start the open request. This is intended
944 * for X11, agent, tcp forwarding, and should be filled with channel-specific
945 * options, with the calling function calling encrypt_packet() after
946 * completion. It is mandatory for the caller to encrypt_packet() if
947 * DROPBEAR_SUCCESS is returned */
send_msg_channel_open_init(int fd,const struct ChanType * type)948 int send_msg_channel_open_init(int fd, const struct ChanType *type) {
949
950 struct Channel* chan;
951
952 TRACE(("enter send_msg_channel_open_init()"))
953 chan = newchannel(0, type, 0, 0);
954 if (!chan) {
955 TRACE(("leave send_msg_channel_open_init() - FAILED in newchannel()"))
956 return DROPBEAR_FAILURE;
957 }
958
959 /* set fd non-blocking */
960 setnonblocking(fd);
961
962 chan->writefd = chan->readfd = fd;
963 ses.maxfd = MAX(ses.maxfd, fd);
964
965 chan->await_open = 1;
966
967 /* now open the channel connection */
968 CHECKCLEARTOWRITE();
969
970 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN);
971 buf_putstring(ses.writepayload, type->name, strlen(type->name));
972 buf_putint(ses.writepayload, chan->index);
973 buf_putint(ses.writepayload, RECV_MAXWINDOW);
974 buf_putint(ses.writepayload, RECV_MAXPACKET);
975
976 TRACE(("leave send_msg_channel_open_init()"))
977 return DROPBEAR_SUCCESS;
978 }
979
980 /* Confirmation that our channel open request (for forwardings) was
981 * successful*/
recv_msg_channel_open_confirmation()982 void recv_msg_channel_open_confirmation() {
983
984 struct Channel * channel;
985 int ret;
986
987 TRACE(("enter recv_msg_channel_open_confirmation"))
988
989 channel = getchannel();
990
991 if (!channel->await_open) {
992 dropbear_exit("unexpected channel reply");
993 }
994 channel->await_open = 0;
995
996 channel->remotechan = buf_getint(ses.payload);
997 channel->transwindow = buf_getint(ses.payload);
998 channel->transmaxpacket = buf_getint(ses.payload);
999
1000 TRACE(("new chan remote %d local %d",
1001 channel->remotechan, channel->index))
1002
1003 /* Run the inithandler callback */
1004 if (channel->type->inithandler) {
1005 ret = channel->type->inithandler(channel);
1006 if (ret > 0) {
1007 remove_channel(channel);
1008 TRACE(("inithandler returned failure %d", ret))
1009 }
1010 }
1011
1012
1013 TRACE(("leave recv_msg_channel_open_confirmation"))
1014 }
1015
1016 /* Notification that our channel open request failed */
recv_msg_channel_open_failure()1017 void recv_msg_channel_open_failure() {
1018
1019 struct Channel * channel;
1020
1021 channel = getchannel();
1022
1023 if (!channel->await_open) {
1024 dropbear_exit("unexpected channel reply");
1025 }
1026 channel->await_open = 0;
1027
1028 remove_channel(channel);
1029 }
1030 #endif /* USING_LISTENERS */
1031