1 /* $OpenBSD: nchan.c,v 1.63 2010/01/26 01:28:35 djm Exp $ */ 2 /* 3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "includes.h" 27 28 #include <sys/types.h> 29 #include <sys/socket.h> 30 31 #include <errno.h> 32 #include <string.h> 33 #include <stdarg.h> 34 35 #include "openbsd-compat/sys-queue.h" 36 #include "ssh1.h" 37 #include "ssh2.h" 38 #include "buffer.h" 39 #include "packet.h" 40 #include "channels.h" 41 #include "compat.h" 42 #include "log.h" 43 44 /* 45 * SSH Protocol 1.5 aka New Channel Protocol 46 * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored. 47 * Written by Markus Friedl in October 1999 48 * 49 * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the 50 * tear down of channels: 51 * 52 * 1.3: strict request-ack-protocol: 53 * CLOSE -> 54 * <- CLOSE_CONFIRM 55 * 56 * 1.5: uses variations of: 57 * IEOF -> 58 * <- OCLOSE 59 * <- IEOF 60 * OCLOSE -> 61 * i.e. both sides have to close the channel 62 * 63 * 2.0: the EOF messages are optional 64 * 65 * See the debugging output from 'ssh -v' and 'sshd -d' of 66 * ssh-1.2.27 as an example. 67 * 68 */ 69 70 /* functions manipulating channel states */ 71 /* 72 * EVENTS update channel input/output states execute ACTIONS 73 */ 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 static void chan_send_eow2(Channel *); 82 83 /* helper */ 84 static void chan_shutdown_write(Channel *); 85 static void chan_shutdown_read(Channel *); 86 87 static char *ostates[] = { "open", "drain", "wait_ieof", "closed" }; 88 static char *istates[] = { "open", "drain", "wait_oclose", "closed" }; 89 90 static void 91 chan_set_istate(Channel *c, u_int next) 92 { 93 if (c->istate > CHAN_INPUT_CLOSED || next > CHAN_INPUT_CLOSED) 94 fatal("chan_set_istate: bad state %d -> %d", c->istate, next); 95 debug2("channel %d: input %s -> %s", c->self, istates[c->istate], 96 istates[next]); 97 c->istate = next; 98 } 99 static void 100 chan_set_ostate(Channel *c, u_int next) 101 { 102 if (c->ostate > CHAN_OUTPUT_CLOSED || next > CHAN_OUTPUT_CLOSED) 103 fatal("chan_set_ostate: bad state %d -> %d", c->ostate, next); 104 debug2("channel %d: output %s -> %s", c->self, ostates[c->ostate], 105 ostates[next]); 106 c->ostate = next; 107 } 108 109 /* 110 * SSH1 specific implementation of event functions 111 */ 112 113 static void 114 chan_rcvd_oclose1(Channel *c) 115 { 116 debug2("channel %d: rcvd oclose", c->self); 117 switch (c->istate) { 118 case CHAN_INPUT_WAIT_OCLOSE: 119 chan_set_istate(c, CHAN_INPUT_CLOSED); 120 break; 121 case CHAN_INPUT_OPEN: 122 chan_shutdown_read(c); 123 chan_send_ieof1(c); 124 chan_set_istate(c, CHAN_INPUT_CLOSED); 125 break; 126 case CHAN_INPUT_WAIT_DRAIN: 127 /* both local read_failed and remote write_failed */ 128 chan_send_ieof1(c); 129 chan_set_istate(c, CHAN_INPUT_CLOSED); 130 break; 131 default: 132 error("channel %d: protocol error: rcvd_oclose for istate %d", 133 c->self, c->istate); 134 return; 135 } 136 } 137 void 138 chan_read_failed(Channel *c) 139 { 140 debug2("channel %d: read failed", c->self); 141 switch (c->istate) { 142 case CHAN_INPUT_OPEN: 143 chan_shutdown_read(c); 144 chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN); 145 break; 146 default: 147 error("channel %d: chan_read_failed for istate %d", 148 c->self, c->istate); 149 break; 150 } 151 } 152 void 153 chan_ibuf_empty(Channel *c) 154 { 155 debug2("channel %d: ibuf empty", c->self); 156 if (buffer_len(&c->input)) { 157 error("channel %d: chan_ibuf_empty for non empty buffer", 158 c->self); 159 return; 160 } 161 switch (c->istate) { 162 case CHAN_INPUT_WAIT_DRAIN: 163 if (compat20) { 164 if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL))) 165 chan_send_eof2(c); 166 chan_set_istate(c, CHAN_INPUT_CLOSED); 167 } else { 168 chan_send_ieof1(c); 169 chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE); 170 } 171 break; 172 default: 173 error("channel %d: chan_ibuf_empty for istate %d", 174 c->self, c->istate); 175 break; 176 } 177 } 178 static void 179 chan_rcvd_ieof1(Channel *c) 180 { 181 debug2("channel %d: rcvd ieof", c->self); 182 switch (c->ostate) { 183 case CHAN_OUTPUT_OPEN: 184 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); 185 break; 186 case CHAN_OUTPUT_WAIT_IEOF: 187 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 188 break; 189 default: 190 error("channel %d: protocol error: rcvd_ieof for ostate %d", 191 c->self, c->ostate); 192 break; 193 } 194 } 195 static void 196 chan_write_failed1(Channel *c) 197 { 198 debug2("channel %d: write failed", c->self); 199 switch (c->ostate) { 200 case CHAN_OUTPUT_OPEN: 201 chan_shutdown_write(c); 202 chan_send_oclose1(c); 203 chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF); 204 break; 205 case CHAN_OUTPUT_WAIT_DRAIN: 206 chan_shutdown_write(c); 207 chan_send_oclose1(c); 208 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 209 break; 210 default: 211 error("channel %d: chan_write_failed for ostate %d", 212 c->self, c->ostate); 213 break; 214 } 215 } 216 void 217 chan_obuf_empty(Channel *c) 218 { 219 debug2("channel %d: obuf empty", c->self); 220 if (buffer_len(&c->output)) { 221 error("channel %d: chan_obuf_empty for non empty buffer", 222 c->self); 223 return; 224 } 225 switch (c->ostate) { 226 case CHAN_OUTPUT_WAIT_DRAIN: 227 chan_shutdown_write(c); 228 if (!compat20) 229 chan_send_oclose1(c); 230 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 231 break; 232 default: 233 error("channel %d: internal error: obuf_empty for ostate %d", 234 c->self, c->ostate); 235 break; 236 } 237 } 238 static void 239 chan_send_ieof1(Channel *c) 240 { 241 debug2("channel %d: send ieof", c->self); 242 switch (c->istate) { 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: 250 error("channel %d: cannot send ieof for istate %d", 251 c->self, c->istate); 252 break; 253 } 254 } 255 static void 256 chan_send_oclose1(Channel *c) 257 { 258 debug2("channel %d: send oclose", c->self); 259 switch (c->ostate) { 260 case CHAN_OUTPUT_OPEN: 261 case CHAN_OUTPUT_WAIT_DRAIN: 262 buffer_clear(&c->output); 263 packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE); 264 packet_put_int(c->remote_id); 265 packet_send(); 266 break; 267 default: 268 error("channel %d: cannot send oclose for ostate %d", 269 c->self, c->ostate); 270 break; 271 } 272 } 273 274 /* 275 * the same for SSH2 276 */ 277 static void 278 chan_rcvd_close2(Channel *c) 279 { 280 debug2("channel %d: rcvd close", c->self); 281 if (!(c->flags & CHAN_LOCAL)) { 282 if (c->flags & CHAN_CLOSE_RCVD) 283 error("channel %d: protocol error: close rcvd twice", 284 c->self); 285 c->flags |= CHAN_CLOSE_RCVD; 286 } 287 if (c->type == SSH_CHANNEL_LARVAL) { 288 /* tear down larval channels immediately */ 289 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 290 chan_set_istate(c, CHAN_INPUT_CLOSED); 291 return; 292 } 293 switch (c->ostate) { 294 case CHAN_OUTPUT_OPEN: 295 /* 296 * wait until a data from the channel is consumed if a CLOSE 297 * is received 298 */ 299 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); 300 break; 301 } 302 switch (c->istate) { 303 case CHAN_INPUT_OPEN: 304 chan_shutdown_read(c); 305 chan_set_istate(c, CHAN_INPUT_CLOSED); 306 break; 307 case CHAN_INPUT_WAIT_DRAIN: 308 if (!(c->flags & CHAN_LOCAL)) 309 chan_send_eof2(c); 310 chan_set_istate(c, CHAN_INPUT_CLOSED); 311 break; 312 } 313 } 314 315 void 316 chan_rcvd_eow(Channel *c) 317 { 318 debug2("channel %d: rcvd eow", c->self); 319 switch (c->istate) { 320 case CHAN_INPUT_OPEN: 321 chan_shutdown_read(c); 322 chan_set_istate(c, CHAN_INPUT_CLOSED); 323 break; 324 } 325 } 326 static void 327 chan_rcvd_eof2(Channel *c) 328 { 329 debug2("channel %d: rcvd eof", c->self); 330 c->flags |= CHAN_EOF_RCVD; 331 if (c->ostate == CHAN_OUTPUT_OPEN) 332 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); 333 } 334 static void 335 chan_write_failed2(Channel *c) 336 { 337 debug2("channel %d: write failed", c->self); 338 switch (c->ostate) { 339 case CHAN_OUTPUT_OPEN: 340 case CHAN_OUTPUT_WAIT_DRAIN: 341 chan_shutdown_write(c); 342 if (strcmp(c->ctype, "session") == 0) 343 chan_send_eow2(c); 344 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 345 break; 346 default: 347 error("channel %d: chan_write_failed for ostate %d", 348 c->self, c->ostate); 349 break; 350 } 351 } 352 static void 353 chan_send_eof2(Channel *c) 354 { 355 debug2("channel %d: send eof", c->self); 356 switch (c->istate) { 357 case CHAN_INPUT_WAIT_DRAIN: 358 packet_start(SSH2_MSG_CHANNEL_EOF); 359 packet_put_int(c->remote_id); 360 packet_send(); 361 c->flags |= CHAN_EOF_SENT; 362 break; 363 default: 364 error("channel %d: cannot send eof for istate %d", 365 c->self, c->istate); 366 break; 367 } 368 } 369 static void 370 chan_send_close2(Channel *c) 371 { 372 debug2("channel %d: send close", c->self); 373 if (c->ostate != CHAN_OUTPUT_CLOSED || 374 c->istate != CHAN_INPUT_CLOSED) { 375 error("channel %d: cannot send close for istate/ostate %d/%d", 376 c->self, c->istate, c->ostate); 377 } else if (c->flags & CHAN_CLOSE_SENT) { 378 error("channel %d: already sent close", c->self); 379 } else { 380 packet_start(SSH2_MSG_CHANNEL_CLOSE); 381 packet_put_int(c->remote_id); 382 packet_send(); 383 c->flags |= CHAN_CLOSE_SENT; 384 } 385 } 386 static void 387 chan_send_eow2(Channel *c) 388 { 389 debug2("channel %d: send eow", c->self); 390 if (c->ostate == CHAN_OUTPUT_CLOSED) { 391 error("channel %d: must not sent eow on closed output", 392 c->self); 393 return; 394 } 395 if (!(datafellows & SSH_NEW_OPENSSH)) 396 return; 397 packet_start(SSH2_MSG_CHANNEL_REQUEST); 398 packet_put_int(c->remote_id); 399 packet_put_cstring("eow (at) openssh.com"); 400 packet_put_char(0); 401 packet_send(); 402 } 403 404 /* shared */ 405 406 void 407 chan_rcvd_ieof(Channel *c) 408 { 409 if (compat20) 410 chan_rcvd_eof2(c); 411 else 412 chan_rcvd_ieof1(c); 413 if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN && 414 buffer_len(&c->output) == 0 && 415 !CHANNEL_EFD_OUTPUT_ACTIVE(c)) 416 chan_obuf_empty(c); 417 } 418 void 419 chan_rcvd_oclose(Channel *c) 420 { 421 if (compat20) 422 chan_rcvd_close2(c); 423 else 424 chan_rcvd_oclose1(c); 425 } 426 void 427 chan_write_failed(Channel *c) 428 { 429 if (compat20) 430 chan_write_failed2(c); 431 else 432 chan_write_failed1(c); 433 } 434 435 void 436 chan_mark_dead(Channel *c) 437 { 438 c->type = SSH_CHANNEL_ZOMBIE; 439 } 440 441 int 442 chan_is_dead(Channel *c, int do_send) 443 { 444 if (c->type == SSH_CHANNEL_ZOMBIE) { 445 debug2("channel %d: zombie", c->self); 446 return 1; 447 } 448 if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED) 449 return 0; 450 if (!compat20) { 451 debug2("channel %d: is dead", c->self); 452 return 1; 453 } 454 if ((datafellows & SSH_BUG_EXTEOF) && 455 c->extended_usage == CHAN_EXTENDED_WRITE && 456 c->efd != -1 && 457 buffer_len(&c->extended) > 0) { 458 debug2("channel %d: active efd: %d len %d", 459 c->self, c->efd, buffer_len(&c->extended)); 460 return 0; 461 } 462 if (c->flags & CHAN_LOCAL) { 463 debug2("channel %d: is dead (local)", c->self); 464 return 1; 465 } 466 if (!(c->flags & CHAN_CLOSE_SENT)) { 467 if (do_send) { 468 chan_send_close2(c); 469 } else { 470 /* channel would be dead if we sent a close */ 471 if (c->flags & CHAN_CLOSE_RCVD) { 472 debug2("channel %d: almost dead", 473 c->self); 474 return 1; 475 } 476 } 477 } 478 if ((c->flags & CHAN_CLOSE_SENT) && 479 (c->flags & CHAN_CLOSE_RCVD)) { 480 debug2("channel %d: is dead", c->self); 481 return 1; 482 } 483 return 0; 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 debug2("channel %d: close_write", c->self); 495 if (c->sock != -1) { 496 if (shutdown(c->sock, SHUT_WR) < 0) 497 debug2("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 logit("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 debug2("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 logit("channel %d: chan_shutdown_read: " 528 "close() failed for fd %d: %.100s", 529 c->self, c->rfd, strerror(errno)); 530 } 531 } 532