Annotation of src/usr.bin/ssh/nchan.c, Revision 1.39
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.39 ! markus 26: RCSID("$OpenBSD: nchan.c,v 1.38 2002/01/14 13:22:35 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
277: chan_rcvd_oclose2(Channel *c)
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);
301: break;
302: case CHAN_INPUT_WAIT_DRAIN:
303: chan_send_eof2(c);
304: break;
305: }
1.37 markus 306: chan_set_istate(c, CHAN_INPUT_CLOSED);
1.13 markus 307: }
308: static void
309: chan_ibuf_empty2(Channel *c)
310: {
1.39 ! markus 311: chan_ibuf_empty1(c);
1.13 markus 312: }
313: static void
314: chan_rcvd_ieof2(Channel *c)
315: {
316: debug("channel %d: rcvd eof", c->self);
1.37 markus 317: if (c->ostate == CHAN_OUTPUT_OPEN)
318: chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
1.13 markus 319: }
320: static void
321: chan_write_failed2(Channel *c)
322: {
323: debug("channel %d: write failed", c->self);
324: switch (c->ostate) {
325: case CHAN_OUTPUT_OPEN:
1.15 markus 326: chan_shutdown_write(c); /* ?? */
1.37 markus 327: chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.13 markus 328: break;
329: case CHAN_OUTPUT_WAIT_DRAIN:
330: chan_shutdown_write(c);
1.37 markus 331: chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.13 markus 332: break;
333: default:
1.28 markus 334: error("channel %d: chan_write_failed for ostate %d",
1.13 markus 335: c->self, c->ostate);
336: break;
337: }
338: }
339: static void
340: chan_obuf_empty2(Channel *c)
341: {
1.39 ! markus 342: chan_obuf_empty1(c);
1.13 markus 343: }
1.3 markus 344: static void
1.13 markus 345: chan_send_eof2(Channel *c)
1.6 markus 346: {
1.13 markus 347: debug("channel %d: send eof", c->self);
348: switch (c->istate) {
349: case CHAN_INPUT_WAIT_DRAIN:
350: packet_start(SSH2_MSG_CHANNEL_EOF);
351: packet_put_int(c->remote_id);
352: packet_send();
353: break;
354: default:
1.28 markus 355: error("channel %d: cannot send eof for istate %d",
1.13 markus 356: c->self, c->istate);
357: break;
358: }
1.1 markus 359: }
1.3 markus 360: static void
1.13 markus 361: chan_send_close2(Channel *c)
1.6 markus 362: {
1.13 markus 363: debug("channel %d: send close", c->self);
364: if (c->ostate != CHAN_OUTPUT_CLOSED ||
365: c->istate != CHAN_INPUT_CLOSED) {
1.28 markus 366: error("channel %d: cannot send close for istate/ostate %d/%d",
1.13 markus 367: c->self, c->istate, c->ostate);
368: } else if (c->flags & CHAN_CLOSE_SENT) {
1.28 markus 369: error("channel %d: already sent close", c->self);
1.13 markus 370: } else {
371: packet_start(SSH2_MSG_CHANNEL_CLOSE);
372: packet_put_int(c->remote_id);
373: packet_send();
374: c->flags |= CHAN_CLOSE_SENT;
375: }
1.1 markus 376: }
1.23 markus 377:
378: /* shared */
379:
1.24 markus 380: void
381: chan_mark_dead(Channel *c)
382: {
1.26 markus 383: c->type = SSH_CHANNEL_ZOMBIE;
1.24 markus 384: }
385:
1.23 markus 386: int
1.32 markus 387: chan_is_dead(Channel *c, int send)
1.6 markus 388: {
1.26 markus 389: if (c->type == SSH_CHANNEL_ZOMBIE) {
390: debug("channel %d: zombie", c->self);
1.24 markus 391: return 1;
1.26 markus 392: }
1.23 markus 393: if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
394: return 0;
395: if (!compat20) {
396: debug("channel %d: is dead", c->self);
397: return 1;
398: }
399: /*
400: * we have to delay the close message if the efd (for stderr) is
401: * still active
402: */
403: if (((c->extended_usage != CHAN_EXTENDED_IGNORE) &&
404: buffer_len(&c->extended) > 0)
405: #if 0
406: || ((c->extended_usage == CHAN_EXTENDED_READ) &&
407: c->efd != -1)
408: #endif
409: ) {
410: debug2("channel %d: active efd: %d len %d type %s",
411: c->self, c->efd, buffer_len(&c->extended),
412: c->extended_usage==CHAN_EXTENDED_READ ?
1.33 deraadt 413: "read": "write");
1.23 markus 414: } else {
1.13 markus 415: if (!(c->flags & CHAN_CLOSE_SENT)) {
1.32 markus 416: if (send) {
417: chan_send_close2(c);
418: } else {
419: /* channel would be dead if we sent a close */
420: if (c->flags & CHAN_CLOSE_RCVD) {
421: debug("channel %d: almost dead",
422: c->self);
423: return 1;
424: }
425: }
1.13 markus 426: }
1.14 markus 427: if ((c->flags & CHAN_CLOSE_SENT) &&
1.13 markus 428: (c->flags & CHAN_CLOSE_RCVD)) {
1.23 markus 429: debug("channel %d: is dead", c->self);
430: return 1;
1.14 markus 431: }
1.1 markus 432: }
1.23 markus 433: return 0;
1.3 markus 434: }
1.13 markus 435:
1.3 markus 436: void
1.6 markus 437: chan_init_iostates(Channel *c)
438: {
439: c->ostate = CHAN_OUTPUT_OPEN;
440: c->istate = CHAN_INPUT_OPEN;
1.13 markus 441: c->flags = 0;
442: }
443:
444: /* init */
445: void
446: chan_init(void)
447: {
448: if (compat20) {
449: chan_rcvd_oclose = chan_rcvd_oclose2;
450: chan_read_failed = chan_read_failed_12;
451: chan_ibuf_empty = chan_ibuf_empty2;
452:
453: chan_rcvd_ieof = chan_rcvd_ieof2;
454: chan_write_failed = chan_write_failed2;
455: chan_obuf_empty = chan_obuf_empty2;
456: } else {
457: chan_rcvd_oclose = chan_rcvd_oclose1;
458: chan_read_failed = chan_read_failed_12;
459: chan_ibuf_empty = chan_ibuf_empty1;
460:
461: chan_rcvd_ieof = chan_rcvd_ieof1;
462: chan_write_failed = chan_write_failed1;
463: chan_obuf_empty = chan_obuf_empty1;
464: }
465: }
466:
467: /* helper */
468: static void
469: chan_shutdown_write(Channel *c)
470: {
1.34 markus 471: buffer_clear(&c->output);
1.13 markus 472: if (compat20 && c->type == SSH_CHANNEL_LARVAL)
473: return;
474: /* shutdown failure is allowed if write failed already */
475: debug("channel %d: close_write", c->self);
476: if (c->sock != -1) {
477: if (shutdown(c->sock, SHUT_WR) < 0)
1.28 markus 478: debug("channel %d: chan_shutdown_write: "
479: "shutdown() failed for fd%d: %.100s",
1.13 markus 480: c->self, c->sock, strerror(errno));
481: } else {
1.31 markus 482: if (channel_close_fd(&c->wfd) < 0)
1.28 markus 483: log("channel %d: chan_shutdown_write: "
484: "close() failed for fd%d: %.100s",
1.13 markus 485: c->self, c->wfd, strerror(errno));
486: }
487: }
488: static void
489: chan_shutdown_read(Channel *c)
490: {
491: if (compat20 && c->type == SSH_CHANNEL_LARVAL)
492: return;
493: debug("channel %d: close_read", c->self);
494: if (c->sock != -1) {
495: if (shutdown(c->sock, SHUT_RD) < 0)
1.28 markus 496: error("channel %d: chan_shutdown_read: "
497: "shutdown() failed for fd%d [i%d o%d]: %.100s",
498: c->self, c->sock, c->istate, c->ostate,
499: strerror(errno));
1.13 markus 500: } else {
1.31 markus 501: if (channel_close_fd(&c->rfd) < 0)
1.28 markus 502: log("channel %d: chan_shutdown_read: "
503: "close() failed for fd%d: %.100s",
1.13 markus 504: c->self, c->rfd, strerror(errno));
505: }
1.1 markus 506: }