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