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