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