1 /* 2 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * All rights reserved 5 * The main loop for the interactive session (client side). 6 * 7 * As far as I am concerned, the code I have written for this software 8 * can be used freely for any purpose. Any derived versions of this 9 * software must be clearly marked as such, and if the derived work is 10 * incompatible with the protocol description in the RFC file, it must be 11 * called by a name other than "ssh" or "Secure Shell". 12 * 13 * 14 * Copyright (c) 1999 Theo de Raadt. All rights reserved. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 * 36 * 37 * SSH2 support added by Markus Friedl. 38 * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 50 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 51 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 52 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 53 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 54 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 55 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 56 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 57 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 58 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 59 */ 60 61 #include "includes.h" 62 RCSID("$OpenBSD: clientloop.c,v 1.121 2004/05/21 11:33:11 djm Exp $"); 63 64 #include "ssh.h" 65 #include "ssh1.h" 66 #include "ssh2.h" 67 #include "xmalloc.h" 68 #include "packet.h" 69 #include "buffer.h" 70 #include "compat.h" 71 #include "channels.h" 72 #include "dispatch.h" 73 #include "buffer.h" 74 #include "bufaux.h" 75 #include "key.h" 76 #include "kex.h" 77 #include "log.h" 78 #include "readconf.h" 79 #include "clientloop.h" 80 #include "authfd.h" 81 #include "atomicio.h" 82 #include "sshpty.h" 83 #include "misc.h" 84 85 /* import options */ 86 extern Options options; 87 88 /* Flag indicating that stdin should be redirected from /dev/null. */ 89 extern int stdin_null_flag; 90 91 /* Flag indicating that no shell has been requested */ 92 extern int no_shell_flag; 93 94 /* 95 * Name of the host we are connecting to. This is the name given on the 96 * command line, or the HostName specified for the user-supplied name in a 97 * configuration file. 98 */ 99 extern char *host; 100 101 /* 102 * Flag to indicate that we have received a window change signal which has 103 * not yet been processed. This will cause a message indicating the new 104 * window size to be sent to the server a little later. This is volatile 105 * because this is updated in a signal handler. 106 */ 107 static volatile sig_atomic_t received_window_change_signal = 0; 108 static volatile sig_atomic_t received_signal = 0; 109 110 /* Flag indicating whether the user\'s terminal is in non-blocking mode. */ 111 static int in_non_blocking_mode = 0; 112 113 /* Common data for the client loop code. */ 114 static int quit_pending; /* Set to non-zero to quit the client loop. */ 115 static int escape_char; /* Escape character. */ 116 static int escape_pending; /* Last character was the escape character */ 117 static int last_was_cr; /* Last character was a newline. */ 118 static int exit_status; /* Used to store the exit status of the command. */ 119 static int stdin_eof; /* EOF has been encountered on standard error. */ 120 static Buffer stdin_buffer; /* Buffer for stdin data. */ 121 static Buffer stdout_buffer; /* Buffer for stdout data. */ 122 static Buffer stderr_buffer; /* Buffer for stderr data. */ 123 static u_long stdin_bytes, stdout_bytes, stderr_bytes; 124 static u_int buffer_high;/* Soft max buffer size. */ 125 static int connection_in; /* Connection to server (input). */ 126 static int connection_out; /* Connection to server (output). */ 127 static int need_rekeying; /* Set to non-zero if rekeying is requested. */ 128 static int session_closed = 0; /* In SSH2: login session closed. */ 129 static int server_alive_timeouts = 0; 130 131 static void client_init_dispatch(void); 132 int session_ident = -1; 133 134 /*XXX*/ 135 extern Kex *xxx_kex; 136 137 /* Restores stdin to blocking mode. */ 138 139 static void 140 leave_non_blocking(void) 141 { 142 if (in_non_blocking_mode) { 143 (void) fcntl(fileno(stdin), F_SETFL, 0); 144 in_non_blocking_mode = 0; 145 } 146 } 147 148 /* Puts stdin terminal in non-blocking mode. */ 149 150 static void 151 enter_non_blocking(void) 152 { 153 in_non_blocking_mode = 1; 154 (void) fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); 155 } 156 157 /* 158 * Signal handler for the window change signal (SIGWINCH). This just sets a 159 * flag indicating that the window has changed. 160 */ 161 162 static void 163 window_change_handler(int sig) 164 { 165 received_window_change_signal = 1; 166 signal(SIGWINCH, window_change_handler); 167 } 168 169 /* 170 * Signal handler for signals that cause the program to terminate. These 171 * signals must be trapped to restore terminal modes. 172 */ 173 174 static void 175 signal_handler(int sig) 176 { 177 received_signal = sig; 178 quit_pending = 1; 179 } 180 181 /* 182 * Returns current time in seconds from Jan 1, 1970 with the maximum 183 * available resolution. 184 */ 185 186 static double 187 get_current_time(void) 188 { 189 struct timeval tv; 190 gettimeofday(&tv, NULL); 191 return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; 192 } 193 194 /* 195 * This is called when the interactive is entered. This checks if there is 196 * an EOF coming on stdin. We must check this explicitly, as select() does 197 * not appear to wake up when redirecting from /dev/null. 198 */ 199 200 static void 201 client_check_initial_eof_on_stdin(void) 202 { 203 int len; 204 char buf[1]; 205 206 /* 207 * If standard input is to be "redirected from /dev/null", we simply 208 * mark that we have seen an EOF and send an EOF message to the 209 * server. Otherwise, we try to read a single character; it appears 210 * that for some files, such /dev/null, select() never wakes up for 211 * read for this descriptor, which means that we never get EOF. This 212 * way we will get the EOF if stdin comes from /dev/null or similar. 213 */ 214 if (stdin_null_flag) { 215 /* Fake EOF on stdin. */ 216 debug("Sending eof."); 217 stdin_eof = 1; 218 packet_start(SSH_CMSG_EOF); 219 packet_send(); 220 } else { 221 enter_non_blocking(); 222 223 /* Check for immediate EOF on stdin. */ 224 len = read(fileno(stdin), buf, 1); 225 if (len == 0) { 226 /* EOF. Record that we have seen it and send EOF to server. */ 227 debug("Sending eof."); 228 stdin_eof = 1; 229 packet_start(SSH_CMSG_EOF); 230 packet_send(); 231 } else if (len > 0) { 232 /* 233 * Got data. We must store the data in the buffer, 234 * and also process it as an escape character if 235 * appropriate. 236 */ 237 if ((u_char) buf[0] == escape_char) 238 escape_pending = 1; 239 else 240 buffer_append(&stdin_buffer, buf, 1); 241 } 242 leave_non_blocking(); 243 } 244 } 245 246 247 /* 248 * Make packets from buffered stdin data, and buffer them for sending to the 249 * connection. 250 */ 251 252 static void 253 client_make_packets_from_stdin_data(void) 254 { 255 u_int len; 256 257 /* Send buffered stdin data to the server. */ 258 while (buffer_len(&stdin_buffer) > 0 && 259 packet_not_very_much_data_to_write()) { 260 len = buffer_len(&stdin_buffer); 261 /* Keep the packets at reasonable size. */ 262 if (len > packet_get_maxsize()) 263 len = packet_get_maxsize(); 264 packet_start(SSH_CMSG_STDIN_DATA); 265 packet_put_string(buffer_ptr(&stdin_buffer), len); 266 packet_send(); 267 buffer_consume(&stdin_buffer, len); 268 stdin_bytes += len; 269 /* If we have a pending EOF, send it now. */ 270 if (stdin_eof && buffer_len(&stdin_buffer) == 0) { 271 packet_start(SSH_CMSG_EOF); 272 packet_send(); 273 } 274 } 275 } 276 277 /* 278 * Checks if the client window has changed, and sends a packet about it to 279 * the server if so. The actual change is detected elsewhere (by a software 280 * interrupt on Unix); this just checks the flag and sends a message if 281 * appropriate. 282 */ 283 284 static void 285 client_check_window_change(void) 286 { 287 struct winsize ws; 288 289 if (! received_window_change_signal) 290 return; 291 /** XXX race */ 292 received_window_change_signal = 0; 293 294 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) 295 return; 296 297 debug2("client_check_window_change: changed"); 298 299 if (compat20) { 300 channel_request_start(session_ident, "window-change", 0); 301 packet_put_int(ws.ws_col); 302 packet_put_int(ws.ws_row); 303 packet_put_int(ws.ws_xpixel); 304 packet_put_int(ws.ws_ypixel); 305 packet_send(); 306 } else { 307 packet_start(SSH_CMSG_WINDOW_SIZE); 308 packet_put_int(ws.ws_row); 309 packet_put_int(ws.ws_col); 310 packet_put_int(ws.ws_xpixel); 311 packet_put_int(ws.ws_ypixel); 312 packet_send(); 313 } 314 } 315 316 static void 317 client_global_request_reply(int type, u_int32_t seq, void *ctxt) 318 { 319 server_alive_timeouts = 0; 320 client_global_request_reply_fwd(type, seq, ctxt); 321 } 322 323 static void 324 server_alive_check(void) 325 { 326 if (++server_alive_timeouts > options.server_alive_count_max) 327 packet_disconnect("Timeout, server not responding."); 328 packet_start(SSH2_MSG_GLOBAL_REQUEST); 329 packet_put_cstring("keepalive@openssh.com"); 330 packet_put_char(1); /* boolean: want reply */ 331 packet_send(); 332 } 333 334 /* 335 * Waits until the client can do something (some data becomes available on 336 * one of the file descriptors). 337 */ 338 339 static void 340 client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, 341 int *maxfdp, int *nallocp, int rekeying) 342 { 343 struct timeval tv, *tvp; 344 int ret; 345 346 /* Add any selections by the channel mechanism. */ 347 channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying); 348 349 if (!compat20) { 350 /* Read from the connection, unless our buffers are full. */ 351 if (buffer_len(&stdout_buffer) < buffer_high && 352 buffer_len(&stderr_buffer) < buffer_high && 353 channel_not_very_much_buffered_data()) 354 FD_SET(connection_in, *readsetp); 355 /* 356 * Read from stdin, unless we have seen EOF or have very much 357 * buffered data to send to the server. 358 */ 359 if (!stdin_eof && packet_not_very_much_data_to_write()) 360 FD_SET(fileno(stdin), *readsetp); 361 362 /* Select stdout/stderr if have data in buffer. */ 363 if (buffer_len(&stdout_buffer) > 0) 364 FD_SET(fileno(stdout), *writesetp); 365 if (buffer_len(&stderr_buffer) > 0) 366 FD_SET(fileno(stderr), *writesetp); 367 } else { 368 /* channel_prepare_select could have closed the last channel */ 369 if (session_closed && !channel_still_open() && 370 !packet_have_data_to_write()) { 371 /* clear mask since we did not call select() */ 372 memset(*readsetp, 0, *nallocp); 373 memset(*writesetp, 0, *nallocp); 374 return; 375 } else { 376 FD_SET(connection_in, *readsetp); 377 } 378 } 379 380 /* Select server connection if have data to write to the server. */ 381 if (packet_have_data_to_write()) 382 FD_SET(connection_out, *writesetp); 383 384 /* 385 * Wait for something to happen. This will suspend the process until 386 * some selected descriptor can be read, written, or has some other 387 * event pending. 388 */ 389 390 if (options.server_alive_interval == 0 || !compat20) 391 tvp = NULL; 392 else { 393 tv.tv_sec = options.server_alive_interval; 394 tv.tv_usec = 0; 395 tvp = &tv; 396 } 397 ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); 398 if (ret < 0) { 399 char buf[100]; 400 401 /* 402 * We have to clear the select masks, because we return. 403 * We have to return, because the mainloop checks for the flags 404 * set by the signal handlers. 405 */ 406 memset(*readsetp, 0, *nallocp); 407 memset(*writesetp, 0, *nallocp); 408 409 if (errno == EINTR) 410 return; 411 /* Note: we might still have data in the buffers. */ 412 snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); 413 buffer_append(&stderr_buffer, buf, strlen(buf)); 414 quit_pending = 1; 415 } else if (ret == 0) 416 server_alive_check(); 417 } 418 419 static void 420 client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) 421 { 422 struct winsize oldws, newws; 423 424 /* Flush stdout and stderr buffers. */ 425 if (buffer_len(bout) > 0) 426 atomicio(vwrite, fileno(stdout), buffer_ptr(bout), buffer_len(bout)); 427 if (buffer_len(berr) > 0) 428 atomicio(vwrite, fileno(stderr), buffer_ptr(berr), buffer_len(berr)); 429 430 leave_raw_mode(); 431 432 /* 433 * Free (and clear) the buffer to reduce the amount of data that gets 434 * written to swap. 435 */ 436 buffer_free(bin); 437 buffer_free(bout); 438 buffer_free(berr); 439 440 /* Save old window size. */ 441 ioctl(fileno(stdin), TIOCGWINSZ, &oldws); 442 443 /* Send the suspend signal to the program itself. */ 444 kill(getpid(), SIGTSTP); 445 446 /* Check if the window size has changed. */ 447 if (ioctl(fileno(stdin), TIOCGWINSZ, &newws) >= 0 && 448 (oldws.ws_row != newws.ws_row || 449 oldws.ws_col != newws.ws_col || 450 oldws.ws_xpixel != newws.ws_xpixel || 451 oldws.ws_ypixel != newws.ws_ypixel)) 452 received_window_change_signal = 1; 453 454 /* OK, we have been continued by the user. Reinitialize buffers. */ 455 buffer_init(bin); 456 buffer_init(bout); 457 buffer_init(berr); 458 459 enter_raw_mode(); 460 } 461 462 static void 463 client_process_net_input(fd_set * readset) 464 { 465 int len; 466 char buf[8192]; 467 468 /* 469 * Read input from the server, and add any such data to the buffer of 470 * the packet subsystem. 471 */ 472 if (FD_ISSET(connection_in, readset)) { 473 /* Read as much as possible. */ 474 len = read(connection_in, buf, sizeof(buf)); 475 if (len == 0) { 476 /* Received EOF. The remote host has closed the connection. */ 477 snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n", 478 host); 479 buffer_append(&stderr_buffer, buf, strlen(buf)); 480 quit_pending = 1; 481 return; 482 } 483 /* 484 * There is a kernel bug on Solaris that causes select to 485 * sometimes wake up even though there is no data available. 486 */ 487 if (len < 0 && (errno == EAGAIN || errno == EINTR)) 488 len = 0; 489 490 if (len < 0) { 491 /* An error has encountered. Perhaps there is a network problem. */ 492 snprintf(buf, sizeof buf, "Read from remote host %.300s: %.100s\r\n", 493 host, strerror(errno)); 494 buffer_append(&stderr_buffer, buf, strlen(buf)); 495 quit_pending = 1; 496 return; 497 } 498 packet_process_incoming(buf, len); 499 } 500 } 501 502 static void 503 process_cmdline(void) 504 { 505 void (*handler)(int); 506 char *s, *cmd; 507 u_short fwd_port, fwd_host_port; 508 char buf[1024], sfwd_port[6], sfwd_host_port[6]; 509 int delete = 0; 510 int local = 0; 511 512 leave_raw_mode(); 513 handler = signal(SIGINT, SIG_IGN); 514 cmd = s = read_passphrase("\r\nssh> ", RP_ECHO); 515 if (s == NULL) 516 goto out; 517 while (*s && isspace(*s)) 518 s++; 519 if (*s == '-') 520 s++; /* Skip cmdline '-', if any */ 521 if (*s == '\0') 522 goto out; 523 524 if (*s == '?') { 525 logit("Commands:"); 526 logit(" -Lport:host:hostport Request local forward"); 527 logit(" -Rport:host:hostport Request remote forward"); 528 logit(" -KRhostport Cancel remote forward"); 529 goto out; 530 } 531 532 if (*s == 'K') { 533 delete = 1; 534 s++; 535 } 536 if (*s != 'L' && *s != 'R') { 537 logit("Invalid command."); 538 goto out; 539 } 540 if (*s == 'L') 541 local = 1; 542 if (local && delete) { 543 logit("Not supported."); 544 goto out; 545 } 546 if ((!local || delete) && !compat20) { 547 logit("Not supported for SSH protocol version 1."); 548 goto out; 549 } 550 551 s++; 552 while (*s && isspace(*s)) 553 s++; 554 555 if (delete) { 556 if (sscanf(s, "%5[0-9]", sfwd_host_port) != 1) { 557 logit("Bad forwarding specification."); 558 goto out; 559 } 560 if ((fwd_host_port = a2port(sfwd_host_port)) == 0) { 561 logit("Bad forwarding port(s)."); 562 goto out; 563 } 564 channel_request_rforward_cancel(fwd_host_port); 565 } else { 566 if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]", 567 sfwd_port, buf, sfwd_host_port) != 3 && 568 sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]", 569 sfwd_port, buf, sfwd_host_port) != 3) { 570 logit("Bad forwarding specification."); 571 goto out; 572 } 573 if ((fwd_port = a2port(sfwd_port)) == 0 || 574 (fwd_host_port = a2port(sfwd_host_port)) == 0) { 575 logit("Bad forwarding port(s)."); 576 goto out; 577 } 578 if (local) { 579 if (channel_setup_local_fwd_listener(fwd_port, buf, 580 fwd_host_port, options.gateway_ports) < 0) { 581 logit("Port forwarding failed."); 582 goto out; 583 } 584 } else 585 channel_request_remote_forwarding(fwd_port, buf, 586 fwd_host_port); 587 logit("Forwarding port."); 588 } 589 590 out: 591 signal(SIGINT, handler); 592 enter_raw_mode(); 593 if (cmd) 594 xfree(cmd); 595 } 596 597 /* process the characters one by one */ 598 static int 599 process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len) 600 { 601 char string[1024]; 602 pid_t pid; 603 int bytes = 0; 604 u_int i; 605 u_char ch; 606 char *s; 607 608 for (i = 0; i < len; i++) { 609 /* Get one character at a time. */ 610 ch = buf[i]; 611 612 if (escape_pending) { 613 /* We have previously seen an escape character. */ 614 /* Clear the flag now. */ 615 escape_pending = 0; 616 617 /* Process the escaped character. */ 618 switch (ch) { 619 case '.': 620 /* Terminate the connection. */ 621 snprintf(string, sizeof string, "%c.\r\n", escape_char); 622 buffer_append(berr, string, strlen(string)); 623 624 quit_pending = 1; 625 return -1; 626 627 case 'Z' - 64: 628 /* Suspend the program. */ 629 /* Print a message to that effect to the user. */ 630 snprintf(string, sizeof string, "%c^Z [suspend ssh]\r\n", escape_char); 631 buffer_append(berr, string, strlen(string)); 632 633 /* Restore terminal modes and suspend. */ 634 client_suspend_self(bin, bout, berr); 635 636 /* We have been continued. */ 637 continue; 638 639 case 'B': 640 if (compat20) { 641 snprintf(string, sizeof string, 642 "%cB\r\n", escape_char); 643 buffer_append(berr, string, 644 strlen(string)); 645 channel_request_start(session_ident, 646 "break", 0); 647 packet_put_int(1000); 648 packet_send(); 649 } 650 continue; 651 652 case 'R': 653 if (compat20) { 654 if (datafellows & SSH_BUG_NOREKEY) 655 logit("Server does not support re-keying"); 656 else 657 need_rekeying = 1; 658 } 659 continue; 660 661 case '&': 662 /* 663 * Detach the program (continue to serve connections, 664 * but put in background and no more new connections). 665 */ 666 /* Restore tty modes. */ 667 leave_raw_mode(); 668 669 /* Stop listening for new connections. */ 670 channel_stop_listening(); 671 672 snprintf(string, sizeof string, 673 "%c& [backgrounded]\n", escape_char); 674 buffer_append(berr, string, strlen(string)); 675 676 /* Fork into background. */ 677 pid = fork(); 678 if (pid < 0) { 679 error("fork: %.100s", strerror(errno)); 680 continue; 681 } 682 if (pid != 0) { /* This is the parent. */ 683 /* The parent just exits. */ 684 exit(0); 685 } 686 /* The child continues serving connections. */ 687 if (compat20) { 688 buffer_append(bin, "\004", 1); 689 /* fake EOF on stdin */ 690 return -1; 691 } else if (!stdin_eof) { 692 /* 693 * Sending SSH_CMSG_EOF alone does not always appear 694 * to be enough. So we try to send an EOF character 695 * first. 696 */ 697 packet_start(SSH_CMSG_STDIN_DATA); 698 packet_put_string("\004", 1); 699 packet_send(); 700 /* Close stdin. */ 701 stdin_eof = 1; 702 if (buffer_len(bin) == 0) { 703 packet_start(SSH_CMSG_EOF); 704 packet_send(); 705 } 706 } 707 continue; 708 709 case '?': 710 snprintf(string, sizeof string, 711 "%c?\r\n\ 712 Supported escape sequences:\r\n\ 713 %c. - terminate connection\r\n\ 714 %cB - send a BREAK to the remote system\r\n\ 715 %cC - open a command line\r\n\ 716 %cR - Request rekey (SSH protocol 2 only)\r\n\ 717 %c^Z - suspend ssh\r\n\ 718 %c# - list forwarded connections\r\n\ 719 %c& - background ssh (when waiting for connections to terminate)\r\n\ 720 %c? - this message\r\n\ 721 %c%c - send the escape character by typing it twice\r\n\ 722 (Note that escapes are only recognized immediately after newline.)\r\n", 723 escape_char, escape_char, escape_char, escape_char, 724 escape_char, escape_char, escape_char, escape_char, 725 escape_char, escape_char, escape_char); 726 buffer_append(berr, string, strlen(string)); 727 continue; 728 729 case '#': 730 snprintf(string, sizeof string, "%c#\r\n", escape_char); 731 buffer_append(berr, string, strlen(string)); 732 s = channel_open_message(); 733 buffer_append(berr, s, strlen(s)); 734 xfree(s); 735 continue; 736 737 case 'C': 738 process_cmdline(); 739 continue; 740 741 default: 742 if (ch != escape_char) { 743 buffer_put_char(bin, escape_char); 744 bytes++; 745 } 746 /* Escaped characters fall through here */ 747 break; 748 } 749 } else { 750 /* 751 * The previous character was not an escape char. Check if this 752 * is an escape. 753 */ 754 if (last_was_cr && ch == escape_char) { 755 /* It is. Set the flag and continue to next character. */ 756 escape_pending = 1; 757 continue; 758 } 759 } 760 761 /* 762 * Normal character. Record whether it was a newline, 763 * and append it to the buffer. 764 */ 765 last_was_cr = (ch == '\r' || ch == '\n'); 766 buffer_put_char(bin, ch); 767 bytes++; 768 } 769 return bytes; 770 } 771 772 static void 773 client_process_input(fd_set * readset) 774 { 775 int len; 776 char buf[8192]; 777 778 /* Read input from stdin. */ 779 if (FD_ISSET(fileno(stdin), readset)) { 780 /* Read as much as possible. */ 781 len = read(fileno(stdin), buf, sizeof(buf)); 782 if (len < 0 && (errno == EAGAIN || errno == EINTR)) 783 return; /* we'll try again later */ 784 if (len <= 0) { 785 /* 786 * Received EOF or error. They are treated 787 * similarly, except that an error message is printed 788 * if it was an error condition. 789 */ 790 if (len < 0) { 791 snprintf(buf, sizeof buf, "read: %.100s\r\n", strerror(errno)); 792 buffer_append(&stderr_buffer, buf, strlen(buf)); 793 } 794 /* Mark that we have seen EOF. */ 795 stdin_eof = 1; 796 /* 797 * Send an EOF message to the server unless there is 798 * data in the buffer. If there is data in the 799 * buffer, no message will be sent now. Code 800 * elsewhere will send the EOF when the buffer 801 * becomes empty if stdin_eof is set. 802 */ 803 if (buffer_len(&stdin_buffer) == 0) { 804 packet_start(SSH_CMSG_EOF); 805 packet_send(); 806 } 807 } else if (escape_char == SSH_ESCAPECHAR_NONE) { 808 /* 809 * Normal successful read, and no escape character. 810 * Just append the data to buffer. 811 */ 812 buffer_append(&stdin_buffer, buf, len); 813 } else { 814 /* 815 * Normal, successful read. But we have an escape character 816 * and have to process the characters one by one. 817 */ 818 if (process_escapes(&stdin_buffer, &stdout_buffer, 819 &stderr_buffer, buf, len) == -1) 820 return; 821 } 822 } 823 } 824 825 static void 826 client_process_output(fd_set * writeset) 827 { 828 int len; 829 char buf[100]; 830 831 /* Write buffered output to stdout. */ 832 if (FD_ISSET(fileno(stdout), writeset)) { 833 /* Write as much data as possible. */ 834 len = write(fileno(stdout), buffer_ptr(&stdout_buffer), 835 buffer_len(&stdout_buffer)); 836 if (len <= 0) { 837 if (errno == EINTR || errno == EAGAIN) 838 len = 0; 839 else { 840 /* 841 * An error or EOF was encountered. Put an 842 * error message to stderr buffer. 843 */ 844 snprintf(buf, sizeof buf, "write stdout: %.50s\r\n", strerror(errno)); 845 buffer_append(&stderr_buffer, buf, strlen(buf)); 846 quit_pending = 1; 847 return; 848 } 849 } 850 /* Consume printed data from the buffer. */ 851 buffer_consume(&stdout_buffer, len); 852 stdout_bytes += len; 853 } 854 /* Write buffered output to stderr. */ 855 if (FD_ISSET(fileno(stderr), writeset)) { 856 /* Write as much data as possible. */ 857 len = write(fileno(stderr), buffer_ptr(&stderr_buffer), 858 buffer_len(&stderr_buffer)); 859 if (len <= 0) { 860 if (errno == EINTR || errno == EAGAIN) 861 len = 0; 862 else { 863 /* EOF or error, but can't even print error message. */ 864 quit_pending = 1; 865 return; 866 } 867 } 868 /* Consume printed characters from the buffer. */ 869 buffer_consume(&stderr_buffer, len); 870 stderr_bytes += len; 871 } 872 } 873 874 /* 875 * Get packets from the connection input buffer, and process them as long as 876 * there are packets available. 877 * 878 * Any unknown packets received during the actual 879 * session cause the session to terminate. This is 880 * intended to make debugging easier since no 881 * confirmations are sent. Any compatible protocol 882 * extensions must be negotiated during the 883 * preparatory phase. 884 */ 885 886 static void 887 client_process_buffered_input_packets(void) 888 { 889 dispatch_run(DISPATCH_NONBLOCK, &quit_pending, compat20 ? xxx_kex : NULL); 890 } 891 892 /* scan buf[] for '~' before sending data to the peer */ 893 894 static int 895 simple_escape_filter(Channel *c, char *buf, int len) 896 { 897 /* XXX we assume c->extended is writeable */ 898 return process_escapes(&c->input, &c->output, &c->extended, buf, len); 899 } 900 901 static void 902 client_channel_closed(int id, void *arg) 903 { 904 if (id != session_ident) 905 error("client_channel_closed: id %d != session_ident %d", 906 id, session_ident); 907 channel_cancel_cleanup(id); 908 session_closed = 1; 909 leave_raw_mode(); 910 } 911 912 /* 913 * Implements the interactive session with the server. This is called after 914 * the user has been authenticated, and a command has been started on the 915 * remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character 916 * used as an escape character for terminating or suspending the session. 917 */ 918 919 int 920 client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) 921 { 922 fd_set *readset = NULL, *writeset = NULL; 923 double start_time, total_time; 924 int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0; 925 char buf[100]; 926 927 debug("Entering interactive session."); 928 929 start_time = get_current_time(); 930 931 /* Initialize variables. */ 932 escape_pending = 0; 933 last_was_cr = 1; 934 exit_status = -1; 935 stdin_eof = 0; 936 buffer_high = 64 * 1024; 937 connection_in = packet_get_connection_in(); 938 connection_out = packet_get_connection_out(); 939 max_fd = MAX(connection_in, connection_out); 940 941 if (!compat20) { 942 /* enable nonblocking unless tty */ 943 if (!isatty(fileno(stdin))) 944 set_nonblock(fileno(stdin)); 945 if (!isatty(fileno(stdout))) 946 set_nonblock(fileno(stdout)); 947 if (!isatty(fileno(stderr))) 948 set_nonblock(fileno(stderr)); 949 max_fd = MAX(max_fd, fileno(stdin)); 950 max_fd = MAX(max_fd, fileno(stdout)); 951 max_fd = MAX(max_fd, fileno(stderr)); 952 } 953 stdin_bytes = 0; 954 stdout_bytes = 0; 955 stderr_bytes = 0; 956 quit_pending = 0; 957 escape_char = escape_char_arg; 958 959 /* Initialize buffers. */ 960 buffer_init(&stdin_buffer); 961 buffer_init(&stdout_buffer); 962 buffer_init(&stderr_buffer); 963 964 client_init_dispatch(); 965 966 /* 967 * Set signal handlers, (e.g. to restore non-blocking mode) 968 * but don't overwrite SIG_IGN, matches behaviour from rsh(1) 969 */ 970 if (signal(SIGINT, SIG_IGN) != SIG_IGN) 971 signal(SIGINT, signal_handler); 972 if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) 973 signal(SIGQUIT, signal_handler); 974 if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 975 signal(SIGTERM, signal_handler); 976 if (have_pty) 977 signal(SIGWINCH, window_change_handler); 978 979 if (have_pty) 980 enter_raw_mode(); 981 982 if (compat20) { 983 session_ident = ssh2_chan_id; 984 if (escape_char != SSH_ESCAPECHAR_NONE) 985 channel_register_filter(session_ident, 986 simple_escape_filter); 987 if (session_ident != -1) 988 channel_register_cleanup(session_ident, 989 client_channel_closed); 990 } else { 991 /* Check if we should immediately send eof on stdin. */ 992 client_check_initial_eof_on_stdin(); 993 } 994 995 /* Main loop of the client for the interactive session mode. */ 996 while (!quit_pending) { 997 998 /* Process buffered packets sent by the server. */ 999 client_process_buffered_input_packets(); 1000 1001 if (compat20 && session_closed && !channel_still_open()) 1002 break; 1003 1004 rekeying = (xxx_kex != NULL && !xxx_kex->done); 1005 1006 if (rekeying) { 1007 debug("rekeying in progress"); 1008 } else { 1009 /* 1010 * Make packets of buffered stdin data, and buffer 1011 * them for sending to the server. 1012 */ 1013 if (!compat20) 1014 client_make_packets_from_stdin_data(); 1015 1016 /* 1017 * Make packets from buffered channel data, and 1018 * enqueue them for sending to the server. 1019 */ 1020 if (packet_not_very_much_data_to_write()) 1021 channel_output_poll(); 1022 1023 /* 1024 * Check if the window size has changed, and buffer a 1025 * message about it to the server if so. 1026 */ 1027 client_check_window_change(); 1028 1029 if (quit_pending) 1030 break; 1031 } 1032 /* 1033 * Wait until we have something to do (something becomes 1034 * available on one of the descriptors). 1035 */ 1036 max_fd2 = max_fd; 1037 client_wait_until_can_do_something(&readset, &writeset, 1038 &max_fd2, &nalloc, rekeying); 1039 1040 if (quit_pending) 1041 break; 1042 1043 /* Do channel operations unless rekeying in progress. */ 1044 if (!rekeying) { 1045 channel_after_select(readset, writeset); 1046 if (need_rekeying || packet_need_rekeying()) { 1047 debug("need rekeying"); 1048 xxx_kex->done = 0; 1049 kex_send_kexinit(xxx_kex); 1050 need_rekeying = 0; 1051 } 1052 } 1053 1054 /* Buffer input from the connection. */ 1055 client_process_net_input(readset); 1056 1057 if (quit_pending) 1058 break; 1059 1060 if (!compat20) { 1061 /* Buffer data from stdin */ 1062 client_process_input(readset); 1063 /* 1064 * Process output to stdout and stderr. Output to 1065 * the connection is processed elsewhere (above). 1066 */ 1067 client_process_output(writeset); 1068 } 1069 1070 /* Send as much buffered packet data as possible to the sender. */ 1071 if (FD_ISSET(connection_out, writeset)) 1072 packet_write_poll(); 1073 } 1074 if (readset) 1075 xfree(readset); 1076 if (writeset) 1077 xfree(writeset); 1078 1079 /* Terminate the session. */ 1080 1081 /* Stop watching for window change. */ 1082 if (have_pty) 1083 signal(SIGWINCH, SIG_DFL); 1084 1085 channel_free_all(); 1086 1087 if (have_pty) 1088 leave_raw_mode(); 1089 1090 /* restore blocking io */ 1091 if (!isatty(fileno(stdin))) 1092 unset_nonblock(fileno(stdin)); 1093 if (!isatty(fileno(stdout))) 1094 unset_nonblock(fileno(stdout)); 1095 if (!isatty(fileno(stderr))) 1096 unset_nonblock(fileno(stderr)); 1097 1098 /* 1099 * If there was no shell or command requested, there will be no remote 1100 * exit status to be returned. In that case, clear error code if the 1101 * connection was deliberately terminated at this end. 1102 */ 1103 if (no_shell_flag && received_signal == SIGTERM) { 1104 received_signal = 0; 1105 exit_status = 0; 1106 } 1107 1108 if (received_signal) 1109 fatal("Killed by signal %d.", (int) received_signal); 1110 1111 /* 1112 * In interactive mode (with pseudo tty) display a message indicating 1113 * that the connection has been closed. 1114 */ 1115 if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) { 1116 snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host); 1117 buffer_append(&stderr_buffer, buf, strlen(buf)); 1118 } 1119 1120 /* Output any buffered data for stdout. */ 1121 while (buffer_len(&stdout_buffer) > 0) { 1122 len = write(fileno(stdout), buffer_ptr(&stdout_buffer), 1123 buffer_len(&stdout_buffer)); 1124 if (len <= 0) { 1125 error("Write failed flushing stdout buffer."); 1126 break; 1127 } 1128 buffer_consume(&stdout_buffer, len); 1129 stdout_bytes += len; 1130 } 1131 1132 /* Output any buffered data for stderr. */ 1133 while (buffer_len(&stderr_buffer) > 0) { 1134 len = write(fileno(stderr), buffer_ptr(&stderr_buffer), 1135 buffer_len(&stderr_buffer)); 1136 if (len <= 0) { 1137 error("Write failed flushing stderr buffer."); 1138 break; 1139 } 1140 buffer_consume(&stderr_buffer, len); 1141 stderr_bytes += len; 1142 } 1143 1144 /* Clear and free any buffers. */ 1145 memset(buf, 0, sizeof(buf)); 1146 buffer_free(&stdin_buffer); 1147 buffer_free(&stdout_buffer); 1148 buffer_free(&stderr_buffer); 1149 1150 /* Report bytes transferred, and transfer rates. */ 1151 total_time = get_current_time() - start_time; 1152 debug("Transferred: stdin %lu, stdout %lu, stderr %lu bytes in %.1f seconds", 1153 stdin_bytes, stdout_bytes, stderr_bytes, total_time); 1154 if (total_time > 0) 1155 debug("Bytes per second: stdin %.1f, stdout %.1f, stderr %.1f", 1156 stdin_bytes / total_time, stdout_bytes / total_time, 1157 stderr_bytes / total_time); 1158 1159 /* Return the exit status of the program. */ 1160 debug("Exit status %d", exit_status); 1161 return exit_status; 1162 } 1163 1164 /*********/ 1165 1166 static void 1167 client_input_stdout_data(int type, u_int32_t seq, void *ctxt) 1168 { 1169 u_int data_len; 1170 char *data = packet_get_string(&data_len); 1171 packet_check_eom(); 1172 buffer_append(&stdout_buffer, data, data_len); 1173 memset(data, 0, data_len); 1174 xfree(data); 1175 } 1176 static void 1177 client_input_stderr_data(int type, u_int32_t seq, void *ctxt) 1178 { 1179 u_int data_len; 1180 char *data = packet_get_string(&data_len); 1181 packet_check_eom(); 1182 buffer_append(&stderr_buffer, data, data_len); 1183 memset(data, 0, data_len); 1184 xfree(data); 1185 } 1186 static void 1187 client_input_exit_status(int type, u_int32_t seq, void *ctxt) 1188 { 1189 exit_status = packet_get_int(); 1190 packet_check_eom(); 1191 /* Acknowledge the exit. */ 1192 packet_start(SSH_CMSG_EXIT_CONFIRMATION); 1193 packet_send(); 1194 /* 1195 * Must wait for packet to be sent since we are 1196 * exiting the loop. 1197 */ 1198 packet_write_wait(); 1199 /* Flag that we want to exit. */ 1200 quit_pending = 1; 1201 } 1202 static void 1203 client_input_agent_open(int type, u_int32_t seq, void *ctxt) 1204 { 1205 Channel *c = NULL; 1206 int remote_id, sock; 1207 1208 /* Read the remote channel number from the message. */ 1209 remote_id = packet_get_int(); 1210 packet_check_eom(); 1211 1212 /* 1213 * Get a connection to the local authentication agent (this may again 1214 * get forwarded). 1215 */ 1216 sock = ssh_get_authentication_socket(); 1217 1218 /* 1219 * If we could not connect the agent, send an error message back to 1220 * the server. This should never happen unless the agent dies, 1221 * because authentication forwarding is only enabled if we have an 1222 * agent. 1223 */ 1224 if (sock >= 0) { 1225 c = channel_new("", SSH_CHANNEL_OPEN, sock, sock, 1226 -1, 0, 0, 0, "authentication agent connection", 1); 1227 c->remote_id = remote_id; 1228 c->force_drain = 1; 1229 } 1230 if (c == NULL) { 1231 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); 1232 packet_put_int(remote_id); 1233 } else { 1234 /* Send a confirmation to the remote host. */ 1235 debug("Forwarding authentication connection."); 1236 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); 1237 packet_put_int(remote_id); 1238 packet_put_int(c->self); 1239 } 1240 packet_send(); 1241 } 1242 1243 static Channel * 1244 client_request_forwarded_tcpip(const char *request_type, int rchan) 1245 { 1246 Channel *c = NULL; 1247 char *listen_address, *originator_address; 1248 int listen_port, originator_port; 1249 int sock; 1250 1251 /* Get rest of the packet */ 1252 listen_address = packet_get_string(NULL); 1253 listen_port = packet_get_int(); 1254 originator_address = packet_get_string(NULL); 1255 originator_port = packet_get_int(); 1256 packet_check_eom(); 1257 1258 debug("client_request_forwarded_tcpip: listen %s port %d, originator %s port %d", 1259 listen_address, listen_port, originator_address, originator_port); 1260 1261 sock = channel_connect_by_listen_address(listen_port); 1262 if (sock < 0) { 1263 xfree(originator_address); 1264 xfree(listen_address); 1265 return NULL; 1266 } 1267 c = channel_new("forwarded-tcpip", 1268 SSH_CHANNEL_CONNECTING, sock, sock, -1, 1269 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, 1270 originator_address, 1); 1271 xfree(originator_address); 1272 xfree(listen_address); 1273 return c; 1274 } 1275 1276 static Channel * 1277 client_request_x11(const char *request_type, int rchan) 1278 { 1279 Channel *c = NULL; 1280 char *originator; 1281 int originator_port; 1282 int sock; 1283 1284 if (!options.forward_x11) { 1285 error("Warning: ssh server tried X11 forwarding."); 1286 error("Warning: this is probably a break in attempt by a malicious server."); 1287 return NULL; 1288 } 1289 originator = packet_get_string(NULL); 1290 if (datafellows & SSH_BUG_X11FWD) { 1291 debug2("buggy server: x11 request w/o originator_port"); 1292 originator_port = 0; 1293 } else { 1294 originator_port = packet_get_int(); 1295 } 1296 packet_check_eom(); 1297 /* XXX check permission */ 1298 debug("client_request_x11: request from %s %d", originator, 1299 originator_port); 1300 xfree(originator); 1301 sock = x11_connect_display(); 1302 if (sock < 0) 1303 return NULL; 1304 c = channel_new("x11", 1305 SSH_CHANNEL_X11_OPEN, sock, sock, -1, 1306 CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); 1307 c->force_drain = 1; 1308 return c; 1309 } 1310 1311 static Channel * 1312 client_request_agent(const char *request_type, int rchan) 1313 { 1314 Channel *c = NULL; 1315 int sock; 1316 1317 if (!options.forward_agent) { 1318 error("Warning: ssh server tried agent forwarding."); 1319 error("Warning: this is probably a break in attempt by a malicious server."); 1320 return NULL; 1321 } 1322 sock = ssh_get_authentication_socket(); 1323 if (sock < 0) 1324 return NULL; 1325 c = channel_new("authentication agent connection", 1326 SSH_CHANNEL_OPEN, sock, sock, -1, 1327 CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, 1328 "authentication agent connection", 1); 1329 c->force_drain = 1; 1330 return c; 1331 } 1332 1333 /* XXXX move to generic input handler */ 1334 static void 1335 client_input_channel_open(int type, u_int32_t seq, void *ctxt) 1336 { 1337 Channel *c = NULL; 1338 char *ctype; 1339 int rchan; 1340 u_int rmaxpack, rwindow, len; 1341 1342 ctype = packet_get_string(&len); 1343 rchan = packet_get_int(); 1344 rwindow = packet_get_int(); 1345 rmaxpack = packet_get_int(); 1346 1347 debug("client_input_channel_open: ctype %s rchan %d win %d max %d", 1348 ctype, rchan, rwindow, rmaxpack); 1349 1350 if (strcmp(ctype, "forwarded-tcpip") == 0) { 1351 c = client_request_forwarded_tcpip(ctype, rchan); 1352 } else if (strcmp(ctype, "x11") == 0) { 1353 c = client_request_x11(ctype, rchan); 1354 } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { 1355 c = client_request_agent(ctype, rchan); 1356 } 1357 /* XXX duplicate : */ 1358 if (c != NULL) { 1359 debug("confirm %s", ctype); 1360 c->remote_id = rchan; 1361 c->remote_window = rwindow; 1362 c->remote_maxpacket = rmaxpack; 1363 if (c->type != SSH_CHANNEL_CONNECTING) { 1364 packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); 1365 packet_put_int(c->remote_id); 1366 packet_put_int(c->self); 1367 packet_put_int(c->local_window); 1368 packet_put_int(c->local_maxpacket); 1369 packet_send(); 1370 } 1371 } else { 1372 debug("failure %s", ctype); 1373 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); 1374 packet_put_int(rchan); 1375 packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); 1376 if (!(datafellows & SSH_BUG_OPENFAILURE)) { 1377 packet_put_cstring("open failed"); 1378 packet_put_cstring(""); 1379 } 1380 packet_send(); 1381 } 1382 xfree(ctype); 1383 } 1384 static void 1385 client_input_channel_req(int type, u_int32_t seq, void *ctxt) 1386 { 1387 Channel *c = NULL; 1388 int id, reply, success = 0; 1389 char *rtype; 1390 1391 id = packet_get_int(); 1392 rtype = packet_get_string(NULL); 1393 reply = packet_get_char(); 1394 1395 debug("client_input_channel_req: channel %d rtype %s reply %d", 1396 id, rtype, reply); 1397 1398 if (session_ident == -1) { 1399 error("client_input_channel_req: no channel %d", session_ident); 1400 } else if (id != session_ident) { 1401 error("client_input_channel_req: channel %d: wrong channel: %d", 1402 session_ident, id); 1403 } 1404 c = channel_lookup(id); 1405 if (c == NULL) { 1406 error("client_input_channel_req: channel %d: unknown channel", id); 1407 } else if (strcmp(rtype, "exit-status") == 0) { 1408 success = 1; 1409 exit_status = packet_get_int(); 1410 packet_check_eom(); 1411 } 1412 if (reply) { 1413 packet_start(success ? 1414 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); 1415 packet_put_int(c->remote_id); 1416 packet_send(); 1417 } 1418 xfree(rtype); 1419 } 1420 static void 1421 client_input_global_request(int type, u_int32_t seq, void *ctxt) 1422 { 1423 char *rtype; 1424 int want_reply; 1425 int success = 0; 1426 1427 rtype = packet_get_string(NULL); 1428 want_reply = packet_get_char(); 1429 debug("client_input_global_request: rtype %s want_reply %d", 1430 rtype, want_reply); 1431 if (want_reply) { 1432 packet_start(success ? 1433 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); 1434 packet_send(); 1435 packet_write_wait(); 1436 } 1437 xfree(rtype); 1438 } 1439 1440 static void 1441 client_init_dispatch_20(void) 1442 { 1443 dispatch_init(&dispatch_protocol_error); 1444 1445 dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); 1446 dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); 1447 dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); 1448 dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); 1449 dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open); 1450 dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); 1451 dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); 1452 dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req); 1453 dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); 1454 dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request); 1455 1456 /* rekeying */ 1457 dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); 1458 1459 /* global request reply messages */ 1460 dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply); 1461 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply); 1462 } 1463 static void 1464 client_init_dispatch_13(void) 1465 { 1466 dispatch_init(NULL); 1467 dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); 1468 dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); 1469 dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); 1470 dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); 1471 dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); 1472 dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); 1473 dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status); 1474 dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data); 1475 dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data); 1476 1477 dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ? 1478 &client_input_agent_open : &deny_input_open); 1479 dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ? 1480 &x11_input_open : &deny_input_open); 1481 } 1482 static void 1483 client_init_dispatch_15(void) 1484 { 1485 client_init_dispatch_13(); 1486 dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); 1487 dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose); 1488 } 1489 static void 1490 client_init_dispatch(void) 1491 { 1492 if (compat20) 1493 client_init_dispatch_20(); 1494 else if (compat13) 1495 client_init_dispatch_13(); 1496 else 1497 client_init_dispatch_15(); 1498 } 1499 1500 /* client specific fatal cleanup */ 1501 void 1502 cleanup_exit(int i) 1503 { 1504 leave_raw_mode(); 1505 leave_non_blocking(); 1506 _exit(i); 1507 } 1508