/*

channels.c

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

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

Created: Fri Mar 24 16:35:24 1995 ylo

This file contains functions for generic socket connection forwarding.
There is also code for initiating connection forwarding for X11 connections,
arbitrary tcp/ip connections, and the authentication agent connection.

*/

#include "includes.h"
RCSID("$Id: channels.c,v 1.5 1999/11/12 04:19:27 damien Exp $");

#include "ssh.h"
#include "packet.h"
#include "xmalloc.h"
#include "buffer.h"
#include "authfd.h"
#include "uidswap.h"
#include "readconf.h"
#include "servconf.h"

#include "channels.h"
#include "nchan.h"
#include "compat.h"

/* Maximum number of fake X11 displays to try. */
#define MAX_DISPLAYS  1000

/* Max len of agent socket */
#define MAX_SOCKET_NAME 100

/* Pointer to an array containing all allocated channels.  The array is
   dynamically extended as needed. */
static Channel *channels = NULL;

/* Size of the channel array.  All slots of the array must always be
   initialized (at least the type field); unused slots are marked with
   type SSH_CHANNEL_FREE. */
static int channels_alloc = 0;

/* Maximum file descriptor value used in any of the channels.  This is updated
   in channel_allocate. */
static int channel_max_fd_value = 0;

/* Name and directory of socket for authentication agent forwarding. */
static char *channel_forwarded_auth_socket_name = NULL;
static char *channel_forwarded_auth_socket_dir  = NULL;

/* Saved X11 authentication protocol name. */
char *x11_saved_proto = NULL;

/* Saved X11 authentication data.  This is the real data. */
char *x11_saved_data = NULL;
unsigned int x11_saved_data_len = 0;

/* Fake X11 authentication data.  This is what the server will be sending
   us; we should replace any occurrences of this by the real data. */
char *x11_fake_data = NULL;
unsigned int x11_fake_data_len;

/* Data structure for storing which hosts are permitted for forward requests.
   The local sides of any remote forwards are stored in this array to prevent
   a corrupt remote server from accessing arbitrary TCP/IP ports on our
   local network (which might be behind a firewall). */
typedef struct
{
  char *host;		/* Host name. */
  int port;		/* Port number. */
} ForwardPermission;

/* List of all permitted host/port pairs to connect. */
static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
/* Number of permitted host/port pairs in the array. */
static int num_permitted_opens = 0;
/* If this is true, all opens are permitted.  This is the case on the
   server on which we have to trust the client anyway, and the user could
   do anything after logging in anyway. */
static int all_opens_permitted = 0;

/* This is set to true if both sides support SSH_PROTOFLAG_HOST_IN_FWD_OPEN. */
static int have_hostname_in_open = 0;

/* Sets specific protocol options. */

void channel_set_options(int hostname_in_open)
{
  have_hostname_in_open = hostname_in_open;
}

/* Permits opening to any host/port in SSH_MSG_PORT_OPEN.  This is usually
   called by the server, because the user could connect to any port anyway,
   and the server has no way to know but to trust the client anyway. */

void channel_permit_all_opens()
{
  all_opens_permitted = 1;
}

/* Allocate a new channel object and set its type and socket. 
   This will cause remote_name to be freed. */

int channel_allocate(int type, int sock, char *remote_name)
{
  int i, found;
  Channel *c;

  /* Update the maximum file descriptor value. */
  if (sock > channel_max_fd_value)
    channel_max_fd_value = sock;

  /* Do initial allocation if this is the first call. */
  if (channels_alloc == 0)
    {
      channels_alloc = 10;
      channels = xmalloc(channels_alloc * sizeof(Channel));
      for (i = 0; i < channels_alloc; i++)
	channels[i].type = SSH_CHANNEL_FREE;

      /* Kludge: arrange a call to channel_stop_listening if we terminate
	 with fatal(). */
      fatal_add_cleanup((void (*)(void *))channel_stop_listening, NULL);
    }

  /* Try to find a free slot where to put the new channel. */
  for (found = -1, i = 0; i < channels_alloc; i++)
    if (channels[i].type == SSH_CHANNEL_FREE)
      {
	/* Found a free slot. */
	found = i;
	break;
      }

  if (found == -1)
    {
      /* There are no free slots.  Take last+1 slot and expand the array.  */
      found = channels_alloc;
      channels_alloc += 10;
      debug("channel: expanding %d", channels_alloc);
      channels = xrealloc(channels, channels_alloc * sizeof(Channel));
      for (i = found; i < channels_alloc; i++)
        channels[i].type = SSH_CHANNEL_FREE;
    }

  /* Initialize and return new channel number. */
  c=&channels[found];
  buffer_init(&c->input);
  buffer_init(&c->output);
  chan_init_iostates(c);
  c->self = found;
  c->type = type;
  c->sock = sock;
  c->remote_id = -1;
  c->remote_name = remote_name;
  debug("channel %d: new [%s]", found, remote_name);
  return found;
}

/* Free the channel and close its socket. */

void channel_free(int channel)
{
  if (channel < 0 || channel >= channels_alloc ||
      channels[channel].type == SSH_CHANNEL_FREE)
    packet_disconnect("channel free: bad local channel %d", channel);

  if(compat13)
    shutdown(channels[channel].sock, SHUT_RDWR);
  close(channels[channel].sock);
  buffer_free(&channels[channel].input);
  buffer_free(&channels[channel].output);
  channels[channel].type = SSH_CHANNEL_FREE;
  if (channels[channel].remote_name)
    {
      xfree(channels[channel].remote_name);
      channels[channel].remote_name = NULL;
    }
}

/* This is called just before select() to add any bits relevant to
   channels in the select bitmasks. */

void channel_prepare_select(fd_set *readset, fd_set *writeset)
{
  int i;
  Channel *ch;
  unsigned char *ucp;
  unsigned int proto_len, data_len;

  for (i = 0; i < channels_alloc; i++)
    {
      ch = &channels[i];
    redo:
      switch (ch->type)
	{
	case SSH_CHANNEL_X11_LISTENER:
	case SSH_CHANNEL_PORT_LISTENER:
	case SSH_CHANNEL_AUTH_SOCKET:
	  FD_SET(ch->sock, readset);
	  break;

	case SSH_CHANNEL_OPEN:
	  if(compat13){
	    if (buffer_len(&ch->input) < 32768)
	      FD_SET(ch->sock, readset);
	    if (buffer_len(&ch->output) > 0)
	      FD_SET(ch->sock, writeset);
	    break;
	  }
	  /* test whether sockets are 'alive' for read/write */
          if (ch->istate == CHAN_INPUT_OPEN)
            if (buffer_len(&ch->input) < 32768)
              FD_SET(ch->sock, readset);
          if (ch->ostate == CHAN_OUTPUT_OPEN || ch->ostate == CHAN_OUTPUT_WAIT_DRAIN){
            if (buffer_len(&ch->output) > 0){
              FD_SET(ch->sock, writeset);
            }else if(ch->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
              chan_obuf_empty(ch);
            }
          }
          break;

	case SSH_CHANNEL_INPUT_DRAINING:
 	  if (!compat13)
	    fatal("cannot happen: IN_DRAIN");
	  if (buffer_len(&ch->input) == 0)
	    {
	      packet_start(SSH_MSG_CHANNEL_CLOSE);
	      packet_put_int(ch->remote_id);
	      packet_send();
	      ch->type = SSH_CHANNEL_CLOSED;
	      debug("Closing channel %d after input drain.", i);
	      break;
	    }
	  break;

	case SSH_CHANNEL_OUTPUT_DRAINING:
 	  if (!compat13)
	    fatal("cannot happen: OUT_DRAIN");
	  if (buffer_len(&ch->output) == 0)
	    {
	      /* debug("Freeing channel %d after output drain.", i); */
	      channel_free(i);
	      break;
	    }
	  FD_SET(ch->sock, writeset);
	  break;

	case SSH_CHANNEL_X11_OPEN:
	  /* This is a special state for X11 authentication spoofing.  An
	     opened X11 connection (when authentication spoofing is being
	     done) remains in this state until the first packet has been
	     completely read.  The authentication data in that packet is
	     then substituted by the real data if it matches the fake data,
	     and the channel is put into normal mode. */

	  /* Check if the fixed size part of the packet is in buffer. */
	  if (buffer_len(&ch->output) < 12)
	    break;

	  /* Parse the lengths of variable-length fields. */
	  ucp = (unsigned char *)buffer_ptr(&ch->output);
	  if (ucp[0] == 0x42)
	    { /* Byte order MSB first. */
	      proto_len = 256 * ucp[6] + ucp[7];
	      data_len = 256 * ucp[8] + ucp[9];
	    }
	  else
	    if (ucp[0] == 0x6c)
	      { /* Byte order LSB first. */
		proto_len = ucp[6] + 256 * ucp[7];
		data_len = ucp[8] + 256 * ucp[9];
	      }
	    else
	      {
		debug("Initial X11 packet contains bad byte order byte: 0x%x",
		      ucp[0]);
		ch->type = SSH_CHANNEL_OPEN;
		goto reject;
	      }

	  /* Check if the whole packet is in buffer. */
	  if (buffer_len(&ch->output) <
	      12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3))
	    break;
	  
	  /* Check if authentication protocol matches. */
	  if (proto_len != strlen(x11_saved_proto) || 
	      memcmp(ucp + 12, x11_saved_proto, proto_len) != 0)
	    {
	      debug("X11 connection uses different authentication protocol.");
	      ch->type = SSH_CHANNEL_OPEN;
	      goto reject;
	    }

	  /* Check if authentication data matches our fake data. */
	  if (data_len != x11_fake_data_len ||
	      memcmp(ucp + 12 + ((proto_len + 3) & ~3),
		     x11_fake_data, x11_fake_data_len) != 0)
	    {
	      debug("X11 auth data does not match fake data.");
	      ch->type = SSH_CHANNEL_OPEN;
	      goto reject;
	    }

	  /* Check fake data length */
	  if (x11_fake_data_len != x11_saved_data_len)
	    {
	      error("X11 fake_data_len %d != saved_data_len %d",
		     x11_fake_data_len, x11_saved_data_len);
	      ch->type = SSH_CHANNEL_OPEN;
	      goto reject;
	    }

	  /* Received authentication protocol and data match our fake data.
	     Substitute the fake data with real data. */
	  memcpy(ucp + 12 + ((proto_len + 3) & ~3),
		 x11_saved_data, x11_saved_data_len);

	  /* Start normal processing for the channel. */
	  ch->type = SSH_CHANNEL_OPEN;
	  goto redo;
	  
	reject:
	  /* We have received an X11 connection that has bad authentication
	     information. */
	  log("X11 connection rejected because of wrong authentication.\r\n");
	  buffer_clear(&ch->input);
	  buffer_clear(&ch->output);
	  if (compat13) {
            close(ch->sock);
            ch->sock = -1;
            ch->type = SSH_CHANNEL_CLOSED;
            packet_start(SSH_MSG_CHANNEL_CLOSE);
            packet_put_int(ch->remote_id);
            packet_send();
          }else{
	    debug("X11 rejected %d i%d/o%d", ch->self, ch->istate, ch->ostate);
	    chan_read_failed(ch);
	    chan_write_failed(ch);
	    debug("X11 rejected %d i%d/o%d", ch->self, ch->istate, ch->ostate);
	  }
	  break;

	case SSH_CHANNEL_FREE:
	default:
	  continue;
	}
    }
}

/* After select, perform any appropriate operations for channels which
   have events pending. */

void channel_after_select(fd_set *readset, fd_set *writeset)
{
  struct sockaddr addr;
  int addrlen, newsock, i, newch, len;
  Channel *ch;
  char buf[16384], *remote_hostname;
  
  /* Loop over all channels... */
  for (i = 0; i < channels_alloc; i++)
    {
      ch = &channels[i];
      switch (ch->type)
	{
	case SSH_CHANNEL_X11_LISTENER:
	  /* This is our fake X11 server socket. */
	  if (FD_ISSET(ch->sock, readset))
	    {
	      debug("X11 connection requested.");
	      addrlen = sizeof(addr);
	      newsock = accept(ch->sock, &addr, &addrlen);
	      if (newsock < 0)
		{
		  error("accept: %.100s", strerror(errno));
		  break;
		}
	      remote_hostname = get_remote_hostname(newsock);
	      snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",
		      remote_hostname, get_peer_port(newsock));
	      xfree(remote_hostname);
	      newch = channel_allocate(SSH_CHANNEL_OPENING, newsock, 
				       xstrdup(buf));
	      packet_start(SSH_SMSG_X11_OPEN);
	      packet_put_int(newch);
	      if (have_hostname_in_open)
		packet_put_string(buf, strlen(buf));
	      packet_send();
	    }
	  break;
	  
	case SSH_CHANNEL_PORT_LISTENER:
	  /* This socket is listening for connections to a forwarded TCP/IP
	     port. */
	  if (FD_ISSET(ch->sock, readset))
	    {
	      debug("Connection to port %d forwarding to %.100s:%d requested.",
		    ch->listening_port, ch->path, ch->host_port);
	      addrlen = sizeof(addr);
	      newsock = accept(ch->sock, &addr, &addrlen);
	      if (newsock < 0)
		{
		  error("accept: %.100s", strerror(errno));
		  break;
		}
	      remote_hostname = get_remote_hostname(newsock);
	      snprintf(buf, sizeof buf, "listen port %d:%.100s:%d, connect from %.200s:%d",
		      ch->listening_port, ch->path, ch->host_port,
		      remote_hostname, get_peer_port(newsock));
	      xfree(remote_hostname);
	      newch = channel_allocate(SSH_CHANNEL_OPENING, newsock, 
				       xstrdup(buf));
	      packet_start(SSH_MSG_PORT_OPEN);
	      packet_put_int(newch);
	      packet_put_string(ch->path, strlen(ch->path));
	      packet_put_int(ch->host_port);
	      if (have_hostname_in_open)
		packet_put_string(buf, strlen(buf));
	      packet_send();
	    }
	  break;

	case SSH_CHANNEL_AUTH_SOCKET:
	  /* This is the authentication agent socket listening for connections
	     from clients. */
	  if (FD_ISSET(ch->sock, readset))
	    {
	      int nchan;
	      len = sizeof(addr);
	      newsock = accept(ch->sock, &addr, &len);
	      if (newsock < 0)
		{
		  error("accept from auth socket: %.100s", strerror(errno));
		  break;
		}

	      nchan = channel_allocate(SSH_CHANNEL_OPENING, newsock,
				     xstrdup("accepted auth socket"));
	      packet_start(SSH_SMSG_AGENT_OPEN);
	      packet_put_int(nchan);
	      packet_send();
	    }
	  break;

	case SSH_CHANNEL_OPEN:
	  /* This is an open two-way communication channel.  It is not of
	     interest to us at this point what kind of data is being
	     transmitted. */

	  /* Read available incoming data and append it to buffer;
	     shutdown socket, if read or write failes */
	  if (FD_ISSET(ch->sock, readset))
	    {
	      len = read(ch->sock, buf, sizeof(buf));
	      if (len <= 0)
		{
		  if (compat13) {
                    buffer_consume(&ch->output, buffer_len(&ch->output));
                    ch->type = SSH_CHANNEL_INPUT_DRAINING;
                    debug("Channel %d status set to input draining.", i);
                  }else{
                    chan_read_failed(ch);
		  }
		  break;
		}
	      buffer_append(&ch->input, buf, len);
	    }
	  /* Send buffered output data to the socket. */
	  if (FD_ISSET(ch->sock, writeset) && buffer_len(&ch->output) > 0)
	    {
	      len = write(ch->sock, buffer_ptr(&ch->output),
			  buffer_len(&ch->output));
	      if (len <= 0)
		{
		  if (compat13) {
                    buffer_consume(&ch->output, buffer_len(&ch->output));
                    debug("Channel %d status set to input draining.", i);
                    ch->type = SSH_CHANNEL_INPUT_DRAINING;
                  }else{
                    chan_write_failed(ch);
		  }
		  break;
		}
	      buffer_consume(&ch->output, len);
	    }
	  break;

	case SSH_CHANNEL_OUTPUT_DRAINING:
 	  if (!compat13)
		fatal("cannot happen: OUT_DRAIN");
	  /* Send buffered output data to the socket. */
	  if (FD_ISSET(ch->sock, writeset) && buffer_len(&ch->output) > 0)
	    {
	      len = write(ch->sock, buffer_ptr(&ch->output),
			  buffer_len(&ch->output));
	      if (len <= 0)
		buffer_consume(&ch->output, buffer_len(&ch->output));
	      else
		buffer_consume(&ch->output, len);
	    }
	  break;

	case SSH_CHANNEL_X11_OPEN:
	case SSH_CHANNEL_FREE:
	default:
	  continue;
	}
    }
}

/* If there is data to send to the connection, send some of it now. */

void channel_output_poll()
{
  int len, i;
  Channel *ch;

  for (i = 0; i < channels_alloc; i++)
    {
      ch = &channels[i];
      /* We are only interested in channels that can have buffered incoming
	 data. */
      if (ch->type != SSH_CHANNEL_OPEN && 
	  ch->type != SSH_CHANNEL_INPUT_DRAINING)
	continue;

      /* Get the amount of buffered data for this channel. */
      len = buffer_len(&ch->input);
      if (len > 0)
	{
	  /* Send some data for the other side over the secure connection. */
	  if (packet_is_interactive())
	    {
	      if (len > 1024)
		len = 512;
	    }
	  else
	    {
	      if (len > 16384)
		len = 16384;  /* Keep the packets at reasonable size. */
	    }
	  packet_start(SSH_MSG_CHANNEL_DATA);
	  packet_put_int(ch->remote_id);
	  packet_put_string(buffer_ptr(&ch->input), len);
	  packet_send();
	  buffer_consume(&ch->input, len);
	}
      else if(ch->istate == CHAN_INPUT_WAIT_DRAIN)
     	{
 	  if (compat13)
	     fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3");
	  /* input-buffer is empty and read-socket shutdown:
	     tell peer, that we will not send more data: send IEOF */
	  chan_ibuf_empty(ch);
     	}
    }
}

/* This is called when a packet of type CHANNEL_DATA has just been received.
   The message type has already been consumed, but channel number and data
   is still there. */

void channel_input_data(int payload_len)
{
  int channel;
  char *data;
  unsigned int data_len;

  /* Get the channel number and verify it. */
  channel = packet_get_int();
  if (channel < 0 || channel >= channels_alloc ||
      channels[channel].type == SSH_CHANNEL_FREE)
    packet_disconnect("Received data for nonexistent channel %d.", channel);

  /* Ignore any data for non-open channels (might happen on close) */
  if (channels[channel].type != SSH_CHANNEL_OPEN &&
      channels[channel].type != SSH_CHANNEL_X11_OPEN)
    return; 

  /* Get the data. */
  data = packet_get_string(&data_len);
  packet_integrity_check(payload_len, 4 + 4+data_len, SSH_MSG_CHANNEL_DATA);
  buffer_append(&channels[channel].output, data, data_len);
  xfree(data);
}

/* Returns true if no channel has too much buffered data, and false if
   one or more channel is overfull. */

int channel_not_very_much_buffered_data()
{
  unsigned int i;
  Channel *ch;
  
  for (i = 0; i < channels_alloc; i++)
    {
      ch = &channels[i];
      switch (ch->type)
	{
	case SSH_CHANNEL_X11_LISTENER:
	case SSH_CHANNEL_PORT_LISTENER:
	case SSH_CHANNEL_AUTH_SOCKET:
	  continue;
	case SSH_CHANNEL_OPEN:
	  if (buffer_len(&ch->input) > 32768)
	    return 0;
	  if (buffer_len(&ch->output) > 32768)
	    return 0;
	  continue;
	case SSH_CHANNEL_INPUT_DRAINING:
	case SSH_CHANNEL_OUTPUT_DRAINING:
	case SSH_CHANNEL_X11_OPEN:
	case SSH_CHANNEL_FREE:
	default:
	  continue;
	}
    }
  return 1;
}

/* This is called after receiving CHANNEL_CLOSE/IEOF. */

void channel_input_close()
{
  int channel;

  /* Get the channel number and verify it. */
  channel = packet_get_int();
  if (channel < 0 || channel >= channels_alloc ||
      channels[channel].type == SSH_CHANNEL_FREE)
    packet_disconnect("Received data for nonexistent channel %d.", channel);

  if(!compat13){
    /* proto version 1.5 overloads CLOSE with IEOF */
    chan_rcvd_ieof(&channels[channel]);
    return;
  }

  /* Send a confirmation that we have closed the channel and no more data is
     coming for it. */
  packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION);
  packet_put_int(channels[channel].remote_id);
  packet_send();

  /* If the channel is in closed state, we have sent a close request, and
     the other side will eventually respond with a confirmation.  Thus,
     we cannot free the channel here, because then there would be no-one to
     receive the confirmation.  The channel gets freed when the confirmation
     arrives. */
  if (channels[channel].type != SSH_CHANNEL_CLOSED)
    {
      /* Not a closed channel - mark it as draining, which will cause it to
	 be freed later. */
      buffer_consume(&channels[channel].input, 
		     buffer_len(&channels[channel].input));
      channels[channel].type = SSH_CHANNEL_OUTPUT_DRAINING;
      /* debug("Setting status to output draining; output len = %d",
	 buffer_len(&channels[channel].output)); */
    }
}

/* This is called after receiving CHANNEL_CLOSE_CONFIRMATION/OCLOSE. */

void channel_input_close_confirmation()
{
  int channel;

  /* Get the channel number and verify it. */
  channel = packet_get_int();
  if (channel < 0 || channel >= channels_alloc)
    packet_disconnect("Received close confirmation for out-of-range channel %d.",
		      channel);

  if(!compat13){
    /* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
    chan_rcvd_oclose(&channels[channel]);
    return;
  }

  if (channels[channel].type != SSH_CHANNEL_CLOSED)
    packet_disconnect("Received close confirmation for non-closed channel %d (type %d).",
		      channel, channels[channel].type);

  /* Free the channel. */
  channel_free(channel);
}

/* This is called after receiving CHANNEL_OPEN_CONFIRMATION. */

void channel_input_open_confirmation()
{
  int channel, remote_channel;

  /* Get the channel number and verify it. */
  channel = packet_get_int();
  if (channel < 0 || channel >= channels_alloc ||
      channels[channel].type != SSH_CHANNEL_OPENING)
    packet_disconnect("Received open confirmation for non-opening channel %d.",
		      channel);

  /* Get remote side's id for this channel. */
  remote_channel = packet_get_int();

  /* Record the remote channel number and mark that the channel is now open. */
  channels[channel].remote_id = remote_channel;
  channels[channel].type = SSH_CHANNEL_OPEN;
}

/* This is called after receiving CHANNEL_OPEN_FAILURE from the other side. */

void channel_input_open_failure()
{
  int channel;

  /* Get the channel number and verify it. */
  channel = packet_get_int();
  if (channel < 0 || channel >= channels_alloc ||
      channels[channel].type != SSH_CHANNEL_OPENING)
    packet_disconnect("Received open failure for non-opening channel %d.",
		      channel);
  
  /* Free the channel.  This will also close the socket. */
  channel_free(channel);
}

/* Stops listening for channels, and removes any unix domain sockets that
   we might have. */

void channel_stop_listening()
{
  int i;
  for (i = 0; i < channels_alloc; i++)
    {
      switch (channels[i].type)
	{
	case SSH_CHANNEL_AUTH_SOCKET:
	  close(channels[i].sock);
	  remove(channels[i].path);
	  channel_free(i);
	  break;
	case SSH_CHANNEL_PORT_LISTENER:
	case SSH_CHANNEL_X11_LISTENER:
	  close(channels[i].sock);
	  channel_free(i);
	  break;
	default:
	  break;
	}
    }
}

/* Closes the sockets of all channels.  This is used to close extra file
   descriptors after a fork. */

void channel_close_all()
{
  int i;
  for (i = 0; i < channels_alloc; i++)
    {
      if (channels[i].type != SSH_CHANNEL_FREE)
	close(channels[i].sock);
    }
}

/* Returns the maximum file descriptor number used by the channels. */

int channel_max_fd()
{
  return channel_max_fd_value;
}

/* Returns true if any channel is still open. */

int channel_still_open()
{
  unsigned int i;
  for (i = 0; i < channels_alloc; i++)
    switch (channels[i].type)
      {
      case SSH_CHANNEL_FREE:
      case SSH_CHANNEL_X11_LISTENER:
      case SSH_CHANNEL_PORT_LISTENER:
      case SSH_CHANNEL_CLOSED:
      case SSH_CHANNEL_AUTH_SOCKET:
	continue;
      case SSH_CHANNEL_OPENING:
      case SSH_CHANNEL_OPEN:
      case SSH_CHANNEL_X11_OPEN:
	return 1;
      case SSH_CHANNEL_INPUT_DRAINING:
      case SSH_CHANNEL_OUTPUT_DRAINING:
 	if (!compat13)
	  fatal("cannot happen: OUT_DRAIN");
	return 1;
      default:
	fatal("channel_still_open: bad channel type %d", channels[i].type);
	/*NOTREACHED*/
      }
  return 0;
}

/* Returns a message describing the currently open forwarded
   connections, suitable for sending to the client.  The message
   contains crlf pairs for newlines. */

char *channel_open_message()
{
  Buffer buffer;
  int i;
  char buf[512], *cp;

  buffer_init(&buffer);
  snprintf(buf, sizeof buf, "The following connections are open:\r\n");
  buffer_append(&buffer, buf, strlen(buf));
  for (i = 0; i < channels_alloc; i++){
    Channel *c=&channels[i];
    switch (c->type)
      {
      case SSH_CHANNEL_FREE:
      case SSH_CHANNEL_X11_LISTENER:
      case SSH_CHANNEL_PORT_LISTENER:
      case SSH_CHANNEL_CLOSED:
      case SSH_CHANNEL_AUTH_SOCKET:
	continue;
      case SSH_CHANNEL_OPENING:
      case SSH_CHANNEL_OPEN:
      case SSH_CHANNEL_X11_OPEN:
      case SSH_CHANNEL_INPUT_DRAINING:
      case SSH_CHANNEL_OUTPUT_DRAINING:
	snprintf(buf, sizeof buf, "  #%d %.300s (t%d r%d i%d o%d)\r\n",
		 c->self,c->remote_name,
		 c->type,c->remote_id, c->istate,c->ostate);
	buffer_append(&buffer, buf, strlen(buf));
	continue;
      default:
	fatal("channel_still_open: bad channel type %d", c->type);
	/*NOTREACHED*/
      }
  }
  buffer_append(&buffer, "\0", 1);
  cp = xstrdup(buffer_ptr(&buffer));
  buffer_free(&buffer);
  return cp;
}

/* Initiate forwarding of connections to local port "port" through the secure
   channel to host:port from remote side. */

void channel_request_local_forwarding(int port, const char *host,
				      int host_port)
{
  int ch, sock;
  struct sockaddr_in sin;
  extern Options options;

  if (strlen(host) > sizeof(channels[0].path) - 1)
    packet_disconnect("Forward host name too long.");
  
  /* Create a port to listen for the host. */
  sock = socket(AF_INET, SOCK_STREAM, 0);
  if (sock < 0)
    packet_disconnect("socket: %.100s", strerror(errno));

  /* Initialize socket address. */
  memset(&sin, 0, sizeof(sin));
  sin.sin_family = AF_INET;
  if (options.gateway_ports == 1)
    sin.sin_addr.s_addr = htonl(INADDR_ANY);
  else
    sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  sin.sin_port = htons(port);
  
  /* Bind the socket to the address. */
  if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    packet_disconnect("bind: %.100s", strerror(errno));
      
  /* Start listening for connections on the socket. */
  if (listen(sock, 5) < 0)
    packet_disconnect("listen: %.100s", strerror(errno));
	    
  /* Allocate a channel number for the socket. */
  ch = channel_allocate(SSH_CHANNEL_PORT_LISTENER, sock,
			xstrdup("port listener"));
  strcpy(channels[ch].path, host); /* note: host name stored here */
  channels[ch].host_port = host_port; /* port on host to connect to */
  channels[ch].listening_port = port; /* port being listened */
}  

/* Initiate forwarding of connections to port "port" on remote host through
   the secure channel to host:port from local side. */

void channel_request_remote_forwarding(int port, const char *host,
				       int remote_port)
{
  int payload_len;
  /* Record locally that connection to this host/port is permitted. */
  if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
    fatal("channel_request_remote_forwarding: too many forwards");
  permitted_opens[num_permitted_opens].host = xstrdup(host);
  permitted_opens[num_permitted_opens].port = remote_port;
  num_permitted_opens++;

  /* Send the forward request to the remote side. */
  packet_start(SSH_CMSG_PORT_FORWARD_REQUEST);
  packet_put_int(port);
  packet_put_string(host, strlen(host));
  packet_put_int(remote_port);
  packet_send();
  packet_write_wait();
  
  /* Wait for response from the remote side.  It will send a disconnect
     message on failure, and we will never see it here. */
  packet_read_expect(&payload_len, SSH_SMSG_SUCCESS);
}

/* This is called after receiving CHANNEL_FORWARDING_REQUEST.  This initates
   listening for the port, and sends back a success reply (or disconnect
   message if there was an error).  This never returns if there was an 
   error. */

void channel_input_port_forward_request(int is_root)
{
  int port, host_port;
  char *hostname;
  
  /* Get arguments from the packet. */
  port = packet_get_int();
  hostname = packet_get_string(NULL);
  host_port = packet_get_int();
  
  /* Port numbers are 16 bit quantities. */
  if ((port & 0xffff) != port)
    packet_disconnect("Requested forwarding of nonexistent port %d.", port);

  /* Check that an unprivileged user is not trying to forward a privileged
     port. */
  if (port < IPPORT_RESERVED && !is_root)
    packet_disconnect("Requested forwarding of port %d but user is not root.",
		      port);

  /* Initiate forwarding. */
  channel_request_local_forwarding(port, hostname, host_port);

  /* Free the argument string. */
  xfree(hostname);
}

/* This is called after receiving PORT_OPEN message.  This attempts to connect
   to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION or
   CHANNEL_OPEN_FAILURE. */

void channel_input_port_open(int payload_len)
{
  int remote_channel, sock, newch, host_port, i;
  struct sockaddr_in sin;
  char *host, *originator_string;
  struct hostent *hp;
  int host_len, originator_len;

  /* Get remote channel number. */
  remote_channel = packet_get_int();

  /* Get host name to connect to. */
  host = packet_get_string(&host_len);

  /* Get port to connect to. */
  host_port = packet_get_int();

  /* Get remote originator name. */
  if (have_hostname_in_open)
    originator_string = packet_get_string(&originator_len);
  else
    originator_string = xstrdup("unknown (remote did not supply name)");

  packet_integrity_check(payload_len,
			 4 + 4 + host_len + 4 + 4 + originator_len,
			 SSH_MSG_PORT_OPEN);

  /* Check if opening that port is permitted. */
  if (!all_opens_permitted)
    {
      /* Go trough all permitted ports. */
      for (i = 0; i < num_permitted_opens; i++)
	if (permitted_opens[i].port == host_port &&
	    strcmp(permitted_opens[i].host, host) == 0)
	  break;

      /* Check if we found the requested port among those permitted. */
      if (i >= num_permitted_opens)
	{
	  /* The port is not permitted. */
	  log("Received request to connect to %.100s:%d, but the request was denied.",
	      host, host_port);
	  packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
	  packet_put_int(remote_channel);
	  packet_send();
	}
    }
  
  memset(&sin, 0, sizeof(sin));
  sin.sin_addr.s_addr = inet_addr(host);
  if ((sin.sin_addr.s_addr & 0xffffffff) != 0xffffffff)
    {
      /* It was a valid numeric host address. */
      sin.sin_family = AF_INET;
    }
  else
    {
      /* Look up the host address from the name servers. */
      hp = gethostbyname(host);
      if (!hp)
	{
	  error("%.100s: unknown host.", host);
	  goto fail;
	}
      if (!hp->h_addr_list[0])
	{
	  error("%.100s: host has no IP address.", host);
	  goto fail;
	}
      sin.sin_family = hp->h_addrtype;
      memcpy(&sin.sin_addr, hp->h_addr_list[0], 
	     sizeof(sin.sin_addr));
    }
  sin.sin_port = htons(host_port);

  /* Create the socket. */
  sock = socket(sin.sin_family, SOCK_STREAM, 0);
  if (sock < 0)
    {
      error("socket: %.100s", strerror(errno));
      goto fail;
    }

  /* Connect to the host/port. */
  if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    {
      error("connect %.100s:%d: %.100s", host, host_port,
	    strerror(errno));
      close(sock);
      goto fail;
    }

  /* Successful connection. */

  /* Allocate a channel for this connection. */
  newch = channel_allocate(SSH_CHANNEL_OPEN, sock, originator_string);
  channels[newch].remote_id = remote_channel;
  
  /* Send a confirmation to the remote host. */
  packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
  packet_put_int(remote_channel);
  packet_put_int(newch);
  packet_send();

  /* Free the argument string. */
  xfree(host);
  
  return;

 fail:
  /* Free the argument string. */
  xfree(host);

  /* Send refusal to the remote host. */
  packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
  packet_put_int(remote_channel);
  packet_send();
}

/* Creates an internet domain socket for listening for X11 connections. 
   Returns a suitable value for the DISPLAY variable, or NULL if an error
   occurs. */

char *x11_create_display_inet(int screen_number)
{
  extern ServerOptions options;
  int display_number, port, sock;
  struct sockaddr_in sin;
  char buf[512];
  char hostname[MAXHOSTNAMELEN];

  for (display_number = options.x11_display_offset; display_number < MAX_DISPLAYS; display_number++)
    {
      port = 6000 + display_number;
      memset(&sin, 0, sizeof(sin));
      sin.sin_family = AF_INET;
      sin.sin_addr.s_addr = htonl(INADDR_ANY);
      sin.sin_port = htons(port);
      
      sock = socket(AF_INET, SOCK_STREAM, 0);
      if (sock < 0)
	{
	  error("socket: %.100s", strerror(errno));
	  return NULL;
	}
      
      if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
	{
	  debug("bind port %d: %.100s", port, strerror(errno));
	  shutdown(sock, SHUT_RDWR);
	  close(sock);
	  continue;
	}
      break;
    }
  if (display_number >= MAX_DISPLAYS)
    {
      error("Failed to allocate internet-domain X11 display socket.");
      return NULL;
    }

  /* Start listening for connections on the socket. */
  if (listen(sock, 5) < 0)
    {
      error("listen: %.100s", strerror(errno));
      shutdown(sock, SHUT_RDWR);
      close(sock);
      return NULL;
    }

  /* Set up a suitable value for the DISPLAY variable. */
  if (gethostname(hostname, sizeof(hostname)) < 0)
    fatal("gethostname: %.100s", strerror(errno));
  snprintf(buf, sizeof buf, "%.400s:%d.%d", hostname,
    display_number, screen_number);
	    
  /* Allocate a channel for the socket. */
  (void)channel_allocate(SSH_CHANNEL_X11_LISTENER, sock,
			 xstrdup("X11 inet listener"));

  /* Return a suitable value for the DISPLAY environment variable. */
  return xstrdup(buf);
}

#ifndef X_UNIX_PATH
#define X_UNIX_PATH "/tmp/.X11-unix/X"
#endif

static
int
connect_local_xsocket(unsigned dnr)
{
  static const char *const x_sockets[] = {
    X_UNIX_PATH "%u",
    "/var/X/.X11-unix/X" "%u",
    "/usr/spool/sockets/X11/" "%u",
    NULL
  };
  int sock;
  struct sockaddr_un addr;
  const char *const *path;

  for (path = x_sockets; *path; ++path)
    {
      sock = socket(AF_UNIX, SOCK_STREAM, 0);
      if (sock < 0)
	error("socket: %.100s", strerror(errno));
      memset(&addr, 0, sizeof(addr));
      addr.sun_family = AF_UNIX;
      snprintf(addr.sun_path, sizeof addr.sun_path, *path, dnr);
      if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)
	return sock;
      close(sock);
    }
  error("connect %.100s: %.100s", addr.sun_path, strerror(errno));
  return -1;
}


/* This is called when SSH_SMSG_X11_OPEN is received.  The packet contains
   the remote channel number.  We should do whatever we want, and respond
   with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. */

void x11_input_open(int payload_len)
{
  int remote_channel, display_number, sock, newch;
  const char *display;
  struct sockaddr_in sin;
  char buf[1024], *cp, *remote_host;
  struct hostent *hp;
  int remote_len;

  /* Get remote channel number. */
  remote_channel = packet_get_int();

  /* Get remote originator name. */
  if (have_hostname_in_open)
    remote_host = packet_get_string(&remote_len);
  else
    remote_host = xstrdup("unknown (remote did not supply name)");

  debug("Received X11 open request.");
  packet_integrity_check(payload_len, 4 + 4+remote_len, SSH_SMSG_X11_OPEN);

  /* Try to open a socket for the local X server. */
  display = getenv("DISPLAY");
  if (!display)
    {
      error("DISPLAY not set.");
      goto fail;
    }
  
  /* Now we decode the value of the DISPLAY variable and make a connection
     to the real X server. */

  /* Check if it is a unix domain socket.  Unix domain displays are in one
     of the following formats: unix:d[.s], :d[.s], ::d[.s] */
  if (strncmp(display, "unix:", 5) == 0 ||
      display[0] == ':')
    {
      /* Connect to the unix domain socket. */
      if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1)
	{
	  error("Could not parse display number from DISPLAY: %.100s",
		display);
	  goto fail;
	}
      /* Create a socket. */
      sock = connect_local_xsocket(display_number);
      if (sock < 0)
	goto fail;

      /* OK, we now have a connection to the display. */
      goto success;
    }
  
  /* Connect to an inet socket.  The DISPLAY value is supposedly
      hostname:d[.s], where hostname may also be numeric IP address. */
  strncpy(buf, display, sizeof(buf));
  buf[sizeof(buf) - 1] = 0;
  cp = strchr(buf, ':');
  if (!cp)
    {
      error("Could not find ':' in DISPLAY: %.100s", display);
      goto fail;
    }
  *cp = 0;
  /* buf now contains the host name.  But first we parse the display number. */
  if (sscanf(cp + 1, "%d", &display_number) != 1)
    {
       error("Could not parse display number from DISPLAY: %.100s",
	     display);
      goto fail;
    }
  
  /* Try to parse the host name as a numeric IP address. */
  memset(&sin, 0, sizeof(sin));
  sin.sin_addr.s_addr = inet_addr(buf);
  if ((sin.sin_addr.s_addr & 0xffffffff) != 0xffffffff)
    {
      /* It was a valid numeric host address. */
      sin.sin_family = AF_INET;
    }
  else
    {
      /* Not a numeric IP address. */
      /* Look up the host address from the name servers. */
      hp = gethostbyname(buf);
      if (!hp)
	{
	  error("%.100s: unknown host.", buf);
	  goto fail;
	}
      if (!hp->h_addr_list[0])
	{
	  error("%.100s: host has no IP address.", buf);
	  goto fail;
	}
      sin.sin_family = hp->h_addrtype;
      memcpy(&sin.sin_addr, hp->h_addr_list[0], 
	     sizeof(sin.sin_addr));
    }
  /* Set port number. */
  sin.sin_port = htons(6000 + display_number);

  /* Create a socket. */
  sock = socket(sin.sin_family, SOCK_STREAM, 0);
  if (sock < 0)
    {
      error("socket: %.100s", strerror(errno));
      goto fail;
    }
  /* Connect it to the display. */
  if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    {
      error("connect %.100s:%d: %.100s", buf, 6000 + display_number, 
	    strerror(errno));
      close(sock);
      goto fail;
    }

 success:
  /* We have successfully obtained a connection to the real X display. */
  
  /* Allocate a channel for this connection. */
  if (x11_saved_proto == NULL)
    newch = channel_allocate(SSH_CHANNEL_OPEN, sock, remote_host);
  else
    newch = channel_allocate(SSH_CHANNEL_X11_OPEN, sock, remote_host);
  channels[newch].remote_id = remote_channel;
  
  /* Send a confirmation to the remote host. */
  packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
  packet_put_int(remote_channel);
  packet_put_int(newch);
  packet_send();
  
  return;

 fail:
  /* Send refusal to the remote host. */
  packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
  packet_put_int(remote_channel);
  packet_send();
}

/* Requests forwarding of X11 connections, generates fake authentication
   data, and enables authentication spoofing. */

void x11_request_forwarding_with_spoofing(const char *proto, const char *data)
{
  unsigned int data_len = (unsigned int)strlen(data) / 2;
  unsigned int i, value;
  char *new_data;
  int screen_number;
  const char *cp;
  u_int32_t rand = 0;

  cp = getenv("DISPLAY");
  if (cp)
    cp = strchr(cp, ':');
  if (cp)
    cp = strchr(cp, '.');
  if (cp)
    screen_number = atoi(cp + 1);
  else
    screen_number = 0;

  /* Save protocol name. */
  x11_saved_proto = xstrdup(proto);

  /* Extract real authentication data and generate fake data of the same
     length. */
  x11_saved_data = xmalloc(data_len);
  x11_fake_data = xmalloc(data_len);
  for (i = 0; i < data_len; i++)
    {
      if (sscanf(data + 2 * i, "%2x", &value) != 1)
	fatal("x11_request_forwarding: bad authentication data: %.100s", data);
      if (i % 4 == 0)
	rand = arc4random();
      x11_saved_data[i] = value;
      x11_fake_data[i] = rand & 0xff;
      rand >>= 8;
    }
  x11_saved_data_len = data_len;
  x11_fake_data_len = data_len;

  /* Convert the fake data into hex. */
  new_data = xmalloc(2 * data_len + 1);
  for (i = 0; i < data_len; i++)
    sprintf(new_data + 2 * i, "%02x", (unsigned char)x11_fake_data[i]);

  /* Send the request packet. */
  packet_start(SSH_CMSG_X11_REQUEST_FORWARDING);
  packet_put_string(proto, strlen(proto));
  packet_put_string(new_data, strlen(new_data));
  packet_put_int(screen_number);
  packet_send();
  packet_write_wait();
  xfree(new_data);
}

/* Sends a message to the server to request authentication fd forwarding. */

void auth_request_forwarding()
{
  packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING);
  packet_send();
  packet_write_wait();
}

/* Returns the name of the forwarded authentication socket.  Returns NULL
   if there is no forwarded authentication socket.  The returned value
   points to a static buffer. */

char *auth_get_socket_name()
{
  return channel_forwarded_auth_socket_name;
}

/* removes the agent forwarding socket */

void cleanup_socket(void) {
  remove(channel_forwarded_auth_socket_name);
  rmdir(channel_forwarded_auth_socket_dir);
}

/* This if called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server.
   This starts forwarding authentication requests. */

void auth_input_request_forwarding(struct passwd *pw)
{
  int sock, newch;
  struct sockaddr_un sunaddr;
  
  if (auth_get_socket_name() != NULL)
    fatal("Protocol error: authentication forwarding requested twice.");

  /* Temporarily drop privileged uid for mkdir/bind. */
  temporarily_use_uid(pw->pw_uid);

  /* Allocate a buffer for the socket name, and format the name. */
  channel_forwarded_auth_socket_name = xmalloc(MAX_SOCKET_NAME);
  channel_forwarded_auth_socket_dir  = xmalloc(MAX_SOCKET_NAME);
  strlcpy(channel_forwarded_auth_socket_dir, "/tmp/ssh-XXXXXXXX", MAX_SOCKET_NAME);

  /* Create private directory for socket */
  if (mkdtemp(channel_forwarded_auth_socket_dir) == NULL)
    packet_disconnect("mkdtemp: %.100s", strerror(errno));
  snprintf(channel_forwarded_auth_socket_name, MAX_SOCKET_NAME,
	   "%s/agent.%d", channel_forwarded_auth_socket_dir, (int)getpid());

  if (atexit(cleanup_socket) < 0) {
    int saved=errno;
    cleanup_socket();
    packet_disconnect("socket: %.100s", strerror(saved));
  }

  /* Create the socket. */
  sock = socket(AF_UNIX, SOCK_STREAM, 0);
  if (sock < 0)
    packet_disconnect("socket: %.100s", strerror(errno));

  /* Bind it to the name. */
  memset(&sunaddr, 0, sizeof(sunaddr));
  sunaddr.sun_family = AF_UNIX;
  strncpy(sunaddr.sun_path, channel_forwarded_auth_socket_name, 
          sizeof(sunaddr.sun_path));

  if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0)
    packet_disconnect("bind: %.100s", strerror(errno));

  /* Restore the privileged uid. */
  restore_uid();

  /* Start listening on the socket. */
  if (listen(sock, 5) < 0)
    packet_disconnect("listen: %.100s", strerror(errno));

  /* Allocate a channel for the authentication agent socket. */
  newch = channel_allocate(SSH_CHANNEL_AUTH_SOCKET, sock,
    		       xstrdup("auth socket"));
  strcpy(channels[newch].path, channel_forwarded_auth_socket_name);
}

/* This is called to process an SSH_SMSG_AGENT_OPEN message. */

void auth_input_open_request()
{
  int remch, sock, newch;
  char *dummyname;

  /* Read the remote channel number from the message. */
  remch = packet_get_int();
  
  /* Get a connection to the local authentication agent (this may again get
     forwarded). */
  sock = ssh_get_authentication_socket();

  /* If we could not connect the agent, send an error message back to
     the server. This should never happen unless the agent
     dies, because authentication forwarding is only enabled if we have an
     agent. */
  if (sock < 0){
    packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
    packet_put_int(remch);
    packet_send();
    return;
  }

  debug("Forwarding authentication connection.");

  /* Dummy host name.  This will be freed when the channel is freed; it will
     still be valid in the packet_put_string below since the channel cannot
     yet be freed at that point. */
  dummyname = xstrdup("authentication agent connection");
  
  newch = channel_allocate(SSH_CHANNEL_OPEN, sock, dummyname);
  channels[newch].remote_id = remch;
  
  /* Send a confirmation to the remote host. */
  packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
  packet_put_int(remch);
  packet_put_int(newch);
  packet_send();
}
