Annotation of src/usr.bin/ssh/nchan.c, Revision 1.37
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.37 ! markus 26: RCSID("$OpenBSD: nchan.c,v 1.36 2002/01/10 12:47:59 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.13 markus 162: chan_send_ieof1(c);
1.37 ! markus 163: chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE);
1.3 markus 164: break;
165: default:
1.28 markus 166: error("channel %d: chan_ibuf_empty for istate %d",
1.13 markus 167: c->self, c->istate);
1.3 markus 168: break;
1.1 markus 169: }
170: }
1.13 markus 171: static void
172: chan_rcvd_ieof1(Channel *c)
1.6 markus 173: {
1.13 markus 174: debug("channel %d: rcvd ieof", c->self);
1.6 markus 175: switch (c->ostate) {
1.3 markus 176: case CHAN_OUTPUT_OPEN:
1.37 ! markus 177: chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
1.3 markus 178: break;
179: case CHAN_OUTPUT_WAIT_IEOF:
1.37 ! markus 180: chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.3 markus 181: break;
182: default:
1.28 markus 183: error("channel %d: protocol error: rcvd_ieof for ostate %d",
1.13 markus 184: c->self, c->ostate);
1.3 markus 185: break;
186: }
187: }
1.13 markus 188: static void
189: chan_write_failed1(Channel *c)
1.6 markus 190: {
1.13 markus 191: debug("channel %d: write failed", c->self);
1.6 markus 192: switch (c->ostate) {
1.3 markus 193: case CHAN_OUTPUT_OPEN:
1.13 markus 194: chan_send_oclose1(c);
1.37 ! markus 195: chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF);
1.3 markus 196: break;
197: case CHAN_OUTPUT_WAIT_DRAIN:
1.13 markus 198: chan_send_oclose1(c);
1.37 ! markus 199: chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.3 markus 200: break;
201: default:
1.28 markus 202: error("channel %d: chan_write_failed for ostate %d",
1.13 markus 203: c->self, c->ostate);
1.3 markus 204: break;
205: }
206: }
1.13 markus 207: static void
208: chan_obuf_empty1(Channel *c)
1.6 markus 209: {
1.13 markus 210: debug("channel %d: obuf empty", c->self);
1.6 markus 211: if (buffer_len(&c->output)) {
1.28 markus 212: error("channel %d: chan_obuf_empty for non empty buffer",
1.13 markus 213: c->self);
1.3 markus 214: return;
215: }
1.6 markus 216: switch (c->ostate) {
1.3 markus 217: case CHAN_OUTPUT_WAIT_DRAIN:
1.13 markus 218: chan_send_oclose1(c);
1.37 ! markus 219: chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.3 markus 220: break;
221: default:
1.28 markus 222: error("channel %d: internal error: obuf_empty for ostate %d",
1.13 markus 223: c->self, c->ostate);
1.3 markus 224: break;
225: }
226: }
227: static void
1.13 markus 228: chan_send_ieof1(Channel *c)
1.6 markus 229: {
1.13 markus 230: debug("channel %d: send ieof", c->self);
1.6 markus 231: switch (c->istate) {
1.3 markus 232: case CHAN_INPUT_OPEN:
233: case CHAN_INPUT_WAIT_DRAIN:
234: packet_start(SSH_MSG_CHANNEL_INPUT_EOF);
235: packet_put_int(c->remote_id);
236: packet_send();
237: break;
238: default:
1.28 markus 239: error("channel %d: cannot send ieof for istate %d",
1.13 markus 240: c->self, c->istate);
1.3 markus 241: break;
1.1 markus 242: }
243: }
1.3 markus 244: static void
1.13 markus 245: chan_send_oclose1(Channel *c)
1.6 markus 246: {
1.13 markus 247: debug("channel %d: send oclose", c->self);
1.6 markus 248: switch (c->ostate) {
1.3 markus 249: case CHAN_OUTPUT_OPEN:
250: case CHAN_OUTPUT_WAIT_DRAIN:
251: chan_shutdown_write(c);
1.34 markus 252: buffer_clear(&c->output);
1.3 markus 253: packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE);
254: packet_put_int(c->remote_id);
255: packet_send();
256: break;
257: default:
1.28 markus 258: error("channel %d: cannot send oclose for ostate %d",
1.33 deraadt 259: c->self, c->ostate);
1.3 markus 260: break;
1.1 markus 261: }
262: }
1.6 markus 263:
1.13 markus 264: /*
265: * the same for SSH2
266: */
267: static void
268: chan_rcvd_oclose2(Channel *c)
269: {
270: debug("channel %d: rcvd close", c->self);
271: if (c->flags & CHAN_CLOSE_RCVD)
272: error("channel %d: protocol error: close rcvd twice", c->self);
273: c->flags |= CHAN_CLOSE_RCVD;
274: if (c->type == SSH_CHANNEL_LARVAL) {
275: /* tear down larval channels immediately */
1.37 ! markus 276: chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
! 277: chan_set_istate(c, CHAN_INPUT_CLOSED);
1.13 markus 278: return;
279: }
280: switch (c->ostate) {
281: case CHAN_OUTPUT_OPEN:
1.28 markus 282: /*
283: * wait until a data from the channel is consumed if a CLOSE
284: * is received
285: */
1.37 ! markus 286: chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
1.13 markus 287: break;
288: }
289: switch (c->istate) {
290: case CHAN_INPUT_OPEN:
291: chan_shutdown_read(c);
292: break;
293: case CHAN_INPUT_WAIT_DRAIN:
294: chan_send_eof2(c);
295: break;
296: }
1.37 ! markus 297: chan_set_istate(c, CHAN_INPUT_CLOSED);
1.13 markus 298: }
299: static void
300: chan_ibuf_empty2(Channel *c)
301: {
302: debug("channel %d: ibuf empty", c->self);
303: if (buffer_len(&c->input)) {
1.28 markus 304: error("channel %d: chan_ibuf_empty for non empty buffer",
1.33 deraadt 305: c->self);
1.13 markus 306: return;
307: }
308: switch (c->istate) {
309: case CHAN_INPUT_WAIT_DRAIN:
310: if (!(c->flags & CHAN_CLOSE_SENT))
311: chan_send_eof2(c);
1.37 ! markus 312: chan_set_istate(c, CHAN_INPUT_CLOSED);
1.13 markus 313: break;
314: default:
1.28 markus 315: error("channel %d: chan_ibuf_empty for istate %d",
1.33 deraadt 316: c->self, c->istate);
1.13 markus 317: break;
318: }
319: }
320: static void
321: chan_rcvd_ieof2(Channel *c)
322: {
323: debug("channel %d: rcvd eof", c->self);
1.37 ! markus 324: if (c->ostate == CHAN_OUTPUT_OPEN)
! 325: chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
1.13 markus 326: }
327: static void
328: chan_write_failed2(Channel *c)
329: {
330: debug("channel %d: write failed", c->self);
331: switch (c->ostate) {
332: case CHAN_OUTPUT_OPEN:
1.15 markus 333: chan_shutdown_write(c); /* ?? */
1.37 ! markus 334: chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.13 markus 335: break;
336: case CHAN_OUTPUT_WAIT_DRAIN:
337: chan_shutdown_write(c);
1.37 ! markus 338: chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.13 markus 339: break;
340: default:
1.28 markus 341: error("channel %d: chan_write_failed for ostate %d",
1.13 markus 342: c->self, c->ostate);
343: break;
344: }
345: }
346: static void
347: chan_obuf_empty2(Channel *c)
348: {
349: debug("channel %d: obuf empty", c->self);
350: if (buffer_len(&c->output)) {
1.28 markus 351: error("channel %d: chan_obuf_empty for non empty buffer",
1.13 markus 352: c->self);
353: return;
354: }
355: switch (c->ostate) {
356: case CHAN_OUTPUT_WAIT_DRAIN:
357: chan_shutdown_write(c);
1.37 ! markus 358: chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
1.13 markus 359: break;
360: default:
1.28 markus 361: error("channel %d: chan_obuf_empty for ostate %d",
1.13 markus 362: c->self, c->ostate);
363: break;
364: }
365: }
1.3 markus 366: static void
1.13 markus 367: chan_send_eof2(Channel *c)
1.6 markus 368: {
1.13 markus 369: debug("channel %d: send eof", c->self);
370: switch (c->istate) {
371: case CHAN_INPUT_WAIT_DRAIN:
372: packet_start(SSH2_MSG_CHANNEL_EOF);
373: packet_put_int(c->remote_id);
374: packet_send();
375: break;
376: default:
1.28 markus 377: error("channel %d: cannot send eof for istate %d",
1.13 markus 378: c->self, c->istate);
379: break;
380: }
1.1 markus 381: }
1.3 markus 382: static void
1.13 markus 383: chan_send_close2(Channel *c)
1.6 markus 384: {
1.13 markus 385: debug("channel %d: send close", c->self);
386: if (c->ostate != CHAN_OUTPUT_CLOSED ||
387: c->istate != CHAN_INPUT_CLOSED) {
1.28 markus 388: error("channel %d: cannot send close for istate/ostate %d/%d",
1.13 markus 389: c->self, c->istate, c->ostate);
390: } else if (c->flags & CHAN_CLOSE_SENT) {
1.28 markus 391: error("channel %d: already sent close", c->self);
1.13 markus 392: } else {
393: packet_start(SSH2_MSG_CHANNEL_CLOSE);
394: packet_put_int(c->remote_id);
395: packet_send();
396: c->flags |= CHAN_CLOSE_SENT;
397: }
1.1 markus 398: }
1.23 markus 399:
400: /* shared */
401:
1.24 markus 402: void
403: chan_mark_dead(Channel *c)
404: {
1.26 markus 405: c->type = SSH_CHANNEL_ZOMBIE;
1.24 markus 406: }
407:
1.23 markus 408: int
1.32 markus 409: chan_is_dead(Channel *c, int send)
1.6 markus 410: {
1.26 markus 411: if (c->type == SSH_CHANNEL_ZOMBIE) {
412: debug("channel %d: zombie", c->self);
1.24 markus 413: return 1;
1.26 markus 414: }
1.23 markus 415: if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
416: return 0;
417: if (!compat20) {
418: debug("channel %d: is dead", c->self);
419: return 1;
420: }
421: /*
422: * we have to delay the close message if the efd (for stderr) is
423: * still active
424: */
425: if (((c->extended_usage != CHAN_EXTENDED_IGNORE) &&
426: buffer_len(&c->extended) > 0)
427: #if 0
428: || ((c->extended_usage == CHAN_EXTENDED_READ) &&
429: c->efd != -1)
430: #endif
431: ) {
432: debug2("channel %d: active efd: %d len %d type %s",
433: c->self, c->efd, buffer_len(&c->extended),
434: c->extended_usage==CHAN_EXTENDED_READ ?
1.33 deraadt 435: "read": "write");
1.23 markus 436: } else {
1.13 markus 437: if (!(c->flags & CHAN_CLOSE_SENT)) {
1.32 markus 438: if (send) {
439: chan_send_close2(c);
440: } else {
441: /* channel would be dead if we sent a close */
442: if (c->flags & CHAN_CLOSE_RCVD) {
443: debug("channel %d: almost dead",
444: c->self);
445: return 1;
446: }
447: }
1.13 markus 448: }
1.14 markus 449: if ((c->flags & CHAN_CLOSE_SENT) &&
1.13 markus 450: (c->flags & CHAN_CLOSE_RCVD)) {
1.23 markus 451: debug("channel %d: is dead", c->self);
452: return 1;
1.14 markus 453: }
1.1 markus 454: }
1.23 markus 455: return 0;
1.3 markus 456: }
1.13 markus 457:
1.3 markus 458: void
1.6 markus 459: chan_init_iostates(Channel *c)
460: {
461: c->ostate = CHAN_OUTPUT_OPEN;
462: c->istate = CHAN_INPUT_OPEN;
1.13 markus 463: c->flags = 0;
464: }
465:
466: /* init */
467: void
468: chan_init(void)
469: {
470: if (compat20) {
471: chan_rcvd_oclose = chan_rcvd_oclose2;
472: chan_read_failed = chan_read_failed_12;
473: chan_ibuf_empty = chan_ibuf_empty2;
474:
475: chan_rcvd_ieof = chan_rcvd_ieof2;
476: chan_write_failed = chan_write_failed2;
477: chan_obuf_empty = chan_obuf_empty2;
478: } else {
479: chan_rcvd_oclose = chan_rcvd_oclose1;
480: chan_read_failed = chan_read_failed_12;
481: chan_ibuf_empty = chan_ibuf_empty1;
482:
483: chan_rcvd_ieof = chan_rcvd_ieof1;
484: chan_write_failed = chan_write_failed1;
485: chan_obuf_empty = chan_obuf_empty1;
486: }
487: }
488:
489: /* helper */
490: static void
491: chan_shutdown_write(Channel *c)
492: {
1.34 markus 493: buffer_clear(&c->output);
1.13 markus 494: if (compat20 && c->type == SSH_CHANNEL_LARVAL)
495: return;
496: /* shutdown failure is allowed if write failed already */
497: debug("channel %d: close_write", c->self);
498: if (c->sock != -1) {
499: if (shutdown(c->sock, SHUT_WR) < 0)
1.28 markus 500: debug("channel %d: chan_shutdown_write: "
501: "shutdown() failed for fd%d: %.100s",
1.13 markus 502: c->self, c->sock, strerror(errno));
503: } else {
1.31 markus 504: if (channel_close_fd(&c->wfd) < 0)
1.28 markus 505: log("channel %d: chan_shutdown_write: "
506: "close() failed for fd%d: %.100s",
1.13 markus 507: c->self, c->wfd, strerror(errno));
508: }
509: }
510: static void
511: chan_shutdown_read(Channel *c)
512: {
513: if (compat20 && c->type == SSH_CHANNEL_LARVAL)
514: return;
515: debug("channel %d: close_read", c->self);
516: if (c->sock != -1) {
517: if (shutdown(c->sock, SHUT_RD) < 0)
1.28 markus 518: error("channel %d: chan_shutdown_read: "
519: "shutdown() failed for fd%d [i%d o%d]: %.100s",
520: c->self, c->sock, c->istate, c->ostate,
521: strerror(errno));
1.13 markus 522: } else {
1.31 markus 523: if (channel_close_fd(&c->rfd) < 0)
1.28 markus 524: log("channel %d: chan_shutdown_read: "
525: "close() failed for fd%d: %.100s",
1.13 markus 526: c->self, c->rfd, strerror(errno));
527: }
1.1 markus 528: }