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