1 /* $OpenBSD: nchan.c,v 1.65 2017/04/30 23:28:42 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 <sys/types.h> 27 #include <sys/socket.h> 28 #include <sys/queue.h> 29 30 #include <errno.h> 31 #include <string.h> 32 #include <stdarg.h> 33 34 #include "ssh2.h" 35 #include "buffer.h" 36 #include "packet.h" 37 #include "channels.h" 38 #include "compat.h" 39 #include "log.h" 40 41 /* 42 * SSH Protocol 1.5 aka New Channel Protocol 43 * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored. 44 * Written by Markus Friedl in October 1999 45 * 46 * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the 47 * tear down of channels: 48 * 49 * 1.3: strict request-ack-protocol: 50 * CLOSE -> 51 * <- CLOSE_CONFIRM 52 * 53 * 1.5: uses variations of: 54 * IEOF -> 55 * <- OCLOSE 56 * <- IEOF 57 * OCLOSE -> 58 * i.e. both sides have to close the channel 59 * 60 * 2.0: the EOF messages are optional 61 * 62 * See the debugging output from 'ssh -v' and 'sshd -d' of 63 * ssh-1.2.27 as an example. 64 * 65 */ 66 67 /* functions manipulating channel states */ 68 /* 69 * EVENTS update channel input/output states execute ACTIONS 70 */ 71 /* 72 * ACTIONS: should never update the channel states 73 */ 74 static void chan_send_eof2(Channel *); 75 static void chan_send_eow2(Channel *); 76 77 /* helper */ 78 static void chan_shutdown_write(Channel *); 79 static void chan_shutdown_read(Channel *); 80 81 static char *ostates[] = { "open", "drain", "wait_ieof", "closed" }; 82 static char *istates[] = { "open", "drain", "wait_oclose", "closed" }; 83 84 static void 85 chan_set_istate(Channel *c, u_int next) 86 { 87 if (c->istate > CHAN_INPUT_CLOSED || next > CHAN_INPUT_CLOSED) 88 fatal("chan_set_istate: bad state %d -> %d", c->istate, next); 89 debug2("channel %d: input %s -> %s", c->self, istates[c->istate], 90 istates[next]); 91 c->istate = next; 92 } 93 94 static void 95 chan_set_ostate(Channel *c, u_int next) 96 { 97 if (c->ostate > CHAN_OUTPUT_CLOSED || next > CHAN_OUTPUT_CLOSED) 98 fatal("chan_set_ostate: bad state %d -> %d", c->ostate, next); 99 debug2("channel %d: output %s -> %s", c->self, ostates[c->ostate], 100 ostates[next]); 101 c->ostate = next; 102 } 103 104 void 105 chan_read_failed(Channel *c) 106 { 107 debug2("channel %d: read failed", c->self); 108 switch (c->istate) { 109 case CHAN_INPUT_OPEN: 110 chan_shutdown_read(c); 111 chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN); 112 break; 113 default: 114 error("channel %d: chan_read_failed for istate %d", 115 c->self, c->istate); 116 break; 117 } 118 } 119 120 void 121 chan_ibuf_empty(Channel *c) 122 { 123 debug2("channel %d: ibuf empty", c->self); 124 if (buffer_len(&c->input)) { 125 error("channel %d: chan_ibuf_empty for non empty buffer", 126 c->self); 127 return; 128 } 129 switch (c->istate) { 130 case CHAN_INPUT_WAIT_DRAIN: 131 if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL))) 132 chan_send_eof2(c); 133 chan_set_istate(c, CHAN_INPUT_CLOSED); 134 break; 135 default: 136 error("channel %d: chan_ibuf_empty for istate %d", 137 c->self, c->istate); 138 break; 139 } 140 } 141 142 void 143 chan_obuf_empty(Channel *c) 144 { 145 debug2("channel %d: obuf empty", c->self); 146 if (buffer_len(&c->output)) { 147 error("channel %d: chan_obuf_empty for non empty buffer", 148 c->self); 149 return; 150 } 151 switch (c->ostate) { 152 case CHAN_OUTPUT_WAIT_DRAIN: 153 chan_shutdown_write(c); 154 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 155 break; 156 default: 157 error("channel %d: internal error: obuf_empty for ostate %d", 158 c->self, c->ostate); 159 break; 160 } 161 } 162 163 void 164 chan_rcvd_eow(Channel *c) 165 { 166 debug2("channel %d: rcvd eow", c->self); 167 switch (c->istate) { 168 case CHAN_INPUT_OPEN: 169 chan_shutdown_read(c); 170 chan_set_istate(c, CHAN_INPUT_CLOSED); 171 break; 172 } 173 } 174 175 static void 176 chan_send_eof2(Channel *c) 177 { 178 debug2("channel %d: send eof", c->self); 179 switch (c->istate) { 180 case CHAN_INPUT_WAIT_DRAIN: 181 packet_start(SSH2_MSG_CHANNEL_EOF); 182 packet_put_int(c->remote_id); 183 packet_send(); 184 c->flags |= CHAN_EOF_SENT; 185 break; 186 default: 187 error("channel %d: cannot send eof for istate %d", 188 c->self, c->istate); 189 break; 190 } 191 } 192 193 static void 194 chan_send_close2(Channel *c) 195 { 196 debug2("channel %d: send close", c->self); 197 if (c->ostate != CHAN_OUTPUT_CLOSED || 198 c->istate != CHAN_INPUT_CLOSED) { 199 error("channel %d: cannot send close for istate/ostate %d/%d", 200 c->self, c->istate, c->ostate); 201 } else if (c->flags & CHAN_CLOSE_SENT) { 202 error("channel %d: already sent close", c->self); 203 } else { 204 packet_start(SSH2_MSG_CHANNEL_CLOSE); 205 packet_put_int(c->remote_id); 206 packet_send(); 207 c->flags |= CHAN_CLOSE_SENT; 208 } 209 } 210 211 static void 212 chan_send_eow2(Channel *c) 213 { 214 debug2("channel %d: send eow", c->self); 215 if (c->ostate == CHAN_OUTPUT_CLOSED) { 216 error("channel %d: must not sent eow on closed output", 217 c->self); 218 return; 219 } 220 if (!(datafellows & SSH_NEW_OPENSSH)) 221 return; 222 packet_start(SSH2_MSG_CHANNEL_REQUEST); 223 packet_put_int(c->remote_id); 224 packet_put_cstring("eow@openssh.com"); 225 packet_put_char(0); 226 packet_send(); 227 } 228 229 /* shared */ 230 231 void 232 chan_rcvd_ieof(Channel *c) 233 { 234 debug2("channel %d: rcvd eof", c->self); 235 c->flags |= CHAN_EOF_RCVD; 236 if (c->ostate == CHAN_OUTPUT_OPEN) 237 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); 238 if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN && 239 buffer_len(&c->output) == 0 && 240 !CHANNEL_EFD_OUTPUT_ACTIVE(c)) 241 chan_obuf_empty(c); 242 } 243 244 void 245 chan_rcvd_oclose(Channel *c) 246 { 247 debug2("channel %d: rcvd close", c->self); 248 if (!(c->flags & CHAN_LOCAL)) { 249 if (c->flags & CHAN_CLOSE_RCVD) 250 error("channel %d: protocol error: close rcvd twice", 251 c->self); 252 c->flags |= CHAN_CLOSE_RCVD; 253 } 254 if (c->type == SSH_CHANNEL_LARVAL) { 255 /* tear down larval channels immediately */ 256 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 257 chan_set_istate(c, CHAN_INPUT_CLOSED); 258 return; 259 } 260 switch (c->ostate) { 261 case CHAN_OUTPUT_OPEN: 262 /* 263 * wait until a data from the channel is consumed if a CLOSE 264 * is received 265 */ 266 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); 267 break; 268 } 269 switch (c->istate) { 270 case CHAN_INPUT_OPEN: 271 chan_shutdown_read(c); 272 chan_set_istate(c, CHAN_INPUT_CLOSED); 273 break; 274 case CHAN_INPUT_WAIT_DRAIN: 275 if (!(c->flags & CHAN_LOCAL)) 276 chan_send_eof2(c); 277 chan_set_istate(c, CHAN_INPUT_CLOSED); 278 break; 279 } 280 } 281 282 void 283 chan_write_failed(Channel *c) 284 { 285 debug2("channel %d: write failed", c->self); 286 switch (c->ostate) { 287 case CHAN_OUTPUT_OPEN: 288 case CHAN_OUTPUT_WAIT_DRAIN: 289 chan_shutdown_write(c); 290 if (strcmp(c->ctype, "session") == 0) 291 chan_send_eow2(c); 292 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 293 break; 294 default: 295 error("channel %d: chan_write_failed for ostate %d", 296 c->self, c->ostate); 297 break; 298 } 299 } 300 301 void 302 chan_mark_dead(Channel *c) 303 { 304 c->type = SSH_CHANNEL_ZOMBIE; 305 } 306 307 int 308 chan_is_dead(Channel *c, int do_send) 309 { 310 if (c->type == SSH_CHANNEL_ZOMBIE) { 311 debug2("channel %d: zombie", c->self); 312 return 1; 313 } 314 if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED) 315 return 0; 316 if ((datafellows & SSH_BUG_EXTEOF) && 317 c->extended_usage == CHAN_EXTENDED_WRITE && 318 c->efd != -1 && 319 buffer_len(&c->extended) > 0) { 320 debug2("channel %d: active efd: %d len %d", 321 c->self, c->efd, buffer_len(&c->extended)); 322 return 0; 323 } 324 if (c->flags & CHAN_LOCAL) { 325 debug2("channel %d: is dead (local)", c->self); 326 return 1; 327 } 328 if (!(c->flags & CHAN_CLOSE_SENT)) { 329 if (do_send) { 330 chan_send_close2(c); 331 } else { 332 /* channel would be dead if we sent a close */ 333 if (c->flags & CHAN_CLOSE_RCVD) { 334 debug2("channel %d: almost dead", 335 c->self); 336 return 1; 337 } 338 } 339 } 340 if ((c->flags & CHAN_CLOSE_SENT) && 341 (c->flags & CHAN_CLOSE_RCVD)) { 342 debug2("channel %d: is dead", c->self); 343 return 1; 344 } 345 return 0; 346 } 347 348 /* helper */ 349 static void 350 chan_shutdown_write(Channel *c) 351 { 352 buffer_clear(&c->output); 353 if (c->type == SSH_CHANNEL_LARVAL) 354 return; 355 /* shutdown failure is allowed if write failed already */ 356 debug2("channel %d: close_write", c->self); 357 if (c->sock != -1) { 358 if (shutdown(c->sock, SHUT_WR) < 0) 359 debug2("channel %d: chan_shutdown_write: " 360 "shutdown() failed for fd %d: %.100s", 361 c->self, c->sock, strerror(errno)); 362 } else { 363 if (channel_close_fd(&c->wfd) < 0) 364 logit("channel %d: chan_shutdown_write: " 365 "close() failed for fd %d: %.100s", 366 c->self, c->wfd, strerror(errno)); 367 } 368 } 369 370 static void 371 chan_shutdown_read(Channel *c) 372 { 373 if (c->type == SSH_CHANNEL_LARVAL) 374 return; 375 debug2("channel %d: close_read", c->self); 376 if (c->sock != -1) { 377 if (shutdown(c->sock, SHUT_RD) < 0) 378 error("channel %d: chan_shutdown_read: " 379 "shutdown() failed for fd %d [i%d o%d]: %.100s", 380 c->self, c->sock, c->istate, c->ostate, 381 strerror(errno)); 382 } else { 383 if (channel_close_fd(&c->rfd) < 0) 384 logit("channel %d: chan_shutdown_read: " 385 "close() failed for fd %d: %.100s", 386 c->self, c->rfd, strerror(errno)); 387 } 388 } 389