clientloop.c revision 224638
1/* $OpenBSD: clientloop.c,v 1.231 2011/01/16 12:05:59 djm Exp $ */ 2/* $FreeBSD$ */ 3/* 4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 6 * All rights reserved 7 * The main loop for the interactive session (client side). 8 * 9 * As far as I am concerned, the code I have written for this software 10 * can be used freely for any purpose. Any derived versions of this 11 * software must be clearly marked as such, and if the derived work is 12 * incompatible with the protocol description in the RFC file, it must be 13 * called by a name other than "ssh" or "Secure Shell". 14 * 15 * 16 * Copyright (c) 1999 Theo de Raadt. All rights reserved. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions 20 * are met: 21 * 1. Redistributions of source code must retain the above copyright 22 * notice, this list of conditions and the following disclaimer. 23 * 2. Redistributions in binary form must reproduce the above copyright 24 * notice, this list of conditions and the following disclaimer in the 25 * documentation and/or other materials provided with the distribution. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 28 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 31 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 32 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 36 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 * 38 * 39 * SSH2 support added by Markus Friedl. 40 * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 52 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 53 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 54 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 55 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 60 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 61 */ 62 63#include "includes.h" 64 65#include <sys/types.h> 66#include <sys/ioctl.h> 67#include <sys/param.h> 68#ifdef HAVE_SYS_STAT_H 69# include <sys/stat.h> 70#endif 71#ifdef HAVE_SYS_TIME_H 72# include <sys/time.h> 73#endif 74#include <sys/socket.h> 75 76#include <ctype.h> 77#include <errno.h> 78#ifdef HAVE_PATHS_H 79#include <paths.h> 80#endif 81#include <signal.h> 82#include <stdarg.h> 83#include <stdio.h> 84#include <stdlib.h> 85#include <string.h> 86#include <termios.h> 87#include <pwd.h> 88#include <unistd.h> 89 90#include "openbsd-compat/sys-queue.h" 91#include "xmalloc.h" 92#include "ssh.h" 93#include "ssh1.h" 94#include "ssh2.h" 95#include "packet.h" 96#include "buffer.h" 97#include "compat.h" 98#include "channels.h" 99#include "dispatch.h" 100#include "key.h" 101#include "cipher.h" 102#include "kex.h" 103#include "log.h" 104#include "readconf.h" 105#include "clientloop.h" 106#include "sshconnect.h" 107#include "authfd.h" 108#include "atomicio.h" 109#include "sshpty.h" 110#include "misc.h" 111#include "match.h" 112#include "msg.h" 113#include "roaming.h" 114 115/* import options */ 116extern Options options; 117 118/* Flag indicating that stdin should be redirected from /dev/null. */ 119extern int stdin_null_flag; 120 121/* Flag indicating that no shell has been requested */ 122extern int no_shell_flag; 123 124/* Control socket */ 125extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */ 126 127/* 128 * Name of the host we are connecting to. This is the name given on the 129 * command line, or the HostName specified for the user-supplied name in a 130 * configuration file. 131 */ 132extern char *host; 133 134/* Force TTY allocation */ 135extern int force_tty_flag; 136 137/* 138 * Flag to indicate that we have received a window change signal which has 139 * not yet been processed. This will cause a message indicating the new 140 * window size to be sent to the server a little later. This is volatile 141 * because this is updated in a signal handler. 142 */ 143static volatile sig_atomic_t received_window_change_signal = 0; 144static volatile sig_atomic_t received_signal = 0; 145 146/* Flag indicating whether the user's terminal is in non-blocking mode. */ 147static int in_non_blocking_mode = 0; 148 149/* Time when backgrounded control master using ControlPersist should exit */ 150static time_t control_persist_exit_time = 0; 151 152/* Common data for the client loop code. */ 153volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ 154static int escape_char1; /* Escape character. (proto1 only) */ 155static int escape_pending1; /* Last character was an escape (proto1 only) */ 156static int last_was_cr; /* Last character was a newline. */ 157static int exit_status; /* Used to store the command exit status. */ 158static int stdin_eof; /* EOF has been encountered on stderr. */ 159static Buffer stdin_buffer; /* Buffer for stdin data. */ 160static Buffer stdout_buffer; /* Buffer for stdout data. */ 161static Buffer stderr_buffer; /* Buffer for stderr data. */ 162static u_int buffer_high; /* Soft max buffer size. */ 163static int connection_in; /* Connection to server (input). */ 164static int connection_out; /* Connection to server (output). */ 165static int need_rekeying; /* Set to non-zero if rekeying is requested. */ 166static int session_closed; /* In SSH2: login session closed. */ 167static int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ 168 169static void client_init_dispatch(void); 170int session_ident = -1; 171 172int session_resumed = 0; 173 174/* Track escape per proto2 channel */ 175struct escape_filter_ctx { 176 int escape_pending; 177 int escape_char; 178}; 179 180/* Context for channel confirmation replies */ 181struct channel_reply_ctx { 182 const char *request_type; 183 int id, do_close; 184}; 185 186/* Global request success/failure callbacks */ 187struct global_confirm { 188 TAILQ_ENTRY(global_confirm) entry; 189 global_confirm_cb *cb; 190 void *ctx; 191 int ref_count; 192}; 193TAILQ_HEAD(global_confirms, global_confirm); 194static struct global_confirms global_confirms = 195 TAILQ_HEAD_INITIALIZER(global_confirms); 196 197/*XXX*/ 198extern Kex *xxx_kex; 199 200void ssh_process_session2_setup(int, int, int, Buffer *); 201 202/* Restores stdin to blocking mode. */ 203 204static void 205leave_non_blocking(void) 206{ 207 if (in_non_blocking_mode) { 208 unset_nonblock(fileno(stdin)); 209 in_non_blocking_mode = 0; 210 } 211} 212 213/* Puts stdin terminal in non-blocking mode. */ 214 215static void 216enter_non_blocking(void) 217{ 218 in_non_blocking_mode = 1; 219 set_nonblock(fileno(stdin)); 220} 221 222/* 223 * Signal handler for the window change signal (SIGWINCH). This just sets a 224 * flag indicating that the window has changed. 225 */ 226/*ARGSUSED */ 227static void 228window_change_handler(int sig) 229{ 230 received_window_change_signal = 1; 231 signal(SIGWINCH, window_change_handler); 232} 233 234/* 235 * Signal handler for signals that cause the program to terminate. These 236 * signals must be trapped to restore terminal modes. 237 */ 238/*ARGSUSED */ 239static void 240signal_handler(int sig) 241{ 242 received_signal = sig; 243 quit_pending = 1; 244} 245 246/* 247 * Returns current time in seconds from Jan 1, 1970 with the maximum 248 * available resolution. 249 */ 250 251static double 252get_current_time(void) 253{ 254 struct timeval tv; 255 gettimeofday(&tv, NULL); 256 return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; 257} 258 259/* 260 * Sets control_persist_exit_time to the absolute time when the 261 * backgrounded control master should exit due to expiry of the 262 * ControlPersist timeout. Sets it to 0 if we are not a backgrounded 263 * control master process, or if there is no ControlPersist timeout. 264 */ 265static void 266set_control_persist_exit_time(void) 267{ 268 if (muxserver_sock == -1 || !options.control_persist 269 || options.control_persist_timeout == 0) 270 /* not using a ControlPersist timeout */ 271 control_persist_exit_time = 0; 272 else if (channel_still_open()) { 273 /* some client connections are still open */ 274 if (control_persist_exit_time > 0) 275 debug2("%s: cancel scheduled exit", __func__); 276 control_persist_exit_time = 0; 277 } else if (control_persist_exit_time <= 0) { 278 /* a client connection has recently closed */ 279 control_persist_exit_time = time(NULL) + 280 (time_t)options.control_persist_timeout; 281 debug2("%s: schedule exit in %d seconds", __func__, 282 options.control_persist_timeout); 283 } 284 /* else we are already counting down to the timeout */ 285} 286 287#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" 288void 289client_x11_get_proto(const char *display, const char *xauth_path, 290 u_int trusted, u_int timeout, char **_proto, char **_data) 291{ 292 char cmd[1024]; 293 char line[512]; 294 char xdisplay[512]; 295 static char proto[512], data[512]; 296 FILE *f; 297 int got_data = 0, generated = 0, do_unlink = 0, i; 298 char *xauthdir, *xauthfile; 299 struct stat st; 300 u_int now; 301 302 xauthdir = xauthfile = NULL; 303 *_proto = proto; 304 *_data = data; 305 proto[0] = data[0] = '\0'; 306 307 if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) { 308 debug("No xauth program."); 309 } else { 310 if (display == NULL) { 311 debug("x11_get_proto: DISPLAY not set"); 312 return; 313 } 314 /* 315 * Handle FamilyLocal case where $DISPLAY does 316 * not match an authorization entry. For this we 317 * just try "xauth list unix:displaynum.screennum". 318 * XXX: "localhost" match to determine FamilyLocal 319 * is not perfect. 320 */ 321 if (strncmp(display, "localhost:", 10) == 0) { 322 snprintf(xdisplay, sizeof(xdisplay), "unix:%s", 323 display + 10); 324 display = xdisplay; 325 } 326 if (trusted == 0) { 327 xauthdir = xmalloc(MAXPATHLEN); 328 xauthfile = xmalloc(MAXPATHLEN); 329 mktemp_proto(xauthdir, MAXPATHLEN); 330 if (mkdtemp(xauthdir) != NULL) { 331 do_unlink = 1; 332 snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", 333 xauthdir); 334 snprintf(cmd, sizeof(cmd), 335 "%s -f %s generate %s " SSH_X11_PROTO 336 " untrusted timeout %u 2>" _PATH_DEVNULL, 337 xauth_path, xauthfile, display, timeout); 338 debug2("x11_get_proto: %s", cmd); 339 if (system(cmd) == 0) 340 generated = 1; 341 if (x11_refuse_time == 0) { 342 now = time(NULL) + 1; 343 if (UINT_MAX - timeout < now) 344 x11_refuse_time = UINT_MAX; 345 else 346 x11_refuse_time = now + timeout; 347 } 348 } 349 } 350 351 /* 352 * When in untrusted mode, we read the cookie only if it was 353 * successfully generated as an untrusted one in the step 354 * above. 355 */ 356 if (trusted || generated) { 357 snprintf(cmd, sizeof(cmd), 358 "%s %s%s list %s 2>" _PATH_DEVNULL, 359 xauth_path, 360 generated ? "-f " : "" , 361 generated ? xauthfile : "", 362 display); 363 debug2("x11_get_proto: %s", cmd); 364 f = popen(cmd, "r"); 365 if (f && fgets(line, sizeof(line), f) && 366 sscanf(line, "%*s %511s %511s", proto, data) == 2) 367 got_data = 1; 368 if (f) 369 pclose(f); 370 } else 371 error("Warning: untrusted X11 forwarding setup failed: " 372 "xauth key data not generated"); 373 } 374 375 if (do_unlink) { 376 unlink(xauthfile); 377 rmdir(xauthdir); 378 } 379 if (xauthdir) 380 xfree(xauthdir); 381 if (xauthfile) 382 xfree(xauthfile); 383 384 /* 385 * If we didn't get authentication data, just make up some 386 * data. The forwarding code will check the validity of the 387 * response anyway, and substitute this data. The X11 388 * server, however, will ignore this fake data and use 389 * whatever authentication mechanisms it was using otherwise 390 * for the local connection. 391 */ 392 if (!got_data) { 393 u_int32_t rnd = 0; 394 395 logit("Warning: No xauth data; " 396 "using fake authentication data for X11 forwarding."); 397 strlcpy(proto, SSH_X11_PROTO, sizeof proto); 398 for (i = 0; i < 16; i++) { 399 if (i % 4 == 0) 400 rnd = arc4random(); 401 snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", 402 rnd & 0xff); 403 rnd >>= 8; 404 } 405 } 406} 407 408/* 409 * This is called when the interactive is entered. This checks if there is 410 * an EOF coming on stdin. We must check this explicitly, as select() does 411 * not appear to wake up when redirecting from /dev/null. 412 */ 413 414static void 415client_check_initial_eof_on_stdin(void) 416{ 417 int len; 418 char buf[1]; 419 420 /* 421 * If standard input is to be "redirected from /dev/null", we simply 422 * mark that we have seen an EOF and send an EOF message to the 423 * server. Otherwise, we try to read a single character; it appears 424 * that for some files, such /dev/null, select() never wakes up for 425 * read for this descriptor, which means that we never get EOF. This 426 * way we will get the EOF if stdin comes from /dev/null or similar. 427 */ 428 if (stdin_null_flag) { 429 /* Fake EOF on stdin. */ 430 debug("Sending eof."); 431 stdin_eof = 1; 432 packet_start(SSH_CMSG_EOF); 433 packet_send(); 434 } else { 435 enter_non_blocking(); 436 437 /* Check for immediate EOF on stdin. */ 438 len = read(fileno(stdin), buf, 1); 439 if (len == 0) { 440 /* 441 * EOF. Record that we have seen it and send 442 * EOF to server. 443 */ 444 debug("Sending eof."); 445 stdin_eof = 1; 446 packet_start(SSH_CMSG_EOF); 447 packet_send(); 448 } else if (len > 0) { 449 /* 450 * Got data. We must store the data in the buffer, 451 * and also process it as an escape character if 452 * appropriate. 453 */ 454 if ((u_char) buf[0] == escape_char1) 455 escape_pending1 = 1; 456 else 457 buffer_append(&stdin_buffer, buf, 1); 458 } 459 leave_non_blocking(); 460 } 461} 462 463 464/* 465 * Make packets from buffered stdin data, and buffer them for sending to the 466 * connection. 467 */ 468 469static void 470client_make_packets_from_stdin_data(void) 471{ 472 u_int len; 473 474 /* Send buffered stdin data to the server. */ 475 while (buffer_len(&stdin_buffer) > 0 && 476 packet_not_very_much_data_to_write()) { 477 len = buffer_len(&stdin_buffer); 478 /* Keep the packets at reasonable size. */ 479 if (len > packet_get_maxsize()) 480 len = packet_get_maxsize(); 481 packet_start(SSH_CMSG_STDIN_DATA); 482 packet_put_string(buffer_ptr(&stdin_buffer), len); 483 packet_send(); 484 buffer_consume(&stdin_buffer, len); 485 /* If we have a pending EOF, send it now. */ 486 if (stdin_eof && buffer_len(&stdin_buffer) == 0) { 487 packet_start(SSH_CMSG_EOF); 488 packet_send(); 489 } 490 } 491} 492 493/* 494 * Checks if the client window has changed, and sends a packet about it to 495 * the server if so. The actual change is detected elsewhere (by a software 496 * interrupt on Unix); this just checks the flag and sends a message if 497 * appropriate. 498 */ 499 500static void 501client_check_window_change(void) 502{ 503 struct winsize ws; 504 505 if (! received_window_change_signal) 506 return; 507 /** XXX race */ 508 received_window_change_signal = 0; 509 510 debug2("client_check_window_change: changed"); 511 512 if (compat20) { 513 channel_send_window_changes(); 514 } else { 515 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) 516 return; 517 packet_start(SSH_CMSG_WINDOW_SIZE); 518 packet_put_int((u_int)ws.ws_row); 519 packet_put_int((u_int)ws.ws_col); 520 packet_put_int((u_int)ws.ws_xpixel); 521 packet_put_int((u_int)ws.ws_ypixel); 522 packet_send(); 523 } 524} 525 526static void 527client_global_request_reply(int type, u_int32_t seq, void *ctxt) 528{ 529 struct global_confirm *gc; 530 531 if ((gc = TAILQ_FIRST(&global_confirms)) == NULL) 532 return; 533 if (gc->cb != NULL) 534 gc->cb(type, seq, gc->ctx); 535 if (--gc->ref_count <= 0) { 536 TAILQ_REMOVE(&global_confirms, gc, entry); 537 bzero(gc, sizeof(*gc)); 538 xfree(gc); 539 } 540 541 packet_set_alive_timeouts(0); 542} 543 544static void 545server_alive_check(void) 546{ 547 if (packet_inc_alive_timeouts() > options.server_alive_count_max) { 548 logit("Timeout, server %s not responding.", host); 549 cleanup_exit(255); 550 } 551 packet_start(SSH2_MSG_GLOBAL_REQUEST); 552 packet_put_cstring("keepalive@openssh.com"); 553 packet_put_char(1); /* boolean: want reply */ 554 packet_send(); 555 /* Insert an empty placeholder to maintain ordering */ 556 client_register_global_confirm(NULL, NULL); 557} 558 559/* 560 * Waits until the client can do something (some data becomes available on 561 * one of the file descriptors). 562 */ 563static void 564client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, 565 int *maxfdp, u_int *nallocp, int rekeying) 566{ 567 struct timeval tv, *tvp; 568 int timeout_secs; 569 int ret; 570 571 /* Add any selections by the channel mechanism. */ 572 channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying); 573 574 if (!compat20) { 575 /* Read from the connection, unless our buffers are full. */ 576 if (buffer_len(&stdout_buffer) < buffer_high && 577 buffer_len(&stderr_buffer) < buffer_high && 578 channel_not_very_much_buffered_data()) 579 FD_SET(connection_in, *readsetp); 580 /* 581 * Read from stdin, unless we have seen EOF or have very much 582 * buffered data to send to the server. 583 */ 584 if (!stdin_eof && packet_not_very_much_data_to_write()) 585 FD_SET(fileno(stdin), *readsetp); 586 587 /* Select stdout/stderr if have data in buffer. */ 588 if (buffer_len(&stdout_buffer) > 0) 589 FD_SET(fileno(stdout), *writesetp); 590 if (buffer_len(&stderr_buffer) > 0) 591 FD_SET(fileno(stderr), *writesetp); 592 } else { 593 /* channel_prepare_select could have closed the last channel */ 594 if (session_closed && !channel_still_open() && 595 !packet_have_data_to_write()) { 596 /* clear mask since we did not call select() */ 597 memset(*readsetp, 0, *nallocp); 598 memset(*writesetp, 0, *nallocp); 599 return; 600 } else { 601 FD_SET(connection_in, *readsetp); 602 } 603 } 604 605 /* Select server connection if have data to write to the server. */ 606 if (packet_have_data_to_write()) 607 FD_SET(connection_out, *writesetp); 608 609 /* 610 * Wait for something to happen. This will suspend the process until 611 * some selected descriptor can be read, written, or has some other 612 * event pending, or a timeout expires. 613 */ 614 615 timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */ 616 if (options.server_alive_interval > 0 && compat20) 617 timeout_secs = options.server_alive_interval; 618 set_control_persist_exit_time(); 619 if (control_persist_exit_time > 0) { 620 timeout_secs = MIN(timeout_secs, 621 control_persist_exit_time - time(NULL)); 622 if (timeout_secs < 0) 623 timeout_secs = 0; 624 } 625 if (timeout_secs == INT_MAX) 626 tvp = NULL; 627 else { 628 tv.tv_sec = timeout_secs; 629 tv.tv_usec = 0; 630 tvp = &tv; 631 } 632 633 ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); 634 if (ret < 0) { 635 char buf[100]; 636 637 /* 638 * We have to clear the select masks, because we return. 639 * We have to return, because the mainloop checks for the flags 640 * set by the signal handlers. 641 */ 642 memset(*readsetp, 0, *nallocp); 643 memset(*writesetp, 0, *nallocp); 644 645 if (errno == EINTR) 646 return; 647 /* Note: we might still have data in the buffers. */ 648 snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); 649 buffer_append(&stderr_buffer, buf, strlen(buf)); 650 quit_pending = 1; 651 } else if (ret == 0) 652 server_alive_check(); 653} 654 655static void 656client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) 657{ 658 /* Flush stdout and stderr buffers. */ 659 if (buffer_len(bout) > 0) 660 atomicio(vwrite, fileno(stdout), buffer_ptr(bout), 661 buffer_len(bout)); 662 if (buffer_len(berr) > 0) 663 atomicio(vwrite, fileno(stderr), buffer_ptr(berr), 664 buffer_len(berr)); 665 666 leave_raw_mode(force_tty_flag); 667 668 /* 669 * Free (and clear) the buffer to reduce the amount of data that gets 670 * written to swap. 671 */ 672 buffer_free(bin); 673 buffer_free(bout); 674 buffer_free(berr); 675 676 /* Send the suspend signal to the program itself. */ 677 kill(getpid(), SIGTSTP); 678 679 /* Reset window sizes in case they have changed */ 680 received_window_change_signal = 1; 681 682 /* OK, we have been continued by the user. Reinitialize buffers. */ 683 buffer_init(bin); 684 buffer_init(bout); 685 buffer_init(berr); 686 687 enter_raw_mode(force_tty_flag); 688} 689 690static void 691client_process_net_input(fd_set *readset) 692{ 693 int len, cont = 0; 694 char buf[SSH_IOBUFSZ]; 695 696 /* 697 * Read input from the server, and add any such data to the buffer of 698 * the packet subsystem. 699 */ 700 if (FD_ISSET(connection_in, readset)) { 701 /* Read as much as possible. */ 702 len = roaming_read(connection_in, buf, sizeof(buf), &cont); 703 if (len == 0 && cont == 0) { 704 /* 705 * Received EOF. The remote host has closed the 706 * connection. 707 */ 708 snprintf(buf, sizeof buf, 709 "Connection to %.300s closed by remote host.\r\n", 710 host); 711 buffer_append(&stderr_buffer, buf, strlen(buf)); 712 quit_pending = 1; 713 return; 714 } 715 /* 716 * There is a kernel bug on Solaris that causes select to 717 * sometimes wake up even though there is no data available. 718 */ 719 if (len < 0 && 720 (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)) 721 len = 0; 722 723 if (len < 0) { 724 /* 725 * An error has encountered. Perhaps there is a 726 * network problem. 727 */ 728 snprintf(buf, sizeof buf, 729 "Read from remote host %.300s: %.100s\r\n", 730 host, strerror(errno)); 731 buffer_append(&stderr_buffer, buf, strlen(buf)); 732 quit_pending = 1; 733 return; 734 } 735 packet_process_incoming(buf, len); 736 } 737} 738 739static void 740client_status_confirm(int type, Channel *c, void *ctx) 741{ 742 struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx; 743 char errmsg[256]; 744 int tochan; 745 746 /* XXX supress on mux _client_ quietmode */ 747 tochan = options.log_level >= SYSLOG_LEVEL_ERROR && 748 c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE; 749 750 if (type == SSH2_MSG_CHANNEL_SUCCESS) { 751 debug2("%s request accepted on channel %d", 752 cr->request_type, c->self); 753 } else if (type == SSH2_MSG_CHANNEL_FAILURE) { 754 if (tochan) { 755 snprintf(errmsg, sizeof(errmsg), 756 "%s request failed\r\n", cr->request_type); 757 } else { 758 snprintf(errmsg, sizeof(errmsg), 759 "%s request failed on channel %d", 760 cr->request_type, c->self); 761 } 762 /* If error occurred on primary session channel, then exit */ 763 if (cr->do_close && c->self == session_ident) 764 fatal("%s", errmsg); 765 /* If error occurred on mux client, append to their stderr */ 766 if (tochan) 767 buffer_append(&c->extended, errmsg, strlen(errmsg)); 768 else 769 error("%s", errmsg); 770 if (cr->do_close) { 771 chan_read_failed(c); 772 chan_write_failed(c); 773 } 774 } 775 xfree(cr); 776} 777 778static void 779client_abandon_status_confirm(Channel *c, void *ctx) 780{ 781 xfree(ctx); 782} 783 784static void 785client_expect_confirm(int id, const char *request, int do_close) 786{ 787 struct channel_reply_ctx *cr = xmalloc(sizeof(*cr)); 788 789 cr->request_type = request; 790 cr->do_close = do_close; 791 792 channel_register_status_confirm(id, client_status_confirm, 793 client_abandon_status_confirm, cr); 794} 795 796void 797client_register_global_confirm(global_confirm_cb *cb, void *ctx) 798{ 799 struct global_confirm *gc, *last_gc; 800 801 /* Coalesce identical callbacks */ 802 last_gc = TAILQ_LAST(&global_confirms, global_confirms); 803 if (last_gc && last_gc->cb == cb && last_gc->ctx == ctx) { 804 if (++last_gc->ref_count >= INT_MAX) 805 fatal("%s: last_gc->ref_count = %d", 806 __func__, last_gc->ref_count); 807 return; 808 } 809 810 gc = xmalloc(sizeof(*gc)); 811 gc->cb = cb; 812 gc->ctx = ctx; 813 gc->ref_count = 1; 814 TAILQ_INSERT_TAIL(&global_confirms, gc, entry); 815} 816 817static void 818process_cmdline(void) 819{ 820 void (*handler)(int); 821 char *s, *cmd, *cancel_host; 822 int delete = 0; 823 int local = 0, remote = 0, dynamic = 0; 824 int cancel_port; 825 Forward fwd; 826 827 bzero(&fwd, sizeof(fwd)); 828 fwd.listen_host = fwd.connect_host = NULL; 829 830 leave_raw_mode(force_tty_flag); 831 handler = signal(SIGINT, SIG_IGN); 832 cmd = s = read_passphrase("\r\nssh> ", RP_ECHO); 833 if (s == NULL) 834 goto out; 835 while (isspace(*s)) 836 s++; 837 if (*s == '-') 838 s++; /* Skip cmdline '-', if any */ 839 if (*s == '\0') 840 goto out; 841 842 if (*s == 'h' || *s == 'H' || *s == '?') { 843 logit("Commands:"); 844 logit(" -L[bind_address:]port:host:hostport " 845 "Request local forward"); 846 logit(" -R[bind_address:]port:host:hostport " 847 "Request remote forward"); 848 logit(" -D[bind_address:]port " 849 "Request dynamic forward"); 850 logit(" -KR[bind_address:]port " 851 "Cancel remote forward"); 852 if (!options.permit_local_command) 853 goto out; 854 logit(" !args " 855 "Execute local command"); 856 goto out; 857 } 858 859 if (*s == '!' && options.permit_local_command) { 860 s++; 861 ssh_local_cmd(s); 862 goto out; 863 } 864 865 if (*s == 'K') { 866 delete = 1; 867 s++; 868 } 869 if (*s == 'L') 870 local = 1; 871 else if (*s == 'R') 872 remote = 1; 873 else if (*s == 'D') 874 dynamic = 1; 875 else { 876 logit("Invalid command."); 877 goto out; 878 } 879 880 if ((local || dynamic) && delete) { 881 logit("Not supported."); 882 goto out; 883 } 884 if (remote && delete && !compat20) { 885 logit("Not supported for SSH protocol version 1."); 886 goto out; 887 } 888 889 while (isspace(*++s)) 890 ; 891 892 /* XXX update list of forwards in options */ 893 if (delete) { 894 cancel_port = 0; 895 cancel_host = hpdelim(&s); /* may be NULL */ 896 if (s != NULL) { 897 cancel_port = a2port(s); 898 cancel_host = cleanhostname(cancel_host); 899 } else { 900 cancel_port = a2port(cancel_host); 901 cancel_host = NULL; 902 } 903 if (cancel_port <= 0) { 904 logit("Bad forwarding close port"); 905 goto out; 906 } 907 channel_request_rforward_cancel(cancel_host, cancel_port); 908 } else { 909 if (!parse_forward(&fwd, s, dynamic, remote)) { 910 logit("Bad forwarding specification."); 911 goto out; 912 } 913 if (local || dynamic) { 914 if (channel_setup_local_fwd_listener(fwd.listen_host, 915 fwd.listen_port, fwd.connect_host, 916 fwd.connect_port, options.gateway_ports) < 0) { 917 logit("Port forwarding failed."); 918 goto out; 919 } 920 } else { 921 if (channel_request_remote_forwarding(fwd.listen_host, 922 fwd.listen_port, fwd.connect_host, 923 fwd.connect_port) < 0) { 924 logit("Port forwarding failed."); 925 goto out; 926 } 927 } 928 929 logit("Forwarding port."); 930 } 931 932out: 933 signal(SIGINT, handler); 934 enter_raw_mode(force_tty_flag); 935 if (cmd) 936 xfree(cmd); 937 if (fwd.listen_host != NULL) 938 xfree(fwd.listen_host); 939 if (fwd.connect_host != NULL) 940 xfree(fwd.connect_host); 941} 942 943/* 944 * Process the characters one by one, call with c==NULL for proto1 case. 945 */ 946static int 947process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, 948 char *buf, int len) 949{ 950 char string[1024]; 951 pid_t pid; 952 int bytes = 0; 953 u_int i; 954 u_char ch; 955 char *s; 956 int *escape_pendingp, escape_char; 957 struct escape_filter_ctx *efc; 958 959 if (c == NULL) { 960 escape_pendingp = &escape_pending1; 961 escape_char = escape_char1; 962 } else { 963 if (c->filter_ctx == NULL) 964 return 0; 965 efc = (struct escape_filter_ctx *)c->filter_ctx; 966 escape_pendingp = &efc->escape_pending; 967 escape_char = efc->escape_char; 968 } 969 970 if (len <= 0) 971 return (0); 972 973 for (i = 0; i < (u_int)len; i++) { 974 /* Get one character at a time. */ 975 ch = buf[i]; 976 977 if (*escape_pendingp) { 978 /* We have previously seen an escape character. */ 979 /* Clear the flag now. */ 980 *escape_pendingp = 0; 981 982 /* Process the escaped character. */ 983 switch (ch) { 984 case '.': 985 /* Terminate the connection. */ 986 snprintf(string, sizeof string, "%c.\r\n", 987 escape_char); 988 buffer_append(berr, string, strlen(string)); 989 990 if (c && c->ctl_chan != -1) { 991 chan_read_failed(c); 992 chan_write_failed(c); 993 return 0; 994 } else 995 quit_pending = 1; 996 return -1; 997 998 case 'Z' - 64: 999 /* XXX support this for mux clients */ 1000 if (c && c->ctl_chan != -1) { 1001 noescape: 1002 snprintf(string, sizeof string, 1003 "%c%c escape not available to " 1004 "multiplexed sessions\r\n", 1005 escape_char, ch); 1006 buffer_append(berr, string, 1007 strlen(string)); 1008 continue; 1009 } 1010 /* Suspend the program. Inform the user */ 1011 snprintf(string, sizeof string, 1012 "%c^Z [suspend ssh]\r\n", escape_char); 1013 buffer_append(berr, string, strlen(string)); 1014 1015 /* Restore terminal modes and suspend. */ 1016 client_suspend_self(bin, bout, berr); 1017 1018 /* We have been continued. */ 1019 continue; 1020 1021 case 'B': 1022 if (compat20) { 1023 snprintf(string, sizeof string, 1024 "%cB\r\n", escape_char); 1025 buffer_append(berr, string, 1026 strlen(string)); 1027 channel_request_start(session_ident, 1028 "break", 0); 1029 packet_put_int(1000); 1030 packet_send(); 1031 } 1032 continue; 1033 1034 case 'R': 1035 if (compat20) { 1036 if (datafellows & SSH_BUG_NOREKEY) 1037 logit("Server does not " 1038 "support re-keying"); 1039 else 1040 need_rekeying = 1; 1041 } 1042 continue; 1043 1044 case '&': 1045 if (c && c->ctl_chan != -1) 1046 goto noescape; 1047 /* 1048 * Detach the program (continue to serve 1049 * connections, but put in background and no 1050 * more new connections). 1051 */ 1052 /* Restore tty modes. */ 1053 leave_raw_mode(force_tty_flag); 1054 1055 /* Stop listening for new connections. */ 1056 channel_stop_listening(); 1057 1058 snprintf(string, sizeof string, 1059 "%c& [backgrounded]\n", escape_char); 1060 buffer_append(berr, string, strlen(string)); 1061 1062 /* Fork into background. */ 1063 pid = fork(); 1064 if (pid < 0) { 1065 error("fork: %.100s", strerror(errno)); 1066 continue; 1067 } 1068 if (pid != 0) { /* This is the parent. */ 1069 /* The parent just exits. */ 1070 exit(0); 1071 } 1072 /* The child continues serving connections. */ 1073 if (compat20) { 1074 buffer_append(bin, "\004", 1); 1075 /* fake EOF on stdin */ 1076 return -1; 1077 } else if (!stdin_eof) { 1078 /* 1079 * Sending SSH_CMSG_EOF alone does not 1080 * always appear to be enough. So we 1081 * try to send an EOF character first. 1082 */ 1083 packet_start(SSH_CMSG_STDIN_DATA); 1084 packet_put_string("\004", 1); 1085 packet_send(); 1086 /* Close stdin. */ 1087 stdin_eof = 1; 1088 if (buffer_len(bin) == 0) { 1089 packet_start(SSH_CMSG_EOF); 1090 packet_send(); 1091 } 1092 } 1093 continue; 1094 1095 case '?': 1096 if (c && c->ctl_chan != -1) { 1097 snprintf(string, sizeof string, 1098"%c?\r\n\ 1099Supported escape sequences:\r\n\ 1100 %c. - terminate session\r\n\ 1101 %cB - send a BREAK to the remote system\r\n\ 1102 %cR - Request rekey (SSH protocol 2 only)\r\n\ 1103 %c# - list forwarded connections\r\n\ 1104 %c? - this message\r\n\ 1105 %c%c - send the escape character by typing it twice\r\n\ 1106(Note that escapes are only recognized immediately after newline.)\r\n", 1107 escape_char, escape_char, 1108 escape_char, escape_char, 1109 escape_char, escape_char, 1110 escape_char, escape_char); 1111 } else { 1112 snprintf(string, sizeof string, 1113"%c?\r\n\ 1114Supported escape sequences:\r\n\ 1115 %c. - terminate connection (and any multiplexed sessions)\r\n\ 1116 %cB - send a BREAK to the remote system\r\n\ 1117 %cC - open a command line\r\n\ 1118 %cR - Request rekey (SSH protocol 2 only)\r\n\ 1119 %c^Z - suspend ssh\r\n\ 1120 %c# - list forwarded connections\r\n\ 1121 %c& - background ssh (when waiting for connections to terminate)\r\n\ 1122 %c? - this message\r\n\ 1123 %c%c - send the escape character by typing it twice\r\n\ 1124(Note that escapes are only recognized immediately after newline.)\r\n", 1125 escape_char, escape_char, 1126 escape_char, escape_char, 1127 escape_char, escape_char, 1128 escape_char, escape_char, 1129 escape_char, escape_char, 1130 escape_char); 1131 } 1132 buffer_append(berr, string, strlen(string)); 1133 continue; 1134 1135 case '#': 1136 snprintf(string, sizeof string, "%c#\r\n", 1137 escape_char); 1138 buffer_append(berr, string, strlen(string)); 1139 s = channel_open_message(); 1140 buffer_append(berr, s, strlen(s)); 1141 xfree(s); 1142 continue; 1143 1144 case 'C': 1145 if (c && c->ctl_chan != -1) 1146 goto noescape; 1147 process_cmdline(); 1148 continue; 1149 1150 default: 1151 if (ch != escape_char) { 1152 buffer_put_char(bin, escape_char); 1153 bytes++; 1154 } 1155 /* Escaped characters fall through here */ 1156 break; 1157 } 1158 } else { 1159 /* 1160 * The previous character was not an escape char. 1161 * Check if this is an escape. 1162 */ 1163 if (last_was_cr && ch == escape_char) { 1164 /* 1165 * It is. Set the flag and continue to 1166 * next character. 1167 */ 1168 *escape_pendingp = 1; 1169 continue; 1170 } 1171 } 1172 1173 /* 1174 * Normal character. Record whether it was a newline, 1175 * and append it to the buffer. 1176 */ 1177 last_was_cr = (ch == '\r' || ch == '\n'); 1178 buffer_put_char(bin, ch); 1179 bytes++; 1180 } 1181 return bytes; 1182} 1183 1184static void 1185client_process_input(fd_set *readset) 1186{ 1187 int len; 1188 char buf[SSH_IOBUFSZ]; 1189 1190 /* Read input from stdin. */ 1191 if (FD_ISSET(fileno(stdin), readset)) { 1192 /* Read as much as possible. */ 1193 len = read(fileno(stdin), buf, sizeof(buf)); 1194 if (len < 0 && 1195 (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)) 1196 return; /* we'll try again later */ 1197 if (len <= 0) { 1198 /* 1199 * Received EOF or error. They are treated 1200 * similarly, except that an error message is printed 1201 * if it was an error condition. 1202 */ 1203 if (len < 0) { 1204 snprintf(buf, sizeof buf, "read: %.100s\r\n", 1205 strerror(errno)); 1206 buffer_append(&stderr_buffer, buf, strlen(buf)); 1207 } 1208 /* Mark that we have seen EOF. */ 1209 stdin_eof = 1; 1210 /* 1211 * Send an EOF message to the server unless there is 1212 * data in the buffer. If there is data in the 1213 * buffer, no message will be sent now. Code 1214 * elsewhere will send the EOF when the buffer 1215 * becomes empty if stdin_eof is set. 1216 */ 1217 if (buffer_len(&stdin_buffer) == 0) { 1218 packet_start(SSH_CMSG_EOF); 1219 packet_send(); 1220 } 1221 } else if (escape_char1 == SSH_ESCAPECHAR_NONE) { 1222 /* 1223 * Normal successful read, and no escape character. 1224 * Just append the data to buffer. 1225 */ 1226 buffer_append(&stdin_buffer, buf, len); 1227 } else { 1228 /* 1229 * Normal, successful read. But we have an escape 1230 * character and have to process the characters one 1231 * by one. 1232 */ 1233 if (process_escapes(NULL, &stdin_buffer, 1234 &stdout_buffer, &stderr_buffer, buf, len) == -1) 1235 return; 1236 } 1237 } 1238} 1239 1240static void 1241client_process_output(fd_set *writeset) 1242{ 1243 int len; 1244 char buf[100]; 1245 1246 /* Write buffered output to stdout. */ 1247 if (FD_ISSET(fileno(stdout), writeset)) { 1248 /* Write as much data as possible. */ 1249 len = write(fileno(stdout), buffer_ptr(&stdout_buffer), 1250 buffer_len(&stdout_buffer)); 1251 if (len <= 0) { 1252 if (errno == EINTR || errno == EAGAIN || 1253 errno == EWOULDBLOCK) 1254 len = 0; 1255 else { 1256 /* 1257 * An error or EOF was encountered. Put an 1258 * error message to stderr buffer. 1259 */ 1260 snprintf(buf, sizeof buf, 1261 "write stdout: %.50s\r\n", strerror(errno)); 1262 buffer_append(&stderr_buffer, buf, strlen(buf)); 1263 quit_pending = 1; 1264 return; 1265 } 1266 } 1267 /* Consume printed data from the buffer. */ 1268 buffer_consume(&stdout_buffer, len); 1269 } 1270 /* Write buffered output to stderr. */ 1271 if (FD_ISSET(fileno(stderr), writeset)) { 1272 /* Write as much data as possible. */ 1273 len = write(fileno(stderr), buffer_ptr(&stderr_buffer), 1274 buffer_len(&stderr_buffer)); 1275 if (len <= 0) { 1276 if (errno == EINTR || errno == EAGAIN || 1277 errno == EWOULDBLOCK) 1278 len = 0; 1279 else { 1280 /* 1281 * EOF or error, but can't even print 1282 * error message. 1283 */ 1284 quit_pending = 1; 1285 return; 1286 } 1287 } 1288 /* Consume printed characters from the buffer. */ 1289 buffer_consume(&stderr_buffer, len); 1290 } 1291} 1292 1293/* 1294 * Get packets from the connection input buffer, and process them as long as 1295 * there are packets available. 1296 * 1297 * Any unknown packets received during the actual 1298 * session cause the session to terminate. This is 1299 * intended to make debugging easier since no 1300 * confirmations are sent. Any compatible protocol 1301 * extensions must be negotiated during the 1302 * preparatory phase. 1303 */ 1304 1305static void 1306client_process_buffered_input_packets(void) 1307{ 1308 dispatch_run(DISPATCH_NONBLOCK, &quit_pending, 1309 compat20 ? xxx_kex : NULL); 1310} 1311 1312/* scan buf[] for '~' before sending data to the peer */ 1313 1314/* Helper: allocate a new escape_filter_ctx and fill in its escape char */ 1315void * 1316client_new_escape_filter_ctx(int escape_char) 1317{ 1318 struct escape_filter_ctx *ret; 1319 1320 ret = xmalloc(sizeof(*ret)); 1321 ret->escape_pending = 0; 1322 ret->escape_char = escape_char; 1323 return (void *)ret; 1324} 1325 1326/* Free the escape filter context on channel free */ 1327void 1328client_filter_cleanup(int cid, void *ctx) 1329{ 1330 xfree(ctx); 1331} 1332 1333int 1334client_simple_escape_filter(Channel *c, char *buf, int len) 1335{ 1336 if (c->extended_usage != CHAN_EXTENDED_WRITE) 1337 return 0; 1338 1339 return process_escapes(c, &c->input, &c->output, &c->extended, 1340 buf, len); 1341} 1342 1343static void 1344client_channel_closed(int id, void *arg) 1345{ 1346 channel_cancel_cleanup(id); 1347 session_closed = 1; 1348 leave_raw_mode(force_tty_flag); 1349} 1350 1351/* 1352 * Implements the interactive session with the server. This is called after 1353 * the user has been authenticated, and a command has been started on the 1354 * remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character 1355 * used as an escape character for terminating or suspending the session. 1356 */ 1357 1358int 1359client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) 1360{ 1361 fd_set *readset = NULL, *writeset = NULL; 1362 double start_time, total_time; 1363 int max_fd = 0, max_fd2 = 0, len, rekeying = 0; 1364 u_int64_t ibytes, obytes; 1365 u_int nalloc = 0; 1366 char buf[100]; 1367 1368 debug("Entering interactive session."); 1369 1370 start_time = get_current_time(); 1371 1372 /* Initialize variables. */ 1373 escape_pending1 = 0; 1374 last_was_cr = 1; 1375 exit_status = -1; 1376 stdin_eof = 0; 1377 buffer_high = 64 * 1024; 1378 connection_in = packet_get_connection_in(); 1379 connection_out = packet_get_connection_out(); 1380 max_fd = MAX(connection_in, connection_out); 1381 1382 if (!compat20) { 1383 /* enable nonblocking unless tty */ 1384 if (!isatty(fileno(stdin))) 1385 set_nonblock(fileno(stdin)); 1386 if (!isatty(fileno(stdout))) 1387 set_nonblock(fileno(stdout)); 1388 if (!isatty(fileno(stderr))) 1389 set_nonblock(fileno(stderr)); 1390 max_fd = MAX(max_fd, fileno(stdin)); 1391 max_fd = MAX(max_fd, fileno(stdout)); 1392 max_fd = MAX(max_fd, fileno(stderr)); 1393 } 1394 quit_pending = 0; 1395 escape_char1 = escape_char_arg; 1396 1397 /* Initialize buffers. */ 1398 buffer_init(&stdin_buffer); 1399 buffer_init(&stdout_buffer); 1400 buffer_init(&stderr_buffer); 1401 1402 client_init_dispatch(); 1403 1404 /* 1405 * Set signal handlers, (e.g. to restore non-blocking mode) 1406 * but don't overwrite SIG_IGN, matches behaviour from rsh(1) 1407 */ 1408 if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 1409 signal(SIGHUP, signal_handler); 1410 if (signal(SIGINT, SIG_IGN) != SIG_IGN) 1411 signal(SIGINT, signal_handler); 1412 if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) 1413 signal(SIGQUIT, signal_handler); 1414 if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 1415 signal(SIGTERM, signal_handler); 1416 signal(SIGWINCH, window_change_handler); 1417 1418 if (have_pty) 1419 enter_raw_mode(force_tty_flag); 1420 1421 if (compat20) { 1422 session_ident = ssh2_chan_id; 1423 if (escape_char_arg != SSH_ESCAPECHAR_NONE) 1424 channel_register_filter(session_ident, 1425 client_simple_escape_filter, NULL, 1426 client_filter_cleanup, 1427 client_new_escape_filter_ctx(escape_char_arg)); 1428 if (session_ident != -1) 1429 channel_register_cleanup(session_ident, 1430 client_channel_closed, 0); 1431 } else { 1432 /* Check if we should immediately send eof on stdin. */ 1433 client_check_initial_eof_on_stdin(); 1434 } 1435 1436 /* Main loop of the client for the interactive session mode. */ 1437 while (!quit_pending) { 1438 1439 /* Process buffered packets sent by the server. */ 1440 client_process_buffered_input_packets(); 1441 1442 if (compat20 && session_closed && !channel_still_open()) 1443 break; 1444 1445 rekeying = (xxx_kex != NULL && !xxx_kex->done); 1446 1447 if (rekeying) { 1448 debug("rekeying in progress"); 1449 } else { 1450 /* 1451 * Make packets of buffered stdin data, and buffer 1452 * them for sending to the server. 1453 */ 1454 if (!compat20) 1455 client_make_packets_from_stdin_data(); 1456 1457 /* 1458 * Make packets from buffered channel data, and 1459 * enqueue them for sending to the server. 1460 */ 1461 if (packet_not_very_much_data_to_write()) 1462 channel_output_poll(); 1463 1464 /* 1465 * Check if the window size has changed, and buffer a 1466 * message about it to the server if so. 1467 */ 1468 client_check_window_change(); 1469 1470 if (quit_pending) 1471 break; 1472 } 1473 /* 1474 * Wait until we have something to do (something becomes 1475 * available on one of the descriptors). 1476 */ 1477 max_fd2 = max_fd; 1478 client_wait_until_can_do_something(&readset, &writeset, 1479 &max_fd2, &nalloc, rekeying); 1480 1481 if (quit_pending) 1482 break; 1483 1484 /* Do channel operations unless rekeying in progress. */ 1485 if (!rekeying) { 1486 channel_after_select(readset, writeset); 1487 if (need_rekeying || packet_need_rekeying()) { 1488 debug("need rekeying"); 1489 xxx_kex->done = 0; 1490 kex_send_kexinit(xxx_kex); 1491 need_rekeying = 0; 1492 } 1493 } 1494 1495 /* Buffer input from the connection. */ 1496 client_process_net_input(readset); 1497 1498 if (quit_pending) 1499 break; 1500 1501 if (!compat20) { 1502 /* Buffer data from stdin */ 1503 client_process_input(readset); 1504 /* 1505 * Process output to stdout and stderr. Output to 1506 * the connection is processed elsewhere (above). 1507 */ 1508 client_process_output(writeset); 1509 } 1510 1511 if (session_resumed) { 1512 connection_in = packet_get_connection_in(); 1513 connection_out = packet_get_connection_out(); 1514 max_fd = MAX(max_fd, connection_out); 1515 max_fd = MAX(max_fd, connection_in); 1516 session_resumed = 0; 1517 } 1518 1519 /* 1520 * Send as much buffered packet data as possible to the 1521 * sender. 1522 */ 1523 if (FD_ISSET(connection_out, writeset)) 1524 packet_write_poll(); 1525 1526 /* 1527 * If we are a backgrounded control master, and the 1528 * timeout has expired without any active client 1529 * connections, then quit. 1530 */ 1531 if (control_persist_exit_time > 0) { 1532 if (time(NULL) >= control_persist_exit_time) { 1533 debug("ControlPersist timeout expired"); 1534 break; 1535 } 1536 } 1537 } 1538 if (readset) 1539 xfree(readset); 1540 if (writeset) 1541 xfree(writeset); 1542 1543 /* Terminate the session. */ 1544 1545 /* Stop watching for window change. */ 1546 signal(SIGWINCH, SIG_DFL); 1547 1548 if (compat20) { 1549 packet_start(SSH2_MSG_DISCONNECT); 1550 packet_put_int(SSH2_DISCONNECT_BY_APPLICATION); 1551 packet_put_cstring("disconnected by user"); 1552 packet_put_cstring(""); /* language tag */ 1553 packet_send(); 1554 packet_write_wait(); 1555 } 1556 1557 channel_free_all(); 1558 1559 if (have_pty) 1560 leave_raw_mode(force_tty_flag); 1561 1562 /* restore blocking io */ 1563 if (!isatty(fileno(stdin))) 1564 unset_nonblock(fileno(stdin)); 1565 if (!isatty(fileno(stdout))) 1566 unset_nonblock(fileno(stdout)); 1567 if (!isatty(fileno(stderr))) 1568 unset_nonblock(fileno(stderr)); 1569 1570 /* 1571 * If there was no shell or command requested, there will be no remote 1572 * exit status to be returned. In that case, clear error code if the 1573 * connection was deliberately terminated at this end. 1574 */ 1575 if (no_shell_flag && received_signal == SIGTERM) { 1576 received_signal = 0; 1577 exit_status = 0; 1578 } 1579 1580 if (received_signal) 1581 fatal("Killed by signal %d.", (int) received_signal); 1582 1583 /* 1584 * In interactive mode (with pseudo tty) display a message indicating 1585 * that the connection has been closed. 1586 */ 1587 if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) { 1588 snprintf(buf, sizeof buf, 1589 "Connection to %.64s closed.\r\n", host); 1590 buffer_append(&stderr_buffer, buf, strlen(buf)); 1591 } 1592 1593 /* Output any buffered data for stdout. */ 1594 if (buffer_len(&stdout_buffer) > 0) { 1595 len = atomicio(vwrite, fileno(stdout), 1596 buffer_ptr(&stdout_buffer), buffer_len(&stdout_buffer)); 1597 if (len < 0 || (u_int)len != buffer_len(&stdout_buffer)) 1598 error("Write failed flushing stdout buffer."); 1599 else 1600 buffer_consume(&stdout_buffer, len); 1601 } 1602 1603 /* Output any buffered data for stderr. */ 1604 if (buffer_len(&stderr_buffer) > 0) { 1605 len = atomicio(vwrite, fileno(stderr), 1606 buffer_ptr(&stderr_buffer), buffer_len(&stderr_buffer)); 1607 if (len < 0 || (u_int)len != buffer_len(&stderr_buffer)) 1608 error("Write failed flushing stderr buffer."); 1609 else 1610 buffer_consume(&stderr_buffer, len); 1611 } 1612 1613 /* Clear and free any buffers. */ 1614 memset(buf, 0, sizeof(buf)); 1615 buffer_free(&stdin_buffer); 1616 buffer_free(&stdout_buffer); 1617 buffer_free(&stderr_buffer); 1618 1619 /* Report bytes transferred, and transfer rates. */ 1620 total_time = get_current_time() - start_time; 1621 packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes); 1622 packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes); 1623 verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds", 1624 (unsigned long long)obytes, (unsigned long long)ibytes, total_time); 1625 if (total_time > 0) 1626 verbose("Bytes per second: sent %.1f, received %.1f", 1627 obytes / total_time, ibytes / total_time); 1628 /* Return the exit status of the program. */ 1629 debug("Exit status %d", exit_status); 1630 return exit_status; 1631} 1632 1633/*********/ 1634 1635static void 1636client_input_stdout_data(int type, u_int32_t seq, void *ctxt) 1637{ 1638 u_int data_len; 1639 char *data = packet_get_string(&data_len); 1640 packet_check_eom(); 1641 buffer_append(&stdout_buffer, data, data_len); 1642 memset(data, 0, data_len); 1643 xfree(data); 1644} 1645static void 1646client_input_stderr_data(int type, u_int32_t seq, void *ctxt) 1647{ 1648 u_int data_len; 1649 char *data = packet_get_string(&data_len); 1650 packet_check_eom(); 1651 buffer_append(&stderr_buffer, data, data_len); 1652 memset(data, 0, data_len); 1653 xfree(data); 1654} 1655static void 1656client_input_exit_status(int type, u_int32_t seq, void *ctxt) 1657{ 1658 exit_status = packet_get_int(); 1659 packet_check_eom(); 1660 /* Acknowledge the exit. */ 1661 packet_start(SSH_CMSG_EXIT_CONFIRMATION); 1662 packet_send(); 1663 /* 1664 * Must wait for packet to be sent since we are 1665 * exiting the loop. 1666 */ 1667 packet_write_wait(); 1668 /* Flag that we want to exit. */ 1669 quit_pending = 1; 1670} 1671static void 1672client_input_agent_open(int type, u_int32_t seq, void *ctxt) 1673{ 1674 Channel *c = NULL; 1675 int remote_id, sock; 1676 1677 /* Read the remote channel number from the message. */ 1678 remote_id = packet_get_int(); 1679 packet_check_eom(); 1680 1681 /* 1682 * Get a connection to the local authentication agent (this may again 1683 * get forwarded). 1684 */ 1685 sock = ssh_get_authentication_socket(); 1686 1687 /* 1688 * If we could not connect the agent, send an error message back to 1689 * the server. This should never happen unless the agent dies, 1690 * because authentication forwarding is only enabled if we have an 1691 * agent. 1692 */ 1693 if (sock >= 0) { 1694 c = channel_new("", SSH_CHANNEL_OPEN, sock, sock, 1695 -1, 0, 0, 0, "authentication agent connection", 1); 1696 c->remote_id = remote_id; 1697 c->force_drain = 1; 1698 } 1699 if (c == NULL) { 1700 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); 1701 packet_put_int(remote_id); 1702 } else { 1703 /* Send a confirmation to the remote host. */ 1704 debug("Forwarding authentication connection."); 1705 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); 1706 packet_put_int(remote_id); 1707 packet_put_int(c->self); 1708 } 1709 packet_send(); 1710} 1711 1712static Channel * 1713client_request_forwarded_tcpip(const char *request_type, int rchan) 1714{ 1715 Channel *c = NULL; 1716 char *listen_address, *originator_address; 1717 u_short listen_port, originator_port; 1718 1719 /* Get rest of the packet */ 1720 listen_address = packet_get_string(NULL); 1721 listen_port = packet_get_int(); 1722 originator_address = packet_get_string(NULL); 1723 originator_port = packet_get_int(); 1724 packet_check_eom(); 1725 1726 debug("client_request_forwarded_tcpip: listen %s port %d, " 1727 "originator %s port %d", listen_address, listen_port, 1728 originator_address, originator_port); 1729 1730 c = channel_connect_by_listen_address(listen_port, 1731 "forwarded-tcpip", originator_address); 1732 1733 xfree(originator_address); 1734 xfree(listen_address); 1735 return c; 1736} 1737 1738static Channel * 1739client_request_x11(const char *request_type, int rchan) 1740{ 1741 Channel *c = NULL; 1742 char *originator; 1743 u_short originator_port; 1744 int sock; 1745 1746 if (!options.forward_x11) { 1747 error("Warning: ssh server tried X11 forwarding."); 1748 error("Warning: this is probably a break-in attempt by a " 1749 "malicious server."); 1750 return NULL; 1751 } 1752 if (x11_refuse_time != 0 && time(NULL) >= x11_refuse_time) { 1753 verbose("Rejected X11 connection after ForwardX11Timeout " 1754 "expired"); 1755 return NULL; 1756 } 1757 originator = packet_get_string(NULL); 1758 if (datafellows & SSH_BUG_X11FWD) { 1759 debug2("buggy server: x11 request w/o originator_port"); 1760 originator_port = 0; 1761 } else { 1762 originator_port = packet_get_int(); 1763 } 1764 packet_check_eom(); 1765 /* XXX check permission */ 1766 debug("client_request_x11: request from %s %d", originator, 1767 originator_port); 1768 xfree(originator); 1769 sock = x11_connect_display(); 1770 if (sock < 0) 1771 return NULL; 1772 if (options.hpn_disabled) 1773 c = channel_new("x11", SSH_CHANNEL_X11_OPEN, sock, sock, -1, 1774 CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 1775 0, "x11", 1); 1776 else 1777 c = channel_new("x11", SSH_CHANNEL_X11_OPEN, sock, sock, -1, 1778 options.hpn_buffer_size, CHAN_X11_PACKET_DEFAULT, 1779 0, "x11", 1); 1780 c->force_drain = 1; 1781 return c; 1782} 1783 1784static Channel * 1785client_request_agent(const char *request_type, int rchan) 1786{ 1787 Channel *c = NULL; 1788 int sock; 1789 1790 if (!options.forward_agent) { 1791 error("Warning: ssh server tried agent forwarding."); 1792 error("Warning: this is probably a break-in attempt by a " 1793 "malicious server."); 1794 return NULL; 1795 } 1796 sock = ssh_get_authentication_socket(); 1797 if (sock < 0) 1798 return NULL; 1799 if (options.hpn_disabled) 1800 c = channel_new("authentication agent connection", 1801 SSH_CHANNEL_OPEN, sock, sock, -1, 1802 CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, 1803 "authentication agent connection", 1); 1804 else 1805 c = channel_new("authentication agent connection", 1806 SSH_CHANNEL_OPEN, sock, sock, -1, 1807 options.hpn_buffer_size, options.hpn_buffer_size, 0, 1808 "authentication agent connection", 1); 1809 c->force_drain = 1; 1810 return c; 1811} 1812 1813int 1814client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun) 1815{ 1816 Channel *c; 1817 int fd; 1818 1819 if (tun_mode == SSH_TUNMODE_NO) 1820 return 0; 1821 1822 if (!compat20) { 1823 error("Tunnel forwarding is not supported for protocol 1"); 1824 return -1; 1825 } 1826 1827 debug("Requesting tun unit %d in mode %d", local_tun, tun_mode); 1828 1829 /* Open local tunnel device */ 1830 if ((fd = tun_open(local_tun, tun_mode)) == -1) { 1831 error("Tunnel device open failed."); 1832 return -1; 1833 } 1834 1835 if (options.hpn_disabled) 1836 c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, 1837 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 1838 0, "tun", 1); 1839 else 1840 c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, 1841 options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 1842 0, "tun", 1); 1843 c->datagram = 1; 1844 1845#if defined(SSH_TUN_FILTER) 1846 if (options.tun_open == SSH_TUNMODE_POINTOPOINT) 1847 channel_register_filter(c->self, sys_tun_infilter, 1848 sys_tun_outfilter, NULL, NULL); 1849#endif 1850 1851 packet_start(SSH2_MSG_CHANNEL_OPEN); 1852 packet_put_cstring("tun@openssh.com"); 1853 packet_put_int(c->self); 1854 packet_put_int(c->local_window_max); 1855 packet_put_int(c->local_maxpacket); 1856 packet_put_int(tun_mode); 1857 packet_put_int(remote_tun); 1858 packet_send(); 1859 1860 return 0; 1861} 1862 1863/* XXXX move to generic input handler */ 1864static void 1865client_input_channel_open(int type, u_int32_t seq, void *ctxt) 1866{ 1867 Channel *c = NULL; 1868 char *ctype; 1869 int rchan; 1870 u_int rmaxpack, rwindow, len; 1871 1872 ctype = packet_get_string(&len); 1873 rchan = packet_get_int(); 1874 rwindow = packet_get_int(); 1875 rmaxpack = packet_get_int(); 1876 1877 debug("client_input_channel_open: ctype %s rchan %d win %d max %d", 1878 ctype, rchan, rwindow, rmaxpack); 1879 1880 if (strcmp(ctype, "forwarded-tcpip") == 0) { 1881 c = client_request_forwarded_tcpip(ctype, rchan); 1882 } else if (strcmp(ctype, "x11") == 0) { 1883 c = client_request_x11(ctype, rchan); 1884 } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { 1885 c = client_request_agent(ctype, rchan); 1886 } 1887/* XXX duplicate : */ 1888 if (c != NULL) { 1889 debug("confirm %s", ctype); 1890 c->remote_id = rchan; 1891 c->remote_window = rwindow; 1892 c->remote_maxpacket = rmaxpack; 1893 if (c->type != SSH_CHANNEL_CONNECTING) { 1894 packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); 1895 packet_put_int(c->remote_id); 1896 packet_put_int(c->self); 1897 packet_put_int(c->local_window); 1898 packet_put_int(c->local_maxpacket); 1899 packet_send(); 1900 } 1901 } else { 1902 debug("failure %s", ctype); 1903 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); 1904 packet_put_int(rchan); 1905 packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); 1906 if (!(datafellows & SSH_BUG_OPENFAILURE)) { 1907 packet_put_cstring("open failed"); 1908 packet_put_cstring(""); 1909 } 1910 packet_send(); 1911 } 1912 xfree(ctype); 1913} 1914static void 1915client_input_channel_req(int type, u_int32_t seq, void *ctxt) 1916{ 1917 Channel *c = NULL; 1918 int exitval, id, reply, success = 0; 1919 char *rtype; 1920 1921 id = packet_get_int(); 1922 rtype = packet_get_string(NULL); 1923 reply = packet_get_char(); 1924 1925 debug("client_input_channel_req: channel %d rtype %s reply %d", 1926 id, rtype, reply); 1927 1928 if (id == -1) { 1929 error("client_input_channel_req: request for channel -1"); 1930 } else if ((c = channel_lookup(id)) == NULL) { 1931 error("client_input_channel_req: channel %d: " 1932 "unknown channel", id); 1933 } else if (strcmp(rtype, "eow@openssh.com") == 0) { 1934 packet_check_eom(); 1935 chan_rcvd_eow(c); 1936 } else if (strcmp(rtype, "exit-status") == 0) { 1937 exitval = packet_get_int(); 1938 if (c->ctl_chan != -1) { 1939 mux_exit_message(c, exitval); 1940 success = 1; 1941 } else if (id == session_ident) { 1942 /* Record exit value of local session */ 1943 success = 1; 1944 exit_status = exitval; 1945 } else { 1946 /* Probably for a mux channel that has already closed */ 1947 debug("%s: no sink for exit-status on channel %d", 1948 __func__, id); 1949 } 1950 packet_check_eom(); 1951 } 1952 if (reply && c != NULL) { 1953 packet_start(success ? 1954 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); 1955 packet_put_int(c->remote_id); 1956 packet_send(); 1957 } 1958 xfree(rtype); 1959} 1960static void 1961client_input_global_request(int type, u_int32_t seq, void *ctxt) 1962{ 1963 char *rtype; 1964 int want_reply; 1965 int success = 0; 1966 1967 rtype = packet_get_string(NULL); 1968 want_reply = packet_get_char(); 1969 debug("client_input_global_request: rtype %s want_reply %d", 1970 rtype, want_reply); 1971 if (want_reply) { 1972 packet_start(success ? 1973 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); 1974 packet_send(); 1975 packet_write_wait(); 1976 } 1977 xfree(rtype); 1978} 1979 1980void 1981client_session2_setup(int id, int want_tty, int want_subsystem, 1982 const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env) 1983{ 1984 int len; 1985 Channel *c = NULL; 1986 1987 debug2("%s: id %d", __func__, id); 1988 1989 if ((c = channel_lookup(id)) == NULL) 1990 fatal("client_session2_setup: channel %d: unknown channel", id); 1991 1992 packet_set_interactive(want_tty, 1993 options.ip_qos_interactive, options.ip_qos_bulk); 1994 1995 if (want_tty) { 1996 struct winsize ws; 1997 1998 /* Store window size in the packet. */ 1999 if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0) 2000 memset(&ws, 0, sizeof(ws)); 2001 2002 channel_request_start(id, "pty-req", 1); 2003 client_expect_confirm(id, "PTY allocation", 1); 2004 packet_put_cstring(term != NULL ? term : ""); 2005 packet_put_int((u_int)ws.ws_col); 2006 packet_put_int((u_int)ws.ws_row); 2007 packet_put_int((u_int)ws.ws_xpixel); 2008 packet_put_int((u_int)ws.ws_ypixel); 2009 if (tiop == NULL) 2010 tiop = get_saved_tio(); 2011 tty_make_modes(-1, tiop); 2012 packet_send(); 2013 /* XXX wait for reply */ 2014 c->client_tty = 1; 2015 } 2016 2017 /* Transfer any environment variables from client to server */ 2018 if (options.num_send_env != 0 && env != NULL) { 2019 int i, j, matched; 2020 char *name, *val; 2021 2022 debug("Sending environment."); 2023 for (i = 0; env[i] != NULL; i++) { 2024 /* Split */ 2025 name = xstrdup(env[i]); 2026 if ((val = strchr(name, '=')) == NULL) { 2027 xfree(name); 2028 continue; 2029 } 2030 *val++ = '\0'; 2031 2032 matched = 0; 2033 for (j = 0; j < options.num_send_env; j++) { 2034 if (match_pattern(name, options.send_env[j])) { 2035 matched = 1; 2036 break; 2037 } 2038 } 2039 if (!matched) { 2040 debug3("Ignored env %s", name); 2041 xfree(name); 2042 continue; 2043 } 2044 2045 debug("Sending env %s = %s", name, val); 2046 channel_request_start(id, "env", 0); 2047 packet_put_cstring(name); 2048 packet_put_cstring(val); 2049 packet_send(); 2050 xfree(name); 2051 } 2052 } 2053 2054 len = buffer_len(cmd); 2055 if (len > 0) { 2056 if (len > 900) 2057 len = 900; 2058 if (want_subsystem) { 2059 debug("Sending subsystem: %.*s", 2060 len, (u_char*)buffer_ptr(cmd)); 2061 channel_request_start(id, "subsystem", 1); 2062 client_expect_confirm(id, "subsystem", 1); 2063 } else { 2064 debug("Sending command: %.*s", 2065 len, (u_char*)buffer_ptr(cmd)); 2066 channel_request_start(id, "exec", 1); 2067 client_expect_confirm(id, "exec", 1); 2068 } 2069 packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); 2070 packet_send(); 2071 } else { 2072 channel_request_start(id, "shell", 1); 2073 client_expect_confirm(id, "shell", 1); 2074 packet_send(); 2075 } 2076} 2077 2078static void 2079client_init_dispatch_20(void) 2080{ 2081 dispatch_init(&dispatch_protocol_error); 2082 2083 dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); 2084 dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); 2085 dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); 2086 dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); 2087 dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open); 2088 dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); 2089 dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); 2090 dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req); 2091 dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); 2092 dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm); 2093 dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm); 2094 dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request); 2095 2096 /* rekeying */ 2097 dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); 2098 2099 /* global request reply messages */ 2100 dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply); 2101 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply); 2102} 2103 2104static void 2105client_init_dispatch_13(void) 2106{ 2107 dispatch_init(NULL); 2108 dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); 2109 dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); 2110 dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); 2111 dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); 2112 dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); 2113 dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); 2114 dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status); 2115 dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data); 2116 dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data); 2117 2118 dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ? 2119 &client_input_agent_open : &deny_input_open); 2120 dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ? 2121 &x11_input_open : &deny_input_open); 2122} 2123 2124static void 2125client_init_dispatch_15(void) 2126{ 2127 client_init_dispatch_13(); 2128 dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); 2129 dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose); 2130} 2131 2132static void 2133client_init_dispatch(void) 2134{ 2135 if (compat20) 2136 client_init_dispatch_20(); 2137 else if (compat13) 2138 client_init_dispatch_13(); 2139 else 2140 client_init_dispatch_15(); 2141} 2142 2143/* client specific fatal cleanup */ 2144void 2145cleanup_exit(int i) 2146{ 2147 leave_raw_mode(force_tty_flag); 2148 leave_non_blocking(); 2149 if (options.control_path != NULL && muxserver_sock != -1) 2150 unlink(options.control_path); 2151 ssh_kill_proxy_command(); 2152 _exit(i); 2153} 2154