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