Home | History | Annotate | Line # | Download | only in dist
nchan.c revision 1.9
      1 /*	$NetBSD: nchan.c,v 1.9 2017/10/07 19:39:19 christos Exp $	*/
      2 /* $OpenBSD: nchan.c,v 1.67 2017/09/12 06:35:32 djm Exp $ */
      3 /*
      4  * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl.  All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include "includes.h"
     28 __RCSID("$NetBSD: nchan.c,v 1.9 2017/10/07 19:39:19 christos Exp $");
     29 #include <sys/types.h>
     30 #include <sys/socket.h>
     31 #include <sys/queue.h>
     32 
     33 #include <errno.h>
     34 #include <string.h>
     35 #include <stdarg.h>
     36 
     37 #include "ssh2.h"
     38 #include "sshbuf.h"
     39 #include "ssherr.h"
     40 #include "packet.h"
     41 #include "channels.h"
     42 #include "compat.h"
     43 #include "log.h"
     44 
     45 /*
     46  * SSH Protocol 1.5 aka New Channel Protocol
     47  * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored.
     48  * Written by Markus Friedl in October 1999
     49  *
     50  * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the
     51  * tear down of channels:
     52  *
     53  * 1.3:	strict request-ack-protocol:
     54  *	CLOSE	->
     55  *		<-  CLOSE_CONFIRM
     56  *
     57  * 1.5:	uses variations of:
     58  *	IEOF	->
     59  *		<-  OCLOSE
     60  *		<-  IEOF
     61  *	OCLOSE	->
     62  *	i.e. both sides have to close the channel
     63  *
     64  * 2.0: the EOF messages are optional
     65  *
     66  * See the debugging output from 'ssh -v' and 'sshd -d' of
     67  * ssh-1.2.27 as an example.
     68  *
     69  */
     70 
     71 /* functions manipulating channel states */
     72 /*
     73  * EVENTS update channel input/output states execute ACTIONS
     74  */
     75 /*
     76  * ACTIONS: should never update the channel states
     77  */
     78 static void	chan_send_eof2(struct ssh *, Channel *);
     79 static void	chan_send_eow2(struct ssh *, Channel *);
     80 
     81 /* helper */
     82 static void	chan_shutdown_write(struct ssh *, Channel *);
     83 static void	chan_shutdown_read(struct ssh *, Channel *);
     84 
     85 static const char *ostates[] = { "open", "drain", "wait_ieof", "closed" };
     86 static const char *istates[] = { "open", "drain", "wait_oclose", "closed" };
     87 
     88 static void
     89 chan_set_istate(Channel *c, u_int next)
     90 {
     91 	if (c->istate > CHAN_INPUT_CLOSED || next > CHAN_INPUT_CLOSED)
     92 		fatal("chan_set_istate: bad state %d -> %d", c->istate, next);
     93 	debug2("channel %d: input %s -> %s", c->self, istates[c->istate],
     94 	    istates[next]);
     95 	c->istate = next;
     96 }
     97 
     98 static void
     99 chan_set_ostate(Channel *c, u_int next)
    100 {
    101 	if (c->ostate > CHAN_OUTPUT_CLOSED || next > CHAN_OUTPUT_CLOSED)
    102 		fatal("chan_set_ostate: bad state %d -> %d", c->ostate, next);
    103 	debug2("channel %d: output %s -> %s", c->self, ostates[c->ostate],
    104 	    ostates[next]);
    105 	c->ostate = next;
    106 }
    107 
    108 void
    109 chan_read_failed(struct ssh *ssh, Channel *c)
    110 {
    111 	debug2("channel %d: read failed", c->self);
    112 	switch (c->istate) {
    113 	case CHAN_INPUT_OPEN:
    114 		chan_shutdown_read(ssh, c);
    115 		chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN);
    116 		break;
    117 	default:
    118 		error("channel %d: chan_read_failed for istate %d",
    119 		    c->self, c->istate);
    120 		break;
    121 	}
    122 }
    123 
    124 void
    125 chan_ibuf_empty(struct ssh *ssh, Channel *c)
    126 {
    127 	debug2("channel %d: ibuf empty", c->self);
    128 	if (sshbuf_len(c->input)) {
    129 		error("channel %d: chan_ibuf_empty for non empty buffer",
    130 		    c->self);
    131 		return;
    132 	}
    133 	switch (c->istate) {
    134 	case CHAN_INPUT_WAIT_DRAIN:
    135 		if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
    136 			chan_send_eof2(ssh, c);
    137 		chan_set_istate(c, CHAN_INPUT_CLOSED);
    138 		break;
    139 	default:
    140 		error("channel %d: chan_ibuf_empty for istate %d",
    141 		    c->self, c->istate);
    142 		break;
    143 	}
    144 }
    145 
    146 void
    147 chan_obuf_empty(struct ssh *ssh, Channel *c)
    148 {
    149 	debug2("channel %d: obuf empty", c->self);
    150 	if (sshbuf_len(c->output)) {
    151 		error("channel %d: chan_obuf_empty for non empty buffer",
    152 		    c->self);
    153 		return;
    154 	}
    155 	switch (c->ostate) {
    156 	case CHAN_OUTPUT_WAIT_DRAIN:
    157 		chan_shutdown_write(ssh, c);
    158 		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
    159 		break;
    160 	default:
    161 		error("channel %d: internal error: obuf_empty for ostate %d",
    162 		    c->self, c->ostate);
    163 		break;
    164 	}
    165 }
    166 
    167 void
    168 chan_rcvd_eow(struct ssh *ssh, Channel *c)
    169 {
    170 	debug2("channel %d: rcvd eow", c->self);
    171 	switch (c->istate) {
    172 	case CHAN_INPUT_OPEN:
    173 		chan_shutdown_read(ssh, c);
    174 		chan_set_istate(c, CHAN_INPUT_CLOSED);
    175 		break;
    176 	}
    177 }
    178 
    179 static void
    180 chan_send_eof2(struct ssh *ssh, Channel *c)
    181 {
    182 	int r;
    183 
    184 	debug2("channel %d: send eof", c->self);
    185 	switch (c->istate) {
    186 	case CHAN_INPUT_WAIT_DRAIN:
    187 		if (!c->have_remote_id)
    188 			fatal("%s: channel %d: no remote_id",
    189 			    __func__, c->self);
    190 		if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EOF)) != 0 ||
    191 		    (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
    192 		    (r = sshpkt_send(ssh)) != 0)
    193 			fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
    194 		c->flags |= CHAN_EOF_SENT;
    195 		break;
    196 	default:
    197 		error("channel %d: cannot send eof for istate %d",
    198 		    c->self, c->istate);
    199 		break;
    200 	}
    201 }
    202 
    203 static void
    204 chan_send_close2(struct ssh *ssh, Channel *c)
    205 {
    206 	int r;
    207 
    208 	debug2("channel %d: send close", c->self);
    209 	if (c->ostate != CHAN_OUTPUT_CLOSED ||
    210 	    c->istate != CHAN_INPUT_CLOSED) {
    211 		error("channel %d: cannot send close for istate/ostate %d/%d",
    212 		    c->self, c->istate, c->ostate);
    213 	} else if (c->flags & CHAN_CLOSE_SENT) {
    214 		error("channel %d: already sent close", c->self);
    215 	} else {
    216 		if (!c->have_remote_id)
    217 			fatal("%s: channel %d: no remote_id",
    218 			    __func__, c->self);
    219 		if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_CLOSE)) != 0 ||
    220 		    (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
    221 		    (r = sshpkt_send(ssh)) != 0)
    222 			fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
    223 		c->flags |= CHAN_CLOSE_SENT;
    224 	}
    225 }
    226 
    227 static void
    228 chan_send_eow2(struct ssh *ssh, Channel *c)
    229 {
    230 	int r;
    231 
    232 	debug2("channel %d: send eow", c->self);
    233 	if (c->ostate == CHAN_OUTPUT_CLOSED) {
    234 		error("channel %d: must not sent eow on closed output",
    235 		    c->self);
    236 		return;
    237 	}
    238 	if (!(datafellows & SSH_NEW_OPENSSH))
    239 		return;
    240 	if (!c->have_remote_id)
    241 		fatal("%s: channel %d: no remote_id", __func__, c->self);
    242 	if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||
    243 	    (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
    244 	    (r = sshpkt_put_cstring(ssh, "eow (at) openssh.com")) != 0 ||
    245 	    (r = sshpkt_put_u8(ssh, 0)) != 0 ||
    246 	    (r = sshpkt_send(ssh)) != 0)
    247 		fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
    248 }
    249 
    250 /* shared */
    251 
    252 void
    253 chan_rcvd_ieof(struct ssh *ssh, Channel *c)
    254 {
    255 	debug2("channel %d: rcvd eof", c->self);
    256 	c->flags |= CHAN_EOF_RCVD;
    257 	if (c->ostate == CHAN_OUTPUT_OPEN)
    258 		chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
    259 	if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
    260 	    sshbuf_len(c->output) == 0 &&
    261 	    !CHANNEL_EFD_OUTPUT_ACTIVE(c))
    262 		chan_obuf_empty(ssh, c);
    263 }
    264 
    265 void
    266 chan_rcvd_oclose(struct ssh *ssh, Channel *c)
    267 {
    268 	debug2("channel %d: rcvd close", c->self);
    269 	if (!(c->flags & CHAN_LOCAL)) {
    270 		if (c->flags & CHAN_CLOSE_RCVD)
    271 			error("channel %d: protocol error: close rcvd twice",
    272 			    c->self);
    273 		c->flags |= CHAN_CLOSE_RCVD;
    274 	}
    275 	if (c->type == SSH_CHANNEL_LARVAL) {
    276 		/* tear down larval channels immediately */
    277 		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
    278 		chan_set_istate(c, CHAN_INPUT_CLOSED);
    279 		return;
    280 	}
    281 	switch (c->ostate) {
    282 	case CHAN_OUTPUT_OPEN:
    283 		/*
    284 		 * wait until a data from the channel is consumed if a CLOSE
    285 		 * is received
    286 		 */
    287 		chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
    288 		break;
    289 	}
    290 	switch (c->istate) {
    291 	case CHAN_INPUT_OPEN:
    292 		chan_shutdown_read(ssh, c);
    293 		chan_set_istate(c, CHAN_INPUT_CLOSED);
    294 		break;
    295 	case CHAN_INPUT_WAIT_DRAIN:
    296 		if (!(c->flags & CHAN_LOCAL))
    297 			chan_send_eof2(ssh, c);
    298 		chan_set_istate(c, CHAN_INPUT_CLOSED);
    299 		break;
    300 	}
    301 }
    302 
    303 void
    304 chan_write_failed(struct ssh *ssh, Channel *c)
    305 {
    306 	debug2("channel %d: write failed", c->self);
    307 	switch (c->ostate) {
    308 	case CHAN_OUTPUT_OPEN:
    309 	case CHAN_OUTPUT_WAIT_DRAIN:
    310 		chan_shutdown_write(ssh, c);
    311 		if (strcmp(c->ctype, "session") == 0)
    312 			chan_send_eow2(ssh, c);
    313 		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
    314 		break;
    315 	default:
    316 		error("channel %d: chan_write_failed for ostate %d",
    317 		    c->self, c->ostate);
    318 		break;
    319 	}
    320 }
    321 
    322 void
    323 chan_mark_dead(struct ssh *ssh, Channel *c)
    324 {
    325 	c->type = SSH_CHANNEL_ZOMBIE;
    326 }
    327 
    328 int
    329 chan_is_dead(struct ssh *ssh, Channel *c, int do_send)
    330 {
    331 	if (c->type == SSH_CHANNEL_ZOMBIE) {
    332 		debug2("channel %d: zombie", c->self);
    333 		return 1;
    334 	}
    335 	if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
    336 		return 0;
    337 	if ((datafellows & SSH_BUG_EXTEOF) &&
    338 	    c->extended_usage == CHAN_EXTENDED_WRITE &&
    339 	    c->efd != -1 &&
    340 	    sshbuf_len(c->extended) > 0) {
    341 		debug2("channel %d: active efd: %d len %zu",
    342 		    c->self, c->efd, sshbuf_len(c->extended));
    343 		return 0;
    344 	}
    345 	if (c->flags & CHAN_LOCAL) {
    346 		debug2("channel %d: is dead (local)", c->self);
    347 		return 1;
    348 	}
    349 	if (!(c->flags & CHAN_CLOSE_SENT)) {
    350 		if (do_send) {
    351 			chan_send_close2(ssh, c);
    352 		} else {
    353 			/* channel would be dead if we sent a close */
    354 			if (c->flags & CHAN_CLOSE_RCVD) {
    355 				debug2("channel %d: almost dead",
    356 				    c->self);
    357 				return 1;
    358 			}
    359 		}
    360 	}
    361 	if ((c->flags & CHAN_CLOSE_SENT) &&
    362 	    (c->flags & CHAN_CLOSE_RCVD)) {
    363 		debug2("channel %d: is dead", c->self);
    364 		return 1;
    365 	}
    366 	return 0;
    367 }
    368 
    369 /* helper */
    370 static void
    371 chan_shutdown_write(struct ssh *ssh, Channel *c)
    372 {
    373 	sshbuf_reset(c->output);
    374 	if (c->type == SSH_CHANNEL_LARVAL)
    375 		return;
    376 	/* shutdown failure is allowed if write failed already */
    377 	debug2("channel %d: close_write", c->self);
    378 	if (c->sock != -1) {
    379 		if (shutdown(c->sock, SHUT_WR) < 0)
    380 			debug2("channel %d: chan_shutdown_write: "
    381 			    "shutdown() failed for fd %d: %.100s",
    382 			    c->self, c->sock, strerror(errno));
    383 	} else {
    384 		if (channel_close_fd(ssh, &c->wfd) < 0)
    385 			logit("channel %d: chan_shutdown_write: "
    386 			    "close() failed for fd %d: %.100s",
    387 			    c->self, c->wfd, strerror(errno));
    388 	}
    389 }
    390 
    391 static void
    392 chan_shutdown_read(struct ssh *ssh, Channel *c)
    393 {
    394 	if (c->type == SSH_CHANNEL_LARVAL)
    395 		return;
    396 	debug2("channel %d: close_read", c->self);
    397 	if (c->sock != -1) {
    398 		if (shutdown(c->sock, SHUT_RD) < 0)
    399 			error("channel %d: chan_shutdown_read: "
    400 			    "shutdown() failed for fd %d [i%d o%d]: %.100s",
    401 			    c->self, c->sock, c->istate, c->ostate,
    402 			    strerror(errno));
    403 	} else {
    404 		if (channel_close_fd(ssh, &c->rfd) < 0)
    405 			logit("channel %d: chan_shutdown_read: "
    406 			    "close() failed for fd %d: %.100s",
    407 			    c->self, c->rfd, strerror(errno));
    408 	}
    409 }
    410