nchan.c revision 181111
1/* $OpenBSD: nchan.c,v 1.60 2008/06/30 12:16:02 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 */ 77static void chan_send_ieof1(Channel *); 78static void chan_send_oclose1(Channel *); 79static void chan_send_close2(Channel *); 80static void chan_send_eof2(Channel *); 81static void chan_send_eow2(Channel *); 82 83/* helper */ 84static void chan_shutdown_write(Channel *); 85static void chan_shutdown_read(Channel *); 86 87static char *ostates[] = { "open", "drain", "wait_ieof", "closed" }; 88static char *istates[] = { "open", "drain", "wait_oclose", "closed" }; 89 90static void 91chan_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} 99static void 100chan_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 113static void 114chan_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} 137void 138chan_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} 152void 153chan_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)) 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} 178static void 179chan_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} 195static void 196chan_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} 216void 217chan_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} 238static void 239chan_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} 255static void 256chan_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 */ 277static void 278chan_rcvd_close2(Channel *c) 279{ 280 debug2("channel %d: rcvd close", c->self); 281 if (c->flags & CHAN_CLOSE_RCVD) 282 error("channel %d: protocol error: close rcvd twice", c->self); 283 c->flags |= CHAN_CLOSE_RCVD; 284 if (c->type == SSH_CHANNEL_LARVAL) { 285 /* tear down larval channels immediately */ 286 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 287 chan_set_istate(c, CHAN_INPUT_CLOSED); 288 return; 289 } 290 switch (c->ostate) { 291 case CHAN_OUTPUT_OPEN: 292 /* 293 * wait until a data from the channel is consumed if a CLOSE 294 * is received 295 */ 296 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); 297 break; 298 } 299 switch (c->istate) { 300 case CHAN_INPUT_OPEN: 301 chan_shutdown_read(c); 302 chan_set_istate(c, CHAN_INPUT_CLOSED); 303 break; 304 case CHAN_INPUT_WAIT_DRAIN: 305 chan_send_eof2(c); 306 chan_set_istate(c, CHAN_INPUT_CLOSED); 307 break; 308 } 309} 310void 311chan_rcvd_eow(Channel *c) 312{ 313 debug2("channel %d: rcvd eow", c->self); 314 switch (c->istate) { 315 case CHAN_INPUT_OPEN: 316 chan_shutdown_read(c); 317 chan_set_istate(c, CHAN_INPUT_CLOSED); 318 break; 319 } 320} 321static void 322chan_rcvd_eof2(Channel *c) 323{ 324 debug2("channel %d: rcvd eof", c->self); 325 c->flags |= CHAN_EOF_RCVD; 326 if (c->ostate == CHAN_OUTPUT_OPEN) 327 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); 328} 329static void 330chan_write_failed2(Channel *c) 331{ 332 debug2("channel %d: write failed", c->self); 333 switch (c->ostate) { 334 case CHAN_OUTPUT_OPEN: 335 case CHAN_OUTPUT_WAIT_DRAIN: 336 chan_shutdown_write(c); 337 if (strcmp(c->ctype, "session") == 0) 338 chan_send_eow2(c); 339 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 340 break; 341 default: 342 error("channel %d: chan_write_failed for ostate %d", 343 c->self, c->ostate); 344 break; 345 } 346} 347static void 348chan_send_eof2(Channel *c) 349{ 350 debug2("channel %d: send eof", c->self); 351 switch (c->istate) { 352 case CHAN_INPUT_WAIT_DRAIN: 353 packet_start(SSH2_MSG_CHANNEL_EOF); 354 packet_put_int(c->remote_id); 355 packet_send(); 356 c->flags |= CHAN_EOF_SENT; 357 break; 358 default: 359 error("channel %d: cannot send eof for istate %d", 360 c->self, c->istate); 361 break; 362 } 363} 364static void 365chan_send_close2(Channel *c) 366{ 367 debug2("channel %d: send close", c->self); 368 if (c->ostate != CHAN_OUTPUT_CLOSED || 369 c->istate != CHAN_INPUT_CLOSED) { 370 error("channel %d: cannot send close for istate/ostate %d/%d", 371 c->self, c->istate, c->ostate); 372 } else if (c->flags & CHAN_CLOSE_SENT) { 373 error("channel %d: already sent close", c->self); 374 } else { 375 packet_start(SSH2_MSG_CHANNEL_CLOSE); 376 packet_put_int(c->remote_id); 377 packet_send(); 378 c->flags |= CHAN_CLOSE_SENT; 379 } 380} 381static void 382chan_send_eow2(Channel *c) 383{ 384 debug2("channel %d: send eow", c->self); 385 if (c->ostate == CHAN_OUTPUT_CLOSED) { 386 error("channel %d: must not sent eow on closed output", 387 c->self); 388 return; 389 } 390 packet_start(SSH2_MSG_CHANNEL_REQUEST); 391 packet_put_int(c->remote_id); 392 packet_put_cstring("eow@openssh.com"); 393 packet_put_char(0); 394 packet_send(); 395} 396 397/* shared */ 398 399void 400chan_rcvd_ieof(Channel *c) 401{ 402 if (compat20) 403 chan_rcvd_eof2(c); 404 else 405 chan_rcvd_ieof1(c); 406 if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN && 407 buffer_len(&c->output) == 0 && 408 !CHANNEL_EFD_OUTPUT_ACTIVE(c)) 409 chan_obuf_empty(c); 410} 411void 412chan_rcvd_oclose(Channel *c) 413{ 414 if (compat20) 415 chan_rcvd_close2(c); 416 else 417 chan_rcvd_oclose1(c); 418} 419void 420chan_write_failed(Channel *c) 421{ 422 if (compat20) 423 chan_write_failed2(c); 424 else 425 chan_write_failed1(c); 426} 427 428void 429chan_mark_dead(Channel *c) 430{ 431 c->type = SSH_CHANNEL_ZOMBIE; 432} 433 434int 435chan_is_dead(Channel *c, int do_send) 436{ 437 if (c->type == SSH_CHANNEL_ZOMBIE) { 438 debug2("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 debug2("channel %d: is dead", c->self); 445 return 1; 446 } 447 if ((datafellows & SSH_BUG_EXTEOF) && 448 c->extended_usage == CHAN_EXTENDED_WRITE && 449 c->efd != -1 && 450 buffer_len(&c->extended) > 0) { 451 debug2("channel %d: active efd: %d len %d", 452 c->self, c->efd, buffer_len(&c->extended)); 453 return 0; 454 } 455 if (!(c->flags & CHAN_CLOSE_SENT)) { 456 if (do_send) { 457 chan_send_close2(c); 458 } else { 459 /* channel would be dead if we sent a close */ 460 if (c->flags & CHAN_CLOSE_RCVD) { 461 debug2("channel %d: almost dead", 462 c->self); 463 return 1; 464 } 465 } 466 } 467 if ((c->flags & CHAN_CLOSE_SENT) && 468 (c->flags & CHAN_CLOSE_RCVD)) { 469 debug2("channel %d: is dead", c->self); 470 return 1; 471 } 472 return 0; 473} 474 475/* helper */ 476static void 477chan_shutdown_write(Channel *c) 478{ 479 buffer_clear(&c->output); 480 if (compat20 && c->type == SSH_CHANNEL_LARVAL) 481 return; 482 /* shutdown failure is allowed if write failed already */ 483 debug2("channel %d: close_write", c->self); 484 if (c->sock != -1) { 485 if (shutdown(c->sock, SHUT_WR) < 0) 486 debug2("channel %d: chan_shutdown_write: " 487 "shutdown() failed for fd%d: %.100s", 488 c->self, c->sock, strerror(errno)); 489 } else { 490 if (channel_close_fd(&c->wfd) < 0) 491 logit("channel %d: chan_shutdown_write: " 492 "close() failed for fd%d: %.100s", 493 c->self, c->wfd, strerror(errno)); 494 } 495} 496static void 497chan_shutdown_read(Channel *c) 498{ 499 if (compat20 && c->type == SSH_CHANNEL_LARVAL) 500 return; 501 debug2("channel %d: close_read", c->self); 502 if (c->sock != -1) { 503 /* 504 * shutdown(sock, SHUT_READ) may return ENOTCONN if the 505 * write side has been closed already. (bug on Linux) 506 * HP-UX may return ENOTCONN also. 507 */ 508 if (shutdown(c->sock, SHUT_RD) < 0 509 && errno != ENOTCONN) 510 error("channel %d: chan_shutdown_read: " 511 "shutdown() failed for fd%d [i%d o%d]: %.100s", 512 c->self, c->sock, c->istate, c->ostate, 513 strerror(errno)); 514 } else { 515 if (channel_close_fd(&c->rfd) < 0) 516 logit("channel %d: chan_shutdown_read: " 517 "close() failed for fd%d: %.100s", 518 c->self, c->rfd, strerror(errno)); 519 } 520} 521