11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: clientloop.c,v 1.236 2011/06/22 22:08:42 djm Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Author: Tatu Ylonen <ylo@cs.hut.fi> 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * All rights reserved 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The main loop for the interactive session (client side). 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * As far as I am concerned, the code I have written for this software 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * can be used freely for any purpose. Any derived versions of this 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * software must be clearly marked as such, and if the derived work is 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * incompatible with the protocol description in the RFC file, it must be 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * called by a name other than "ssh" or "Secure Shell". 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1999 Theo de Raadt. All rights reserved. 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met: 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer. 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer in the 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * documentation and/or other materials provided with the distribution. 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * SSH2 support added by Markus Friedl. 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met: 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer. 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer in the 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * documentation and/or other materials provided with the distribution. 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/ioctl.h> 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/param.h> 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_SYS_STAT_H 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# include <sys/stat.h> 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_SYS_TIME_H 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# include <sys/time.h> 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/socket.h> 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <ctype.h> 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h> 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_PATHS_H 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <paths.h> 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <signal.h> 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h> 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdio.h> 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdlib.h> 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <termios.h> 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <pwd.h> 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <unistd.h> 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "openbsd-compat/sys-queue.h" 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h" 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh.h" 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh1.h" 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh2.h" 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "packet.h" 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h" 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "compat.h" 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "channels.h" 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "dispatch.h" 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "key.h" 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "cipher.h" 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "kex.h" 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h" 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "readconf.h" 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "clientloop.h" 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "sshconnect.h" 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "authfd.h" 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "atomicio.h" 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "sshpty.h" 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "misc.h" 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "match.h" 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "msg.h" 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "roaming.h" 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* import options */ 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern Options options; 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Flag indicating that stdin should be redirected from /dev/null. */ 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern int stdin_null_flag; 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Flag indicating that no shell has been requested */ 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern int no_shell_flag; 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Control socket */ 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern int muxserver_sock; /* XXX use mux_client_cleanup() instead */ 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Name of the host we are connecting to. This is the name given on the 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * command line, or the HostName specified for the user-supplied name in a 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * configuration file. 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern char *host; 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Flag to indicate that we have received a window change signal which has 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * not yet been processed. This will cause a message indicating the new 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * window size to be sent to the server a little later. This is volatile 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * because this is updated in a signal handler. 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic volatile sig_atomic_t received_window_change_signal = 0; 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic volatile sig_atomic_t received_signal = 0; 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Flag indicating whether the user's terminal is in non-blocking mode. */ 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int in_non_blocking_mode = 0; 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Time when backgrounded control master using ControlPersist should exit */ 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic time_t control_persist_exit_time = 0; 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Common data for the client loop code. */ 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvolatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int escape_char1; /* Escape character. (proto1 only) */ 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int escape_pending1; /* Last character was an escape (proto1 only) */ 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int last_was_cr; /* Last character was a newline. */ 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int exit_status; /* Used to store the command exit status. */ 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int stdin_eof; /* EOF has been encountered on stderr. */ 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Buffer stdin_buffer; /* Buffer for stdin data. */ 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Buffer stdout_buffer; /* Buffer for stdout data. */ 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Buffer stderr_buffer; /* Buffer for stderr data. */ 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic u_int buffer_high; /* Soft max buffer size. */ 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int connection_in; /* Connection to server (input). */ 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int connection_out; /* Connection to server (output). */ 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int need_rekeying; /* Set to non-zero if rekeying is requested. */ 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int session_closed; /* In SSH2: login session closed. */ 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void client_init_dispatch(void); 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint session_ident = -1; 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint session_resumed = 0; 1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Track escape per proto2 channel */ 1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct escape_filter_ctx { 1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int escape_pending; 1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int escape_char; 1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}; 1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Context for channel confirmation replies */ 1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct channel_reply_ctx { 1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *request_type; 1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int id; 1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood enum confirm_action action; 1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}; 1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Global request success/failure callbacks */ 1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct global_confirm { 1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_ENTRY(global_confirm) entry; 1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood global_confirm_cb *cb; 1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood void *ctx; 1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ref_count; 1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}; 1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodTAILQ_HEAD(global_confirms, global_confirm); 1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic struct global_confirms global_confirms = 1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_HEAD_INITIALIZER(global_confirms); 1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*XXX*/ 1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern Kex *xxx_kex; 1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid ssh_process_session2_setup(int, int, int, Buffer *); 1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Restores stdin to blocking mode. */ 2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodleave_non_blocking(void) 2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (in_non_blocking_mode) { 2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood unset_nonblock(fileno(stdin)); 2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood in_non_blocking_mode = 0; 2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Puts stdin terminal in non-blocking mode. */ 2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodenter_non_blocking(void) 2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood in_non_blocking_mode = 1; 2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood set_nonblock(fileno(stdin)); 2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Signal handler for the window change signal (SIGWINCH). This just sets a 2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * flag indicating that the window has changed. 2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*ARGSUSED */ 2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodwindow_change_handler(int sig) 2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood received_window_change_signal = 1; 2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGWINCH, window_change_handler); 2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Signal handler for signals that cause the program to terminate. These 2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * signals must be trapped to restore terminal modes. 2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*ARGSUSED */ 2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsignal_handler(int sig) 2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood received_signal = sig; 2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood quit_pending = 1; 2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Returns current time in seconds from Jan 1, 1970 with the maximum 2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * available resolution. 2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic double 2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodget_current_time(void) 2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct timeval tv; 2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gettimeofday(&tv, NULL); 2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0; 2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Sets control_persist_exit_time to the absolute time when the 2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * backgrounded control master should exit due to expiry of the 2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ControlPersist timeout. Sets it to 0 if we are not a backgrounded 2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * control master process, or if there is no ControlPersist timeout. 2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodset_control_persist_exit_time(void) 2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (muxserver_sock == -1 || !options.control_persist 2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood || options.control_persist_timeout == 0) { 2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* not using a ControlPersist timeout */ 2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood control_persist_exit_time = 0; 2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (channel_still_open()) { 2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* some client connections are still open */ 2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (control_persist_exit_time > 0) 2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("%s: cancel scheduled exit", __func__); 2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood control_persist_exit_time = 0; 2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (control_persist_exit_time <= 0) { 2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* a client connection has recently closed */ 2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood control_persist_exit_time = time(NULL) + 2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (time_t)options.control_persist_timeout; 2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("%s: schedule exit in %d seconds", __func__, 2791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.control_persist_timeout); 2801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* else we are already counting down to the timeout */ 2821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" 2851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 2861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_x11_get_proto(const char *display, const char *xauth_path, 2871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int trusted, u_int timeout, char **_proto, char **_data) 2881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char cmd[1024]; 2901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char line[512]; 2911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char xdisplay[512]; 2921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static char proto[512], data[512]; 2931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FILE *f; 2941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int got_data = 0, generated = 0, do_unlink = 0, i; 2951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *xauthdir, *xauthfile; 2961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct stat st; 2971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int now; 2981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xauthdir = xauthfile = NULL; 3001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *_proto = proto; 3011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *_data = data; 3021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood proto[0] = data[0] = '\0'; 3031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) { 3051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("No xauth program."); 3061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 3071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (display == NULL) { 3081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("x11_get_proto: DISPLAY not set"); 3091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 3101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 3121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Handle FamilyLocal case where $DISPLAY does 3131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * not match an authorization entry. For this we 3141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * just try "xauth list unix:displaynum.screennum". 3151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * XXX: "localhost" match to determine FamilyLocal 3161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * is not perfect. 3171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 3181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strncmp(display, "localhost:", 10) == 0) { 3191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(xdisplay, sizeof(xdisplay), "unix:%s", 3201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood display + 10); 3211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood display = xdisplay; 3221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (trusted == 0) { 3241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xauthdir = xmalloc(MAXPATHLEN); 3251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xauthfile = xmalloc(MAXPATHLEN); 3261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood mktemp_proto(xauthdir, MAXPATHLEN); 3271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (mkdtemp(xauthdir) != NULL) { 3281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_unlink = 1; 3291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", 3301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xauthdir); 3311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(cmd, sizeof(cmd), 3321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "%s -f %s generate %s " SSH_X11_PROTO 3331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood " untrusted timeout %u 2>" _PATH_DEVNULL, 3341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xauth_path, xauthfile, display, timeout); 3351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("x11_get_proto: %s", cmd); 3361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (system(cmd) == 0) 3371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood generated = 1; 3381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (x11_refuse_time == 0) { 3391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood now = time(NULL) + 1; 3401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (UINT_MAX - timeout < now) 3411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood x11_refuse_time = UINT_MAX; 3421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 3431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood x11_refuse_time = now + timeout; 3441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 3491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * When in untrusted mode, we read the cookie only if it was 3501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * successfully generated as an untrusted one in the step 3511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * above. 3521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 3531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (trusted || generated) { 3541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(cmd, sizeof(cmd), 3551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "%s %s%s list %s 2>" _PATH_DEVNULL, 3561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xauth_path, 3571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood generated ? "-f " : "" , 3581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood generated ? xauthfile : "", 3591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood display); 3601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("x11_get_proto: %s", cmd); 3611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood f = popen(cmd, "r"); 3621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (f && fgets(line, sizeof(line), f) && 3631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sscanf(line, "%*s %511s %511s", proto, data) == 2) 3641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood got_data = 1; 3651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (f) 3661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pclose(f); 3671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else 3681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Warning: untrusted X11 forwarding setup failed: " 3691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "xauth key data not generated"); 3701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (do_unlink) { 3731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood unlink(xauthfile); 3741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rmdir(xauthdir); 3751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (xauthdir) 3771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(xauthdir); 3781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (xauthfile) 3791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(xauthfile); 3801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 3821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If we didn't get authentication data, just make up some 3831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * data. The forwarding code will check the validity of the 3841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * response anyway, and substitute this data. The X11 3851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * server, however, will ignore this fake data and use 3861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * whatever authentication mechanisms it was using otherwise 3871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * for the local connection. 3881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 3891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!got_data) { 3901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int32_t rnd = 0; 3911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Warning: No xauth data; " 3931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "using fake authentication data for X11 forwarding."); 3941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcpy(proto, SSH_X11_PROTO, sizeof proto); 3951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < 16; i++) { 3961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (i % 4 == 0) 3971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rnd = arc4random(); 3981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", 3991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rnd & 0xff); 4001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rnd >>= 8; 4011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 4061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * This is called when the interactive is entered. This checks if there is 4071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * an EOF coming on stdin. We must check this explicitly, as select() does 4081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * not appear to wake up when redirecting from /dev/null. 4091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 4101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 4121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_check_initial_eof_on_stdin(void) 4131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int len; 4151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[1]; 4161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 4181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If standard input is to be "redirected from /dev/null", we simply 4191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * mark that we have seen an EOF and send an EOF message to the 4201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * server. Otherwise, we try to read a single character; it appears 4211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * that for some files, such /dev/null, select() never wakes up for 4221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * read for this descriptor, which means that we never get EOF. This 4231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * way we will get the EOF if stdin comes from /dev/null or similar. 4241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 4251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (stdin_null_flag) { 4261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Fake EOF on stdin. */ 4271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Sending eof."); 4281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood stdin_eof = 1; 4291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH_CMSG_EOF); 4301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 4311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 4321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood enter_non_blocking(); 4331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Check for immediate EOF on stdin. */ 4351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = read(fileno(stdin), buf, 1); 4361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len == 0) { 4371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 4381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * EOF. Record that we have seen it and send 4391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * EOF to server. 4401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 4411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Sending eof."); 4421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood stdin_eof = 1; 4431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH_CMSG_EOF); 4441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 4451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (len > 0) { 4461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 4471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Got data. We must store the data in the buffer, 4481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * and also process it as an escape character if 4491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * appropriate. 4501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 4511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((u_char) buf[0] == escape_char1) 4521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_pending1 = 1; 4531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 4541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&stdin_buffer, buf, 1); 4551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood leave_non_blocking(); 4571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 4621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Make packets from buffered stdin data, and buffer them for sending to the 4631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * connection. 4641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 4651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 4671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_make_packets_from_stdin_data(void) 4681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int len; 4701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Send buffered stdin data to the server. */ 4721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (buffer_len(&stdin_buffer) > 0 && 4731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_not_very_much_data_to_write()) { 4741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = buffer_len(&stdin_buffer); 4751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Keep the packets at reasonable size. */ 4761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len > packet_get_maxsize()) 4771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = packet_get_maxsize(); 4781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH_CMSG_STDIN_DATA); 4791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(buffer_ptr(&stdin_buffer), len); 4801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 4811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_consume(&stdin_buffer, len); 4821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* If we have a pending EOF, send it now. */ 4831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (stdin_eof && buffer_len(&stdin_buffer) == 0) { 4841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH_CMSG_EOF); 4851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 4861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 4911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Checks if the client window has changed, and sends a packet about it to 4921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the server if so. The actual change is detected elsewhere (by a software 4931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * interrupt on Unix); this just checks the flag and sends a message if 4941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * appropriate. 4951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 4961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 4981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_check_window_change(void) 4991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 5001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct winsize ws; 5011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (! received_window_change_signal) 5031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 5041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /** XXX race */ 5051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood received_window_change_signal = 0; 5061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("client_check_window_change: changed"); 5081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) { 5101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_send_window_changes(); 5111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 5121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) 5131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 5141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH_CMSG_WINDOW_SIZE); 5151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int((u_int)ws.ws_row); 5161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int((u_int)ws.ws_col); 5171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int((u_int)ws.ws_xpixel); 5181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int((u_int)ws.ws_ypixel); 5191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 5201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 5221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 5241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_global_request_reply(int type, u_int32_t seq, void *ctxt) 5251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 5261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct global_confirm *gc; 5271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((gc = TAILQ_FIRST(&global_confirms)) == NULL) 5291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 5301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (gc->cb != NULL) 5311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gc->cb(type, seq, gc->ctx); 5321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (--gc->ref_count <= 0) { 5331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_REMOVE(&global_confirms, gc, entry); 5341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bzero(gc, sizeof(*gc)); 5351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(gc); 5361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_set_alive_timeouts(0); 5391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 5401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 5421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodserver_alive_check(void) 5431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 5441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (packet_inc_alive_timeouts() > options.server_alive_count_max) { 5451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Timeout, server %s not responding.", host); 5461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cleanup_exit(255); 5471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_GLOBAL_REQUEST); 5491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring("keepalive@openssh.com"); 5501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_char(1); /* boolean: want reply */ 5511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 5521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Insert an empty placeholder to maintain ordering */ 5531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_register_global_confirm(NULL, NULL); 5541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 5551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 5571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Waits until the client can do something (some data becomes available on 5581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * one of the file descriptors). 5591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 5601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 5611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, 5621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int *maxfdp, u_int *nallocp, int rekeying) 5631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 5641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct timeval tv, *tvp; 5651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int timeout_secs; 5661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ret; 5671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Add any selections by the channel mechanism. */ 5691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying); 5701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!compat20) { 5721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Read from the connection, unless our buffers are full. */ 5731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&stdout_buffer) < buffer_high && 5741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_len(&stderr_buffer) < buffer_high && 5751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_not_very_much_buffered_data()) 5761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FD_SET(connection_in, *readsetp); 5771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 5781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Read from stdin, unless we have seen EOF or have very much 5791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * buffered data to send to the server. 5801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 5811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!stdin_eof && packet_not_very_much_data_to_write()) 5821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FD_SET(fileno(stdin), *readsetp); 5831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Select stdout/stderr if have data in buffer. */ 5851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&stdout_buffer) > 0) 5861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FD_SET(fileno(stdout), *writesetp); 5871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&stderr_buffer) > 0) 5881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FD_SET(fileno(stderr), *writesetp); 5891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 5901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* channel_prepare_select could have closed the last channel */ 5911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (session_closed && !channel_still_open() && 5921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood !packet_have_data_to_write()) { 5931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* clear mask since we did not call select() */ 5941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(*readsetp, 0, *nallocp); 5951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(*writesetp, 0, *nallocp); 5961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 5971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 5981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FD_SET(connection_in, *readsetp); 5991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Select server connection if have data to write to the server. */ 6031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (packet_have_data_to_write()) 6041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FD_SET(connection_out, *writesetp); 6051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 6071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Wait for something to happen. This will suspend the process until 6081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * some selected descriptor can be read, written, or has some other 6091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * event pending, or a timeout expires. 6101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 6111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */ 6131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.server_alive_interval > 0 && compat20) 6141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood timeout_secs = options.server_alive_interval; 6151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood set_control_persist_exit_time(); 6161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (control_persist_exit_time > 0) { 6171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood timeout_secs = MIN(timeout_secs, 6181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood control_persist_exit_time - time(NULL)); 6191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (timeout_secs < 0) 6201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood timeout_secs = 0; 6211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (timeout_secs == INT_MAX) 6231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tvp = NULL; 6241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else { 6251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tv.tv_sec = timeout_secs; 6261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tv.tv_usec = 0; 6271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tvp = &tv; 6281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); 6311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ret < 0) { 6321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[100]; 6331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 6351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * We have to clear the select masks, because we return. 6361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * We have to return, because the mainloop checks for the flags 6371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * set by the signal handlers. 6381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 6391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(*readsetp, 0, *nallocp); 6401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(*writesetp, 0, *nallocp); 6411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (errno == EINTR) 6431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 6441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Note: we might still have data in the buffers. */ 6451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); 6461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&stderr_buffer, buf, strlen(buf)); 6471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood quit_pending = 1; 6481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (ret == 0) 6491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood server_alive_check(); 6501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 6531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) 6541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Flush stdout and stderr buffers. */ 6561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(bout) > 0) 6571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood atomicio(vwrite, fileno(stdout), buffer_ptr(bout), 6581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_len(bout)); 6591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(berr) > 0) 6601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood atomicio(vwrite, fileno(stderr), buffer_ptr(berr), 6611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_len(berr)); 6621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 6641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 6661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Free (and clear) the buffer to reduce the amount of data that gets 6671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * written to swap. 6681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 6691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(bin); 6701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(bout); 6711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(berr); 6721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Send the suspend signal to the program itself. */ 6741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kill(getpid(), SIGTSTP); 6751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Reset window sizes in case they have changed */ 6771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood received_window_change_signal = 1; 6781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* OK, we have been continued by the user. Reinitialize buffers. */ 6801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(bin); 6811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(bout); 6821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(berr); 6831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 6851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 6881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_process_net_input(fd_set *readset) 6891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int len, cont = 0; 6911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[SSH_IOBUFSZ]; 6921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 6941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Read input from the server, and add any such data to the buffer of 6951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the packet subsystem. 6961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 6971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (FD_ISSET(connection_in, readset)) { 6981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Read as much as possible. */ 6991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = roaming_read(connection_in, buf, sizeof(buf), &cont); 7001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len == 0 && cont == 0) { 7011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 7021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Received EOF. The remote host has closed the 7031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * connection. 7041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 7051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf, sizeof buf, 7061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Connection to %.300s closed by remote host.\r\n", 7071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood host); 7081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&stderr_buffer, buf, strlen(buf)); 7091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood quit_pending = 1; 7101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 7111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 7131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * There is a kernel bug on Solaris that causes select to 7141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * sometimes wake up even though there is no data available. 7151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 7161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len < 0 && 7171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)) 7181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = 0; 7191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len < 0) { 7211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 7221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * An error has encountered. Perhaps there is a 7231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * network problem. 7241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 7251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf, sizeof buf, 7261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Read from remote host %.300s: %.100s\r\n", 7271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood host, strerror(errno)); 7281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&stderr_buffer, buf, strlen(buf)); 7291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood quit_pending = 1; 7301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 7311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_process_incoming(buf, len); 7331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 7351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 7371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_status_confirm(int type, Channel *c, void *ctx) 7381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 7391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx; 7401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char errmsg[256]; 7411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int tochan; 7421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 7441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If a TTY was explicitly requested, then a failure to allocate 7451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * one is fatal. 7461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 7471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cr->action == CONFIRM_TTY && 7481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (options.request_tty == REQUEST_TTY_FORCE || 7491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.request_tty == REQUEST_TTY_YES)) 7501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cr->action = CONFIRM_CLOSE; 7511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* XXX supress on mux _client_ quietmode */ 7531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tochan = options.log_level >= SYSLOG_LEVEL_ERROR && 7541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE; 7551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (type == SSH2_MSG_CHANNEL_SUCCESS) { 7571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("%s request accepted on channel %d", 7581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cr->request_type, c->self); 7591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (type == SSH2_MSG_CHANNEL_FAILURE) { 7601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (tochan) { 7611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(errmsg, sizeof(errmsg), 7621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "%s request failed\r\n", cr->request_type); 7631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 7641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(errmsg, sizeof(errmsg), 7651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "%s request failed on channel %d", 7661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cr->request_type, c->self); 7671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* If error occurred on primary session channel, then exit */ 7691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cr->action == CONFIRM_CLOSE && c->self == session_ident) 7701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s", errmsg); 7711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 7721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If error occurred on mux client, append to 7731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * their stderr. 7741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 7751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (tochan) { 7761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&c->extended, errmsg, 7771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlen(errmsg)); 7781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else 7791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s", errmsg); 7801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cr->action == CONFIRM_TTY) { 7811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 7821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If a TTY allocation error occurred, then arrange 7831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * for the correct TTY to leave raw mode. 7841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 7851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->self == session_ident) 7861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood leave_raw_mode(0); 7871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 7881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood mux_tty_alloc_failed(c); 7891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (cr->action == CONFIRM_CLOSE) { 7901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_read_failed(c); 7911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_write_failed(c); 7921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(cr); 7951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 7961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 7981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_abandon_status_confirm(Channel *c, void *ctx) 7991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(ctx); 8011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 8041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_expect_confirm(int id, const char *request, 8051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood enum confirm_action action) 8061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct channel_reply_ctx *cr = xmalloc(sizeof(*cr)); 8081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cr->request_type = request; 8101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cr->action = action; 8111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_register_status_confirm(id, client_status_confirm, 8131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_abandon_status_confirm, cr); 8141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 8171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_register_global_confirm(global_confirm_cb *cb, void *ctx) 8181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct global_confirm *gc, *last_gc; 8201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Coalesce identical callbacks */ 8221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood last_gc = TAILQ_LAST(&global_confirms, global_confirms); 8231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (last_gc && last_gc->cb == cb && last_gc->ctx == ctx) { 8241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (++last_gc->ref_count >= INT_MAX) 8251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: last_gc->ref_count = %d", 8261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__, last_gc->ref_count); 8271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 8281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gc = xmalloc(sizeof(*gc)); 8311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gc->cb = cb; 8321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gc->ctx = ctx; 8331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gc->ref_count = 1; 8341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_INSERT_TAIL(&global_confirms, gc, entry); 8351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 8381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodprocess_cmdline(void) 8391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood void (*handler)(int); 8411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *s, *cmd, *cancel_host; 8421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int delete = 0; 8431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int local = 0, remote = 0, dynamic = 0; 8441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int cancel_port; 8451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Forward fwd; 8461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bzero(&fwd, sizeof(fwd)); 8481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fwd.listen_host = fwd.connect_host = NULL; 8491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 8511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood handler = signal(SIGINT, SIG_IGN); 8521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cmd = s = read_passphrase("\r\nssh> ", RP_ECHO); 8531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s == NULL) 8541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 8551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (isspace(*s)) 8561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s++; 8571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*s == '-') 8581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s++; /* Skip cmdline '-', if any */ 8591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*s == '\0') 8601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 8611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*s == 'h' || *s == 'H' || *s == '?') { 8631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Commands:"); 8641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit(" -L[bind_address:]port:host:hostport " 8651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Request local forward"); 8661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit(" -R[bind_address:]port:host:hostport " 8671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Request remote forward"); 8681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit(" -D[bind_address:]port " 8691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Request dynamic forward"); 8701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit(" -KR[bind_address:]port " 8711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Cancel remote forward"); 8721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!options.permit_local_command) 8731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 8741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit(" !args " 8751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Execute local command"); 8761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 8771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*s == '!' && options.permit_local_command) { 8801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s++; 8811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ssh_local_cmd(s); 8821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 8831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*s == 'K') { 8861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood delete = 1; 8871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s++; 8881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*s == 'L') 8901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood local = 1; 8911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (*s == 'R') 8921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood remote = 1; 8931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (*s == 'D') 8941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dynamic = 1; 8951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else { 8961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Invalid command."); 8971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 8981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((local || dynamic) && delete) { 9011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Not supported."); 9021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 9031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (remote && delete && !compat20) { 9051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Not supported for SSH protocol version 1."); 9061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 9071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (isspace(*++s)) 9101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ; 9111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* XXX update list of forwards in options */ 9131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (delete) { 9141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cancel_port = 0; 9151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cancel_host = hpdelim(&s); /* may be NULL */ 9161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s != NULL) { 9171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cancel_port = a2port(s); 9181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cancel_host = cleanhostname(cancel_host); 9191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 9201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cancel_port = a2port(cancel_host); 9211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cancel_host = NULL; 9221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cancel_port <= 0) { 9241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Bad forwarding close port"); 9251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 9261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_request_rforward_cancel(cancel_host, cancel_port); 9281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 9291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!parse_forward(&fwd, s, dynamic, remote)) { 9301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Bad forwarding specification."); 9311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 9321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (local || dynamic) { 9341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (channel_setup_local_fwd_listener(fwd.listen_host, 9351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fwd.listen_port, fwd.connect_host, 9361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fwd.connect_port, options.gateway_ports) < 0) { 9371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Port forwarding failed."); 9381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 9391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 9411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (channel_request_remote_forwarding(fwd.listen_host, 9421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fwd.listen_port, fwd.connect_host, 9431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fwd.connect_port) < 0) { 9441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Port forwarding failed."); 9451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto out; 9461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Forwarding port."); 9501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodout: 9531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGINT, handler); 9541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 9551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cmd) 9561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(cmd); 9571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fwd.listen_host != NULL) 9581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(fwd.listen_host); 9591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fwd.connect_host != NULL) 9601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(fwd.connect_host); 9611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 9641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Process the characters one by one, call with c==NULL for proto1 case. 9651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 9661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 9671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodprocess_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, 9681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *buf, int len) 9691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char string[1024]; 9711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pid_t pid; 9721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int bytes = 0; 9731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 9741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char ch; 9751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *s; 9761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int *escape_pendingp, escape_char; 9771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct escape_filter_ctx *efc; 9781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c == NULL) { 9801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_pendingp = &escape_pending1; 9811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char = escape_char1; 9821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 9831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->filter_ctx == NULL) 9841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 9851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood efc = (struct escape_filter_ctx *)c->filter_ctx; 9861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_pendingp = &efc->escape_pending; 9871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char = efc->escape_char; 9881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len <= 0) 9911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (0); 9921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < (u_int)len; i++) { 9941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Get one character at a time. */ 9951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ch = buf[i]; 9961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*escape_pendingp) { 9981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* We have previously seen an escape character. */ 9991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Clear the flag now. */ 10001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *escape_pendingp = 0; 10011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Process the escaped character. */ 10031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (ch) { 10041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case '.': 10051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Terminate the connection. */ 10061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(string, sizeof string, "%c.\r\n", 10071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char); 10081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(berr, string, strlen(string)); 10091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c && c->ctl_chan != -1) { 10111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_read_failed(c); 10121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_write_failed(c); 10131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 10141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else 10151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood quit_pending = 1; 10161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 10171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'Z' - 64: 10191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* XXX support this for mux clients */ 10201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c && c->ctl_chan != -1) { 10211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood noescape: 10221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(string, sizeof string, 10231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "%c%c escape not available to " 10241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "multiplexed sessions\r\n", 10251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char, ch); 10261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(berr, string, 10271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlen(string)); 10281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 10291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Suspend the program. Inform the user */ 10311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(string, sizeof string, 10321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "%c^Z [suspend ssh]\r\n", escape_char); 10331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(berr, string, strlen(string)); 10341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Restore terminal modes and suspend. */ 10361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_suspend_self(bin, bout, berr); 10371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* We have been continued. */ 10391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 10401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'B': 10421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) { 10431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(string, sizeof string, 10441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "%cB\r\n", escape_char); 10451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(berr, string, 10461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlen(string)); 10471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_request_start(session_ident, 10481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "break", 0); 10491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(1000); 10501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 10511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 10531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'R': 10551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) { 10561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (datafellows & SSH_BUG_NOREKEY) 10571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Server does not " 10581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "support re-keying"); 10591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 10601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood need_rekeying = 1; 10611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 10631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case '&': 10651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c && c->ctl_chan != -1) 10661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto noescape; 10671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 10681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Detach the program (continue to serve 10691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * connections, but put in background and no 10701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * more new connections). 10711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 10721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Restore tty modes. */ 10731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood leave_raw_mode( 10741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.request_tty == REQUEST_TTY_FORCE); 10751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Stop listening for new connections. */ 10771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_stop_listening(); 10781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(string, sizeof string, 10801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "%c& [backgrounded]\n", escape_char); 10811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(berr, string, strlen(string)); 10821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Fork into background. */ 10841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pid = fork(); 10851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pid < 0) { 10861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("fork: %.100s", strerror(errno)); 10871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 10881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pid != 0) { /* This is the parent. */ 10901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* The parent just exits. */ 10911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(0); 10921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* The child continues serving connections. */ 10941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) { 10951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(bin, "\004", 1); 10961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* fake EOF on stdin */ 10971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 10981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (!stdin_eof) { 10991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 11001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Sending SSH_CMSG_EOF alone does not 11011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * always appear to be enough. So we 11021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * try to send an EOF character first. 11031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 11041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH_CMSG_STDIN_DATA); 11051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string("\004", 1); 11061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 11071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Close stdin. */ 11081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood stdin_eof = 1; 11091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(bin) == 0) { 11101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH_CMSG_EOF); 11111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 11121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 11151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case '?': 11171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c && c->ctl_chan != -1) { 11181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(string, sizeof string, 11191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood"%c?\r\n\ 11201305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodSupported escape sequences:\r\n\ 11211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood %c. - terminate session\r\n\ 11221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood %cB - send a BREAK to the remote system\r\n\ 11231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood %cR - Request rekey (SSH protocol 2 only)\r\n\ 11241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood %c# - list forwarded connections\r\n\ 11251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood %c? - this message\r\n\ 11261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood %c%c - send the escape character by typing it twice\r\n\ 11271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood(Note that escapes are only recognized immediately after newline.)\r\n", 11281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char, escape_char, 11291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char, escape_char, 11301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char, escape_char, 11311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char, escape_char); 11321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 11331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(string, sizeof string, 11341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood"%c?\r\n\ 11351305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodSupported escape sequences:\r\n\ 11361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood %c. - terminate connection (and any multiplexed sessions)\r\n\ 11371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood %cB - send a BREAK to the remote system\r\n\ 11381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood %cC - open a command line\r\n\ 11391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood %cR - Request rekey (SSH protocol 2 only)\r\n\ 11401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood %c^Z - suspend ssh\r\n\ 11411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood %c# - list forwarded connections\r\n\ 11421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood %c& - background ssh (when waiting for connections to terminate)\r\n\ 11431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood %c? - this message\r\n\ 11441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood %c%c - send the escape character by typing it twice\r\n\ 11451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood(Note that escapes are only recognized immediately after newline.)\r\n", 11461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char, escape_char, 11471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char, escape_char, 11481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char, escape_char, 11491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char, escape_char, 11501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char, escape_char, 11511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char); 11521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(berr, string, strlen(string)); 11541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 11551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case '#': 11571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(string, sizeof string, "%c#\r\n", 11581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char); 11591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(berr, string, strlen(string)); 11601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s = channel_open_message(); 11611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(berr, s, strlen(s)); 11621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s); 11631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 11641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'C': 11661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c && c->ctl_chan != -1) 11671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto noescape; 11681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood process_cmdline(); 11691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 11701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 11721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ch != escape_char) { 11731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(bin, escape_char); 11741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bytes++; 11751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Escaped characters fall through here */ 11771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 11781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 11801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 11811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The previous character was not an escape char. 11821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Check if this is an escape. 11831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 11841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (last_was_cr && ch == escape_char) { 11851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 11861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * It is. Set the flag and continue to 11871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * next character. 11881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 11891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *escape_pendingp = 1; 11901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 11911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 11951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Normal character. Record whether it was a newline, 11961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * and append it to the buffer. 11971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 11981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood last_was_cr = (ch == '\r' || ch == '\n'); 11991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(bin, ch); 12001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bytes++; 12011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return bytes; 12031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 12041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 12061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_process_input(fd_set *readset) 12071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 12081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int len; 12091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[SSH_IOBUFSZ]; 12101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Read input from stdin. */ 12121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (FD_ISSET(fileno(stdin), readset)) { 12131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Read as much as possible. */ 12141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = read(fileno(stdin), buf, sizeof(buf)); 12151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len < 0 && 12161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)) 12171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; /* we'll try again later */ 12181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len <= 0) { 12191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 12201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Received EOF or error. They are treated 12211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * similarly, except that an error message is printed 12221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * if it was an error condition. 12231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 12241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len < 0) { 12251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf, sizeof buf, "read: %.100s\r\n", 12261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strerror(errno)); 12271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&stderr_buffer, buf, strlen(buf)); 12281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Mark that we have seen EOF. */ 12301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood stdin_eof = 1; 12311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 12321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Send an EOF message to the server unless there is 12331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * data in the buffer. If there is data in the 12341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * buffer, no message will be sent now. Code 12351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * elsewhere will send the EOF when the buffer 12361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * becomes empty if stdin_eof is set. 12371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 12381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&stdin_buffer) == 0) { 12391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH_CMSG_EOF); 12401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 12411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (escape_char1 == SSH_ESCAPECHAR_NONE) { 12431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 12441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Normal successful read, and no escape character. 12451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Just append the data to buffer. 12461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 12471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&stdin_buffer, buf, len); 12481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 12491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 12501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Normal, successful read. But we have an escape 12511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * character and have to process the characters one 12521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * by one. 12531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 12541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (process_escapes(NULL, &stdin_buffer, 12551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &stdout_buffer, &stderr_buffer, buf, len) == -1) 12561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 12571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 12601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 12621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_process_output(fd_set *writeset) 12631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 12641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int len; 12651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[100]; 12661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Write buffered output to stdout. */ 12681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (FD_ISSET(fileno(stdout), writeset)) { 12691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Write as much data as possible. */ 12701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = write(fileno(stdout), buffer_ptr(&stdout_buffer), 12711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_len(&stdout_buffer)); 12721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len <= 0) { 12731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (errno == EINTR || errno == EAGAIN || 12741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood errno == EWOULDBLOCK) 12751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = 0; 12761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else { 12771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 12781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * An error or EOF was encountered. Put an 12791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * error message to stderr buffer. 12801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 12811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf, sizeof buf, 12821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "write stdout: %.50s\r\n", strerror(errno)); 12831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&stderr_buffer, buf, strlen(buf)); 12841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood quit_pending = 1; 12851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 12861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Consume printed data from the buffer. */ 12891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_consume(&stdout_buffer, len); 12901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Write buffered output to stderr. */ 12921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (FD_ISSET(fileno(stderr), writeset)) { 12931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Write as much data as possible. */ 12941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = write(fileno(stderr), buffer_ptr(&stderr_buffer), 12951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_len(&stderr_buffer)); 12961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len <= 0) { 12971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (errno == EINTR || errno == EAGAIN || 12981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood errno == EWOULDBLOCK) 12991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = 0; 13001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else { 13011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 13021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * EOF or error, but can't even print 13031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * error message. 13041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 13051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood quit_pending = 1; 13061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 13071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Consume printed characters from the buffer. */ 13101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_consume(&stderr_buffer, len); 13111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 13131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 13151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Get packets from the connection input buffer, and process them as long as 13161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * there are packets available. 13171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 13181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Any unknown packets received during the actual 13191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * session cause the session to terminate. This is 13201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * intended to make debugging easier since no 13211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * confirmations are sent. Any compatible protocol 13221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * extensions must be negotiated during the 13231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * preparatory phase. 13241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 13251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 13271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_process_buffered_input_packets(void) 13281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 13291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_run(DISPATCH_NONBLOCK, &quit_pending, 13301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood compat20 ? xxx_kex : NULL); 13311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 13321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* scan buf[] for '~' before sending data to the peer */ 13341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Helper: allocate a new escape_filter_ctx and fill in its escape char */ 13361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid * 13371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_new_escape_filter_ctx(int escape_char) 13381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 13391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct escape_filter_ctx *ret; 13401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = xmalloc(sizeof(*ret)); 13421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret->escape_pending = 0; 13431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret->escape_char = escape_char; 13441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (void *)ret; 13451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 13461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Free the escape filter context on channel free */ 13481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 13491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_filter_cleanup(int cid, void *ctx) 13501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 13511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(ctx); 13521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 13531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 13551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_simple_escape_filter(Channel *c, char *buf, int len) 13561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 13571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->extended_usage != CHAN_EXTENDED_WRITE) 13581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 13591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return process_escapes(c, &c->input, &c->output, &c->extended, 13611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buf, len); 13621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 13631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 13651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_channel_closed(int id, void *arg) 13661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 13671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_cancel_cleanup(id); 13681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_closed = 1; 13691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 13701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 13711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 13731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Implements the interactive session with the server. This is called after 13741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the user has been authenticated, and a command has been started on the 13751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character 13761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * used as an escape character for terminating or suspending the session. 13771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 13781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 13801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) 13811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 13821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fd_set *readset = NULL, *writeset = NULL; 13831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood double start_time, total_time; 13841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int max_fd = 0, max_fd2 = 0, len, rekeying = 0; 13851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int64_t ibytes, obytes; 13861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int nalloc = 0; 13871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[100]; 13881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Entering interactive session."); 13901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood start_time = get_current_time(); 13921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Initialize variables. */ 13941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_pending1 = 0; 13951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood last_was_cr = 1; 13961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit_status = -1; 13971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood stdin_eof = 0; 13981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_high = 64 * 1024; 13991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood connection_in = packet_get_connection_in(); 14001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood connection_out = packet_get_connection_out(); 14011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max_fd = MAX(connection_in, connection_out); 14021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!compat20) { 14041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* enable nonblocking unless tty */ 14051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!isatty(fileno(stdin))) 14061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood set_nonblock(fileno(stdin)); 14071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!isatty(fileno(stdout))) 14081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood set_nonblock(fileno(stdout)); 14091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!isatty(fileno(stderr))) 14101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood set_nonblock(fileno(stderr)); 14111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max_fd = MAX(max_fd, fileno(stdin)); 14121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max_fd = MAX(max_fd, fileno(stdout)); 14131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max_fd = MAX(max_fd, fileno(stderr)); 14141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood quit_pending = 0; 14161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char1 = escape_char_arg; 14171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Initialize buffers. */ 14191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&stdin_buffer); 14201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&stdout_buffer); 14211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&stderr_buffer); 14221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_init_dispatch(); 14241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 14261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Set signal handlers, (e.g. to restore non-blocking mode) 14271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * but don't overwrite SIG_IGN, matches behaviour from rsh(1) 14281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 14291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 14301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGHUP, signal_handler); 14311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (signal(SIGINT, SIG_IGN) != SIG_IGN) 14321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGINT, signal_handler); 14331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) 14341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGQUIT, signal_handler); 14351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 14361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGTERM, signal_handler); 14371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGWINCH, window_change_handler); 14381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (have_pty) 14401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 14411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) { 14431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_ident = ssh2_chan_id; 14441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (session_ident != -1) { 14451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (escape_char_arg != SSH_ESCAPECHAR_NONE) { 14461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_register_filter(session_ident, 14471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_simple_escape_filter, NULL, 14481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_filter_cleanup, 14491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_new_escape_filter_ctx( 14501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood escape_char_arg)); 14511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_register_cleanup(session_ident, 14531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_channel_closed, 0); 14541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 14561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Check if we should immediately send eof on stdin. */ 14571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_check_initial_eof_on_stdin(); 14581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Main loop of the client for the interactive session mode. */ 14611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (!quit_pending) { 14621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Process buffered packets sent by the server. */ 14641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_process_buffered_input_packets(); 14651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20 && session_closed && !channel_still_open()) 14671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 14681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rekeying = (xxx_kex != NULL && !xxx_kex->done); 14701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (rekeying) { 14721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("rekeying in progress"); 14731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 14741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 14751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Make packets of buffered stdin data, and buffer 14761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * them for sending to the server. 14771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 14781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!compat20) 14791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_make_packets_from_stdin_data(); 14801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 14821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Make packets from buffered channel data, and 14831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * enqueue them for sending to the server. 14841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 14851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (packet_not_very_much_data_to_write()) 14861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_output_poll(); 14871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 14891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Check if the window size has changed, and buffer a 14901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * message about it to the server if so. 14911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 14921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_check_window_change(); 14931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (quit_pending) 14951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 14961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 14981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Wait until we have something to do (something becomes 14991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * available on one of the descriptors). 15001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 15011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max_fd2 = max_fd; 15021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_wait_until_can_do_something(&readset, &writeset, 15031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &max_fd2, &nalloc, rekeying); 15041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (quit_pending) 15061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 15071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Do channel operations unless rekeying in progress. */ 15091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!rekeying) { 15101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_after_select(readset, writeset); 15111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (need_rekeying || packet_need_rekeying()) { 15121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("need rekeying"); 15131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xxx_kex->done = 0; 15141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex_send_kexinit(xxx_kex); 15151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood need_rekeying = 0; 15161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Buffer input from the connection. */ 15201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_process_net_input(readset); 15211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (quit_pending) 15231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 15241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!compat20) { 15261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Buffer data from stdin */ 15271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_process_input(readset); 15281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 15291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Process output to stdout and stderr. Output to 15301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the connection is processed elsewhere (above). 15311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 15321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_process_output(writeset); 15331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (session_resumed) { 15361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood connection_in = packet_get_connection_in(); 15371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood connection_out = packet_get_connection_out(); 15381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max_fd = MAX(max_fd, connection_out); 15391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood max_fd = MAX(max_fd, connection_in); 15401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_resumed = 0; 15411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 15441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Send as much buffered packet data as possible to the 15451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * sender. 15461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 15471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (FD_ISSET(connection_out, writeset)) 15481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_write_poll(); 15491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 15511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If we are a backgrounded control master, and the 15521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * timeout has expired without any active client 15531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * connections, then quit. 15541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 15551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (control_persist_exit_time > 0) { 15561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (time(NULL) >= control_persist_exit_time) { 15571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("ControlPersist timeout expired"); 15581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 15591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (readset) 15631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(readset); 15641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (writeset) 15651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(writeset); 15661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Terminate the session. */ 15681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Stop watching for window change. */ 15701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGWINCH, SIG_DFL); 15711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) { 15731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_DISCONNECT); 15741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(SSH2_DISCONNECT_BY_APPLICATION); 15751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring("disconnected by user"); 15761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(""); /* language tag */ 15771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 15781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_write_wait(); 15791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_free_all(); 15821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (have_pty) 15841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 15851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* restore blocking io */ 15871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!isatty(fileno(stdin))) 15881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood unset_nonblock(fileno(stdin)); 15891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!isatty(fileno(stdout))) 15901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood unset_nonblock(fileno(stdout)); 15911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!isatty(fileno(stderr))) 15921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood unset_nonblock(fileno(stderr)); 15931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 15951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If there was no shell or command requested, there will be no remote 15961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * exit status to be returned. In that case, clear error code if the 15971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * connection was deliberately terminated at this end. 15981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 15991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (no_shell_flag && received_signal == SIGTERM) { 16001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood received_signal = 0; 16011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit_status = 0; 16021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (received_signal) 16051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Killed by signal %d.", (int) received_signal); 16061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 16081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * In interactive mode (with pseudo tty) display a message indicating 16091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * that the connection has been closed. 16101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 16111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) { 16121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf, sizeof buf, 16131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Connection to %.64s closed.\r\n", host); 16141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&stderr_buffer, buf, strlen(buf)); 16151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Output any buffered data for stdout. */ 16181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&stdout_buffer) > 0) { 16191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = atomicio(vwrite, fileno(stdout), 16201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&stdout_buffer), buffer_len(&stdout_buffer)); 16211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len < 0 || (u_int)len != buffer_len(&stdout_buffer)) 16221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Write failed flushing stdout buffer."); 16231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 16241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_consume(&stdout_buffer, len); 16251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Output any buffered data for stderr. */ 16281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&stderr_buffer) > 0) { 16291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = atomicio(vwrite, fileno(stderr), 16301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&stderr_buffer), buffer_len(&stderr_buffer)); 16311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len < 0 || (u_int)len != buffer_len(&stderr_buffer)) 16321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Write failed flushing stderr buffer."); 16331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 16341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_consume(&stderr_buffer, len); 16351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Clear and free any buffers. */ 16381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(buf, 0, sizeof(buf)); 16391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&stdin_buffer); 16401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&stdout_buffer); 16411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&stderr_buffer); 16421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Report bytes transferred, and transfer rates. */ 16441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood total_time = get_current_time() - start_time; 16451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes); 16461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes); 16471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds", 16481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (unsigned long long)obytes, (unsigned long long)ibytes, total_time); 16491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (total_time > 0) 16501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood verbose("Bytes per second: sent %.1f, received %.1f", 16511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood obytes / total_time, ibytes / total_time); 16521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Return the exit status of the program. */ 16531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Exit status %d", exit_status); 16541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return exit_status; 16551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 16561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*********/ 16581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 16601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_input_stdout_data(int type, u_int32_t seq, void *ctxt) 16611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 16621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int data_len; 16631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *data = packet_get_string(&data_len); 16641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 16651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&stdout_buffer, data, data_len); 16661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(data, 0, data_len); 16671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(data); 16681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 16691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 16701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_input_stderr_data(int type, u_int32_t seq, void *ctxt) 16711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 16721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int data_len; 16731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *data = packet_get_string(&data_len); 16741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 16751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&stderr_buffer, data, data_len); 16761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(data, 0, data_len); 16771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(data); 16781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 16791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 16801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_input_exit_status(int type, u_int32_t seq, void *ctxt) 16811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 16821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit_status = packet_get_int(); 16831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 16841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Acknowledge the exit. */ 16851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH_CMSG_EXIT_CONFIRMATION); 16861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 16871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 16881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Must wait for packet to be sent since we are 16891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * exiting the loop. 16901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 16911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_write_wait(); 16921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Flag that we want to exit. */ 16931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood quit_pending = 1; 16941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 16951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 16961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_input_agent_open(int type, u_int32_t seq, void *ctxt) 16971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 16981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Channel *c = NULL; 16991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int remote_id, sock; 17001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Read the remote channel number from the message. */ 17021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood remote_id = packet_get_int(); 17031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 17041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 17061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Get a connection to the local authentication agent (this may again 17071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * get forwarded). 17081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 17091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sock = ssh_get_authentication_socket(); 17101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 17121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If we could not connect the agent, send an error message back to 17131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the server. This should never happen unless the agent dies, 17141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * because authentication forwarding is only enabled if we have an 17151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * agent. 17161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 17171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sock >= 0) { 17181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c = channel_new("", SSH_CHANNEL_OPEN, sock, sock, 17191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood -1, 0, 0, 0, "authentication agent connection", 1); 17201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->remote_id = remote_id; 17211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->force_drain = 1; 17221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 17231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c == NULL) { 17241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); 17251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(remote_id); 17261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 17271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Send a confirmation to the remote host. */ 17281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Forwarding authentication connection."); 17291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); 17301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(remote_id); 17311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(c->self); 17321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 17331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 17341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 17351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Channel * 17371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_request_forwarded_tcpip(const char *request_type, int rchan) 17381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 17391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Channel *c = NULL; 17401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *listen_address, *originator_address; 17411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_short listen_port, originator_port; 17421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Get rest of the packet */ 17441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood listen_address = packet_get_string(NULL); 17451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood listen_port = packet_get_int(); 17461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood originator_address = packet_get_string(NULL); 17471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood originator_port = packet_get_int(); 17481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 17491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("client_request_forwarded_tcpip: listen %s port %d, " 17511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "originator %s port %d", listen_address, listen_port, 17521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood originator_address, originator_port); 17531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c = channel_connect_by_listen_address(listen_port, 17551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "forwarded-tcpip", originator_address); 17561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(originator_address); 17581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(listen_address); 17591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return c; 17601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 17611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Channel * 17631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_request_x11(const char *request_type, int rchan) 17641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 17651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Channel *c = NULL; 17661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *originator; 17671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_short originator_port; 17681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int sock; 17691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!options.forward_x11) { 17711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Warning: ssh server tried X11 forwarding."); 17721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Warning: this is probably a break-in attempt by a " 17731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "malicious server."); 17741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 17751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 17761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (x11_refuse_time != 0 && time(NULL) >= x11_refuse_time) { 17771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood verbose("Rejected X11 connection after ForwardX11Timeout " 17781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "expired"); 17791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 17801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 17811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood originator = packet_get_string(NULL); 17821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (datafellows & SSH_BUG_X11FWD) { 17831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("buggy server: x11 request w/o originator_port"); 17841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood originator_port = 0; 17851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 17861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood originator_port = packet_get_int(); 17871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 17881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 17891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* XXX check permission */ 17901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("client_request_x11: request from %s %d", originator, 17911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood originator_port); 17921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(originator); 17931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sock = x11_connect_display(); 17941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sock < 0) 17951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 17961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c = channel_new("x11", 17971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_CHANNEL_X11_OPEN, sock, sock, -1, 17981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); 17991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->force_drain = 1; 18001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return c; 18011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 18021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Channel * 18041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_request_agent(const char *request_type, int rchan) 18051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 18061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Channel *c = NULL; 18071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int sock; 18081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!options.forward_agent) { 18101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Warning: ssh server tried agent forwarding."); 18111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Warning: this is probably a break-in attempt by a " 18121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "malicious server."); 18131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 18141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sock = ssh_get_authentication_socket(); 18161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sock < 0) 18171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 18181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c = channel_new("authentication agent connection", 18191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_CHANNEL_OPEN, sock, sock, -1, 18201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, 18211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "authentication agent connection", 1); 18221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->force_drain = 1; 18231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return c; 18241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 18251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 18271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_request_tun_fwd(int tun_mode, int local_tun, int remote_tun) 18281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 18291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Channel *c; 18301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int fd; 18311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (tun_mode == SSH_TUNMODE_NO) 18331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 18341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!compat20) { 18361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Tunnel forwarding is not supported for protocol 1"); 18371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 18381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Requesting tun unit %d in mode %d", local_tun, tun_mode); 18411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Open local tunnel device */ 18431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((fd = tun_open(local_tun, tun_mode)) == -1) { 18441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Tunnel device open failed."); 18451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 18461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, 18491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); 18501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->datagram = 1; 18511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if defined(SSH_TUN_FILTER) 18531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.tun_open == SSH_TUNMODE_POINTOPOINT) 18541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_register_filter(c->self, sys_tun_infilter, 18551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sys_tun_outfilter, NULL, NULL); 18561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 18571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_CHANNEL_OPEN); 18591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring("tun@openssh.com"); 18601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(c->self); 18611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(c->local_window_max); 18621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(c->local_maxpacket); 18631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(tun_mode); 18641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(remote_tun); 18651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 18661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 18681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 18691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* XXXX move to generic input handler */ 18711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 18721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_input_channel_open(int type, u_int32_t seq, void *ctxt) 18731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 18741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Channel *c = NULL; 18751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *ctype; 18761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int rchan; 18771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int rmaxpack, rwindow, len; 18781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ctype = packet_get_string(&len); 18801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rchan = packet_get_int(); 18811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rwindow = packet_get_int(); 18821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rmaxpack = packet_get_int(); 18831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("client_input_channel_open: ctype %s rchan %d win %d max %d", 18851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ctype, rchan, rwindow, rmaxpack); 18861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(ctype, "forwarded-tcpip") == 0) { 18881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c = client_request_forwarded_tcpip(ctype, rchan); 18891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(ctype, "x11") == 0) { 18901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c = client_request_x11(ctype, rchan); 18911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { 18921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c = client_request_agent(ctype, rchan); 18931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* XXX duplicate : */ 18951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c != NULL) { 18961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("confirm %s", ctype); 18971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->remote_id = rchan; 18981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->remote_window = rwindow; 18991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->remote_maxpacket = rmaxpack; 19001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->type != SSH_CHANNEL_CONNECTING) { 19011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); 19021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(c->remote_id); 19031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(c->self); 19041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(c->local_window); 19051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(c->local_maxpacket); 19061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 19071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 19091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("failure %s", ctype); 19101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); 19111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(rchan); 19121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); 19131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!(datafellows & SSH_BUG_OPENFAILURE)) { 19141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring("open failed"); 19151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(""); 19161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 19181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(ctype); 19201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 19211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 19221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_input_channel_req(int type, u_int32_t seq, void *ctxt) 19231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 19241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Channel *c = NULL; 19251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int exitval, id, reply, success = 0; 19261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *rtype; 19271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id = packet_get_int(); 19291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rtype = packet_get_string(NULL); 19301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood reply = packet_get_char(); 19311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("client_input_channel_req: channel %d rtype %s reply %d", 19331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id, rtype, reply); 19341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (id == -1) { 19361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("client_input_channel_req: request for channel -1"); 19371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if ((c = channel_lookup(id)) == NULL) { 19381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("client_input_channel_req: channel %d: " 19391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "unknown channel", id); 19401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(rtype, "eow@openssh.com") == 0) { 19411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 19421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_rcvd_eow(c); 19431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(rtype, "exit-status") == 0) { 19441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exitval = packet_get_int(); 19451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->ctl_chan != -1) { 19461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood mux_exit_message(c, exitval); 19471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 1; 19481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (id == session_ident) { 19491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Record exit value of local session */ 19501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 1; 19511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit_status = exitval; 19521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 19531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Probably for a mux channel that has already closed */ 19541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("%s: no sink for exit-status on channel %d", 19551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__, id); 19561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 19581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (reply && c != NULL) { 19601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(success ? 19611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); 19621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(c->remote_id); 19631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 19641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(rtype); 19661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 19671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 19681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_input_global_request(int type, u_int32_t seq, void *ctxt) 19691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 19701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *rtype; 19711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int want_reply; 19721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int success = 0; 19731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rtype = packet_get_string(NULL); 19751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood want_reply = packet_get_char(); 19761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("client_input_global_request: rtype %s want_reply %d", 19771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rtype, want_reply); 19781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (want_reply) { 19791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(success ? 19801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); 19811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 19821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_write_wait(); 19831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(rtype); 19851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 19861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 19881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_session2_setup(int id, int want_tty, int want_subsystem, 19891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env) 19901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 19911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int len; 19921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Channel *c = NULL; 19931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("%s: id %d", __func__, id); 19951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((c = channel_lookup(id)) == NULL) 19971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("client_session2_setup: channel %d: unknown channel", id); 19981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_set_interactive(want_tty, 20001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.ip_qos_interactive, options.ip_qos_bulk); 20011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (want_tty) { 20031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct winsize ws; 20041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Store window size in the packet. */ 20061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0) 20071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(&ws, 0, sizeof(ws)); 20081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_request_start(id, "pty-req", 1); 20101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_expect_confirm(id, "PTY allocation", CONFIRM_TTY); 20111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(term != NULL ? term : ""); 20121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int((u_int)ws.ws_col); 20131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int((u_int)ws.ws_row); 20141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int((u_int)ws.ws_xpixel); 20151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int((u_int)ws.ws_ypixel); 20161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (tiop == NULL) 20171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tiop = get_saved_tio(); 20181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tty_make_modes(-1, tiop); 20191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 20201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* XXX wait for reply */ 20211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->client_tty = 1; 20221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Transfer any environment variables from client to server */ 20251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.num_send_env != 0 && env != NULL) { 20261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i, j, matched; 20271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *name, *val; 20281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Sending environment."); 20301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; env[i] != NULL; i++) { 20311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Split */ 20321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood name = xstrdup(env[i]); 20331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((val = strchr(name, '=')) == NULL) { 20341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(name); 20351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 20361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *val++ = '\0'; 20381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood matched = 0; 20401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (j = 0; j < options.num_send_env; j++) { 20411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (match_pattern(name, options.send_env[j])) { 20421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood matched = 1; 20431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 20441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!matched) { 20471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("Ignored env %s", name); 20481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(name); 20491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 20501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Sending env %s = %s", name, val); 20531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_request_start(id, "env", 0); 20541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(name); 20551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(val); 20561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 20571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(name); 20581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = buffer_len(cmd); 20621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len > 0) { 20631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len > 900) 20641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = 900; 20651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (want_subsystem) { 20661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Sending subsystem: %.*s", 20671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len, (u_char*)buffer_ptr(cmd)); 20681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_request_start(id, "subsystem", 1); 20691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_expect_confirm(id, "subsystem", CONFIRM_CLOSE); 20701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 20711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Sending command: %.*s", 20721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len, (u_char*)buffer_ptr(cmd)); 20731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_request_start(id, "exec", 1); 20741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_expect_confirm(id, "exec", CONFIRM_CLOSE); 20751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); 20771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 20781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 20791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_request_start(id, "shell", 1); 20801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_expect_confirm(id, "shell", CONFIRM_CLOSE); 20811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 20821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 20841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 20861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_init_dispatch_20(void) 20871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 20881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_init(&dispatch_protocol_error); 20891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); 20911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); 20921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); 20931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); 20941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open); 20951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); 20961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); 20971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req); 20981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); 20991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm); 21001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm); 21011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request); 21021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* rekeying */ 21041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); 21051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* global request reply messages */ 21071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply); 21081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply); 21091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 21101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 21121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_init_dispatch_13(void) 21131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 21141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_init(NULL); 21151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close); 21161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation); 21171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data); 21181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); 21191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); 21201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open); 21211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status); 21221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data); 21231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data); 21241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ? 21261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &client_input_agent_open : &deny_input_open); 21271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ? 21281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &x11_input_open : &deny_input_open); 21291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 21301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 21321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_init_dispatch_15(void) 21331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 21341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_init_dispatch_13(); 21351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); 21361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose); 21371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 21381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 21401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_init_dispatch(void) 21411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 21421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) 21431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_init_dispatch_20(); 21441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (compat13) 21451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_init_dispatch_13(); 21461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 21471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_init_dispatch_15(); 21481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 21491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 21511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_stop_mux(void) 21521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 21531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.control_path != NULL && muxserver_sock != -1) 21541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood unlink(options.control_path); 21551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 21561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If we are in persist mode, signal that we should close when all 21571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * active channels are closed. 21581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 21591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.control_persist) { 21601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_closed = 1; 21611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood setproctitle("[stopped mux]"); 21621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 21631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 21641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* client specific fatal cleanup */ 21661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 21671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcleanup_exit(int i) 21681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 21691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 21701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood leave_non_blocking(); 21711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.control_path != NULL && muxserver_sock != -1) 21721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood unlink(options.control_path); 21731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ssh_kill_proxy_command(); 21741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood _exit(i); 21751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2176