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