1 /*
2 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
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
25 #include "includes.h"
26 RCSID("$OpenBSD: nchan.c,v 1.47 2002/06/19 00:27:55 deraadt Exp $");
27
28 #pragma ident "%Z%%M% %I% %E% SMI"
29
30 #include "ssh1.h"
31 #include "ssh2.h"
32 #include "buffer.h"
33 #include "packet.h"
34 #include "channels.h"
35 #include "compat.h"
36 #include "log.h"
37
38 /*
39 * SSH Protocol 1.5 aka New Channel Protocol
40 * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored.
41 * Written by Markus Friedl in October 1999
42 *
43 * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the
44 * tear down of channels:
45 *
46 * 1.3: strict request-ack-protocol:
47 * CLOSE ->
48 * <- CLOSE_CONFIRM
49 *
50 * 1.5: uses variations of:
51 * IEOF ->
52 * <- OCLOSE
53 * <- IEOF
54 * OCLOSE ->
55 * i.e. both sides have to close the channel
56 *
57 * 2.0: the EOF messages are optional
58 *
59 * See the debugging output from 'ssh -v' and 'sshd -d' of
60 * ssh-1.2.27 as an example.
61 *
62 */
63
64 /* functions manipulating channel states */
65 /*
66 * EVENTS update channel input/output states execute ACTIONS
67 */
68 /*
69 * ACTIONS: should never update the channel states
70 */
71 static void chan_send_ieof1(Channel *);
72 static void chan_send_oclose1(Channel *);
73 static void chan_send_close2(Channel *);
74 static void chan_send_eof2(Channel *);
75
76 /* helper */
77 static void chan_shutdown_write(Channel *);
78 static void chan_shutdown_read(Channel *);
79
80 static char *ostates[] = { "open", "drain", "wait_ieof", "closed" };
81 static char *istates[] = { "open", "drain", "wait_oclose", "closed" };
82
83 static void
chan_set_istate(Channel * c,u_int next)84 chan_set_istate(Channel *c, u_int next)
85 {
86 if (c->istate > CHAN_INPUT_CLOSED || next > CHAN_INPUT_CLOSED)
87 fatal("chan_set_istate: bad state %d -> %d", c->istate, next);
88 debug("channel %d: input %s -> %s", c->self, istates[c->istate],
89 istates[next]);
90 c->istate = next;
91 }
92 static void
chan_set_ostate(Channel * c,u_int next)93 chan_set_ostate(Channel *c, u_int next)
94 {
95 if (c->ostate > CHAN_OUTPUT_CLOSED || next > CHAN_OUTPUT_CLOSED)
96 fatal("chan_set_ostate: bad state %d -> %d", c->ostate, next);
97 debug("channel %d: output %s -> %s", c->self, ostates[c->ostate],
98 ostates[next]);
99 c->ostate = next;
100 }
101
102 /*
103 * SSH1 specific implementation of event functions
104 */
105
106 static void
chan_rcvd_oclose1(Channel * c)107 chan_rcvd_oclose1(Channel *c)
108 {
109 debug("channel %d: rcvd oclose", c->self);
110 switch (c->istate) {
111 case CHAN_INPUT_WAIT_OCLOSE:
112 chan_set_istate(c, CHAN_INPUT_CLOSED);
113 break;
114 case CHAN_INPUT_OPEN:
115 chan_shutdown_read(c);
116 chan_send_ieof1(c);
117 chan_set_istate(c, CHAN_INPUT_CLOSED);
118 break;
119 case CHAN_INPUT_WAIT_DRAIN:
120 /* both local read_failed and remote write_failed */
121 chan_send_ieof1(c);
122 chan_set_istate(c, CHAN_INPUT_CLOSED);
123 break;
124 default:
125 error("channel %d: protocol error: rcvd_oclose for istate %d",
126 c->self, c->istate);
127 return;
128 }
129 }
130 void
chan_read_failed(Channel * c)131 chan_read_failed(Channel *c)
132 {
133 debug("channel %d: read failed", c->self);
134 switch (c->istate) {
135 case CHAN_INPUT_OPEN:
136 chan_shutdown_read(c);
137 chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN);
138 break;
139 default:
140 error("channel %d: chan_read_failed for istate %d",
141 c->self, c->istate);
142 break;
143 }
144 }
145 void
chan_ibuf_empty(Channel * c)146 chan_ibuf_empty(Channel *c)
147 {
148 debug("channel %d: ibuf empty", c->self);
149 if (buffer_len(&c->input)) {
150 error("channel %d: chan_ibuf_empty for non empty buffer",
151 c->self);
152 return;
153 }
154 switch (c->istate) {
155 case CHAN_INPUT_WAIT_DRAIN:
156 if (compat20) {
157 if (!(c->flags & CHAN_CLOSE_SENT))
158 chan_send_eof2(c);
159 chan_set_istate(c, CHAN_INPUT_CLOSED);
160 } else {
161 chan_send_ieof1(c);
162 chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE);
163 }
164 break;
165 default:
166 error("channel %d: chan_ibuf_empty for istate %d",
167 c->self, c->istate);
168 break;
169 }
170 }
171 static void
chan_rcvd_ieof1(Channel * c)172 chan_rcvd_ieof1(Channel *c)
173 {
174 debug("channel %d: rcvd ieof", c->self);
175 switch (c->ostate) {
176 case CHAN_OUTPUT_OPEN:
177 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
178 break;
179 case CHAN_OUTPUT_WAIT_IEOF:
180 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
181 break;
182 default:
183 error("channel %d: protocol error: rcvd_ieof for ostate %d",
184 c->self, c->ostate);
185 break;
186 }
187 }
188 static void
chan_write_failed1(Channel * c)189 chan_write_failed1(Channel *c)
190 {
191 debug("channel %d: write failed", c->self);
192 switch (c->ostate) {
193 case CHAN_OUTPUT_OPEN:
194 chan_shutdown_write(c);
195 chan_send_oclose1(c);
196 chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF);
197 break;
198 case CHAN_OUTPUT_WAIT_DRAIN:
199 chan_shutdown_write(c);
200 chan_send_oclose1(c);
201 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
202 break;
203 default:
204 error("channel %d: chan_write_failed for ostate %d",
205 c->self, c->ostate);
206 break;
207 }
208 }
209 void
chan_obuf_empty(Channel * c)210 chan_obuf_empty(Channel *c)
211 {
212 debug("channel %d: obuf empty", c->self);
213 if (buffer_len(&c->output)) {
214 error("channel %d: chan_obuf_empty for non empty buffer",
215 c->self);
216 return;
217 }
218 switch (c->ostate) {
219 case CHAN_OUTPUT_WAIT_DRAIN:
220 chan_shutdown_write(c);
221 if (!compat20)
222 chan_send_oclose1(c);
223 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
224 break;
225 default:
226 error("channel %d: internal error: obuf_empty for ostate %d",
227 c->self, c->ostate);
228 break;
229 }
230 }
231 static void
chan_send_ieof1(Channel * c)232 chan_send_ieof1(Channel *c)
233 {
234 debug("channel %d: send ieof", c->self);
235 switch (c->istate) {
236 case CHAN_INPUT_OPEN:
237 case CHAN_INPUT_WAIT_DRAIN:
238 packet_start(SSH_MSG_CHANNEL_INPUT_EOF);
239 packet_put_int(c->remote_id);
240 packet_send();
241 break;
242 default:
243 error("channel %d: cannot send ieof for istate %d",
244 c->self, c->istate);
245 break;
246 }
247 }
248 static void
chan_send_oclose1(Channel * c)249 chan_send_oclose1(Channel *c)
250 {
251 debug("channel %d: send oclose", c->self);
252 switch (c->ostate) {
253 case CHAN_OUTPUT_OPEN:
254 case CHAN_OUTPUT_WAIT_DRAIN:
255 buffer_clear(&c->output);
256 packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE);
257 packet_put_int(c->remote_id);
258 packet_send();
259 break;
260 default:
261 error("channel %d: cannot send oclose for ostate %d",
262 c->self, c->ostate);
263 break;
264 }
265 }
266
267 /*
268 * the same for SSH2
269 */
270 static void
chan_rcvd_close2(Channel * c)271 chan_rcvd_close2(Channel *c)
272 {
273 debug("channel %d: rcvd close", c->self);
274 if (c->flags & CHAN_CLOSE_RCVD)
275 error("channel %d: protocol error: close rcvd twice", c->self);
276 c->flags |= CHAN_CLOSE_RCVD;
277 if (c->type == SSH_CHANNEL_LARVAL) {
278 /* tear down larval channels immediately */
279 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
280 chan_set_istate(c, CHAN_INPUT_CLOSED);
281 return;
282 }
283 switch (c->ostate) {
284 case CHAN_OUTPUT_OPEN:
285 /*
286 * wait until a data from the channel is consumed if a CLOSE
287 * is received
288 */
289 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
290 break;
291 }
292 switch (c->istate) {
293 case CHAN_INPUT_OPEN:
294 chan_shutdown_read(c);
295 chan_set_istate(c, CHAN_INPUT_CLOSED);
296 break;
297 case CHAN_INPUT_WAIT_DRAIN:
298 chan_send_eof2(c);
299 chan_set_istate(c, CHAN_INPUT_CLOSED);
300 break;
301 }
302 }
303 static void
chan_rcvd_eof2(Channel * c)304 chan_rcvd_eof2(Channel *c)
305 {
306 debug("channel %d: rcvd eof", c->self);
307 c->flags |= CHAN_EOF_RCVD;
308 if (c->ostate == CHAN_OUTPUT_OPEN)
309 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
310 }
311 static void
chan_write_failed2(Channel * c)312 chan_write_failed2(Channel *c)
313 {
314 debug("channel %d: write failed", c->self);
315 switch (c->ostate) {
316 case CHAN_OUTPUT_OPEN:
317 case CHAN_OUTPUT_WAIT_DRAIN:
318 chan_shutdown_write(c);
319 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
320 break;
321 default:
322 error("channel %d: chan_write_failed for ostate %d",
323 c->self, c->ostate);
324 break;
325 }
326 }
327 static void
chan_send_eof2(Channel * c)328 chan_send_eof2(Channel *c)
329 {
330 debug("channel %d: send eof", c->self);
331 switch (c->istate) {
332 case CHAN_INPUT_WAIT_DRAIN:
333 packet_start(SSH2_MSG_CHANNEL_EOF);
334 packet_put_int(c->remote_id);
335 packet_send();
336 c->flags |= CHAN_EOF_SENT;
337 break;
338 default:
339 error("channel %d: cannot send eof for istate %d",
340 c->self, c->istate);
341 break;
342 }
343 }
344 static void
chan_send_close2(Channel * c)345 chan_send_close2(Channel *c)
346 {
347 debug("channel %d: send close", c->self);
348 if (c->ostate != CHAN_OUTPUT_CLOSED ||
349 c->istate != CHAN_INPUT_CLOSED) {
350 error("channel %d: cannot send close for istate/ostate %d/%d",
351 c->self, c->istate, c->ostate);
352 } else if (c->flags & CHAN_CLOSE_SENT) {
353 error("channel %d: already sent close", c->self);
354 } else {
355 packet_start(SSH2_MSG_CHANNEL_CLOSE);
356 packet_put_int(c->remote_id);
357 packet_send();
358 c->flags |= CHAN_CLOSE_SENT;
359 }
360 }
361
362 /* shared */
363
364 void
chan_rcvd_ieof(Channel * c)365 chan_rcvd_ieof(Channel *c)
366 {
367 if (compat20)
368 chan_rcvd_eof2(c);
369 else
370 chan_rcvd_ieof1(c);
371 if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
372 buffer_len(&c->output) == 0 &&
373 !CHANNEL_EFD_OUTPUT_ACTIVE(c))
374 chan_obuf_empty(c);
375 }
376 void
chan_rcvd_oclose(Channel * c)377 chan_rcvd_oclose(Channel *c)
378 {
379 if (compat20)
380 chan_rcvd_close2(c);
381 else
382 chan_rcvd_oclose1(c);
383 }
384 void
chan_write_failed(Channel * c)385 chan_write_failed(Channel *c)
386 {
387 if (compat20)
388 chan_write_failed2(c);
389 else
390 chan_write_failed1(c);
391 }
392
393 void
chan_mark_dead(Channel * c)394 chan_mark_dead(Channel *c)
395 {
396 c->type = SSH_CHANNEL_ZOMBIE;
397 }
398
399 int
chan_is_dead(Channel * c,int send)400 chan_is_dead(Channel *c, int send)
401 {
402 if (c->type == SSH_CHANNEL_ZOMBIE) {
403 debug("channel %d: zombie", c->self);
404 return 1;
405 }
406 if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
407 return 0;
408 if (!compat20) {
409 debug("channel %d: is dead", c->self);
410 return 1;
411 }
412 if ((datafellows & SSH_BUG_EXTEOF) &&
413 c->extended_usage == CHAN_EXTENDED_WRITE &&
414 c->efd != -1 &&
415 buffer_len(&c->extended) > 0) {
416 debug2("channel %d: active efd: %d len %d",
417 c->self, c->efd, buffer_len(&c->extended));
418 return 0;
419 }
420 if (!(c->flags & CHAN_CLOSE_SENT)) {
421 if (send) {
422 chan_send_close2(c);
423 } else {
424 /* channel would be dead if we sent a close */
425 if (c->flags & CHAN_CLOSE_RCVD) {
426 debug("channel %d: almost dead",
427 c->self);
428 return 1;
429 }
430 }
431 }
432 if ((c->flags & CHAN_CLOSE_SENT) &&
433 (c->flags & CHAN_CLOSE_RCVD)) {
434 debug("channel %d: is dead", c->self);
435 return 1;
436 }
437 return 0;
438 }
439
440 /* helper */
441 static void
chan_shutdown_write(Channel * c)442 chan_shutdown_write(Channel *c)
443 {
444 buffer_clear(&c->output);
445 if (compat20 && c->type == SSH_CHANNEL_LARVAL)
446 return;
447 /* shutdown failure is allowed if write failed already */
448 debug("channel %d: close_write", c->self);
449 if (c->sock != -1) {
450 if (shutdown(c->sock, SHUT_WR) < 0)
451 debug("channel %d: chan_shutdown_write: "
452 "shutdown() failed for fd%d: %.100s",
453 c->self, c->sock, strerror(errno));
454 } else {
455 if (channel_close_fd(&c->wfd) < 0)
456 log("channel %d: chan_shutdown_write: "
457 "close() failed for fd%d: %.100s",
458 c->self, c->wfd, strerror(errno));
459 }
460 }
461 static void
chan_shutdown_read(Channel * c)462 chan_shutdown_read(Channel *c)
463 {
464 if (compat20 && c->type == SSH_CHANNEL_LARVAL)
465 return;
466 debug("channel %d: close_read", c->self);
467 if (c->sock != -1) {
468 /*
469 * shutdown(sock, SHUT_READ) may return ENOTCONN if the
470 * write side has been closed already. (bug on Linux)
471 * HP-UX may return ENOTCONN also.
472 */
473 if (shutdown(c->sock, SHUT_RD) < 0
474 && errno != ENOTCONN)
475 error("channel %d: chan_shutdown_read: "
476 "shutdown() failed for fd%d [i%d o%d]: %.100s",
477 c->self, c->sock, c->istate, c->ostate,
478 strerror(errno));
479 } else {
480 if (channel_close_fd(&c->rfd) < 0)
481 log("channel %d: chan_shutdown_read: "
482 "close() failed for fd%d: %.100s",
483 c->self, c->rfd, strerror(errno));
484 }
485 }
486