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