Annotation of src/usr.bin/ssh/nchan.c, Revision 1.65
1.65 ! djm 1: /* $OpenBSD: nchan.c,v 1.64 2017/04/30 23:13:25 djm Exp $ */
1.7 markus 2: /*
1.43 markus 3: * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
1.7 markus 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:
1.54 stevesk 26: #include <sys/types.h>
27: #include <sys/socket.h>
1.58 djm 28: #include <sys/queue.h>
1.55 stevesk 29:
30: #include <errno.h>
1.56 stevesk 31: #include <string.h>
1.57 deraadt 32: #include <stdarg.h>
1.1 markus 33:
1.22 markus 34: #include "ssh2.h"
1.1 markus 35: #include "buffer.h"
1.3 markus 36: #include "packet.h"
1.1 markus 37: #include "channels.h"
1.13 markus 38: #include "compat.h"
1.22 markus 39: #include "log.h"
1.3 markus 40:
1.28 markus 41: /*
42: * SSH Protocol 1.5 aka New Channel Protocol
43: * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored.
44: * Written by Markus Friedl in October 1999
45: *
46: * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the
47: * tear down of channels:
48: *
49: * 1.3: strict request-ack-protocol:
1.51 deraadt 50: * CLOSE ->
51: * <- CLOSE_CONFIRM
1.28 markus 52: *
53: * 1.5: uses variations of:
1.51 deraadt 54: * IEOF ->
55: * <- OCLOSE
56: * <- IEOF
57: * OCLOSE ->
58: * i.e. both sides have to close the channel
1.28 markus 59: *
60: * 2.0: the EOF messages are optional
61: *
62: * See the debugging output from 'ssh -v' and 'sshd -d' of
63: * ssh-1.2.27 as an example.
64: *
65: */
66:
1.13 markus 67: /* functions manipulating channel states */
1.3 markus 68: /*
1.6 markus 69: * EVENTS update channel input/output states execute ACTIONS
1.3 markus 70: */
1.13 markus 71: /*
72: * ACTIONS: should never update the channel states
73: */
1.29 itojun 74: static void chan_send_eof2(Channel *);
1.59 markus 75: static void chan_send_eow2(Channel *);
1.13 markus 76:
77: /* helper */
1.29 itojun 78: static void chan_shutdown_write(Channel *);
79: static void chan_shutdown_read(Channel *);
1.13 markus 80:
1.37 markus 81: static char *ostates[] = { "open", "drain", "wait_ieof", "closed" };
82: static char *istates[] = { "open", "drain", "wait_oclose", "closed" };
83:
84: static void
85: chan_set_istate(Channel *c, u_int next)
86: {
87: if (c->istate > CHAN_INPUT_CLOSED || next > CHAN_INPUT_CLOSED)
88: fatal("chan_set_istate: bad state %d -> %d", c->istate, next);
1.49 markus 89: debug2("channel %d: input %s -> %s", c->self, istates[c->istate],
1.37 markus 90: istates[next]);
91: c->istate = next;
92: }
1.64 djm 93:
1.37 markus 94: static void
95: chan_set_ostate(Channel *c, u_int next)
96: {
97: if (c->ostate > CHAN_OUTPUT_CLOSED || next > CHAN_OUTPUT_CLOSED)
98: fatal("chan_set_ostate: bad state %d -> %d", c->ostate, next);
1.49 markus 99: debug2("channel %d: output %s -> %s", c->self, ostates[c->ostate],
1.37 markus 100: ostates[next]);
101: c->ostate = next;
102: }
103:
1.42 markus 104: void
105: chan_read_failed(Channel *c)
1.6 markus 106: {
1.49 markus 107: debug2("channel %d: read failed", c->self);
1.6 markus 108: switch (c->istate) {
1.3 markus 109: case CHAN_INPUT_OPEN:
110: chan_shutdown_read(c);
1.37 markus 111: chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN);
1.3 markus 112: break;
113: default:
1.28 markus 114: error("channel %d: chan_read_failed for istate %d",
1.13 markus 115: c->self, c->istate);
1.3 markus 116: break;
1.1 markus 117: }
118: }
1.64 djm 119:
1.42 markus 120: void
121: chan_ibuf_empty(Channel *c)
1.6 markus 122: {
1.49 markus 123: debug2("channel %d: ibuf empty", c->self);
1.6 markus 124: if (buffer_len(&c->input)) {
1.28 markus 125: error("channel %d: chan_ibuf_empty for non empty buffer",
1.13 markus 126: c->self);
1.3 markus 127: return;
128: }
1.6 markus 129: switch (c->istate) {
1.3 markus 130: case CHAN_INPUT_WAIT_DRAIN:
1.64 djm 131: if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
132: chan_send_eof2(c);
133: chan_set_istate(c, CHAN_INPUT_CLOSED);
1.3 markus 134: break;
135: default:
1.28 markus 136: error("channel %d: chan_ibuf_empty for istate %d",
1.13 markus 137: c->self, c->istate);
1.3 markus 138: break;
1.1 markus 139: }
140: }
1.64 djm 141:
1.42 markus 142: void
143: chan_obuf_empty(Channel *c)
1.6 markus 144: {
1.49 markus 145: debug2("channel %d: obuf empty", c->self);
1.6 markus 146: if (buffer_len(&c->output)) {
1.28 markus 147: error("channel %d: chan_obuf_empty for non empty buffer",
1.13 markus 148: c->self);
1.3 markus 149: return;
150: }
1.6 markus 151: switch (c->ostate) {
1.3 markus 152: case CHAN_OUTPUT_WAIT_DRAIN:
1.38 markus 153: chan_shutdown_write(c);
1.37 markus 154: chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.3 markus 155: break;
156: default:
1.28 markus 157: error("channel %d: internal error: obuf_empty for ostate %d",
1.13 markus 158: c->self, c->ostate);
1.3 markus 159: break;
160: }
161: }
1.63 djm 162:
1.59 markus 163: void
164: chan_rcvd_eow(Channel *c)
165: {
166: debug2("channel %d: rcvd eow", c->self);
167: switch (c->istate) {
168: case CHAN_INPUT_OPEN:
169: chan_shutdown_read(c);
170: chan_set_istate(c, CHAN_INPUT_CLOSED);
171: break;
172: }
173: }
1.64 djm 174:
1.13 markus 175: static void
176: chan_send_eof2(Channel *c)
1.6 markus 177: {
1.49 markus 178: debug2("channel %d: send eof", c->self);
1.13 markus 179: switch (c->istate) {
180: case CHAN_INPUT_WAIT_DRAIN:
181: packet_start(SSH2_MSG_CHANNEL_EOF);
182: packet_put_int(c->remote_id);
183: packet_send();
1.45 markus 184: c->flags |= CHAN_EOF_SENT;
1.13 markus 185: break;
186: default:
1.28 markus 187: error("channel %d: cannot send eof for istate %d",
1.13 markus 188: c->self, c->istate);
189: break;
190: }
1.1 markus 191: }
1.64 djm 192:
1.3 markus 193: static void
1.13 markus 194: chan_send_close2(Channel *c)
1.6 markus 195: {
1.49 markus 196: debug2("channel %d: send close", c->self);
1.13 markus 197: if (c->ostate != CHAN_OUTPUT_CLOSED ||
198: c->istate != CHAN_INPUT_CLOSED) {
1.28 markus 199: error("channel %d: cannot send close for istate/ostate %d/%d",
1.13 markus 200: c->self, c->istate, c->ostate);
201: } else if (c->flags & CHAN_CLOSE_SENT) {
1.28 markus 202: error("channel %d: already sent close", c->self);
1.13 markus 203: } else {
204: packet_start(SSH2_MSG_CHANNEL_CLOSE);
205: packet_put_int(c->remote_id);
206: packet_send();
207: c->flags |= CHAN_CLOSE_SENT;
208: }
1.59 markus 209: }
1.64 djm 210:
1.59 markus 211: static void
212: chan_send_eow2(Channel *c)
213: {
214: debug2("channel %d: send eow", c->self);
215: if (c->ostate == CHAN_OUTPUT_CLOSED) {
216: error("channel %d: must not sent eow on closed output",
217: c->self);
218: return;
219: }
1.61 markus 220: if (!(datafellows & SSH_NEW_OPENSSH))
221: return;
1.59 markus 222: packet_start(SSH2_MSG_CHANNEL_REQUEST);
223: packet_put_int(c->remote_id);
224: packet_put_cstring("eow@openssh.com");
225: packet_put_char(0);
226: packet_send();
1.1 markus 227: }
1.23 markus 228:
229: /* shared */
230:
1.24 markus 231: void
1.42 markus 232: chan_rcvd_ieof(Channel *c)
233: {
1.64 djm 234: debug2("channel %d: rcvd eof", c->self);
235: c->flags |= CHAN_EOF_RCVD;
236: if (c->ostate == CHAN_OUTPUT_OPEN)
237: chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
1.44 markus 238: if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
1.47 deraadt 239: buffer_len(&c->output) == 0 &&
1.45 markus 240: !CHANNEL_EFD_OUTPUT_ACTIVE(c))
1.44 markus 241: chan_obuf_empty(c);
1.42 markus 242: }
1.64 djm 243:
1.42 markus 244: void
245: chan_rcvd_oclose(Channel *c)
246: {
1.64 djm 247: debug2("channel %d: rcvd close", c->self);
248: if (!(c->flags & CHAN_LOCAL)) {
249: if (c->flags & CHAN_CLOSE_RCVD)
250: error("channel %d: protocol error: close rcvd twice",
251: c->self);
252: c->flags |= CHAN_CLOSE_RCVD;
253: }
254: if (c->type == SSH_CHANNEL_LARVAL) {
255: /* tear down larval channels immediately */
256: chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
257: chan_set_istate(c, CHAN_INPUT_CLOSED);
258: return;
259: }
260: switch (c->ostate) {
261: case CHAN_OUTPUT_OPEN:
262: /*
263: * wait until a data from the channel is consumed if a CLOSE
264: * is received
265: */
266: chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
267: break;
268: }
269: switch (c->istate) {
270: case CHAN_INPUT_OPEN:
271: chan_shutdown_read(c);
272: chan_set_istate(c, CHAN_INPUT_CLOSED);
273: break;
274: case CHAN_INPUT_WAIT_DRAIN:
275: if (!(c->flags & CHAN_LOCAL))
276: chan_send_eof2(c);
277: chan_set_istate(c, CHAN_INPUT_CLOSED);
278: break;
279: }
1.42 markus 280: }
1.64 djm 281:
1.42 markus 282: void
283: chan_write_failed(Channel *c)
284: {
1.64 djm 285: debug2("channel %d: write failed", c->self);
286: switch (c->ostate) {
287: case CHAN_OUTPUT_OPEN:
288: case CHAN_OUTPUT_WAIT_DRAIN:
289: chan_shutdown_write(c);
290: if (strcmp(c->ctype, "session") == 0)
291: chan_send_eow2(c);
292: chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
293: break;
294: default:
295: error("channel %d: chan_write_failed for ostate %d",
296: c->self, c->ostate);
297: break;
298: }
1.42 markus 299: }
300:
301: void
1.24 markus 302: chan_mark_dead(Channel *c)
303: {
1.26 markus 304: c->type = SSH_CHANNEL_ZOMBIE;
1.24 markus 305: }
306:
1.23 markus 307: int
1.50 avsm 308: chan_is_dead(Channel *c, int do_send)
1.6 markus 309: {
1.26 markus 310: if (c->type == SSH_CHANNEL_ZOMBIE) {
1.49 markus 311: debug2("channel %d: zombie", c->self);
1.24 markus 312: return 1;
1.26 markus 313: }
1.23 markus 314: if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
315: return 0;
1.45 markus 316: if ((datafellows & SSH_BUG_EXTEOF) &&
317: c->extended_usage == CHAN_EXTENDED_WRITE &&
318: c->efd != -1 &&
319: buffer_len(&c->extended) > 0) {
1.46 markus 320: debug2("channel %d: active efd: %d len %d",
321: c->self, c->efd, buffer_len(&c->extended));
1.45 markus 322: return 0;
323: }
1.63 djm 324: if (c->flags & CHAN_LOCAL) {
325: debug2("channel %d: is dead (local)", c->self);
326: return 1;
327: }
1.45 markus 328: if (!(c->flags & CHAN_CLOSE_SENT)) {
1.50 avsm 329: if (do_send) {
1.45 markus 330: chan_send_close2(c);
331: } else {
332: /* channel would be dead if we sent a close */
333: if (c->flags & CHAN_CLOSE_RCVD) {
1.49 markus 334: debug2("channel %d: almost dead",
1.45 markus 335: c->self);
336: return 1;
1.32 markus 337: }
1.13 markus 338: }
1.45 markus 339: }
340: if ((c->flags & CHAN_CLOSE_SENT) &&
341: (c->flags & CHAN_CLOSE_RCVD)) {
1.49 markus 342: debug2("channel %d: is dead", c->self);
1.45 markus 343: return 1;
1.1 markus 344: }
1.23 markus 345: return 0;
1.13 markus 346: }
347:
348: /* helper */
349: static void
350: chan_shutdown_write(Channel *c)
351: {
1.34 markus 352: buffer_clear(&c->output);
1.64 djm 353: if (c->type == SSH_CHANNEL_LARVAL)
1.13 markus 354: return;
355: /* shutdown failure is allowed if write failed already */
1.49 markus 356: debug2("channel %d: close_write", c->self);
1.13 markus 357: if (c->sock != -1) {
358: if (shutdown(c->sock, SHUT_WR) < 0)
1.49 markus 359: debug2("channel %d: chan_shutdown_write: "
1.62 stevesk 360: "shutdown() failed for fd %d: %.100s",
1.13 markus 361: c->self, c->sock, strerror(errno));
362: } else {
1.31 markus 363: if (channel_close_fd(&c->wfd) < 0)
1.48 itojun 364: logit("channel %d: chan_shutdown_write: "
1.62 stevesk 365: "close() failed for fd %d: %.100s",
1.13 markus 366: c->self, c->wfd, strerror(errno));
367: }
368: }
1.64 djm 369:
1.13 markus 370: static void
371: chan_shutdown_read(Channel *c)
372: {
1.64 djm 373: if (c->type == SSH_CHANNEL_LARVAL)
1.13 markus 374: return;
1.49 markus 375: debug2("channel %d: close_read", c->self);
1.13 markus 376: if (c->sock != -1) {
377: if (shutdown(c->sock, SHUT_RD) < 0)
1.28 markus 378: error("channel %d: chan_shutdown_read: "
1.62 stevesk 379: "shutdown() failed for fd %d [i%d o%d]: %.100s",
1.28 markus 380: c->self, c->sock, c->istate, c->ostate,
381: strerror(errno));
1.13 markus 382: } else {
1.31 markus 383: if (channel_close_fd(&c->rfd) < 0)
1.48 itojun 384: logit("channel %d: chan_shutdown_read: "
1.62 stevesk 385: "close() failed for fd %d: %.100s",
1.13 markus 386: c->self, c->rfd, strerror(errno));
387: }
1.1 markus 388: }