/*

serverloop.c

Author: Tatu Ylonen <ylo@cs.hut.fi>

Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                   All rights reserved

Created: Sun Sep 10 00:30:37 1995 ylo

Server main loop for handling the interactive session.

*/

#include "includes.h"
#include "xmalloc.h"
#include "ssh.h"
#include "packet.h"
#include "buffer.h"
#include "servconf.h"
#include "pty.h"

static Buffer stdin_buffer;	/* Buffer for stdin data. */
static Buffer stdout_buffer;	/* Buffer for stdout data. */
static Buffer stderr_buffer;	/* Buffer for stderr data. */
static int fdin;		/* Descriptor for stdin (for writing) */
static int fdout;		/* Descriptor for stdout (for reading);
				   May be same number as fdin. */
static int fderr;		/* Descriptor for stderr.  May be -1. */
static long stdin_bytes = 0;	/* Number of bytes written to stdin. */
static long stdout_bytes = 0;	/* Number of stdout bytes sent to client. */
static long stderr_bytes = 0;	/* Number of stderr bytes sent to client. */
static long fdout_bytes = 0;	/* Number of stdout bytes read from program. */
static int stdin_eof = 0;	/* EOF message received from client. */
static int fdout_eof = 0;	/* EOF encountered reading from fdout. */
static int fderr_eof = 0;	/* EOF encountered readung from fderr. */
static int connection_in;	/* Connection to client (input). */
static int connection_out;	/* Connection to client (output). */
static unsigned int buffer_high;/* "Soft" max buffer size. */
static int max_fd;		/* Max file descriptor number for select(). */

/* This SIGCHLD kludge is used to detect when the child exits.  The server
   will exit after that, as soon as forwarded connections have terminated. */

static int child_pid;  			/* Pid of the child. */
static volatile int child_terminated;	/* The child has terminated. */
static volatile int child_wait_status;	/* Status from wait(). */

void sigchld_handler(int sig)
{
  int save_errno = errno;
  int wait_pid;
  debug("Received SIGCHLD.");
  wait_pid = wait((int *)&child_wait_status);
  if (wait_pid != -1)
    {
      if (wait_pid != child_pid)
	error("Strange, got SIGCHLD and wait returned pid %d but child is %d",
	      wait_pid, child_pid);
      if (WIFEXITED(child_wait_status) ||
	  WIFSIGNALED(child_wait_status))
	child_terminated = 1;
    }
  signal(SIGCHLD, sigchld_handler);
  errno = save_errno;
}

/* Process any buffered packets that have been received from the client. */

void process_buffered_input_packets()
{
  int type;
  char *data;
  unsigned int data_len;
  int row, col, xpixel, ypixel;
  int payload_len;

  /* Process buffered packets from the client. */
  while ((type = packet_read_poll(&payload_len)) != SSH_MSG_NONE)
    {
      switch (type)
	{
	case SSH_CMSG_STDIN_DATA:
	  /* Stdin data from the client.  Append it to the buffer. */
	  if (fdin == -1)
	    break; /* Ignore any data if the client has closed stdin. */
	  data = packet_get_string(&data_len);
	  packet_integrity_check(payload_len, (4 + data_len), type);
	  buffer_append(&stdin_buffer, data, data_len);
	  memset(data, 0, data_len);
	  xfree(data);
	  break;
	  
	case SSH_CMSG_EOF:
	  /* Eof from the client.  The stdin descriptor to the program
	     will be closed when all buffered data has drained. */
	  debug("EOF received for stdin.");
	  packet_integrity_check(payload_len, 0, type);
	  stdin_eof = 1;
	  break;

	case SSH_CMSG_WINDOW_SIZE:
	  debug("Window change received.");
	  packet_integrity_check(payload_len, 4*4, type);
	  row = packet_get_int();
	  col = packet_get_int();
	  xpixel = packet_get_int();
	  ypixel = packet_get_int();
	  if (fdin != -1)
	    pty_change_window_size(fdin, row, col, xpixel, ypixel);
	  break;
	  
	case SSH_MSG_PORT_OPEN:
	  debug("Received port open request.");
	  channel_input_port_open(payload_len);
	  break;
	  
	case SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
	  debug("Received channel open confirmation.");
	  packet_integrity_check(payload_len, 4 + 4, type);
	  channel_input_open_confirmation();
	  break;

	case SSH_MSG_CHANNEL_OPEN_FAILURE:
	  debug("Received channel open failure.");
	  packet_integrity_check(payload_len, 4, type);
	  channel_input_open_failure();
	  break;
	  
	case SSH_MSG_CHANNEL_DATA:
	  channel_input_data(payload_len);
	  break;
	  
	case SSH_MSG_CHANNEL_CLOSE:
	  debug("Received channel close.");
	  packet_integrity_check(payload_len, 4, type);
	  channel_input_close();
	  break;

	case SSH_MSG_CHANNEL_CLOSE_CONFIRMATION:
	  debug("Received channel close confirmation.");
	  packet_integrity_check(payload_len, 4, type);
	  channel_input_close_confirmation();
	  break;

	default:
	  /* In this phase, any unexpected messages cause a protocol
	     error.  This is to ease debugging; also, since no 
	     confirmations are sent messages, unprocessed unknown 
	     messages could cause strange problems.  Any compatible 
	     protocol extensions must be negotiated before entering the 
	     interactive session. */
	  packet_disconnect("Protocol error during session: type %d", 
			    type);
	}
    }
}

/* Make packets from buffered stderr data, and buffer it for sending
   to the client. */

void make_packets_from_stderr_data()
{
  int len;

  /* Send buffered stderr data to the client. */
  while (buffer_len(&stderr_buffer) > 0 && 
	 packet_not_very_much_data_to_write())
    {
      len = buffer_len(&stderr_buffer);
      if (packet_is_interactive())
	{
	  if (len > 512)
	    len = 512;
	}
      else
	{
	  if (len > 32768)
	    len = 32768;  /* Keep the packets at reasonable size. */
	}
      packet_start(SSH_SMSG_STDERR_DATA);
      packet_put_string(buffer_ptr(&stderr_buffer), len);
      packet_send();
      buffer_consume(&stderr_buffer, len);
      stderr_bytes += len;
    }
}

/* Make packets from buffered stdout data, and buffer it for sending to the
   client. */

void make_packets_from_stdout_data()
{
  int len;

  /* Send buffered stdout data to the client. */
  while (buffer_len(&stdout_buffer) > 0 && 
	 packet_not_very_much_data_to_write())
    {
      len = buffer_len(&stdout_buffer);
      if (packet_is_interactive())
	{
	  if (len > 512)
	    len = 512;
	}
      else
	{
	  if (len > 32768)
	    len = 32768;  /* Keep the packets at reasonable size. */
	}
      packet_start(SSH_SMSG_STDOUT_DATA);
      packet_put_string(buffer_ptr(&stdout_buffer), len);
      packet_send();
      buffer_consume(&stdout_buffer, len);
      stdout_bytes += len;
    }
}

/* Sleep in select() until we can do something.  This will initialize the
   select masks.  Upon return, the masks will indicate which descriptors
   have data or can accept data.  Optionally, a maximum time can be specified
   for the duration of the wait (0 = infinite). */

void wait_until_can_do_something(fd_set *readset, fd_set *writeset,
				 unsigned int max_time_milliseconds)
{
  struct timeval tv, *tvp;
  int ret;

  /* When select fails we restart from here. */
retry_select:

  /* Initialize select() masks. */
  FD_ZERO(readset);
  
  /* Read packets from the client unless we have too much buffered stdin
     or channel data. */
  if (buffer_len(&stdin_buffer) < 4096 &&
      channel_not_very_much_buffered_data())
    FD_SET(connection_in, readset);
  
  /* If there is not too much data already buffered going to the client,
     try to get some more data from the program. */
  if (packet_not_very_much_data_to_write())
    {
      if (!fdout_eof)
	FD_SET(fdout, readset);
      if (!fderr_eof)
	FD_SET(fderr, readset);
    }
  
  FD_ZERO(writeset);
  
  /* Set masks for channel descriptors. */
  channel_prepare_select(readset, writeset);
  
  /* If we have buffered packet data going to the client, mark that
     descriptor. */
  if (packet_have_data_to_write())
    FD_SET(connection_out, writeset);
  
  /* If we have buffered data, try to write some of that data to the
     program. */
  if (fdin != -1 && buffer_len(&stdin_buffer) > 0)
    FD_SET(fdin, writeset);
  
  /* Update the maximum descriptor number if appropriate. */
  if (channel_max_fd() > max_fd)
    max_fd = channel_max_fd();
  
  /* If child has terminated and there is enough buffer space to read from
     it, then read as much as is available and exit. */
  if (child_terminated && packet_not_very_much_data_to_write())
    if (max_time_milliseconds == 0)
      max_time_milliseconds = 100;
  
  if (max_time_milliseconds == 0)
    tvp = NULL;
  else
    {
      tv.tv_sec = max_time_milliseconds / 1000;
      tv.tv_usec = 1000 * (max_time_milliseconds % 1000);
      tvp = &tv;
    }

  /* Wait for something to happen, or the timeout to expire. */
  ret = select(max_fd + 1, readset, writeset, NULL, tvp);
  
  if (ret < 0)
    {
      if (errno != EINTR)
	error("select: %.100s", strerror(errno));
      else
	goto retry_select;
    }
}

/* Processes input from the client and the program.  Input data is stored
   in buffers and processed later. */

void process_input(fd_set *readset)
{
  int len;
  char buf[16384];

  /* Read and buffer any input data from the client. */
  if (FD_ISSET(connection_in, readset))
    {
      len = read(connection_in, buf, sizeof(buf));
      if (len == 0)
	fatal("Connection closed by remote host.");

      /* There is a kernel bug on Solaris that causes select to sometimes
	 wake up even though there is no data available. */
      if (len < 0 && errno == EAGAIN)
	len = 0;

      if (len < 0)
	fatal("Read error from remote host: %.100s", strerror(errno));

      /* Buffer any received data. */
      packet_process_incoming(buf, len);
    }
  
  /* Read and buffer any available stdout data from the program. */
  if (!fdout_eof && FD_ISSET(fdout, readset))
    {
      len = read(fdout, buf, sizeof(buf));
      if (len <= 0)
	fdout_eof = 1;
      else
	{
	  buffer_append(&stdout_buffer, buf, len);
	  fdout_bytes += len;
	}
    }
  
  /* Read and buffer any available stderr data from the program. */
  if (!fderr_eof && FD_ISSET(fderr, readset))
    {
      len = read(fderr, buf, sizeof(buf));
      if (len <= 0)
	fderr_eof = 1;
      else
	buffer_append(&stderr_buffer, buf, len);
    }
}

/* Sends data from internal buffers to client program stdin. */

void process_output(fd_set *writeset)
{
  int len;

  /* Write buffered data to program stdin. */
  if (fdin != -1 && FD_ISSET(fdin, writeset))
    {
      len = write(fdin, buffer_ptr(&stdin_buffer),
		  buffer_len(&stdin_buffer));
      if (len <= 0)
	{
#ifdef USE_PIPES
	  close(fdin); 
#else
          if (fdout == -1)
            close(fdin);
	  else
	    shutdown(fdin, SHUT_WR); /* We will no longer send. */
#endif
	  fdin = -1;
	}
      else
	{
	  /* Successful write.  Consume the data from the buffer. */
	  buffer_consume(&stdin_buffer, len);
	  /* Update the count of bytes written to the program. */
	  stdin_bytes += len;
	}
    }
  
  /* Send any buffered packet data to the client. */
  if (FD_ISSET(connection_out, writeset))
    packet_write_poll();
}

/* Wait until all buffered output has been sent to the client.
   This is used when the program terminates. */

void drain_output()
{
  /* Send any buffered stdout data to the client. */
  if (buffer_len(&stdout_buffer) > 0)
    {
      packet_start(SSH_SMSG_STDOUT_DATA);
      packet_put_string(buffer_ptr(&stdout_buffer), 
			buffer_len(&stdout_buffer));
      packet_send();
      /* Update the count of sent bytes. */
      stdout_bytes += buffer_len(&stdout_buffer);
    }
  
  /* Send any buffered stderr data to the client. */
  if (buffer_len(&stderr_buffer) > 0)
    {
      packet_start(SSH_SMSG_STDERR_DATA);
      packet_put_string(buffer_ptr(&stderr_buffer), 
			buffer_len(&stderr_buffer));
      packet_send();
      /* Update the count of sent bytes. */
      stderr_bytes += buffer_len(&stderr_buffer);
    }
  
  /* Wait until all buffered data has been written to the client. */
  packet_write_wait();
}

/* Performs the interactive session.  This handles data transmission between
   the client and the program.  Note that the notion of stdin, stdout, and
   stderr in this function is sort of reversed: this function writes to
   stdin (of the child program), and reads from stdout and stderr (of the
   child program). */

void server_loop(int pid, int fdin_arg, int fdout_arg, int fderr_arg)
{
  int wait_status, wait_pid;	/* Status and pid returned by wait(). */
  int waiting_termination = 0;  /* Have displayed waiting close message. */
  unsigned int max_time_milliseconds;
  unsigned int previous_stdout_buffer_bytes;
  unsigned int stdout_buffer_bytes;
  int type;

  debug("Entering interactive session.");

  /* Initialize the SIGCHLD kludge. */
  child_pid = pid;
  child_terminated = 0;
  signal(SIGCHLD, sigchld_handler);

  /* Initialize our global variables. */
  fdin = fdin_arg;
  fdout = fdout_arg;
  fderr = fderr_arg;
  connection_in = packet_get_connection_in();
  connection_out = packet_get_connection_out();
  
  previous_stdout_buffer_bytes = 0;

  /* Set approximate I/O buffer size. */
  if (packet_is_interactive())
    buffer_high = 4096;
  else
    buffer_high = 64 * 1024;

  /* Initialize max_fd to the maximum of the known file descriptors. */
  max_fd = fdin;
  if (fdout > max_fd)
    max_fd = fdout;
  if (fderr != -1 && fderr > max_fd)
    max_fd = fderr;
  if (connection_in > max_fd)
    max_fd = connection_in;
  if (connection_out > max_fd)
    max_fd = connection_out;

  /* Initialize Initialize buffers. */
  buffer_init(&stdin_buffer);
  buffer_init(&stdout_buffer);
  buffer_init(&stderr_buffer);

  /* If we have no separate fderr (which is the case when we have a pty - there
     we cannot make difference between data sent to stdout and stderr),
     indicate that we have seen an EOF from stderr.  This way we don\'t
     need to check the descriptor everywhere. */
  if (fderr == -1)
    fderr_eof = 1;

  /* Main loop of the server for the interactive session mode. */
  for (;;)
    {
      fd_set readset, writeset;

      /* Process buffered packets from the client. */
      process_buffered_input_packets();

      /* If we have received eof, and there is no more pending input data,
	 cause a real eof by closing fdin. */
      if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0)
	{
#ifdef USE_PIPES
	  close(fdin);
#else
          if (fdout == -1)
            close(fdin);
	  else
	    shutdown(fdin, SHUT_WR); /* We will no longer send. */
#endif
	  fdin = -1;
	}

      /* Make packets from buffered stderr data to send to the client. */
      make_packets_from_stderr_data();

      /* Make packets from buffered stdout data to send to the client.
	 If there is very little to send, this arranges to not send them
	 now, but to wait a short while to see if we are getting more data.
	 This is necessary, as some systems wake up readers from a pty after
	 each separate character. */
      max_time_milliseconds = 0;
      stdout_buffer_bytes = buffer_len(&stdout_buffer);
      if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 &&
	  stdout_buffer_bytes != previous_stdout_buffer_bytes)
	max_time_milliseconds = 10; /* try again after a while */
      else
	make_packets_from_stdout_data(); /* Send it now. */
      previous_stdout_buffer_bytes = buffer_len(&stdout_buffer);

      /* Send channel data to the client. */
      if (packet_not_very_much_data_to_write())
	channel_output_poll();

      /* Bail out of the loop if the program has closed its output descriptors,
	 and we have no more data to send to the client, and there is no
	 pending buffered data. */
      if (fdout_eof && fderr_eof && !packet_have_data_to_write() &&
	  buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0)
	{
	  if (!channel_still_open())
	    goto quit;
	  if (!waiting_termination)
	    {
	      const char *s = 
		"Waiting for forwarded connections to terminate...\r\n";
	      char *cp;
	      waiting_termination = 1;
	      buffer_append(&stderr_buffer, s, strlen(s));

	      /* Display list of open channels. */
	      cp = channel_open_message();
	      buffer_append(&stderr_buffer, cp, strlen(cp));
	      xfree(cp);
	    }
	}

      /* Sleep in select() until we can do something. */
      wait_until_can_do_something(&readset, &writeset,
				  max_time_milliseconds);

      /* Process any channel events. */
      channel_after_select(&readset, &writeset);

      /* Process input from the client and from program stdout/stderr. */
      process_input(&readset);

      /* Process output to the client and to program stdin. */
      process_output(&writeset);
    }

 quit:
  /* Cleanup and termination code. */

  /* Wait until all output has been sent to the client. */
  drain_output();

  debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.",
	stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes);

  /* Free and clear the buffers. */
  buffer_free(&stdin_buffer);
  buffer_free(&stdout_buffer);
  buffer_free(&stderr_buffer);

  /* Close the file descriptors. */
  if (fdout != -1)
    close(fdout);
  fdout = -1;
  fdout_eof = 1;
  if (fderr != -1)
    close(fderr);
  fderr = -1;
  fderr_eof = 1;
  if (fdin != -1)
    close(fdin);
  fdin = -1;

  /* Stop listening for channels; this removes unix domain sockets. */
  channel_stop_listening();
  
  /* Wait for the child to exit.  Get its exit status. */
  wait_pid = wait(&wait_status);
  if (wait_pid < 0)
    {
      /* It is possible that the wait was handled by SIGCHLD handler.  This
	 may result in either: this call returning with EINTR, or: this
	 call returning ECHILD. */
      if (child_terminated)
	wait_status = child_wait_status;
      else
	packet_disconnect("wait: %.100s", strerror(errno));
    }
  else
    {
      /* Check if it matches the process we forked. */
      if (wait_pid != pid)
	error("Strange, wait returned pid %d, expected %d", wait_pid, pid);
    }

  /* We no longer want our SIGCHLD handler to be called. */
  signal(SIGCHLD, SIG_DFL);

  /* Check if it exited normally. */
  if (WIFEXITED(wait_status))
    {
      /* Yes, normal exit.  Get exit status and send it to the client. */
      debug("Command exited with status %d.", WEXITSTATUS(wait_status));
      packet_start(SSH_SMSG_EXITSTATUS);
      packet_put_int(WEXITSTATUS(wait_status));
      packet_send();
      packet_write_wait();

      /* Wait for exit confirmation.  Note that there might be other
         packets coming before it; however, the program has already died
	 so we just ignore them.  The client is supposed to respond with
	 the confirmation when it receives the exit status. */
      do
	{
	  int plen;
	  type = packet_read(&plen);
	}
      while (type != SSH_CMSG_EXIT_CONFIRMATION);

      debug("Received exit confirmation.");
      return;
    }

  /* Check if the program terminated due to a signal. */
  if (WIFSIGNALED(wait_status))
    packet_disconnect("Command terminated on signal %d.", 
		      WTERMSIG(wait_status));

  /* Some weird exit cause.  Just exit. */
  packet_disconnect("wait returned status %04x.", wait_status);
  /*NOTREACHED*/
}

