Home | History | Annotate | Line # | Download | only in dist
serverloop.c revision 1.10
      1   1.8  christos /*	$NetBSD: serverloop.c,v 1.10 2015/04/03 23:58:19 christos Exp $	*/
      2  1.10  christos /* $OpenBSD: serverloop.c,v 1.178 2015/02/20 22:17:21 djm Exp $ */
      3   1.1  christos /*
      4   1.1  christos  * Author: Tatu Ylonen <ylo (at) cs.hut.fi>
      5   1.1  christos  * Copyright (c) 1995 Tatu Ylonen <ylo (at) cs.hut.fi>, Espoo, Finland
      6   1.1  christos  *                    All rights reserved
      7   1.1  christos  * Server main loop for handling the interactive session.
      8   1.1  christos  *
      9   1.1  christos  * As far as I am concerned, the code I have written for this software
     10   1.1  christos  * can be used freely for any purpose.  Any derived versions of this
     11   1.1  christos  * software must be clearly marked as such, and if the derived work is
     12   1.1  christos  * incompatible with the protocol description in the RFC file, it must be
     13   1.1  christos  * called by a name other than "ssh" or "Secure Shell".
     14   1.1  christos  *
     15   1.1  christos  * SSH2 support by Markus Friedl.
     16   1.1  christos  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
     17   1.1  christos  *
     18   1.1  christos  * Redistribution and use in source and binary forms, with or without
     19   1.1  christos  * modification, are permitted provided that the following conditions
     20   1.1  christos  * are met:
     21   1.1  christos  * 1. Redistributions of source code must retain the above copyright
     22   1.1  christos  *    notice, this list of conditions and the following disclaimer.
     23   1.1  christos  * 2. Redistributions in binary form must reproduce the above copyright
     24   1.1  christos  *    notice, this list of conditions and the following disclaimer in the
     25   1.1  christos  *    documentation and/or other materials provided with the distribution.
     26   1.1  christos  *
     27   1.1  christos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     28   1.1  christos  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     29   1.1  christos  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     30   1.1  christos  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     31   1.1  christos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     32   1.1  christos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     33   1.1  christos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     34   1.1  christos  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     35   1.1  christos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     36   1.1  christos  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     37   1.1  christos  */
     38   1.1  christos 
     39   1.2  christos #include "includes.h"
     40   1.8  christos __RCSID("$NetBSD: serverloop.c,v 1.10 2015/04/03 23:58:19 christos Exp $");
     41  1.10  christos #include <sys/param.h>	/* MIN MAX */
     42   1.1  christos #include <sys/types.h>
     43   1.1  christos #include <sys/wait.h>
     44   1.1  christos #include <sys/socket.h>
     45   1.1  christos #include <sys/time.h>
     46   1.1  christos #include <sys/queue.h>
     47   1.1  christos 
     48   1.1  christos #include <netinet/in.h>
     49   1.1  christos 
     50   1.1  christos #include <errno.h>
     51   1.1  christos #include <fcntl.h>
     52   1.1  christos #include <pwd.h>
     53   1.1  christos #include <signal.h>
     54   1.1  christos #include <string.h>
     55   1.1  christos #include <termios.h>
     56   1.1  christos #include <unistd.h>
     57   1.1  christos #include <stdarg.h>
     58   1.1  christos 
     59   1.1  christos #include "xmalloc.h"
     60   1.1  christos #include "packet.h"
     61   1.1  christos #include "buffer.h"
     62   1.1  christos #include "log.h"
     63   1.9  christos #include "misc.h"
     64   1.1  christos #include "servconf.h"
     65   1.1  christos #include "canohost.h"
     66   1.1  christos #include "sshpty.h"
     67   1.1  christos #include "channels.h"
     68   1.1  christos #include "compat.h"
     69   1.1  christos #include "ssh1.h"
     70   1.1  christos #include "ssh2.h"
     71   1.1  christos #include "key.h"
     72   1.1  christos #include "cipher.h"
     73   1.1  christos #include "kex.h"
     74   1.1  christos #include "hostfile.h"
     75   1.1  christos #include "auth.h"
     76   1.1  christos #include "session.h"
     77   1.1  christos #include "dispatch.h"
     78   1.1  christos #include "auth-options.h"
     79   1.1  christos #include "serverloop.h"
     80   1.3  christos #include "roaming.h"
     81  1.10  christos #include "ssherr.h"
     82   1.1  christos 
     83   1.1  christos extern ServerOptions options;
     84   1.1  christos 
     85   1.1  christos /* XXX */
     86   1.1  christos extern Authctxt *the_authctxt;
     87   1.1  christos extern int use_privsep;
     88   1.1  christos 
     89   1.1  christos static Buffer stdin_buffer;	/* Buffer for stdin data. */
     90   1.1  christos static Buffer stdout_buffer;	/* Buffer for stdout data. */
     91   1.1  christos static Buffer stderr_buffer;	/* Buffer for stderr data. */
     92   1.1  christos static int fdin;		/* Descriptor for stdin (for writing) */
     93   1.1  christos static int fdout;		/* Descriptor for stdout (for reading);
     94   1.1  christos 				   May be same number as fdin. */
     95   1.1  christos static int fderr;		/* Descriptor for stderr.  May be -1. */
     96   1.2  christos static u_long stdin_bytes = 0;	/* Number of bytes written to stdin. */
     97   1.2  christos static u_long stdout_bytes = 0;	/* Number of stdout bytes sent to client. */
     98   1.2  christos static u_long stderr_bytes = 0;	/* Number of stderr bytes sent to client. */
     99   1.2  christos static u_long fdout_bytes = 0;	/* Number of stdout bytes read from program. */
    100   1.1  christos static int stdin_eof = 0;	/* EOF message received from client. */
    101   1.1  christos static int fdout_eof = 0;	/* EOF encountered reading from fdout. */
    102   1.1  christos static int fderr_eof = 0;	/* EOF encountered readung from fderr. */
    103   1.1  christos static int fdin_is_tty = 0;	/* fdin points to a tty. */
    104   1.1  christos static int connection_in;	/* Connection to client (input). */
    105   1.1  christos static int connection_out;	/* Connection to client (output). */
    106   1.1  christos static int connection_closed = 0;	/* Connection to client closed. */
    107   1.1  christos static u_int buffer_high;	/* "Soft" max buffer size. */
    108   1.1  christos static int no_more_sessions = 0; /* Disallow further sessions. */
    109   1.1  christos 
    110   1.1  christos /*
    111   1.1  christos  * This SIGCHLD kludge is used to detect when the child exits.  The server
    112   1.1  christos  * will exit after that, as soon as forwarded connections have terminated.
    113   1.1  christos  */
    114   1.1  christos 
    115   1.1  christos static volatile sig_atomic_t child_terminated = 0;	/* The child has terminated. */
    116   1.1  christos 
    117   1.1  christos /* Cleanup on signals (!use_privsep case only) */
    118   1.1  christos static volatile sig_atomic_t received_sigterm = 0;
    119   1.1  christos 
    120   1.1  christos /* prototypes */
    121   1.1  christos static void server_init_dispatch(void);
    122   1.1  christos 
    123   1.1  christos /*
    124   1.2  christos  * Returns current time in seconds from Jan 1, 1970 with the maximum
    125   1.2  christos  * available resolution.
    126   1.2  christos  */
    127   1.2  christos 
    128   1.2  christos static double
    129   1.2  christos get_current_time(void)
    130   1.2  christos {
    131   1.2  christos 	struct timeval tv;
    132   1.2  christos 	gettimeofday(&tv, NULL);
    133   1.2  christos 	return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
    134   1.2  christos }
    135   1.2  christos 
    136   1.2  christos /*
    137   1.1  christos  * we write to this pipe if a SIGCHLD is caught in order to avoid
    138   1.1  christos  * the race between select() and child_terminated
    139   1.1  christos  */
    140   1.1  christos static int notify_pipe[2];
    141   1.1  christos static void
    142   1.1  christos notify_setup(void)
    143   1.1  christos {
    144   1.1  christos 	if (pipe(notify_pipe) < 0) {
    145   1.1  christos 		error("pipe(notify_pipe) failed %s", strerror(errno));
    146   1.4  christos 	} else if ((fcntl(notify_pipe[0], F_SETFD, FD_CLOEXEC) == -1) ||
    147   1.4  christos 	    (fcntl(notify_pipe[1], F_SETFD, FD_CLOEXEC) == -1)) {
    148   1.1  christos 		error("fcntl(notify_pipe, F_SETFD) failed %s", strerror(errno));
    149   1.1  christos 		close(notify_pipe[0]);
    150   1.1  christos 		close(notify_pipe[1]);
    151   1.1  christos 	} else {
    152   1.1  christos 		set_nonblock(notify_pipe[0]);
    153   1.1  christos 		set_nonblock(notify_pipe[1]);
    154   1.1  christos 		return;
    155   1.1  christos 	}
    156   1.1  christos 	notify_pipe[0] = -1;	/* read end */
    157   1.1  christos 	notify_pipe[1] = -1;	/* write end */
    158   1.1  christos }
    159   1.1  christos static void
    160   1.1  christos notify_parent(void)
    161   1.1  christos {
    162   1.1  christos 	if (notify_pipe[1] != -1)
    163   1.7  christos 		(void)write(notify_pipe[1], "", 1);
    164   1.1  christos }
    165   1.1  christos static void
    166   1.1  christos notify_prepare(fd_set *readset)
    167   1.1  christos {
    168   1.1  christos 	if (notify_pipe[0] != -1)
    169   1.1  christos 		FD_SET(notify_pipe[0], readset);
    170   1.1  christos }
    171   1.1  christos static void
    172   1.1  christos notify_done(fd_set *readset)
    173   1.1  christos {
    174   1.1  christos 	char c;
    175   1.1  christos 
    176   1.1  christos 	if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset))
    177   1.1  christos 		while (read(notify_pipe[0], &c, 1) != -1)
    178   1.1  christos 			debug2("notify_done: reading");
    179   1.1  christos }
    180   1.1  christos 
    181   1.1  christos /*ARGSUSED*/
    182   1.1  christos static void
    183   1.1  christos sigchld_handler(int sig)
    184   1.1  christos {
    185   1.1  christos 	int save_errno = errno;
    186   1.1  christos 	child_terminated = 1;
    187   1.1  christos 	signal(SIGCHLD, sigchld_handler);
    188   1.1  christos 	notify_parent();
    189   1.1  christos 	errno = save_errno;
    190   1.1  christos }
    191   1.1  christos 
    192   1.1  christos /*ARGSUSED*/
    193   1.1  christos static void
    194   1.1  christos sigterm_handler(int sig)
    195   1.1  christos {
    196   1.1  christos 	received_sigterm = sig;
    197   1.1  christos }
    198   1.1  christos 
    199   1.1  christos /*
    200   1.1  christos  * Make packets from buffered stderr data, and buffer it for sending
    201   1.1  christos  * to the client.
    202   1.1  christos  */
    203   1.1  christos static void
    204   1.1  christos make_packets_from_stderr_data(void)
    205   1.1  christos {
    206   1.1  christos 	u_int len;
    207   1.1  christos 
    208   1.1  christos 	/* Send buffered stderr data to the client. */
    209   1.1  christos 	while (buffer_len(&stderr_buffer) > 0 &&
    210   1.1  christos 	    packet_not_very_much_data_to_write()) {
    211   1.1  christos 		len = buffer_len(&stderr_buffer);
    212   1.1  christos 		if (packet_is_interactive()) {
    213   1.1  christos 			if (len > 512)
    214   1.1  christos 				len = 512;
    215   1.1  christos 		} else {
    216   1.1  christos 			/* Keep the packets at reasonable size. */
    217   1.1  christos 			if (len > packet_get_maxsize())
    218   1.1  christos 				len = packet_get_maxsize();
    219   1.1  christos 		}
    220   1.1  christos 		packet_start(SSH_SMSG_STDERR_DATA);
    221   1.1  christos 		packet_put_string(buffer_ptr(&stderr_buffer), len);
    222   1.1  christos 		packet_send();
    223   1.1  christos 		buffer_consume(&stderr_buffer, len);
    224   1.1  christos 		stderr_bytes += len;
    225   1.1  christos 	}
    226   1.1  christos }
    227   1.1  christos 
    228   1.1  christos /*
    229   1.1  christos  * Make packets from buffered stdout data, and buffer it for sending to the
    230   1.1  christos  * client.
    231   1.1  christos  */
    232   1.1  christos static void
    233   1.1  christos make_packets_from_stdout_data(void)
    234   1.1  christos {
    235   1.1  christos 	u_int len;
    236   1.1  christos 
    237   1.1  christos 	/* Send buffered stdout data to the client. */
    238   1.1  christos 	while (buffer_len(&stdout_buffer) > 0 &&
    239   1.1  christos 	    packet_not_very_much_data_to_write()) {
    240   1.1  christos 		len = buffer_len(&stdout_buffer);
    241   1.1  christos 		if (packet_is_interactive()) {
    242   1.1  christos 			if (len > 512)
    243   1.1  christos 				len = 512;
    244   1.1  christos 		} else {
    245   1.1  christos 			/* Keep the packets at reasonable size. */
    246   1.1  christos 			if (len > packet_get_maxsize())
    247   1.1  christos 				len = packet_get_maxsize();
    248   1.1  christos 		}
    249   1.1  christos 		packet_start(SSH_SMSG_STDOUT_DATA);
    250   1.1  christos 		packet_put_string(buffer_ptr(&stdout_buffer), len);
    251   1.1  christos 		packet_send();
    252   1.1  christos 		buffer_consume(&stdout_buffer, len);
    253   1.1  christos 		stdout_bytes += len;
    254   1.1  christos 	}
    255   1.1  christos }
    256   1.1  christos 
    257   1.1  christos static void
    258   1.1  christos client_alive_check(void)
    259   1.1  christos {
    260   1.1  christos 	int channel_id;
    261   1.1  christos 
    262   1.1  christos 	/* timeout, check to see how many we have had */
    263   1.3  christos 	if (packet_inc_alive_timeouts() > options.client_alive_count_max) {
    264   1.1  christos 		logit("Timeout, client not responding.");
    265   1.1  christos 		cleanup_exit(255);
    266   1.1  christos 	}
    267   1.1  christos 
    268   1.1  christos 	/*
    269   1.1  christos 	 * send a bogus global/channel request with "wantreply",
    270   1.1  christos 	 * we should get back a failure
    271   1.1  christos 	 */
    272   1.1  christos 	if ((channel_id = channel_find_open()) == -1) {
    273   1.1  christos 		packet_start(SSH2_MSG_GLOBAL_REQUEST);
    274   1.1  christos 		packet_put_cstring("keepalive (at) openssh.com");
    275   1.1  christos 		packet_put_char(1);	/* boolean: want reply */
    276   1.1  christos 	} else {
    277   1.1  christos 		channel_request_start(channel_id, "keepalive (at) openssh.com", 1);
    278   1.1  christos 	}
    279   1.1  christos 	packet_send();
    280   1.1  christos }
    281   1.1  christos 
    282   1.1  christos /*
    283   1.1  christos  * Sleep in select() until we can do something.  This will initialize the
    284   1.1  christos  * select masks.  Upon return, the masks will indicate which descriptors
    285   1.1  christos  * have data or can accept data.  Optionally, a maximum time can be specified
    286   1.1  christos  * for the duration of the wait (0 = infinite).
    287   1.1  christos  */
    288   1.1  christos static void
    289   1.1  christos wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
    290   1.7  christos     u_int *nallocp, u_int64_t max_time_milliseconds)
    291   1.1  christos {
    292   1.1  christos 	struct timeval tv, *tvp;
    293   1.1  christos 	int ret;
    294   1.5  christos 	time_t minwait_secs = 0;
    295   1.1  christos 	int client_alive_scheduled = 0;
    296   1.1  christos 
    297   1.5  christos 	/* Allocate and update select() masks for channel descriptors. */
    298   1.5  christos 	channel_prepare_select(readsetp, writesetp, maxfdp, nallocp,
    299   1.5  christos 	    &minwait_secs, 0);
    300   1.5  christos 
    301   1.5  christos 	if (minwait_secs != 0)
    302   1.5  christos 		max_time_milliseconds = MIN(max_time_milliseconds,
    303   1.5  christos 		    (u_int)minwait_secs * 1000);
    304   1.5  christos 
    305   1.1  christos 	/*
    306   1.1  christos 	 * if using client_alive, set the max timeout accordingly,
    307   1.1  christos 	 * and indicate that this particular timeout was for client
    308   1.1  christos 	 * alive by setting the client_alive_scheduled flag.
    309   1.1  christos 	 *
    310   1.1  christos 	 * this could be randomized somewhat to make traffic
    311   1.1  christos 	 * analysis more difficult, but we're not doing it yet.
    312   1.1  christos 	 */
    313   1.1  christos 	if (compat20 &&
    314   1.1  christos 	    max_time_milliseconds == 0 && options.client_alive_interval) {
    315   1.1  christos 		client_alive_scheduled = 1;
    316   1.9  christos 		max_time_milliseconds =
    317   1.9  christos 		    (u_int64_t)options.client_alive_interval * 1000;
    318   1.1  christos 	}
    319   1.1  christos 
    320   1.1  christos 	if (compat20) {
    321   1.1  christos #if 0
    322   1.1  christos 		/* wrong: bad condition XXX */
    323   1.1  christos 		if (channel_not_very_much_buffered_data())
    324   1.1  christos #endif
    325   1.1  christos 		FD_SET(connection_in, *readsetp);
    326   1.1  christos 	} else {
    327   1.1  christos 		/*
    328   1.1  christos 		 * Read packets from the client unless we have too much
    329   1.1  christos 		 * buffered stdin or channel data.
    330   1.1  christos 		 */
    331   1.1  christos 		if (buffer_len(&stdin_buffer) < buffer_high &&
    332   1.1  christos 		    channel_not_very_much_buffered_data())
    333   1.1  christos 			FD_SET(connection_in, *readsetp);
    334   1.1  christos 		/*
    335   1.1  christos 		 * If there is not too much data already buffered going to
    336   1.1  christos 		 * the client, try to get some more data from the program.
    337   1.1  christos 		 */
    338   1.1  christos 		if (packet_not_very_much_data_to_write()) {
    339   1.1  christos 			if (!fdout_eof)
    340   1.1  christos 				FD_SET(fdout, *readsetp);
    341   1.1  christos 			if (!fderr_eof)
    342   1.1  christos 				FD_SET(fderr, *readsetp);
    343   1.1  christos 		}
    344   1.1  christos 		/*
    345   1.1  christos 		 * If we have buffered data, try to write some of that data
    346   1.1  christos 		 * to the program.
    347   1.1  christos 		 */
    348   1.1  christos 		if (fdin != -1 && buffer_len(&stdin_buffer) > 0)
    349   1.1  christos 			FD_SET(fdin, *writesetp);
    350   1.1  christos 	}
    351   1.1  christos 	notify_prepare(*readsetp);
    352   1.1  christos 
    353   1.1  christos 	/*
    354   1.1  christos 	 * If we have buffered packet data going to the client, mark that
    355   1.1  christos 	 * descriptor.
    356   1.1  christos 	 */
    357   1.1  christos 	if (packet_have_data_to_write())
    358   1.1  christos 		FD_SET(connection_out, *writesetp);
    359   1.1  christos 
    360   1.1  christos 	/*
    361   1.1  christos 	 * If child has terminated and there is enough buffer space to read
    362   1.1  christos 	 * from it, then read as much as is available and exit.
    363   1.1  christos 	 */
    364   1.1  christos 	if (child_terminated && packet_not_very_much_data_to_write())
    365   1.1  christos 		if (max_time_milliseconds == 0 || client_alive_scheduled)
    366   1.1  christos 			max_time_milliseconds = 100;
    367   1.1  christos 
    368   1.1  christos 	if (max_time_milliseconds == 0)
    369   1.1  christos 		tvp = NULL;
    370   1.1  christos 	else {
    371   1.1  christos 		tv.tv_sec = max_time_milliseconds / 1000;
    372   1.1  christos 		tv.tv_usec = 1000 * (max_time_milliseconds % 1000);
    373   1.1  christos 		tvp = &tv;
    374   1.1  christos 	}
    375   1.1  christos 
    376   1.1  christos 	/* Wait for something to happen, or the timeout to expire. */
    377   1.1  christos 	ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
    378   1.1  christos 
    379   1.1  christos 	if (ret == -1) {
    380   1.1  christos 		memset(*readsetp, 0, *nallocp);
    381   1.1  christos 		memset(*writesetp, 0, *nallocp);
    382   1.1  christos 		if (errno != EINTR)
    383   1.1  christos 			error("select: %.100s", strerror(errno));
    384   1.1  christos 	} else if (ret == 0 && client_alive_scheduled)
    385   1.1  christos 		client_alive_check();
    386   1.1  christos 
    387   1.1  christos 	notify_done(*readsetp);
    388   1.1  christos }
    389   1.1  christos 
    390   1.1  christos /*
    391   1.1  christos  * Processes input from the client and the program.  Input data is stored
    392   1.1  christos  * in buffers and processed later.
    393   1.1  christos  */
    394   1.1  christos static void
    395   1.1  christos process_input(fd_set *readset)
    396   1.1  christos {
    397   1.1  christos 	int len;
    398   1.1  christos 	char buf[16384];
    399   1.1  christos 
    400   1.1  christos 	/* Read and buffer any input data from the client. */
    401   1.1  christos 	if (FD_ISSET(connection_in, readset)) {
    402   1.3  christos 		int cont = 0;
    403   1.3  christos 		len = roaming_read(connection_in, buf, sizeof(buf), &cont);
    404   1.1  christos 		if (len == 0) {
    405   1.3  christos 			if (cont)
    406   1.3  christos 				return;
    407   1.1  christos 			verbose("Connection closed by %.100s",
    408   1.1  christos 			    get_remote_ipaddr());
    409   1.1  christos 			connection_closed = 1;
    410   1.1  christos 			if (compat20)
    411   1.1  christos 				return;
    412   1.1  christos 			cleanup_exit(255);
    413   1.1  christos 		} else if (len < 0) {
    414   1.1  christos 			if (errno != EINTR && errno != EAGAIN) {
    415   1.1  christos 				verbose("Read error from remote host "
    416   1.1  christos 				    "%.100s: %.100s",
    417   1.1  christos 				    get_remote_ipaddr(), strerror(errno));
    418   1.1  christos 				cleanup_exit(255);
    419   1.1  christos 			}
    420   1.1  christos 		} else {
    421   1.1  christos 			/* Buffer any received data. */
    422   1.1  christos 			packet_process_incoming(buf, len);
    423   1.2  christos 			fdout_bytes += len;
    424   1.1  christos 		}
    425   1.1  christos 	}
    426   1.1  christos 	if (compat20)
    427   1.1  christos 		return;
    428   1.1  christos 
    429   1.1  christos 	/* Read and buffer any available stdout data from the program. */
    430   1.1  christos 	if (!fdout_eof && FD_ISSET(fdout, readset)) {
    431   1.1  christos 		len = read(fdout, buf, sizeof(buf));
    432   1.1  christos 		if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
    433   1.1  christos 			/* do nothing */
    434   1.1  christos 		} else if (len <= 0) {
    435   1.1  christos 			fdout_eof = 1;
    436   1.1  christos 		} else {
    437   1.1  christos 			buffer_append(&stdout_buffer, buf, len);
    438   1.2  christos 			debug ("FD out now: %ld", fdout_bytes);
    439   1.1  christos 			fdout_bytes += len;
    440   1.1  christos 		}
    441   1.1  christos 	}
    442   1.1  christos 	/* Read and buffer any available stderr data from the program. */
    443   1.1  christos 	if (!fderr_eof && FD_ISSET(fderr, readset)) {
    444   1.1  christos 		len = read(fderr, buf, sizeof(buf));
    445   1.1  christos 		if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
    446   1.1  christos 			/* do nothing */
    447   1.1  christos 		} else if (len <= 0) {
    448   1.1  christos 			fderr_eof = 1;
    449   1.1  christos 		} else {
    450   1.1  christos 			buffer_append(&stderr_buffer, buf, len);
    451   1.1  christos 		}
    452   1.1  christos 	}
    453   1.1  christos }
    454   1.1  christos 
    455   1.1  christos /*
    456   1.1  christos  * Sends data from internal buffers to client program stdin.
    457   1.1  christos  */
    458   1.1  christos static void
    459   1.1  christos process_output(fd_set *writeset)
    460   1.1  christos {
    461   1.1  christos 	struct termios tio;
    462   1.1  christos 	u_char *data;
    463   1.1  christos 	u_int dlen;
    464   1.1  christos 	int len;
    465   1.1  christos 
    466   1.1  christos 	/* Write buffered data to program stdin. */
    467   1.1  christos 	if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) {
    468   1.1  christos 		data = buffer_ptr(&stdin_buffer);
    469   1.1  christos 		dlen = buffer_len(&stdin_buffer);
    470   1.1  christos 		len = write(fdin, data, dlen);
    471   1.1  christos 		if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
    472   1.1  christos 			/* do nothing */
    473   1.1  christos 		} else if (len <= 0) {
    474   1.1  christos 			if (fdin != fdout)
    475   1.1  christos 				close(fdin);
    476   1.1  christos 			else
    477   1.1  christos 				shutdown(fdin, SHUT_WR); /* We will no longer send. */
    478   1.1  christos 			fdin = -1;
    479   1.1  christos 		} else {
    480   1.1  christos 			/* Successful write. */
    481   1.1  christos 			if (fdin_is_tty && dlen >= 1 && data[0] != '\r' &&
    482   1.1  christos 			    tcgetattr(fdin, &tio) == 0 &&
    483   1.1  christos 			    !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
    484   1.1  christos 				/*
    485   1.1  christos 				 * Simulate echo to reduce the impact of
    486   1.1  christos 				 * traffic analysis
    487   1.1  christos 				 */
    488   1.1  christos 				packet_send_ignore(len);
    489   1.1  christos 				packet_send();
    490   1.1  christos 			}
    491   1.1  christos 			/* Consume the data from the buffer. */
    492   1.1  christos 			buffer_consume(&stdin_buffer, len);
    493   1.1  christos 			/* Update the count of bytes written to the program. */
    494   1.1  christos 			stdin_bytes += len;
    495   1.1  christos 		}
    496   1.1  christos 	}
    497   1.1  christos 	/* Send any buffered packet data to the client. */
    498   1.1  christos 	if (FD_ISSET(connection_out, writeset))
    499   1.2  christos 		stdin_bytes += packet_write_poll();
    500   1.1  christos }
    501   1.1  christos 
    502   1.1  christos /*
    503   1.1  christos  * Wait until all buffered output has been sent to the client.
    504   1.1  christos  * This is used when the program terminates.
    505   1.1  christos  */
    506   1.1  christos static void
    507   1.1  christos drain_output(void)
    508   1.1  christos {
    509   1.1  christos 	/* Send any buffered stdout data to the client. */
    510   1.1  christos 	if (buffer_len(&stdout_buffer) > 0) {
    511   1.1  christos 		packet_start(SSH_SMSG_STDOUT_DATA);
    512   1.1  christos 		packet_put_string(buffer_ptr(&stdout_buffer),
    513   1.1  christos 				  buffer_len(&stdout_buffer));
    514   1.1  christos 		packet_send();
    515   1.1  christos 		/* Update the count of sent bytes. */
    516   1.1  christos 		stdout_bytes += buffer_len(&stdout_buffer);
    517   1.1  christos 	}
    518   1.1  christos 	/* Send any buffered stderr data to the client. */
    519   1.1  christos 	if (buffer_len(&stderr_buffer) > 0) {
    520   1.1  christos 		packet_start(SSH_SMSG_STDERR_DATA);
    521   1.1  christos 		packet_put_string(buffer_ptr(&stderr_buffer),
    522   1.1  christos 				  buffer_len(&stderr_buffer));
    523   1.1  christos 		packet_send();
    524   1.1  christos 		/* Update the count of sent bytes. */
    525   1.1  christos 		stderr_bytes += buffer_len(&stderr_buffer);
    526   1.1  christos 	}
    527   1.1  christos 	/* Wait until all buffered data has been written to the client. */
    528   1.1  christos 	packet_write_wait();
    529   1.1  christos }
    530   1.1  christos 
    531   1.1  christos static void
    532   1.1  christos process_buffered_input_packets(void)
    533   1.1  christos {
    534  1.10  christos 	dispatch_run(DISPATCH_NONBLOCK, NULL, active_state);
    535   1.1  christos }
    536   1.1  christos 
    537   1.1  christos /*
    538   1.1  christos  * Performs the interactive session.  This handles data transmission between
    539   1.1  christos  * the client and the program.  Note that the notion of stdin, stdout, and
    540   1.1  christos  * stderr in this function is sort of reversed: this function writes to
    541   1.1  christos  * stdin (of the child program), and reads from stdout and stderr (of the
    542   1.1  christos  * child program).
    543   1.1  christos  */
    544   1.1  christos void
    545   1.1  christos server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
    546   1.1  christos {
    547   1.1  christos 	fd_set *readset = NULL, *writeset = NULL;
    548   1.1  christos 	int max_fd = 0;
    549   1.1  christos 	u_int nalloc = 0;
    550   1.1  christos 	int wait_status;	/* Status returned by wait(). */
    551   1.1  christos 	pid_t wait_pid;		/* pid returned by wait(). */
    552   1.1  christos 	int waiting_termination = 0;	/* Have displayed waiting close message. */
    553   1.7  christos 	u_int64_t max_time_milliseconds;
    554   1.1  christos 	u_int previous_stdout_buffer_bytes;
    555   1.1  christos 	u_int stdout_buffer_bytes;
    556   1.1  christos 	int type;
    557   1.1  christos 
    558   1.1  christos 	debug("Entering interactive session.");
    559   1.1  christos 
    560   1.1  christos 	/* Initialize the SIGCHLD kludge. */
    561   1.1  christos 	child_terminated = 0;
    562   1.1  christos 	signal(SIGCHLD, sigchld_handler);
    563   1.1  christos 
    564   1.1  christos 	if (!use_privsep) {
    565   1.1  christos 		signal(SIGTERM, sigterm_handler);
    566   1.1  christos 		signal(SIGINT, sigterm_handler);
    567   1.1  christos 		signal(SIGQUIT, sigterm_handler);
    568   1.1  christos 	}
    569   1.1  christos 
    570   1.1  christos 	/* Initialize our global variables. */
    571   1.1  christos 	fdin = fdin_arg;
    572   1.1  christos 	fdout = fdout_arg;
    573   1.1  christos 	fderr = fderr_arg;
    574   1.1  christos 
    575   1.1  christos 	/* nonblocking IO */
    576   1.1  christos 	set_nonblock(fdin);
    577   1.1  christos 	set_nonblock(fdout);
    578   1.1  christos 	/* we don't have stderr for interactive terminal sessions, see below */
    579   1.1  christos 	if (fderr != -1)
    580   1.1  christos 		set_nonblock(fderr);
    581   1.1  christos 
    582   1.1  christos 	if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin))
    583   1.1  christos 		fdin_is_tty = 1;
    584   1.1  christos 
    585   1.1  christos 	connection_in = packet_get_connection_in();
    586   1.1  christos 	connection_out = packet_get_connection_out();
    587   1.1  christos 
    588   1.1  christos 	notify_setup();
    589   1.1  christos 
    590   1.1  christos 	previous_stdout_buffer_bytes = 0;
    591   1.1  christos 
    592   1.1  christos 	/* Set approximate I/O buffer size. */
    593   1.1  christos 	if (packet_is_interactive())
    594   1.1  christos 		buffer_high = 4096;
    595   1.1  christos 	else
    596   1.1  christos 		buffer_high = 64 * 1024;
    597   1.1  christos 
    598   1.1  christos #if 0
    599   1.1  christos 	/* Initialize max_fd to the maximum of the known file descriptors. */
    600   1.1  christos 	max_fd = MAX(connection_in, connection_out);
    601   1.1  christos 	max_fd = MAX(max_fd, fdin);
    602   1.1  christos 	max_fd = MAX(max_fd, fdout);
    603   1.1  christos 	if (fderr != -1)
    604   1.1  christos 		max_fd = MAX(max_fd, fderr);
    605   1.1  christos #endif
    606   1.1  christos 
    607   1.1  christos 	/* Initialize Initialize buffers. */
    608   1.1  christos 	buffer_init(&stdin_buffer);
    609   1.1  christos 	buffer_init(&stdout_buffer);
    610   1.1  christos 	buffer_init(&stderr_buffer);
    611   1.1  christos 
    612   1.1  christos 	/*
    613   1.1  christos 	 * If we have no separate fderr (which is the case when we have a pty
    614   1.1  christos 	 * - there we cannot make difference between data sent to stdout and
    615   1.1  christos 	 * stderr), indicate that we have seen an EOF from stderr.  This way
    616   1.1  christos 	 * we don't need to check the descriptor everywhere.
    617   1.1  christos 	 */
    618   1.1  christos 	if (fderr == -1)
    619   1.1  christos 		fderr_eof = 1;
    620   1.1  christos 
    621   1.1  christos 	server_init_dispatch();
    622   1.1  christos 
    623   1.1  christos 	/* Main loop of the server for the interactive session mode. */
    624   1.1  christos 	for (;;) {
    625   1.1  christos 
    626   1.1  christos 		/* Process buffered packets from the client. */
    627   1.1  christos 		process_buffered_input_packets();
    628   1.1  christos 
    629   1.1  christos 		/*
    630   1.1  christos 		 * If we have received eof, and there is no more pending
    631   1.1  christos 		 * input data, cause a real eof by closing fdin.
    632   1.1  christos 		 */
    633   1.1  christos 		if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) {
    634   1.1  christos 			if (fdin != fdout)
    635   1.1  christos 				close(fdin);
    636   1.1  christos 			else
    637   1.1  christos 				shutdown(fdin, SHUT_WR); /* We will no longer send. */
    638   1.1  christos 			fdin = -1;
    639   1.1  christos 		}
    640   1.1  christos 		/* Make packets from buffered stderr data to send to the client. */
    641   1.1  christos 		make_packets_from_stderr_data();
    642   1.1  christos 
    643   1.1  christos 		/*
    644   1.1  christos 		 * Make packets from buffered stdout data to send to the
    645   1.1  christos 		 * client. If there is very little to send, this arranges to
    646   1.1  christos 		 * not send them now, but to wait a short while to see if we
    647   1.1  christos 		 * are getting more data. This is necessary, as some systems
    648   1.1  christos 		 * wake up readers from a pty after each separate character.
    649   1.1  christos 		 */
    650   1.1  christos 		max_time_milliseconds = 0;
    651   1.1  christos 		stdout_buffer_bytes = buffer_len(&stdout_buffer);
    652   1.1  christos 		if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 &&
    653   1.1  christos 		    stdout_buffer_bytes != previous_stdout_buffer_bytes) {
    654   1.1  christos 			/* try again after a while */
    655   1.1  christos 			max_time_milliseconds = 10;
    656   1.1  christos 		} else {
    657   1.1  christos 			/* Send it now. */
    658   1.1  christos 			make_packets_from_stdout_data();
    659   1.1  christos 		}
    660   1.1  christos 		previous_stdout_buffer_bytes = buffer_len(&stdout_buffer);
    661   1.1  christos 
    662   1.1  christos 		/* Send channel data to the client. */
    663   1.1  christos 		if (packet_not_very_much_data_to_write())
    664   1.1  christos 			channel_output_poll();
    665   1.1  christos 
    666   1.1  christos 		/*
    667   1.1  christos 		 * Bail out of the loop if the program has closed its output
    668   1.1  christos 		 * descriptors, and we have no more data to send to the
    669   1.1  christos 		 * client, and there is no pending buffered data.
    670   1.1  christos 		 */
    671   1.1  christos 		if (fdout_eof && fderr_eof && !packet_have_data_to_write() &&
    672   1.1  christos 		    buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) {
    673   1.1  christos 			if (!channel_still_open())
    674   1.1  christos 				break;
    675   1.1  christos 			if (!waiting_termination) {
    676   1.1  christos 				const char *s = "Waiting for forwarded connections to terminate...\r\n";
    677   1.1  christos 				char *cp;
    678   1.1  christos 				waiting_termination = 1;
    679   1.1  christos 				buffer_append(&stderr_buffer, s, strlen(s));
    680   1.1  christos 
    681   1.1  christos 				/* Display list of open channels. */
    682   1.1  christos 				cp = channel_open_message();
    683   1.1  christos 				buffer_append(&stderr_buffer, cp, strlen(cp));
    684   1.7  christos 				free(cp);
    685   1.1  christos 			}
    686   1.1  christos 		}
    687   1.1  christos 		max_fd = MAX(connection_in, connection_out);
    688   1.1  christos 		max_fd = MAX(max_fd, fdin);
    689   1.1  christos 		max_fd = MAX(max_fd, fdout);
    690   1.1  christos 		max_fd = MAX(max_fd, fderr);
    691   1.1  christos 		max_fd = MAX(max_fd, notify_pipe[0]);
    692   1.1  christos 
    693   1.1  christos 		/* Sleep in select() until we can do something. */
    694   1.1  christos 		wait_until_can_do_something(&readset, &writeset, &max_fd,
    695   1.1  christos 		    &nalloc, max_time_milliseconds);
    696   1.1  christos 
    697   1.1  christos 		if (received_sigterm) {
    698   1.6  christos 			logit("Exiting on signal %d", (int)received_sigterm);
    699   1.1  christos 			/* Clean up sessions, utmp, etc. */
    700   1.1  christos 			cleanup_exit(255);
    701   1.1  christos 		}
    702   1.1  christos 
    703   1.1  christos 		/* Process any channel events. */
    704   1.1  christos 		channel_after_select(readset, writeset);
    705   1.1  christos 
    706   1.1  christos 		/* Process input from the client and from program stdout/stderr. */
    707   1.1  christos 		process_input(readset);
    708   1.1  christos 
    709   1.1  christos 		/* Process output to the client and to program stdin. */
    710   1.1  christos 		process_output(writeset);
    711   1.1  christos 	}
    712   1.7  christos 	free(readset);
    713   1.7  christos 	free(writeset);
    714   1.1  christos 
    715   1.1  christos 	/* Cleanup and termination code. */
    716   1.1  christos 
    717   1.1  christos 	/* Wait until all output has been sent to the client. */
    718   1.1  christos 	drain_output();
    719   1.1  christos 
    720   1.1  christos 	debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.",
    721   1.1  christos 	    stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes);
    722   1.1  christos 
    723   1.1  christos 	/* Free and clear the buffers. */
    724   1.1  christos 	buffer_free(&stdin_buffer);
    725   1.1  christos 	buffer_free(&stdout_buffer);
    726   1.1  christos 	buffer_free(&stderr_buffer);
    727   1.1  christos 
    728   1.1  christos 	/* Close the file descriptors. */
    729   1.1  christos 	if (fdout != -1)
    730   1.1  christos 		close(fdout);
    731   1.1  christos 	fdout = -1;
    732   1.1  christos 	fdout_eof = 1;
    733   1.1  christos 	if (fderr != -1)
    734   1.1  christos 		close(fderr);
    735   1.1  christos 	fderr = -1;
    736   1.1  christos 	fderr_eof = 1;
    737   1.1  christos 	if (fdin != -1)
    738   1.1  christos 		close(fdin);
    739   1.1  christos 	fdin = -1;
    740   1.1  christos 
    741   1.1  christos 	channel_free_all();
    742   1.1  christos 
    743   1.1  christos 	/* We no longer want our SIGCHLD handler to be called. */
    744   1.1  christos 	signal(SIGCHLD, SIG_DFL);
    745   1.1  christos 
    746   1.1  christos 	while ((wait_pid = waitpid(-1, &wait_status, 0)) < 0)
    747   1.1  christos 		if (errno != EINTR)
    748   1.1  christos 			packet_disconnect("wait: %.100s", strerror(errno));
    749   1.1  christos 	if (wait_pid != pid)
    750   1.1  christos 		error("Strange, wait returned pid %ld, expected %ld",
    751   1.1  christos 		    (long)wait_pid, (long)pid);
    752   1.1  christos 
    753   1.1  christos 	/* Check if it exited normally. */
    754   1.1  christos 	if (WIFEXITED(wait_status)) {
    755   1.1  christos 		/* Yes, normal exit.  Get exit status and send it to the client. */
    756   1.1  christos 		debug("Command exited with status %d.", WEXITSTATUS(wait_status));
    757   1.1  christos 		packet_start(SSH_SMSG_EXITSTATUS);
    758   1.1  christos 		packet_put_int(WEXITSTATUS(wait_status));
    759   1.1  christos 		packet_send();
    760   1.1  christos 		packet_write_wait();
    761   1.1  christos 
    762   1.1  christos 		/*
    763   1.1  christos 		 * Wait for exit confirmation.  Note that there might be
    764   1.1  christos 		 * other packets coming before it; however, the program has
    765   1.1  christos 		 * already died so we just ignore them.  The client is
    766   1.1  christos 		 * supposed to respond with the confirmation when it receives
    767   1.1  christos 		 * the exit status.
    768   1.1  christos 		 */
    769   1.1  christos 		do {
    770   1.1  christos 			type = packet_read();
    771   1.1  christos 		}
    772   1.1  christos 		while (type != SSH_CMSG_EXIT_CONFIRMATION);
    773   1.1  christos 
    774   1.1  christos 		debug("Received exit confirmation.");
    775   1.1  christos 		return;
    776   1.1  christos 	}
    777   1.1  christos 	/* Check if the program terminated due to a signal. */
    778   1.1  christos 	if (WIFSIGNALED(wait_status))
    779   1.1  christos 		packet_disconnect("Command terminated on signal %d.",
    780   1.1  christos 				  WTERMSIG(wait_status));
    781   1.1  christos 
    782   1.1  christos 	/* Some weird exit cause.  Just exit. */
    783   1.1  christos 	packet_disconnect("wait returned status %04x.", wait_status);
    784   1.1  christos 	/* NOTREACHED */
    785   1.1  christos }
    786   1.1  christos 
    787   1.1  christos static void
    788   1.1  christos collect_children(void)
    789   1.1  christos {
    790   1.1  christos 	pid_t pid;
    791   1.1  christos 	sigset_t oset, nset;
    792   1.1  christos 	int status;
    793   1.1  christos 
    794   1.1  christos 	/* block SIGCHLD while we check for dead children */
    795   1.1  christos 	sigemptyset(&nset);
    796   1.1  christos 	sigaddset(&nset, SIGCHLD);
    797   1.1  christos 	sigprocmask(SIG_BLOCK, &nset, &oset);
    798   1.1  christos 	if (child_terminated) {
    799   1.1  christos 		debug("Received SIGCHLD.");
    800   1.1  christos 		while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
    801   1.1  christos 		    (pid < 0 && errno == EINTR))
    802   1.1  christos 			if (pid > 0)
    803   1.1  christos 				session_close_by_pid(pid, status);
    804   1.1  christos 		child_terminated = 0;
    805   1.1  christos 	}
    806   1.1  christos 	sigprocmask(SIG_SETMASK, &oset, NULL);
    807   1.1  christos }
    808   1.1  christos 
    809   1.1  christos void
    810   1.1  christos server_loop2(Authctxt *authctxt)
    811   1.1  christos {
    812   1.1  christos 	fd_set *readset = NULL, *writeset = NULL;
    813   1.2  christos 	int rekeying = 0, max_fd;
    814   1.2  christos 	u_int nalloc = 0;
    815   1.7  christos 	u_int64_t rekey_timeout_ms = 0;
    816   1.2  christos 	double start_time, total_time;
    817   1.1  christos 
    818   1.1  christos 	debug("Entering interactive session for SSH2.");
    819   1.2  christos 	start_time = get_current_time();
    820   1.1  christos 
    821   1.1  christos 	signal(SIGCHLD, sigchld_handler);
    822   1.1  christos 	child_terminated = 0;
    823   1.1  christos 	connection_in = packet_get_connection_in();
    824   1.1  christos 	connection_out = packet_get_connection_out();
    825   1.1  christos 
    826   1.1  christos 	if (!use_privsep) {
    827   1.1  christos 		signal(SIGTERM, sigterm_handler);
    828   1.1  christos 		signal(SIGINT, sigterm_handler);
    829   1.1  christos 		signal(SIGQUIT, sigterm_handler);
    830   1.1  christos 	}
    831   1.1  christos 
    832   1.1  christos 	notify_setup();
    833   1.1  christos 
    834   1.1  christos 	max_fd = MAX(connection_in, connection_out);
    835   1.1  christos 	max_fd = MAX(max_fd, notify_pipe[0]);
    836   1.1  christos 
    837   1.1  christos 	server_init_dispatch();
    838   1.1  christos 
    839   1.1  christos 	for (;;) {
    840   1.1  christos 		process_buffered_input_packets();
    841   1.1  christos 
    842  1.10  christos 		rekeying = (active_state->kex != NULL && !active_state->kex->done);
    843   1.1  christos 
    844   1.1  christos 		if (!rekeying && packet_not_very_much_data_to_write())
    845   1.1  christos 			channel_output_poll();
    846   1.7  christos 		if (options.rekey_interval > 0 && compat20 && !rekeying)
    847   1.7  christos 			rekey_timeout_ms = packet_get_rekey_timeout() * 1000;
    848   1.7  christos 		else
    849   1.7  christos 			rekey_timeout_ms = 0;
    850   1.7  christos 
    851   1.1  christos 		wait_until_can_do_something(&readset, &writeset, &max_fd,
    852   1.7  christos 		    &nalloc, rekey_timeout_ms);
    853   1.1  christos 
    854   1.1  christos 		if (received_sigterm) {
    855   1.6  christos 			logit("Exiting on signal %d", (int)received_sigterm);
    856   1.1  christos 			/* Clean up sessions, utmp, etc. */
    857   1.1  christos 			cleanup_exit(255);
    858   1.1  christos 		}
    859   1.1  christos 
    860   1.1  christos 		collect_children();
    861   1.1  christos 		if (!rekeying) {
    862   1.1  christos 			channel_after_select(readset, writeset);
    863   1.1  christos 			if (packet_need_rekeying()) {
    864   1.1  christos 				debug("need rekeying");
    865  1.10  christos 				active_state->kex->done = 0;
    866  1.10  christos 				kex_send_kexinit(active_state);
    867   1.1  christos 			}
    868   1.1  christos 		}
    869   1.1  christos 		process_input(readset);
    870   1.1  christos 		if (connection_closed)
    871   1.1  christos 			break;
    872   1.1  christos 		process_output(writeset);
    873   1.1  christos 	}
    874   1.1  christos 	collect_children();
    875   1.1  christos 
    876   1.7  christos 	free(readset);
    877   1.7  christos 	free(writeset);
    878   1.1  christos 
    879   1.1  christos 	/* free all channels, no more reads and writes */
    880   1.1  christos 	channel_free_all();
    881   1.1  christos 
    882   1.1  christos 	/* free remaining sessions, e.g. remove wtmp entries */
    883   1.1  christos 	session_destroy_all(NULL);
    884   1.2  christos 	total_time = get_current_time() - start_time;
    885   1.2  christos 	logit("SSH: Server;LType: Throughput;Remote: %s-%d;IN: %lu;OUT: %lu;Duration: %.1f;tPut_in: %.1f;tPut_out: %.1f",
    886   1.2  christos 	      get_remote_ipaddr(), get_remote_port(),
    887   1.2  christos 	      stdin_bytes, fdout_bytes, total_time, stdin_bytes / total_time,
    888   1.2  christos 	      fdout_bytes / total_time);
    889   1.1  christos }
    890   1.1  christos 
    891  1.10  christos static int
    892   1.1  christos server_input_keep_alive(int type, u_int32_t seq, void *ctxt)
    893   1.1  christos {
    894   1.1  christos 	debug("Got %d/%u for keepalive", type, seq);
    895   1.1  christos 	/*
    896   1.1  christos 	 * reset timeout, since we got a sane answer from the client.
    897   1.1  christos 	 * even if this was generated by something other than
    898   1.1  christos 	 * the bogus CHANNEL_REQUEST we send for keepalives.
    899   1.1  christos 	 */
    900   1.3  christos 	packet_set_alive_timeouts(0);
    901  1.10  christos 	return 0;
    902   1.1  christos }
    903   1.1  christos 
    904  1.10  christos static int
    905   1.1  christos server_input_stdin_data(int type, u_int32_t seq, void *ctxt)
    906   1.1  christos {
    907   1.1  christos 	char *data;
    908   1.1  christos 	u_int data_len;
    909   1.1  christos 
    910   1.1  christos 	/* Stdin data from the client.  Append it to the buffer. */
    911   1.1  christos 	/* Ignore any data if the client has closed stdin. */
    912   1.1  christos 	if (fdin == -1)
    913  1.10  christos 		return 0;
    914   1.1  christos 	data = packet_get_string(&data_len);
    915   1.1  christos 	packet_check_eom();
    916   1.1  christos 	buffer_append(&stdin_buffer, data, data_len);
    917   1.9  christos 	explicit_bzero(data, data_len);
    918   1.7  christos 	free(data);
    919  1.10  christos 	return 0;
    920   1.1  christos }
    921   1.1  christos 
    922  1.10  christos static int
    923   1.1  christos server_input_eof(int type, u_int32_t seq, void *ctxt)
    924   1.1  christos {
    925   1.1  christos 	/*
    926   1.1  christos 	 * Eof from the client.  The stdin descriptor to the
    927   1.1  christos 	 * program will be closed when all buffered data has
    928   1.1  christos 	 * drained.
    929   1.1  christos 	 */
    930   1.1  christos 	debug("EOF received for stdin.");
    931   1.1  christos 	packet_check_eom();
    932   1.1  christos 	stdin_eof = 1;
    933  1.10  christos 	return 0;
    934   1.1  christos }
    935   1.1  christos 
    936  1.10  christos static int
    937   1.1  christos server_input_window_size(int type, u_int32_t seq, void *ctxt)
    938   1.1  christos {
    939   1.1  christos 	u_int row = packet_get_int();
    940   1.1  christos 	u_int col = packet_get_int();
    941   1.1  christos 	u_int xpixel = packet_get_int();
    942   1.1  christos 	u_int ypixel = packet_get_int();
    943   1.1  christos 
    944   1.1  christos 	debug("Window change received.");
    945   1.1  christos 	packet_check_eom();
    946   1.1  christos 	if (fdin != -1)
    947   1.1  christos 		pty_change_window_size(fdin, row, col, xpixel, ypixel);
    948  1.10  christos 	return 0;
    949   1.1  christos }
    950   1.1  christos 
    951   1.1  christos static Channel *
    952   1.1  christos server_request_direct_tcpip(void)
    953   1.1  christos {
    954   1.6  christos 	Channel *c = NULL;
    955   1.1  christos 	char *target, *originator;
    956   1.1  christos 	u_short target_port, originator_port;
    957   1.1  christos 
    958   1.1  christos 	target = packet_get_string(NULL);
    959   1.1  christos 	target_port = packet_get_int();
    960   1.1  christos 	originator = packet_get_string(NULL);
    961   1.1  christos 	originator_port = packet_get_int();
    962   1.1  christos 	packet_check_eom();
    963   1.1  christos 
    964   1.1  christos 	debug("server_request_direct_tcpip: originator %s port %d, target %s "
    965   1.1  christos 	    "port %d", originator, originator_port, target, target_port);
    966   1.1  christos 
    967   1.6  christos 	/* XXX fine grained permissions */
    968   1.6  christos 	if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 &&
    969   1.6  christos 	    !no_port_forwarding_flag) {
    970   1.9  christos 		c = channel_connect_to_port(target, target_port,
    971   1.6  christos 		    "direct-tcpip", "direct-tcpip");
    972   1.6  christos 	} else {
    973   1.6  christos 		logit("refused local port forward: "
    974   1.6  christos 		    "originator %s port %d, target %s port %d",
    975   1.6  christos 		    originator, originator_port, target, target_port);
    976   1.6  christos 	}
    977   1.1  christos 
    978   1.7  christos 	free(originator);
    979   1.7  christos 	free(target);
    980   1.1  christos 
    981   1.1  christos 	return c;
    982   1.1  christos }
    983   1.1  christos 
    984   1.1  christos static Channel *
    985   1.9  christos server_request_direct_streamlocal(void)
    986   1.9  christos {
    987   1.9  christos 	Channel *c = NULL;
    988   1.9  christos 	char *target, *originator;
    989   1.9  christos 	u_short originator_port;
    990   1.9  christos 
    991   1.9  christos 	target = packet_get_string(NULL);
    992   1.9  christos 	originator = packet_get_string(NULL);
    993   1.9  christos 	originator_port = packet_get_int();
    994   1.9  christos 	packet_check_eom();
    995   1.9  christos 
    996   1.9  christos 	debug("server_request_direct_streamlocal: originator %s port %d, target %s",
    997   1.9  christos 	    originator, originator_port, target);
    998   1.9  christos 
    999   1.9  christos 	/* XXX fine grained permissions */
   1000   1.9  christos 	if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 &&
   1001   1.9  christos 	    !no_port_forwarding_flag) {
   1002   1.9  christos 		c = channel_connect_to_path(target,
   1003   1.9  christos 		    "direct-streamlocal (at) openssh.com", "direct-streamlocal");
   1004   1.9  christos 	} else {
   1005   1.9  christos 		logit("refused streamlocal port forward: "
   1006   1.9  christos 		    "originator %s port %d, target %s",
   1007   1.9  christos 		    originator, originator_port, target);
   1008   1.9  christos 	}
   1009   1.9  christos 
   1010   1.9  christos 	free(originator);
   1011   1.9  christos 	free(target);
   1012   1.9  christos 
   1013   1.9  christos 	return c;
   1014   1.9  christos }
   1015   1.9  christos 
   1016   1.9  christos static Channel *
   1017   1.1  christos server_request_tun(void)
   1018   1.1  christos {
   1019   1.1  christos 	Channel *c = NULL;
   1020   1.1  christos 	int mode, tun;
   1021   1.1  christos 	int sock;
   1022   1.1  christos 
   1023   1.1  christos 	mode = packet_get_int();
   1024   1.1  christos 	switch (mode) {
   1025   1.1  christos 	case SSH_TUNMODE_POINTOPOINT:
   1026   1.1  christos 	case SSH_TUNMODE_ETHERNET:
   1027   1.1  christos 		break;
   1028   1.1  christos 	default:
   1029   1.1  christos 		packet_send_debug("Unsupported tunnel device mode.");
   1030   1.1  christos 		return NULL;
   1031   1.1  christos 	}
   1032   1.1  christos 	if ((options.permit_tun & mode) == 0) {
   1033   1.1  christos 		packet_send_debug("Server has rejected tunnel device "
   1034   1.1  christos 		    "forwarding");
   1035   1.1  christos 		return NULL;
   1036   1.1  christos 	}
   1037   1.1  christos 
   1038   1.1  christos 	tun = packet_get_int();
   1039   1.1  christos 	if (forced_tun_device != -1) {
   1040   1.1  christos 		if (tun != SSH_TUNID_ANY && forced_tun_device != tun)
   1041   1.1  christos 			goto done;
   1042   1.1  christos 		tun = forced_tun_device;
   1043   1.1  christos 	}
   1044   1.1  christos 	sock = tun_open(tun, mode);
   1045   1.1  christos 	if (sock < 0)
   1046   1.1  christos 		goto done;
   1047   1.2  christos 	if (options.hpn_disabled)
   1048   1.1  christos 	c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
   1049   1.1  christos 	    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
   1050   1.2  christos 	else
   1051   1.2  christos 		c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
   1052   1.2  christos 		    options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
   1053   1.1  christos 	c->datagram = 1;
   1054   1.1  christos 
   1055   1.1  christos  done:
   1056   1.1  christos 	if (c == NULL)
   1057   1.1  christos 		packet_send_debug("Failed to open the tunnel device.");
   1058   1.1  christos 	return c;
   1059   1.1  christos }
   1060   1.1  christos 
   1061   1.1  christos static Channel *
   1062   1.1  christos server_request_session(void)
   1063   1.1  christos {
   1064   1.1  christos 	Channel *c;
   1065   1.1  christos 
   1066   1.1  christos 	debug("input_session_request");
   1067   1.1  christos 	packet_check_eom();
   1068   1.1  christos 
   1069   1.1  christos 	if (no_more_sessions) {
   1070   1.1  christos 		packet_disconnect("Possible attack: attempt to open a session "
   1071   1.1  christos 		    "after additional sessions disabled");
   1072   1.1  christos 	}
   1073   1.1  christos 
   1074   1.1  christos 	/*
   1075   1.1  christos 	 * A server session has no fd to read or write until a
   1076   1.1  christos 	 * CHANNEL_REQUEST for a shell is made, so we set the type to
   1077   1.1  christos 	 * SSH_CHANNEL_LARVAL.  Additionally, a callback for handling all
   1078   1.1  christos 	 * CHANNEL_REQUEST messages is registered.
   1079   1.1  christos 	 */
   1080   1.1  christos 	c = channel_new("session", SSH_CHANNEL_LARVAL,
   1081   1.1  christos 	    -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
   1082   1.1  christos 	    0, "server-session", 1);
   1083   1.2  christos 	if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled))
   1084   1.2  christos 		c->dynamic_window = 1;
   1085   1.1  christos 	if (session_open(the_authctxt, c->self) != 1) {
   1086   1.1  christos 		debug("session open failed, free channel %d", c->self);
   1087   1.1  christos 		channel_free(c);
   1088   1.1  christos 		return NULL;
   1089   1.1  christos 	}
   1090   1.1  christos 	channel_register_cleanup(c->self, session_close_by_channel, 0);
   1091   1.1  christos 	return c;
   1092   1.1  christos }
   1093   1.1  christos 
   1094  1.10  christos static int
   1095   1.1  christos server_input_channel_open(int type, u_int32_t seq, void *ctxt)
   1096   1.1  christos {
   1097   1.1  christos 	Channel *c = NULL;
   1098   1.1  christos 	char *ctype;
   1099   1.1  christos 	int rchan;
   1100   1.1  christos 	u_int rmaxpack, rwindow, len;
   1101   1.1  christos 
   1102   1.1  christos 	ctype = packet_get_string(&len);
   1103   1.1  christos 	rchan = packet_get_int();
   1104   1.1  christos 	rwindow = packet_get_int();
   1105   1.1  christos 	rmaxpack = packet_get_int();
   1106   1.1  christos 
   1107   1.1  christos 	debug("server_input_channel_open: ctype %s rchan %d win %d max %d",
   1108   1.1  christos 	    ctype, rchan, rwindow, rmaxpack);
   1109   1.1  christos 
   1110   1.1  christos 	if (strcmp(ctype, "session") == 0) {
   1111   1.1  christos 		c = server_request_session();
   1112   1.1  christos 	} else if (strcmp(ctype, "direct-tcpip") == 0) {
   1113   1.1  christos 		c = server_request_direct_tcpip();
   1114   1.9  christos 	} else if (strcmp(ctype, "direct-streamlocal (at) openssh.com") == 0) {
   1115   1.9  christos 		c = server_request_direct_streamlocal();
   1116   1.1  christos 	} else if (strcmp(ctype, "tun (at) openssh.com") == 0) {
   1117   1.1  christos 		c = server_request_tun();
   1118   1.1  christos 	}
   1119   1.1  christos 	if (c != NULL) {
   1120   1.1  christos 		debug("server_input_channel_open: confirm %s", ctype);
   1121   1.1  christos 		c->remote_id = rchan;
   1122   1.1  christos 		c->remote_window = rwindow;
   1123   1.1  christos 		c->remote_maxpacket = rmaxpack;
   1124   1.1  christos 		if (c->type != SSH_CHANNEL_CONNECTING) {
   1125   1.1  christos 			packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
   1126   1.1  christos 			packet_put_int(c->remote_id);
   1127   1.1  christos 			packet_put_int(c->self);
   1128   1.1  christos 			packet_put_int(c->local_window);
   1129   1.1  christos 			packet_put_int(c->local_maxpacket);
   1130   1.1  christos 			packet_send();
   1131   1.1  christos 		}
   1132   1.1  christos 	} else {
   1133   1.1  christos 		debug("server_input_channel_open: failure %s", ctype);
   1134   1.1  christos 		packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
   1135   1.1  christos 		packet_put_int(rchan);
   1136   1.1  christos 		packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
   1137   1.1  christos 		if (!(datafellows & SSH_BUG_OPENFAILURE)) {
   1138   1.1  christos 			packet_put_cstring("open failed");
   1139   1.1  christos 			packet_put_cstring("");
   1140   1.1  christos 		}
   1141   1.1  christos 		packet_send();
   1142   1.1  christos 	}
   1143   1.7  christos 	free(ctype);
   1144  1.10  christos 	return 0;
   1145  1.10  christos }
   1146  1.10  christos 
   1147  1.10  christos static int
   1148  1.10  christos server_input_hostkeys_prove(struct sshbuf **respp)
   1149  1.10  christos {
   1150  1.10  christos 	struct ssh *ssh = active_state; /* XXX */
   1151  1.10  christos 	struct sshbuf *resp = NULL;
   1152  1.10  christos 	struct sshbuf *sigbuf = NULL;
   1153  1.10  christos 	struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL;
   1154  1.10  christos 	int r, ndx, success = 0;
   1155  1.10  christos 	const u_char *blob;
   1156  1.10  christos 	u_char *sig = 0;
   1157  1.10  christos 	size_t blen, slen;
   1158  1.10  christos 
   1159  1.10  christos 	if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL)
   1160  1.10  christos 		fatal("%s: sshbuf_new", __func__);
   1161  1.10  christos 
   1162  1.10  christos 	while (ssh_packet_remaining(ssh) > 0) {
   1163  1.10  christos 		sshkey_free(key);
   1164  1.10  christos 		key = NULL;
   1165  1.10  christos 		if ((r = sshpkt_get_string_direct(ssh, &blob, &blen)) != 0 ||
   1166  1.10  christos 		    (r = sshkey_from_blob(blob, blen, &key)) != 0) {
   1167  1.10  christos 			error("%s: couldn't parse key: %s",
   1168  1.10  christos 			    __func__, ssh_err(r));
   1169  1.10  christos 			goto out;
   1170  1.10  christos 		}
   1171  1.10  christos 		/*
   1172  1.10  christos 		 * Better check that this is actually one of our hostkeys
   1173  1.10  christos 		 * before attempting to sign anything with it.
   1174  1.10  christos 		 */
   1175  1.10  christos 		if ((ndx = ssh->kex->host_key_index(key, 1, ssh)) == -1) {
   1176  1.10  christos 			error("%s: unknown host %s key",
   1177  1.10  christos 			    __func__, sshkey_type(key));
   1178  1.10  christos 			goto out;
   1179  1.10  christos 		}
   1180  1.10  christos 		/*
   1181  1.10  christos 		 * XXX refactor: make kex->sign just use an index rather
   1182  1.10  christos 		 * than passing in public and private keys
   1183  1.10  christos 		 */
   1184  1.10  christos 		if ((key_prv = get_hostkey_by_index(ndx)) == NULL &&
   1185  1.10  christos 		    (key_pub = get_hostkey_public_by_index(ndx, ssh)) == NULL) {
   1186  1.10  christos 			error("%s: can't retrieve hostkey %d", __func__, ndx);
   1187  1.10  christos 			goto out;
   1188  1.10  christos 		}
   1189  1.10  christos 		sshbuf_reset(sigbuf);
   1190  1.10  christos 		free(sig);
   1191  1.10  christos 		sig = NULL;
   1192  1.10  christos 		if ((r = sshbuf_put_cstring(sigbuf,
   1193  1.10  christos 		    "hostkeys-prove-00 (at) openssh.com")) != 0 ||
   1194  1.10  christos 		    (r = sshbuf_put_string(sigbuf,
   1195  1.10  christos 		    ssh->kex->session_id, ssh->kex->session_id_len)) != 0 ||
   1196  1.10  christos 		    (r = sshkey_puts(key, sigbuf)) != 0 ||
   1197  1.10  christos 		    (r = ssh->kex->sign(key_prv, key_pub, &sig, &slen,
   1198  1.10  christos 		    sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), 0)) != 0 ||
   1199  1.10  christos 		    (r = sshbuf_put_string(resp, sig, slen)) != 0) {
   1200  1.10  christos 			error("%s: couldn't prepare signature: %s",
   1201  1.10  christos 			    __func__, ssh_err(r));
   1202  1.10  christos 			goto out;
   1203  1.10  christos 		}
   1204  1.10  christos 	}
   1205  1.10  christos 	/* Success */
   1206  1.10  christos 	*respp = resp;
   1207  1.10  christos 	resp = NULL; /* don't free it */
   1208  1.10  christos 	success = 1;
   1209  1.10  christos  out:
   1210  1.10  christos 	free(sig);
   1211  1.10  christos 	sshbuf_free(resp);
   1212  1.10  christos 	sshbuf_free(sigbuf);
   1213  1.10  christos 	sshkey_free(key);
   1214  1.10  christos 	return success;
   1215   1.1  christos }
   1216   1.1  christos 
   1217  1.10  christos static int
   1218   1.1  christos server_input_global_request(int type, u_int32_t seq, void *ctxt)
   1219   1.1  christos {
   1220   1.1  christos 	char *rtype;
   1221   1.1  christos 	int want_reply;
   1222  1.10  christos 	int r, success = 0, allocated_listen_port = 0;
   1223  1.10  christos 	struct sshbuf *resp = NULL;
   1224   1.1  christos 
   1225   1.1  christos 	rtype = packet_get_string(NULL);
   1226   1.1  christos 	want_reply = packet_get_char();
   1227   1.1  christos 	debug("server_input_global_request: rtype %s want_reply %d", rtype, want_reply);
   1228   1.1  christos 
   1229   1.1  christos 	/* -R style forwarding */
   1230   1.1  christos 	if (strcmp(rtype, "tcpip-forward") == 0) {
   1231   1.1  christos 		struct passwd *pw;
   1232   1.9  christos 		struct Forward fwd;
   1233   1.1  christos 
   1234   1.1  christos 		pw = the_authctxt->pw;
   1235   1.1  christos 		if (pw == NULL || !the_authctxt->valid)
   1236   1.1  christos 			fatal("server_input_global_request: no/invalid user");
   1237   1.9  christos 		memset(&fwd, 0, sizeof(fwd));
   1238   1.9  christos 		fwd.listen_host = packet_get_string(NULL);
   1239   1.9  christos 		fwd.listen_port = (u_short)packet_get_int();
   1240   1.1  christos 		debug("server_input_global_request: tcpip-forward listen %s port %d",
   1241   1.9  christos 		    fwd.listen_host, fwd.listen_port);
   1242   1.1  christos 
   1243   1.1  christos 		/* check permissions */
   1244   1.6  christos 		if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 ||
   1245   1.1  christos 		    no_port_forwarding_flag ||
   1246   1.9  christos 		    (!want_reply && fwd.listen_port == 0) ||
   1247   1.9  christos 		    (fwd.listen_port != 0 && fwd.listen_port < IPPORT_RESERVED &&
   1248   1.1  christos 		    pw->pw_uid != 0)) {
   1249   1.1  christos 			success = 0;
   1250   1.1  christos 			packet_send_debug("Server has disabled port forwarding.");
   1251   1.1  christos 		} else {
   1252   1.1  christos 			/* Start listening on the port */
   1253   1.9  christos 			success = channel_setup_remote_fwd_listener(&fwd,
   1254   1.9  christos 			    &allocated_listen_port, &options.fwd_opts);
   1255   1.1  christos 		}
   1256   1.9  christos 		free(fwd.listen_host);
   1257  1.10  christos 		if ((resp = sshbuf_new()) == NULL)
   1258  1.10  christos 			fatal("%s: sshbuf_new", __func__);
   1259  1.10  christos 		if ((r = sshbuf_put_u32(resp, allocated_listen_port)) != 0)
   1260  1.10  christos 			fatal("%s: sshbuf_put_u32: %s", __func__, ssh_err(r));
   1261   1.1  christos 	} else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
   1262   1.9  christos 		struct Forward fwd;
   1263   1.1  christos 
   1264   1.9  christos 		memset(&fwd, 0, sizeof(fwd));
   1265   1.9  christos 		fwd.listen_host = packet_get_string(NULL);
   1266   1.9  christos 		fwd.listen_port = (u_short)packet_get_int();
   1267   1.1  christos 		debug("%s: cancel-tcpip-forward addr %s port %d", __func__,
   1268   1.9  christos 		    fwd.listen_host, fwd.listen_port);
   1269   1.9  christos 
   1270   1.9  christos 		success = channel_cancel_rport_listener(&fwd);
   1271   1.9  christos 		free(fwd.listen_host);
   1272   1.9  christos 	} else if (strcmp(rtype, "streamlocal-forward (at) openssh.com") == 0) {
   1273   1.9  christos 		struct Forward fwd;
   1274   1.9  christos 
   1275   1.9  christos 		memset(&fwd, 0, sizeof(fwd));
   1276   1.9  christos 		fwd.listen_path = packet_get_string(NULL);
   1277   1.9  christos 		debug("server_input_global_request: streamlocal-forward listen path %s",
   1278   1.9  christos 		    fwd.listen_path);
   1279   1.9  christos 
   1280   1.9  christos 		/* check permissions */
   1281   1.9  christos 		if ((options.allow_streamlocal_forwarding & FORWARD_REMOTE) == 0
   1282   1.9  christos 		    || no_port_forwarding_flag) {
   1283   1.9  christos 			success = 0;
   1284   1.9  christos 			packet_send_debug("Server has disabled port forwarding.");
   1285   1.9  christos 		} else {
   1286   1.9  christos 			/* Start listening on the socket */
   1287   1.9  christos 			success = channel_setup_remote_fwd_listener(
   1288   1.9  christos 			    &fwd, NULL, &options.fwd_opts);
   1289   1.9  christos 		}
   1290   1.9  christos 		free(fwd.listen_path);
   1291   1.9  christos 	} else if (strcmp(rtype, "cancel-streamlocal-forward (at) openssh.com") == 0) {
   1292   1.9  christos 		struct Forward fwd;
   1293   1.9  christos 
   1294   1.9  christos 		memset(&fwd, 0, sizeof(fwd));
   1295   1.9  christos 		fwd.listen_path = packet_get_string(NULL);
   1296   1.9  christos 		debug("%s: cancel-streamlocal-forward path %s", __func__,
   1297   1.9  christos 		    fwd.listen_path);
   1298   1.1  christos 
   1299   1.9  christos 		success = channel_cancel_rport_listener(&fwd);
   1300   1.9  christos 		free(fwd.listen_path);
   1301   1.1  christos 	} else if (strcmp(rtype, "no-more-sessions (at) openssh.com") == 0) {
   1302   1.1  christos 		no_more_sessions = 1;
   1303   1.1  christos 		success = 1;
   1304  1.10  christos 	} else if (strcmp(rtype, "hostkeys-prove-00 (at) openssh.com") == 0) {
   1305  1.10  christos 		success = server_input_hostkeys_prove(&resp);
   1306   1.1  christos 	}
   1307   1.1  christos 	if (want_reply) {
   1308   1.1  christos 		packet_start(success ?
   1309   1.1  christos 		    SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
   1310  1.10  christos 		if (success && resp != NULL)
   1311  1.10  christos 			ssh_packet_put_raw(active_state, sshbuf_ptr(resp),
   1312  1.10  christos 			    sshbuf_len(resp));
   1313   1.1  christos 		packet_send();
   1314   1.1  christos 		packet_write_wait();
   1315   1.1  christos 	}
   1316   1.7  christos 	free(rtype);
   1317  1.10  christos 	sshbuf_free(resp);
   1318  1.10  christos 	return 0;
   1319   1.1  christos }
   1320   1.1  christos 
   1321  1.10  christos static int
   1322   1.1  christos server_input_channel_req(int type, u_int32_t seq, void *ctxt)
   1323   1.1  christos {
   1324   1.1  christos 	Channel *c;
   1325   1.1  christos 	int id, reply, success = 0;
   1326   1.1  christos 	char *rtype;
   1327   1.1  christos 
   1328   1.1  christos 	id = packet_get_int();
   1329   1.1  christos 	rtype = packet_get_string(NULL);
   1330   1.1  christos 	reply = packet_get_char();
   1331   1.1  christos 
   1332   1.1  christos 	debug("server_input_channel_req: channel %d request %s reply %d",
   1333   1.1  christos 	    id, rtype, reply);
   1334   1.1  christos 
   1335   1.1  christos 	if ((c = channel_lookup(id)) == NULL)
   1336   1.1  christos 		packet_disconnect("server_input_channel_req: "
   1337   1.1  christos 		    "unknown channel %d", id);
   1338   1.1  christos 	if (!strcmp(rtype, "eow (at) openssh.com")) {
   1339   1.1  christos 		packet_check_eom();
   1340   1.1  christos 		chan_rcvd_eow(c);
   1341   1.1  christos 	} else if ((c->type == SSH_CHANNEL_LARVAL ||
   1342   1.1  christos 	    c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0)
   1343   1.1  christos 		success = session_input_channel_req(c, rtype);
   1344   1.9  christos 	if (reply && !(c->flags & CHAN_CLOSE_SENT)) {
   1345   1.1  christos 		packet_start(success ?
   1346   1.1  christos 		    SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
   1347   1.1  christos 		packet_put_int(c->remote_id);
   1348   1.1  christos 		packet_send();
   1349   1.1  christos 	}
   1350   1.7  christos 	free(rtype);
   1351  1.10  christos 	return 0;
   1352   1.1  christos }
   1353   1.1  christos 
   1354   1.1  christos static void
   1355   1.1  christos server_init_dispatch_20(void)
   1356   1.1  christos {
   1357   1.1  christos 	debug("server_init_dispatch_20");
   1358   1.1  christos 	dispatch_init(&dispatch_protocol_error);
   1359   1.1  christos 	dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
   1360   1.1  christos 	dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data);
   1361   1.1  christos 	dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
   1362   1.1  christos 	dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
   1363   1.1  christos 	dispatch_set(SSH2_MSG_CHANNEL_OPEN, &server_input_channel_open);
   1364   1.1  christos 	dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
   1365   1.1  christos 	dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
   1366   1.1  christos 	dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req);
   1367   1.1  christos 	dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
   1368   1.1  christos 	dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);
   1369   1.1  christos 	/* client_alive */
   1370   1.1  christos 	dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &server_input_keep_alive);
   1371   1.1  christos 	dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive);
   1372   1.1  christos 	dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive);
   1373   1.1  christos 	dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive);
   1374   1.1  christos 	/* rekeying */
   1375   1.1  christos 	dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
   1376   1.1  christos }
   1377   1.1  christos static void
   1378   1.1  christos server_init_dispatch_13(void)
   1379   1.1  christos {
   1380   1.1  christos 	debug("server_init_dispatch_13");
   1381   1.1  christos 	dispatch_init(NULL);
   1382   1.1  christos 	dispatch_set(SSH_CMSG_EOF, &server_input_eof);
   1383   1.1  christos 	dispatch_set(SSH_CMSG_STDIN_DATA, &server_input_stdin_data);
   1384   1.1  christos 	dispatch_set(SSH_CMSG_WINDOW_SIZE, &server_input_window_size);
   1385   1.1  christos 	dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);
   1386   1.1  christos 	dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation);
   1387   1.1  christos 	dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
   1388   1.1  christos 	dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
   1389   1.1  christos 	dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
   1390   1.1  christos 	dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);
   1391   1.1  christos }
   1392   1.1  christos static void
   1393   1.1  christos server_init_dispatch_15(void)
   1394   1.1  christos {
   1395   1.1  christos 	server_init_dispatch_13();
   1396   1.1  christos 	debug("server_init_dispatch_15");
   1397   1.1  christos 	dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
   1398   1.1  christos 	dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_oclose);
   1399   1.1  christos }
   1400   1.1  christos static void
   1401   1.1  christos server_init_dispatch(void)
   1402   1.1  christos {
   1403   1.1  christos 	if (compat20)
   1404   1.1  christos 		server_init_dispatch_20();
   1405   1.1  christos 	else if (compat13)
   1406   1.1  christos 		server_init_dispatch_13();
   1407   1.1  christos 	else
   1408   1.1  christos 		server_init_dispatch_15();
   1409   1.1  christos }
   1410