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