xref: /netbsd/crypto/external/bsd/openssh/dist/nchan.c (revision 6550d01e)
1 /*	$NetBSD: nchan.c,v 1.3 2010/11/21 18:29:49 adam Exp $	*/
2 /* $OpenBSD: nchan.c,v 1.63 2010/01/26 01:28:35 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.3 2010/11/21 18:29:49 adam 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 "ssh1.h"
38 #include "ssh2.h"
39 #include "buffer.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_ieof1(Channel *);
79 static void	chan_send_oclose1(Channel *);
80 static void	chan_send_close2(Channel *);
81 static void	chan_send_eof2(Channel *);
82 static void	chan_send_eow2(Channel *);
83 
84 /* helper */
85 static void	chan_shutdown_write(Channel *);
86 static void	chan_shutdown_read(Channel *);
87 
88 static char *ostates[] = { "open", "drain", "wait_ieof", "closed" };
89 static char *istates[] = { "open", "drain", "wait_oclose", "closed" };
90 
91 static void
92 chan_set_istate(Channel *c, u_int next)
93 {
94 	if (c->istate > CHAN_INPUT_CLOSED || next > CHAN_INPUT_CLOSED)
95 		fatal("chan_set_istate: bad state %d -> %d", c->istate, next);
96 	debug2("channel %d: input %s -> %s", c->self, istates[c->istate],
97 	    istates[next]);
98 	c->istate = next;
99 }
100 static void
101 chan_set_ostate(Channel *c, u_int next)
102 {
103 	if (c->ostate > CHAN_OUTPUT_CLOSED || next > CHAN_OUTPUT_CLOSED)
104 		fatal("chan_set_ostate: bad state %d -> %d", c->ostate, next);
105 	debug2("channel %d: output %s -> %s", c->self, ostates[c->ostate],
106 	    ostates[next]);
107 	c->ostate = next;
108 }
109 
110 /*
111  * SSH1 specific implementation of event functions
112  */
113 
114 static void
115 chan_rcvd_oclose1(Channel *c)
116 {
117 	debug2("channel %d: rcvd oclose", c->self);
118 	switch (c->istate) {
119 	case CHAN_INPUT_WAIT_OCLOSE:
120 		chan_set_istate(c, CHAN_INPUT_CLOSED);
121 		break;
122 	case CHAN_INPUT_OPEN:
123 		chan_shutdown_read(c);
124 		chan_send_ieof1(c);
125 		chan_set_istate(c, CHAN_INPUT_CLOSED);
126 		break;
127 	case CHAN_INPUT_WAIT_DRAIN:
128 		/* both local read_failed and remote write_failed  */
129 		chan_send_ieof1(c);
130 		chan_set_istate(c, CHAN_INPUT_CLOSED);
131 		break;
132 	default:
133 		error("channel %d: protocol error: rcvd_oclose for istate %d",
134 		    c->self, c->istate);
135 		return;
136 	}
137 }
138 void
139 chan_read_failed(Channel *c)
140 {
141 	debug2("channel %d: read failed", c->self);
142 	switch (c->istate) {
143 	case CHAN_INPUT_OPEN:
144 		chan_shutdown_read(c);
145 		chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN);
146 		break;
147 	default:
148 		error("channel %d: chan_read_failed for istate %d",
149 		    c->self, c->istate);
150 		break;
151 	}
152 }
153 void
154 chan_ibuf_empty(Channel *c)
155 {
156 	debug2("channel %d: ibuf empty", c->self);
157 	if (buffer_len(&c->input)) {
158 		error("channel %d: chan_ibuf_empty for non empty buffer",
159 		    c->self);
160 		return;
161 	}
162 	switch (c->istate) {
163 	case CHAN_INPUT_WAIT_DRAIN:
164 		if (compat20) {
165 			if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
166 				chan_send_eof2(c);
167 			chan_set_istate(c, CHAN_INPUT_CLOSED);
168 		} else {
169 			chan_send_ieof1(c);
170 			chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE);
171 		}
172 		break;
173 	default:
174 		error("channel %d: chan_ibuf_empty for istate %d",
175 		    c->self, c->istate);
176 		break;
177 	}
178 }
179 static void
180 chan_rcvd_ieof1(Channel *c)
181 {
182 	debug2("channel %d: rcvd ieof", c->self);
183 	switch (c->ostate) {
184 	case CHAN_OUTPUT_OPEN:
185 		chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
186 		break;
187 	case CHAN_OUTPUT_WAIT_IEOF:
188 		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
189 		break;
190 	default:
191 		error("channel %d: protocol error: rcvd_ieof for ostate %d",
192 		    c->self, c->ostate);
193 		break;
194 	}
195 }
196 static void
197 chan_write_failed1(Channel *c)
198 {
199 	debug2("channel %d: write failed", c->self);
200 	switch (c->ostate) {
201 	case CHAN_OUTPUT_OPEN:
202 		chan_shutdown_write(c);
203 		chan_send_oclose1(c);
204 		chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF);
205 		break;
206 	case CHAN_OUTPUT_WAIT_DRAIN:
207 		chan_shutdown_write(c);
208 		chan_send_oclose1(c);
209 		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
210 		break;
211 	default:
212 		error("channel %d: chan_write_failed for ostate %d",
213 		    c->self, c->ostate);
214 		break;
215 	}
216 }
217 void
218 chan_obuf_empty(Channel *c)
219 {
220 	debug2("channel %d: obuf empty", c->self);
221 	if (buffer_len(&c->output)) {
222 		error("channel %d: chan_obuf_empty for non empty buffer",
223 		    c->self);
224 		return;
225 	}
226 	switch (c->ostate) {
227 	case CHAN_OUTPUT_WAIT_DRAIN:
228 		chan_shutdown_write(c);
229 		if (!compat20)
230 			chan_send_oclose1(c);
231 		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
232 		break;
233 	default:
234 		error("channel %d: internal error: obuf_empty for ostate %d",
235 		    c->self, c->ostate);
236 		break;
237 	}
238 }
239 static void
240 chan_send_ieof1(Channel *c)
241 {
242 	debug2("channel %d: send ieof", c->self);
243 	switch (c->istate) {
244 	case CHAN_INPUT_OPEN:
245 	case CHAN_INPUT_WAIT_DRAIN:
246 		packet_start(SSH_MSG_CHANNEL_INPUT_EOF);
247 		packet_put_int(c->remote_id);
248 		packet_send();
249 		break;
250 	default:
251 		error("channel %d: cannot send ieof for istate %d",
252 		    c->self, c->istate);
253 		break;
254 	}
255 }
256 static void
257 chan_send_oclose1(Channel *c)
258 {
259 	debug2("channel %d: send oclose", c->self);
260 	switch (c->ostate) {
261 	case CHAN_OUTPUT_OPEN:
262 	case CHAN_OUTPUT_WAIT_DRAIN:
263 		buffer_clear(&c->output);
264 		packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE);
265 		packet_put_int(c->remote_id);
266 		packet_send();
267 		break;
268 	default:
269 		error("channel %d: cannot send oclose for ostate %d",
270 		    c->self, c->ostate);
271 		break;
272 	}
273 }
274 
275 /*
276  * the same for SSH2
277  */
278 static void
279 chan_rcvd_close2(Channel *c)
280 {
281 	debug2("channel %d: rcvd close", c->self);
282 	if (!(c->flags & CHAN_LOCAL)) {
283 		if (c->flags & CHAN_CLOSE_RCVD)
284 			error("channel %d: protocol error: close rcvd twice",
285 			    c->self);
286 		c->flags |= CHAN_CLOSE_RCVD;
287 	}
288 	if (c->type == SSH_CHANNEL_LARVAL) {
289 		/* tear down larval channels immediately */
290 		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
291 		chan_set_istate(c, CHAN_INPUT_CLOSED);
292 		return;
293 	}
294 	switch (c->ostate) {
295 	case CHAN_OUTPUT_OPEN:
296 		/*
297 		 * wait until a data from the channel is consumed if a CLOSE
298 		 * is received
299 		 */
300 		chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
301 		break;
302 	}
303 	switch (c->istate) {
304 	case CHAN_INPUT_OPEN:
305 		chan_shutdown_read(c);
306 		chan_set_istate(c, CHAN_INPUT_CLOSED);
307 		break;
308 	case CHAN_INPUT_WAIT_DRAIN:
309 		if (!(c->flags & CHAN_LOCAL))
310 			chan_send_eof2(c);
311 		chan_set_istate(c, CHAN_INPUT_CLOSED);
312 		break;
313 	}
314 }
315 
316 void
317 chan_rcvd_eow(Channel *c)
318 {
319 	debug2("channel %d: rcvd eow", c->self);
320 	switch (c->istate) {
321 	case CHAN_INPUT_OPEN:
322 		chan_shutdown_read(c);
323 		chan_set_istate(c, CHAN_INPUT_CLOSED);
324 		break;
325 	}
326 }
327 static void
328 chan_rcvd_eof2(Channel *c)
329 {
330 	debug2("channel %d: rcvd eof", c->self);
331 	c->flags |= CHAN_EOF_RCVD;
332 	if (c->ostate == CHAN_OUTPUT_OPEN)
333 		chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
334 }
335 static void
336 chan_write_failed2(Channel *c)
337 {
338 	debug2("channel %d: write failed", c->self);
339 	switch (c->ostate) {
340 	case CHAN_OUTPUT_OPEN:
341 	case CHAN_OUTPUT_WAIT_DRAIN:
342 		chan_shutdown_write(c);
343 		if (strcmp(c->ctype, "session") == 0)
344 			chan_send_eow2(c);
345 		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
346 		break;
347 	default:
348 		error("channel %d: chan_write_failed for ostate %d",
349 		    c->self, c->ostate);
350 		break;
351 	}
352 }
353 static void
354 chan_send_eof2(Channel *c)
355 {
356 	debug2("channel %d: send eof", c->self);
357 	switch (c->istate) {
358 	case CHAN_INPUT_WAIT_DRAIN:
359 		packet_start(SSH2_MSG_CHANNEL_EOF);
360 		packet_put_int(c->remote_id);
361 		packet_send();
362 		c->flags |= CHAN_EOF_SENT;
363 		break;
364 	default:
365 		error("channel %d: cannot send eof for istate %d",
366 		    c->self, c->istate);
367 		break;
368 	}
369 }
370 static void
371 chan_send_close2(Channel *c)
372 {
373 	debug2("channel %d: send close", c->self);
374 	if (c->ostate != CHAN_OUTPUT_CLOSED ||
375 	    c->istate != CHAN_INPUT_CLOSED) {
376 		error("channel %d: cannot send close for istate/ostate %d/%d",
377 		    c->self, c->istate, c->ostate);
378 	} else if (c->flags & CHAN_CLOSE_SENT) {
379 		error("channel %d: already sent close", c->self);
380 	} else {
381 		packet_start(SSH2_MSG_CHANNEL_CLOSE);
382 		packet_put_int(c->remote_id);
383 		packet_send();
384 		c->flags |= CHAN_CLOSE_SENT;
385 	}
386 }
387 static void
388 chan_send_eow2(Channel *c)
389 {
390 	debug2("channel %d: send eow", c->self);
391 	if (c->ostate == CHAN_OUTPUT_CLOSED) {
392 		error("channel %d: must not sent eow on closed output",
393 		    c->self);
394 		return;
395 	}
396 	if (!(datafellows & SSH_NEW_OPENSSH))
397 		return;
398 	packet_start(SSH2_MSG_CHANNEL_REQUEST);
399 	packet_put_int(c->remote_id);
400 	packet_put_cstring("eow@openssh.com");
401 	packet_put_char(0);
402 	packet_send();
403 }
404 
405 /* shared */
406 
407 void
408 chan_rcvd_ieof(Channel *c)
409 {
410 	if (compat20)
411 		chan_rcvd_eof2(c);
412 	else
413 		chan_rcvd_ieof1(c);
414 	if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
415 	    buffer_len(&c->output) == 0 &&
416 	    !CHANNEL_EFD_OUTPUT_ACTIVE(c))
417 		chan_obuf_empty(c);
418 }
419 void
420 chan_rcvd_oclose(Channel *c)
421 {
422 	if (compat20)
423 		chan_rcvd_close2(c);
424 	else
425 		chan_rcvd_oclose1(c);
426 }
427 void
428 chan_write_failed(Channel *c)
429 {
430 	if (compat20)
431 		chan_write_failed2(c);
432 	else
433 		chan_write_failed1(c);
434 }
435 
436 void
437 chan_mark_dead(Channel *c)
438 {
439 	c->type = SSH_CHANNEL_ZOMBIE;
440 }
441 
442 int
443 chan_is_dead(Channel *c, int do_send)
444 {
445 	if (c->type == SSH_CHANNEL_ZOMBIE) {
446 		debug2("channel %d: zombie", c->self);
447 		return 1;
448 	}
449 	if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
450 		return 0;
451 	if (!compat20) {
452 		debug2("channel %d: is dead", c->self);
453 		return 1;
454 	}
455 	if ((datafellows & SSH_BUG_EXTEOF) &&
456 	    c->extended_usage == CHAN_EXTENDED_WRITE &&
457 	    c->efd != -1 &&
458 	    buffer_len(&c->extended) > 0) {
459 		debug2("channel %d: active efd: %d len %d",
460 		    c->self, c->efd, buffer_len(&c->extended));
461 		return 0;
462 	}
463 	if (c->flags & CHAN_LOCAL) {
464 		debug2("channel %d: is dead (local)", c->self);
465 		return 1;
466 	}
467 	if (!(c->flags & CHAN_CLOSE_SENT)) {
468 		if (do_send) {
469 			chan_send_close2(c);
470 		} else {
471 			/* channel would be dead if we sent a close */
472 			if (c->flags & CHAN_CLOSE_RCVD) {
473 				debug2("channel %d: almost dead",
474 				    c->self);
475 				return 1;
476 			}
477 		}
478 	}
479 	if ((c->flags & CHAN_CLOSE_SENT) &&
480 	    (c->flags & CHAN_CLOSE_RCVD)) {
481 		debug2("channel %d: is dead", c->self);
482 		return 1;
483 	}
484 	return 0;
485 }
486 
487 /* helper */
488 static void
489 chan_shutdown_write(Channel *c)
490 {
491 	buffer_clear(&c->output);
492 	if (compat20 && c->type == SSH_CHANNEL_LARVAL)
493 		return;
494 	/* shutdown failure is allowed if write failed already */
495 	debug2("channel %d: close_write", c->self);
496 	if (c->sock != -1) {
497 		if (shutdown(c->sock, SHUT_WR) < 0)
498 			debug2("channel %d: chan_shutdown_write: "
499 			    "shutdown() failed for fd %d: %.100s",
500 			    c->self, c->sock, strerror(errno));
501 	} else {
502 		if (channel_close_fd(&c->wfd) < 0)
503 			logit("channel %d: chan_shutdown_write: "
504 			    "close() failed for fd %d: %.100s",
505 			    c->self, c->wfd, strerror(errno));
506 	}
507 }
508 static void
509 chan_shutdown_read(Channel *c)
510 {
511 	if (compat20 && c->type == SSH_CHANNEL_LARVAL)
512 		return;
513 	debug2("channel %d: close_read", c->self);
514 	if (c->sock != -1) {
515 		if (shutdown(c->sock, SHUT_RD) < 0)
516 			error("channel %d: chan_shutdown_read: "
517 			    "shutdown() failed for fd %d [i%d o%d]: %.100s",
518 			    c->self, c->sock, c->istate, c->ostate,
519 			    strerror(errno));
520 	} else {
521 		if (channel_close_fd(&c->rfd) < 0)
522 			logit("channel %d: chan_shutdown_read: "
523 			    "close() failed for fd %d: %.100s",
524 			    c->self, c->rfd, strerror(errno));
525 	}
526 }
527