|
Lines 300-305
channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd,
Link Here
|
| 300 |
int extusage, int nonblock, int is_tty) |
300 |
int extusage, int nonblock, int is_tty) |
| 301 |
{ |
301 |
{ |
| 302 |
struct ssh_channels *sc = ssh->chanctxt; |
302 |
struct ssh_channels *sc = ssh->chanctxt; |
|
|
303 |
int nb; |
| 303 |
|
304 |
|
| 304 |
/* Update the maximum file descriptor value. */ |
305 |
/* Update the maximum file descriptor value. */ |
| 305 |
sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, rfd); |
306 |
sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, rfd); |
|
Lines 323-329
channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd,
Link Here
|
| 323 |
debug2("channel %d: rfd %d isatty", c->self, c->rfd); |
324 |
debug2("channel %d: rfd %d isatty", c->self, c->rfd); |
| 324 |
|
325 |
|
| 325 |
/* enable nonblocking mode */ |
326 |
/* enable nonblocking mode */ |
| 326 |
if (nonblock) { |
327 |
c->restore_block = 0; |
|
|
328 |
if (nonblock == CHANNEL_NONBLOCK_STDIO) { |
| 329 |
/* |
| 330 |
* Special handling for stdio file descriptors: do not set |
| 331 |
* non-blocking mode if they are TTYs. Otherwise prepare to |
| 332 |
* restore their blocking state on exit to avoid interfering |
| 333 |
* with other programs that follow. |
| 334 |
*/ |
| 335 |
if (rfd != -1 && !isatty(rfd) && |
| 336 |
(nb = fcntl(rfd, F_GETFL)) == 0) { |
| 337 |
c->restore_block |= 1; |
| 338 |
set_nonblock(rfd); |
| 339 |
} |
| 340 |
if (wfd != -1 && !isatty(wfd) && |
| 341 |
(nb = fcntl(wfd, F_GETFL)) != -1) { |
| 342 |
c->restore_block |= 1<<1; |
| 343 |
set_nonblock(wfd); |
| 344 |
} |
| 345 |
if (efd != -1 && !isatty(efd) && |
| 346 |
(nb = fcntl(efd, F_GETFL)) != -1) { |
| 347 |
c->restore_block |= 1<<2; |
| 348 |
set_nonblock(efd); |
| 349 |
} |
| 350 |
} else if (nonblock) { |
| 327 |
if (rfd != -1) |
351 |
if (rfd != -1) |
| 328 |
set_nonblock(rfd); |
352 |
set_nonblock(rfd); |
| 329 |
if (wfd != -1) |
353 |
if (wfd != -1) |
|
Lines 378-383
channel_new(struct ssh *ssh, char *ctype, int type, int rfd, int wfd, int efd,
Link Here
|
| 378 |
fatal_fr(r, "sshbuf_set_max_size"); |
402 |
fatal_fr(r, "sshbuf_set_max_size"); |
| 379 |
c->ostate = CHAN_OUTPUT_OPEN; |
403 |
c->ostate = CHAN_OUTPUT_OPEN; |
| 380 |
c->istate = CHAN_INPUT_OPEN; |
404 |
c->istate = CHAN_INPUT_OPEN; |
|
|
405 |
c->restore_block = 0; |
| 381 |
channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, 0); |
406 |
channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, 0); |
| 382 |
c->self = found; |
407 |
c->self = found; |
| 383 |
c->type = type; |
408 |
c->type = type; |
|
Lines 412-428
channel_find_maxfd(struct ssh_channels *sc)
Link Here
|
| 412 |
} |
437 |
} |
| 413 |
|
438 |
|
| 414 |
int |
439 |
int |
| 415 |
channel_close_fd(struct ssh *ssh, int *fdp) |
440 |
channel_close_fd(struct ssh *ssh, Channel *c, int *fdp) |
| 416 |
{ |
441 |
{ |
| 417 |
struct ssh_channels *sc = ssh->chanctxt; |
442 |
struct ssh_channels *sc = ssh->chanctxt; |
| 418 |
int ret = 0, fd = *fdp; |
443 |
int ret, fd = *fdp; |
| 419 |
|
444 |
|
| 420 |
if (fd != -1) { |
445 |
if (fd == -1) |
| 421 |
ret = close(fd); |
446 |
return 0; |
| 422 |
*fdp = -1; |
447 |
|
| 423 |
if (fd == sc->channel_max_fd) |
448 |
if ((*fdp == c->rfd && (c->restore_block & 1) != 0) || |
| 424 |
channel_find_maxfd(sc); |
449 |
(*fdp == c->wfd && (c->restore_block & (1<<1)) != 0) || |
| 425 |
} |
450 |
(*fdp == c->efd && (c->restore_block & (1<<2)) != 0)) |
|
|
451 |
(void)fcntl(*fdp, F_SETFL, 0); /* restore blocking */ |
| 452 |
|
| 453 |
ret = close(fd); |
| 454 |
*fdp = -1; |
| 455 |
if (fd == sc->channel_max_fd) |
| 456 |
channel_find_maxfd(sc); |
| 426 |
return ret; |
457 |
return ret; |
| 427 |
} |
458 |
} |
| 428 |
|
459 |
|
|
Lines 432-444
channel_close_fds(struct ssh *ssh, Channel *c)
Link Here
|
| 432 |
{ |
463 |
{ |
| 433 |
int sock = c->sock, rfd = c->rfd, wfd = c->wfd, efd = c->efd; |
464 |
int sock = c->sock, rfd = c->rfd, wfd = c->wfd, efd = c->efd; |
| 434 |
|
465 |
|
| 435 |
channel_close_fd(ssh, &c->sock); |
466 |
channel_close_fd(ssh, c, &c->sock); |
| 436 |
if (rfd != sock) |
467 |
if (rfd != sock) |
| 437 |
channel_close_fd(ssh, &c->rfd); |
468 |
channel_close_fd(ssh, c, &c->rfd); |
| 438 |
if (wfd != sock && wfd != rfd) |
469 |
if (wfd != sock && wfd != rfd) |
| 439 |
channel_close_fd(ssh, &c->wfd); |
470 |
channel_close_fd(ssh, c, &c->wfd); |
| 440 |
if (efd != sock && efd != rfd && efd != wfd) |
471 |
if (efd != sock && efd != rfd && efd != wfd) |
| 441 |
channel_close_fd(ssh, &c->efd); |
472 |
channel_close_fd(ssh, c, &c->efd); |
| 442 |
} |
473 |
} |
| 443 |
|
474 |
|
| 444 |
static void |
475 |
static void |
|
Lines 692-698
channel_stop_listening(struct ssh *ssh)
Link Here
|
| 692 |
case SSH_CHANNEL_X11_LISTENER: |
723 |
case SSH_CHANNEL_X11_LISTENER: |
| 693 |
case SSH_CHANNEL_UNIX_LISTENER: |
724 |
case SSH_CHANNEL_UNIX_LISTENER: |
| 694 |
case SSH_CHANNEL_RUNIX_LISTENER: |
725 |
case SSH_CHANNEL_RUNIX_LISTENER: |
| 695 |
channel_close_fd(ssh, &c->sock); |
726 |
channel_close_fd(ssh, c, &c->sock); |
| 696 |
channel_free(ssh, c); |
727 |
channel_free(ssh, c); |
| 697 |
break; |
728 |
break; |
| 698 |
} |
729 |
} |
|
Lines 1481-1487
channel_decode_socks5(Channel *c, struct sshbuf *input, struct sshbuf *output)
Link Here
|
| 1481 |
|
1512 |
|
| 1482 |
Channel * |
1513 |
Channel * |
| 1483 |
channel_connect_stdio_fwd(struct ssh *ssh, |
1514 |
channel_connect_stdio_fwd(struct ssh *ssh, |
| 1484 |
const char *host_to_connect, u_short port_to_connect, int in, int out) |
1515 |
const char *host_to_connect, u_short port_to_connect, |
|
|
1516 |
int in, int out, int nonblock) |
| 1485 |
{ |
1517 |
{ |
| 1486 |
Channel *c; |
1518 |
Channel *c; |
| 1487 |
|
1519 |
|
|
Lines 1489-1495
channel_connect_stdio_fwd(struct ssh *ssh,
Link Here
|
| 1489 |
|
1521 |
|
| 1490 |
c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out, |
1522 |
c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out, |
| 1491 |
-1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, |
1523 |
-1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, |
| 1492 |
0, "stdio-forward", /*nonblock*/0); |
1524 |
0, "stdio-forward", nonblock); |
| 1493 |
|
1525 |
|
| 1494 |
c->path = xstrdup(host_to_connect); |
1526 |
c->path = xstrdup(host_to_connect); |
| 1495 |
c->host_port = port_to_connect; |
1527 |
c->host_port = port_to_connect; |
|
Lines 1639-1645
channel_post_x11_listener(struct ssh *ssh, Channel *c,
Link Here
|
| 1639 |
if (c->single_connection) { |
1671 |
if (c->single_connection) { |
| 1640 |
oerrno = errno; |
1672 |
oerrno = errno; |
| 1641 |
debug2("single_connection: closing X11 listener."); |
1673 |
debug2("single_connection: closing X11 listener."); |
| 1642 |
channel_close_fd(ssh, &c->sock); |
1674 |
channel_close_fd(ssh, c, &c->sock); |
| 1643 |
chan_mark_dead(ssh, c); |
1675 |
chan_mark_dead(ssh, c); |
| 1644 |
errno = oerrno; |
1676 |
errno = oerrno; |
| 1645 |
} |
1677 |
} |
|
Lines 2028-2034
channel_handle_efd_write(struct ssh *ssh, Channel *c,
Link Here
|
| 2028 |
return 1; |
2060 |
return 1; |
| 2029 |
if (len <= 0) { |
2061 |
if (len <= 0) { |
| 2030 |
debug2("channel %d: closing write-efd %d", c->self, c->efd); |
2062 |
debug2("channel %d: closing write-efd %d", c->self, c->efd); |
| 2031 |
channel_close_fd(ssh, &c->efd); |
2063 |
channel_close_fd(ssh, c, &c->efd); |
| 2032 |
} else { |
2064 |
} else { |
| 2033 |
if ((r = sshbuf_consume(c->extended, len)) != 0) |
2065 |
if ((r = sshbuf_consume(c->extended, len)) != 0) |
| 2034 |
fatal_fr(r, "channel %i: consume", c->self); |
2066 |
fatal_fr(r, "channel %i: consume", c->self); |
|
Lines 2054-2060
channel_handle_efd_read(struct ssh *ssh, Channel *c,
Link Here
|
| 2054 |
return 1; |
2086 |
return 1; |
| 2055 |
if (len <= 0) { |
2087 |
if (len <= 0) { |
| 2056 |
debug2("channel %d: closing read-efd %d", c->self, c->efd); |
2088 |
debug2("channel %d: closing read-efd %d", c->self, c->efd); |
| 2057 |
channel_close_fd(ssh, &c->efd); |
2089 |
channel_close_fd(ssh, c, &c->efd); |
| 2058 |
} else if (c->extended_usage == CHAN_EXTENDED_IGNORE) |
2090 |
} else if (c->extended_usage == CHAN_EXTENDED_IGNORE) |
| 2059 |
debug3("channel %d: discard efd", c->self); |
2091 |
debug3("channel %d: discard efd", c->self); |
| 2060 |
else if ((r = sshbuf_put(c->extended, buf, len)) != 0) |
2092 |
else if ((r = sshbuf_put(c->extended, buf, len)) != 0) |