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