• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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