diff --git a/channels.c b/channels.c
new file mode 100644
index 0000000..38a65a0
--- /dev/null
+++ b/channels.c
@@ -0,0 +1,1500 @@
+/*
+
+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.1 1999/10/27 03:42:44 damien Exp $");
+
+#include "ssh.h"
+#include "packet.h"
+#include "xmalloc.h"
+#include "buffer.h"
+#include "authfd.h"
+#include "uidswap.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, old_channels;
+
+  /* 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 (i = 0; i < channels_alloc; i++)
+    if (channels[i].type == SSH_CHANNEL_FREE)
+      {
+	/* Found a free slot.  Initialize the fields and return its number. */
+	buffer_init(&channels[i].input);
+	buffer_init(&channels[i].output);
+	channels[i].self = i;
+	channels[i].type = type;
+	channels[i].x11 = 0;
+	channels[i].sock = sock;
+	channels[i].remote_id = -1;
+	channels[i].remote_name = remote_name;
+        chan_init_iostates(&channels[i]);
+	return i;
+      }
+
+  /* There are no free slots.  Must expand the array. */
+  old_channels = channels_alloc;
+  channels_alloc += 10;
+  channels = xrealloc(channels, channels_alloc * sizeof(Channel));
+  for (i = old_channels; i < channels_alloc; i++)
+    channels[i].type = SSH_CHANNEL_FREE;
+
+  /* We know that the next one after the old maximum channel number is now
+     available.  Initialize and return its number. */
+  buffer_init(&channels[old_channels].input);
+  buffer_init(&channels[old_channels].output);
+  channels[old_channels].self = old_channels;
+  channels[old_channels].type = type;
+  channels[old_channels].x11 = 0;
+  channels[old_channels].sock = sock;
+  channels[old_channels].remote_id = -1;
+  channels[old_channels].remote_name = remote_name;
+  chan_init_iostates(&channels[old_channels]);
+  return old_channels;
+}
+
+/* Free the channel and close its socket. */
+
+void channel_free(int channel)
+{
+  assert(channel >= 0 && channel < channels_alloc &&
+	 channels[channel].type != SSH_CHANNEL_FREE);
+  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;
+	    }
+
+	  /* Received authentication protocol and data match our fake data.
+	     Substitute the fake data with real data. */
+	  assert(x11_fake_data_len == x11_saved_data_len);
+	  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;
+	  /* Enable X11 Problem FIX */
+	  ch->x11 = 1;
+	  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 0x%x 0x%x", ch->self, ch->istate, ch->ostate);
+	    chan_read_failed(ch);
+	    chan_write_failed(ch);
+	    debug("X11 rejected %d 0x%x 0x%x", 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, "port %d, connection from %.200s port %d",
+		      ch->listening_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/%d %.300s\r\n",
+		 c->self,c->type,c->remote_name);
+	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();
+}
