xref: /openbsd-src/usr.bin/ssh/nchan.c (revision 3a3fbb3f2e2521ab7c4a56b7ff7462ebd9095ec5)
1 /*
2  * Copyright (c) 1999, 2000, 2001 Markus Friedl.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24 
25 #include "includes.h"
26 RCSID("$OpenBSD: nchan.c,v 1.33 2001/12/19 07:18:56 deraadt Exp $");
27 
28 #include "ssh1.h"
29 #include "ssh2.h"
30 #include "buffer.h"
31 #include "packet.h"
32 #include "channels.h"
33 #include "compat.h"
34 #include "log.h"
35 
36 /*
37  * SSH Protocol 1.5 aka New Channel Protocol
38  * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored.
39  * Written by Markus Friedl in October 1999
40  *
41  * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the
42  * tear down of channels:
43  *
44  * 1.3:	strict request-ack-protocol:
45  * 	CLOSE	->
46  * 		<-  CLOSE_CONFIRM
47  *
48  * 1.5:	uses variations of:
49  * 	IEOF	->
50  * 		<-  OCLOSE
51  * 		<-  IEOF
52  * 	OCLOSE	->
53  * 	i.e. both sides have to close the channel
54  *
55  * 2.0: the EOF messages are optional
56  *
57  * See the debugging output from 'ssh -v' and 'sshd -d' of
58  * ssh-1.2.27 as an example.
59  *
60  */
61 
62 /* functions manipulating channel states */
63 /*
64  * EVENTS update channel input/output states execute ACTIONS
65  */
66 /* events concerning the INPUT from socket for channel (istate) */
67 chan_event_fn *chan_rcvd_oclose			= NULL;
68 chan_event_fn *chan_read_failed			= NULL;
69 chan_event_fn *chan_ibuf_empty			= NULL;
70 /* events concerning the OUTPUT from channel for socket (ostate) */
71 chan_event_fn *chan_rcvd_ieof			= NULL;
72 chan_event_fn *chan_write_failed		= NULL;
73 chan_event_fn *chan_obuf_empty			= NULL;
74 /*
75  * ACTIONS: should never update the channel states
76  */
77 static void	chan_send_ieof1(Channel *);
78 static void	chan_send_oclose1(Channel *);
79 static void	chan_send_close2(Channel *);
80 static void	chan_send_eof2(Channel *);
81 
82 /* helper */
83 static void	chan_shutdown_write(Channel *);
84 static void	chan_shutdown_read(Channel *);
85 
86 /*
87  * SSH1 specific implementation of event functions
88  */
89 
90 static void
91 chan_rcvd_oclose1(Channel *c)
92 {
93 	debug("channel %d: rcvd oclose", c->self);
94 	switch (c->istate) {
95 	case CHAN_INPUT_WAIT_OCLOSE:
96 		debug("channel %d: input wait_oclose -> closed", c->self);
97 		c->istate = CHAN_INPUT_CLOSED;
98 		break;
99 	case CHAN_INPUT_OPEN:
100 		debug("channel %d: input open -> closed", c->self);
101 		chan_shutdown_read(c);
102 		chan_send_ieof1(c);
103 		c->istate = CHAN_INPUT_CLOSED;
104 		break;
105 	case CHAN_INPUT_WAIT_DRAIN:
106 		/* both local read_failed and remote write_failed  */
107 		log("channel %d: input drain -> closed", c->self);
108 		chan_send_ieof1(c);
109 		c->istate = CHAN_INPUT_CLOSED;
110 		break;
111 	default:
112 		error("channel %d: protocol error: rcvd_oclose for istate %d",
113 		    c->self, c->istate);
114 		return;
115 	}
116 }
117 static void
118 chan_read_failed_12(Channel *c)
119 {
120 	debug("channel %d: read failed", c->self);
121 	switch (c->istate) {
122 	case CHAN_INPUT_OPEN:
123 		debug("channel %d: input open -> drain", c->self);
124 		chan_shutdown_read(c);
125 		c->istate = CHAN_INPUT_WAIT_DRAIN;
126 #if 0
127 		if (buffer_len(&c->input) == 0) {
128 			debug("channel %d: input: no drain shortcut", c->self);
129 			chan_ibuf_empty(c);
130 		}
131 #endif
132 		break;
133 	default:
134 		error("channel %d: chan_read_failed for istate %d",
135 		    c->self, c->istate);
136 		break;
137 	}
138 }
139 static void
140 chan_ibuf_empty1(Channel *c)
141 {
142 	debug("channel %d: ibuf empty", c->self);
143 	if (buffer_len(&c->input)) {
144 		error("channel %d: chan_ibuf_empty for non empty buffer",
145 		    c->self);
146 		return;
147 	}
148 	switch (c->istate) {
149 	case CHAN_INPUT_WAIT_DRAIN:
150 		debug("channel %d: input drain -> wait_oclose", c->self);
151 		chan_send_ieof1(c);
152 		c->istate = CHAN_INPUT_WAIT_OCLOSE;
153 		break;
154 	default:
155 		error("channel %d: chan_ibuf_empty for istate %d",
156 		    c->self, c->istate);
157 		break;
158 	}
159 }
160 static void
161 chan_rcvd_ieof1(Channel *c)
162 {
163 	debug("channel %d: rcvd ieof", c->self);
164 	if (c->type != SSH_CHANNEL_OPEN) {
165 		debug("channel %d: non-open", c->self);
166 		if (c->istate == CHAN_INPUT_OPEN) {
167 			debug("channel %d: non-open: input open -> wait_oclose",
168 			    c->self);
169 			chan_shutdown_read(c);
170 			chan_send_ieof1(c);
171 			c->istate = CHAN_INPUT_WAIT_OCLOSE;
172 		} else {
173 			error("channel %d: non-open: istate %d != open",
174 			    c->self, c->istate);
175 		}
176 		if (c->ostate == CHAN_OUTPUT_OPEN) {
177 			debug("channel %d: non-open: output open -> closed",
178 			    c->self);
179 			chan_send_oclose1(c);
180 			c->ostate = CHAN_OUTPUT_CLOSED;
181 		} else {
182 			error("channel %d: non-open: ostate %d != open",
183 			    c->self, c->ostate);
184 		}
185 		return;
186 	}
187 	switch (c->ostate) {
188 	case CHAN_OUTPUT_OPEN:
189 		debug("channel %d: output open -> drain", c->self);
190 		c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
191 		break;
192 	case CHAN_OUTPUT_WAIT_IEOF:
193 		debug("channel %d: output wait_ieof -> closed", c->self);
194 		c->ostate = CHAN_OUTPUT_CLOSED;
195 		break;
196 	default:
197 		error("channel %d: protocol error: rcvd_ieof for ostate %d",
198 		    c->self, c->ostate);
199 		break;
200 	}
201 }
202 static void
203 chan_write_failed1(Channel *c)
204 {
205 	debug("channel %d: write failed", c->self);
206 	switch (c->ostate) {
207 	case CHAN_OUTPUT_OPEN:
208 		debug("channel %d: output open -> wait_ieof", c->self);
209 		chan_send_oclose1(c);
210 		c->ostate = CHAN_OUTPUT_WAIT_IEOF;
211 		break;
212 	case CHAN_OUTPUT_WAIT_DRAIN:
213 		debug("channel %d: output wait_drain -> closed", c->self);
214 		chan_send_oclose1(c);
215 		c->ostate = CHAN_OUTPUT_CLOSED;
216 		break;
217 	default:
218 		error("channel %d: chan_write_failed for ostate %d",
219 		    c->self, c->ostate);
220 		break;
221 	}
222 }
223 static void
224 chan_obuf_empty1(Channel *c)
225 {
226 	debug("channel %d: obuf empty", c->self);
227 	if (buffer_len(&c->output)) {
228 		error("channel %d: chan_obuf_empty for non empty buffer",
229 		    c->self);
230 		return;
231 	}
232 	switch (c->ostate) {
233 	case CHAN_OUTPUT_WAIT_DRAIN:
234 		debug("channel %d: output drain -> closed", c->self);
235 		chan_send_oclose1(c);
236 		c->ostate = CHAN_OUTPUT_CLOSED;
237 		break;
238 	default:
239 		error("channel %d: internal error: obuf_empty for ostate %d",
240 		    c->self, c->ostate);
241 		break;
242 	}
243 }
244 static void
245 chan_send_ieof1(Channel *c)
246 {
247 	debug("channel %d: send ieof", c->self);
248 	switch (c->istate) {
249 	case CHAN_INPUT_OPEN:
250 	case CHAN_INPUT_WAIT_DRAIN:
251 		packet_start(SSH_MSG_CHANNEL_INPUT_EOF);
252 		packet_put_int(c->remote_id);
253 		packet_send();
254 		break;
255 	default:
256 		error("channel %d: cannot send ieof for istate %d",
257 		    c->self, c->istate);
258 		break;
259 	}
260 }
261 static void
262 chan_send_oclose1(Channel *c)
263 {
264 	debug("channel %d: send oclose", c->self);
265 	switch (c->ostate) {
266 	case CHAN_OUTPUT_OPEN:
267 	case CHAN_OUTPUT_WAIT_DRAIN:
268 		chan_shutdown_write(c);
269 		buffer_consume(&c->output, buffer_len(&c->output));
270 		packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE);
271 		packet_put_int(c->remote_id);
272 		packet_send();
273 		break;
274 	default:
275 		error("channel %d: cannot send oclose for ostate %d",
276 		    c->self, c->ostate);
277 		break;
278 	}
279 }
280 
281 /*
282  * the same for SSH2
283  */
284 static void
285 chan_rcvd_oclose2(Channel *c)
286 {
287 	debug("channel %d: rcvd close", c->self);
288 	if (c->flags & CHAN_CLOSE_RCVD)
289 		error("channel %d: protocol error: close rcvd twice", c->self);
290 	c->flags |= CHAN_CLOSE_RCVD;
291 	if (c->type == SSH_CHANNEL_LARVAL) {
292 		/* tear down larval channels immediately */
293 		c->ostate = CHAN_OUTPUT_CLOSED;
294 		c->istate = CHAN_INPUT_CLOSED;
295 		return;
296 	}
297 	switch (c->ostate) {
298 	case CHAN_OUTPUT_OPEN:
299 		/*
300 		 * wait until a data from the channel is consumed if a CLOSE
301 		 * is received
302 		 */
303 		debug("channel %d: output open -> drain", c->self);
304 		c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
305 		break;
306 	}
307 	switch (c->istate) {
308 	case CHAN_INPUT_OPEN:
309 		debug("channel %d: input open -> closed", c->self);
310 		chan_shutdown_read(c);
311 		break;
312 	case CHAN_INPUT_WAIT_DRAIN:
313 		debug("channel %d: input drain -> closed", c->self);
314 		chan_send_eof2(c);
315 		break;
316 	}
317 	c->istate = CHAN_INPUT_CLOSED;
318 }
319 static void
320 chan_ibuf_empty2(Channel *c)
321 {
322 	debug("channel %d: ibuf empty", c->self);
323 	if (buffer_len(&c->input)) {
324 		error("channel %d: chan_ibuf_empty for non empty buffer",
325 		    c->self);
326 		return;
327 	}
328 	switch (c->istate) {
329 	case CHAN_INPUT_WAIT_DRAIN:
330 		debug("channel %d: input drain -> closed", c->self);
331 		if (!(c->flags & CHAN_CLOSE_SENT))
332 			chan_send_eof2(c);
333 		c->istate = CHAN_INPUT_CLOSED;
334 		break;
335 	default:
336 		error("channel %d: chan_ibuf_empty for istate %d",
337 		    c->self, c->istate);
338 		break;
339 	}
340 }
341 static void
342 chan_rcvd_ieof2(Channel *c)
343 {
344 	debug("channel %d: rcvd eof", c->self);
345 	if (c->ostate == CHAN_OUTPUT_OPEN) {
346 		debug("channel %d: output open -> drain", c->self);
347 		c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
348 	}
349 }
350 static void
351 chan_write_failed2(Channel *c)
352 {
353 	debug("channel %d: write failed", c->self);
354 	switch (c->ostate) {
355 	case CHAN_OUTPUT_OPEN:
356 		debug("channel %d: output open -> closed", c->self);
357 		chan_shutdown_write(c); /* ?? */
358 		c->ostate = CHAN_OUTPUT_CLOSED;
359 		break;
360 	case CHAN_OUTPUT_WAIT_DRAIN:
361 		debug("channel %d: output drain -> closed", c->self);
362 		chan_shutdown_write(c);
363 		c->ostate = CHAN_OUTPUT_CLOSED;
364 		break;
365 	default:
366 		error("channel %d: chan_write_failed for ostate %d",
367 		    c->self, c->ostate);
368 		break;
369 	}
370 }
371 static void
372 chan_obuf_empty2(Channel *c)
373 {
374 	debug("channel %d: obuf empty", c->self);
375 	if (buffer_len(&c->output)) {
376 		error("channel %d: chan_obuf_empty for non empty buffer",
377 		    c->self);
378 		return;
379 	}
380 	switch (c->ostate) {
381 	case CHAN_OUTPUT_WAIT_DRAIN:
382 		debug("channel %d: output drain -> closed", c->self);
383 		chan_shutdown_write(c);
384 		c->ostate = CHAN_OUTPUT_CLOSED;
385 		break;
386 	default:
387 		error("channel %d: chan_obuf_empty for ostate %d",
388 		    c->self, c->ostate);
389 		break;
390 	}
391 }
392 static void
393 chan_send_eof2(Channel *c)
394 {
395 	debug("channel %d: send eof", c->self);
396 	switch (c->istate) {
397 	case CHAN_INPUT_WAIT_DRAIN:
398 		packet_start(SSH2_MSG_CHANNEL_EOF);
399 		packet_put_int(c->remote_id);
400 		packet_send();
401 		break;
402 	default:
403 		error("channel %d: cannot send eof for istate %d",
404 		    c->self, c->istate);
405 		break;
406 	}
407 }
408 static void
409 chan_send_close2(Channel *c)
410 {
411 	debug("channel %d: send close", c->self);
412 	if (c->ostate != CHAN_OUTPUT_CLOSED ||
413 	    c->istate != CHAN_INPUT_CLOSED) {
414 		error("channel %d: cannot send close for istate/ostate %d/%d",
415 		    c->self, c->istate, c->ostate);
416 	} else if (c->flags & CHAN_CLOSE_SENT) {
417 		error("channel %d: already sent close", c->self);
418 	} else {
419 		packet_start(SSH2_MSG_CHANNEL_CLOSE);
420 		packet_put_int(c->remote_id);
421 		packet_send();
422 		c->flags |= CHAN_CLOSE_SENT;
423 	}
424 }
425 
426 /* shared */
427 
428 void
429 chan_mark_dead(Channel *c)
430 {
431 	c->type = SSH_CHANNEL_ZOMBIE;
432 }
433 
434 int
435 chan_is_dead(Channel *c, int send)
436 {
437 	if (c->type == SSH_CHANNEL_ZOMBIE) {
438 		debug("channel %d: zombie", c->self);
439 		return 1;
440 	}
441 	if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
442 		return 0;
443 	if (!compat20) {
444 		debug("channel %d: is dead", c->self);
445 		return 1;
446 	}
447 	/*
448 	 * we have to delay the close message if the efd (for stderr) is
449 	 * still active
450 	 */
451 	if (((c->extended_usage != CHAN_EXTENDED_IGNORE) &&
452 	    buffer_len(&c->extended) > 0)
453 #if 0
454 	    || ((c->extended_usage == CHAN_EXTENDED_READ) &&
455 	    c->efd != -1)
456 #endif
457 	    ) {
458 		debug2("channel %d: active efd: %d len %d type %s",
459 		    c->self, c->efd, buffer_len(&c->extended),
460 		    c->extended_usage==CHAN_EXTENDED_READ ?
461 		    "read": "write");
462 	} else {
463 		if (!(c->flags & CHAN_CLOSE_SENT)) {
464 			if (send) {
465 				chan_send_close2(c);
466 			} else {
467 				/* channel would be dead if we sent a close */
468 				if (c->flags & CHAN_CLOSE_RCVD) {
469 					debug("channel %d: almost dead",
470 					    c->self);
471 					return 1;
472 				}
473 			}
474 		}
475 		if ((c->flags & CHAN_CLOSE_SENT) &&
476 		    (c->flags & CHAN_CLOSE_RCVD)) {
477 			debug("channel %d: is dead", c->self);
478 			return 1;
479 		}
480 	}
481 	return 0;
482 }
483 
484 void
485 chan_init_iostates(Channel *c)
486 {
487 	c->ostate = CHAN_OUTPUT_OPEN;
488 	c->istate = CHAN_INPUT_OPEN;
489 	c->flags = 0;
490 }
491 
492 /* init */
493 void
494 chan_init(void)
495 {
496 	if (compat20) {
497 		chan_rcvd_oclose		= chan_rcvd_oclose2;
498 		chan_read_failed		= chan_read_failed_12;
499 		chan_ibuf_empty			= chan_ibuf_empty2;
500 
501 		chan_rcvd_ieof			= chan_rcvd_ieof2;
502 		chan_write_failed		= chan_write_failed2;
503 		chan_obuf_empty			= chan_obuf_empty2;
504 	} else {
505 		chan_rcvd_oclose		= chan_rcvd_oclose1;
506 		chan_read_failed		= chan_read_failed_12;
507 		chan_ibuf_empty			= chan_ibuf_empty1;
508 
509 		chan_rcvd_ieof			= chan_rcvd_ieof1;
510 		chan_write_failed		= chan_write_failed1;
511 		chan_obuf_empty			= chan_obuf_empty1;
512 	}
513 }
514 
515 /* helper */
516 static void
517 chan_shutdown_write(Channel *c)
518 {
519 	buffer_consume(&c->output, buffer_len(&c->output));
520 	if (compat20 && c->type == SSH_CHANNEL_LARVAL)
521 		return;
522 	/* shutdown failure is allowed if write failed already */
523 	debug("channel %d: close_write", c->self);
524 	if (c->sock != -1) {
525 		if (shutdown(c->sock, SHUT_WR) < 0)
526 			debug("channel %d: chan_shutdown_write: "
527 			    "shutdown() failed for fd%d: %.100s",
528 			    c->self, c->sock, strerror(errno));
529 	} else {
530 		if (channel_close_fd(&c->wfd) < 0)
531 			log("channel %d: chan_shutdown_write: "
532 			    "close() failed for fd%d: %.100s",
533 			    c->self, c->wfd, strerror(errno));
534 	}
535 }
536 static void
537 chan_shutdown_read(Channel *c)
538 {
539 	if (compat20 && c->type == SSH_CHANNEL_LARVAL)
540 		return;
541 	debug("channel %d: close_read", c->self);
542 	if (c->sock != -1) {
543 		if (shutdown(c->sock, SHUT_RD) < 0)
544 			error("channel %d: chan_shutdown_read: "
545 			    "shutdown() failed for fd%d [i%d o%d]: %.100s",
546 			    c->self, c->sock, c->istate, c->ostate,
547 			    strerror(errno));
548 	} else {
549 		if (channel_close_fd(&c->rfd) < 0)
550 			log("channel %d: chan_shutdown_read: "
551 			    "close() failed for fd%d: %.100s",
552 			    c->self, c->rfd, strerror(errno));
553 	}
554 }
555