For me this patch (against 1.2.26) fixes the problem of lingering
forwarded agent connections which prevents ssh from terminating.

A simple example of the problem:
     $ ssh SOME_HOSTNAME_HERE ssh-add -l
     SOME_KEY_OUTPUT_HERE
     Waiting for forwarded connections to terminate...
     The following connections are open:
       Forwarded agent connection

The reason for this problem has to do with how ssh tries to gracefully
close a forwarded connection by shutting down the two directions
individually.  On some systems a shutdown() on a unix-domain socket
will not be detected at the other end.  An example of a system where
shutdown() is not detected is HP-UX 10.20.  Linux is an example of a
system where it is detected.  It only matters what system you run ssh
on, not what system you are connecting to.

A forwarded agent connection won't terminate if the agent never
receives the EOF indication on its input which the shutdown() should
have caused.  To work around this we tear down the entire connection
on unix-domain sockets rather than just shutting-down half of the
socket.  This replaces the is_x_connection check and fixes both that
problem and the lingering authentication sockets problem (they are the
same problem if I understand correctly).

Currently we assume all systems fail to detect shutdown()s on AF_UNIX
sockets.  Eventually the configure script should decide if this is
needed on a given system.
                                        Paul H. Hargrove
                                        [EMAIL PROTECTED]


--- ssh-1.2.26/ssh.h.orig       Wed Jul  8 09:40:38 1998
+++ ssh-1.2.26/ssh.h    Fri Apr  9 18:39:04 1999
@@ -656,7 +656,7 @@
 /* Allocate a new channel object and set its type and socket.  Remote_name
    must have been allocated with xmalloc; this will free it when the channel
    is freed. */
-int channel_allocate(int type, int sock, char *remote_name);
+int channel_allocate(int type, int sock, char *remote_name, int family);
 
 /* Free the channel and close its socket. */
 void channel_free(int channel);
--- ssh-1.2.26/newchannels.c.orig       Thu Apr  8 17:58:50 1999
+++ ssh-1.2.26/newchannels.c    Fri Apr  9 18:35:41 1999
@@ -325,7 +325,7 @@
   int listening_port; /* port being listened for forwards */
   char *remote_name;
 
-  int is_x_connection;
+  int family;
 } Channel;
 
 /* Pointer to an array containing all allocated channels.  The array is
@@ -436,7 +436,7 @@
 /* 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 channel_allocate(int type, int sock, char *remote_name, int family)
 {
   int i;
 
@@ -487,9 +487,10 @@
          channels[i].remote_name = remote_name;
          channels[i].status_flags = 0;
          channels[i].local_id = i;
-         channels[i].is_x_connection = 0;
+         channels[i].family = family;
          channels_used++;
          debug("Allocated channel %d of type %d.", i, type);
+         debug("Channel %d linked to socket of addr family %d.", i, family);
          return i;
        }
       i++;
@@ -657,11 +658,14 @@
 
   debug("Channel %d receives input eof.", ch->local_id);
   ch->status_flags |= STATUS_EOF_RECEIVED;
-  if (ch->is_x_connection)
+#ifndef SHUTDOWN_WORKS_ON_AF_UNIX_SOCKETS
+  if (ch->family == AF_UNIX)
     {
-      debug("X problem fix: close the other direction.");
+      debug("Channel %d forcing close of input on AF_UNIX socket.",
+           ch->local_id);
       channel_close_input(ch);
     }
+#endif
   if (ch->type != SSH_CHANNEL_OPEN)
     channel_close_output(ch);
   channel_check_termination(ch);
@@ -945,8 +949,7 @@
              }
 #endif /* LIBWRAP */
              newch = channel_allocate(SSH_CHANNEL_OPENING, newsock, 
-                                      xstrdup(buf));
-             channels[newch].is_x_connection = 1;
+                                      xstrdup(buf), ch->family);
              packet_start(SSH_SMSG_X11_OPEN);
              packet_put_int(newch);
              if (have_hostname_in_open)
@@ -1011,7 +1014,7 @@
              }
 #endif /* LIBWRAP */
              newch = channel_allocate(SSH_CHANNEL_OPENING, newsock, 
-                                      xstrdup(buf));
+                                      xstrdup(buf), ch->family);
              packet_start(SSH_MSG_PORT_OPEN);
              packet_put_int(newch);
              packet_put_string(ch->path, strlen(ch->path));
@@ -1037,7 +1040,7 @@
                }
              sprintf(buf, "Forwarded agent connection");
              newch = channel_allocate(SSH_CHANNEL_OPENING, newsock, 
-                                      xstrdup(buf));
+                                      xstrdup(buf), ch->family);
              packet_start(SSH_SMSG_AGENT_OPEN);
              packet_put_int(newch);
              packet_send();
@@ -1429,7 +1432,7 @@
            
   /* Allocate a channel number for the socket. */
   ch = channel_allocate(SSH_CHANNEL_PORT_LISTENER, sock,
-                       xstrdup("port listener"));
+                       xstrdup("port listener"), AF_INET);
   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 */
@@ -1755,7 +1758,8 @@
 #endif /* O_NONBLOCK && !O_NONBLOCK_BROKEN */
 
   /* Allocate a channel for this connection. */
-  newch = channel_allocate(SSH_CHANNEL_OPEN, sock, originator_string);
+  newch = channel_allocate(SSH_CHANNEL_OPEN, sock,
+                          originator_string, sin.sin_family);
   channels[newch].remote_id = remote_channel;
   
   /* Send a confirmation to the remote host. */
@@ -1883,7 +1887,7 @@
            
   /* Allocate a channel for the socket. */
   (void)channel_allocate(SSH_CHANNEL_X11_LISTENER, sock,
-                        xstrdup("X11 inet listener"));
+                        xstrdup("X11 inet listener"), AF_INET);
 
   /* Return a suitable value for the DISPLAY environment variable. */
   return xstrdup(buf);
@@ -1895,7 +1899,7 @@
 
 void x11_input_open(void)
 {
-  int remote_channel, display_number, sock, newch;
+  int remote_channel, display_number, sock, newch, family;
   const char *display;
   struct sockaddr_un ssun;
   struct sockaddr_in sin;
@@ -1945,6 +1949,7 @@
          goto fail;
        }
       /* Create a socket. */
+      family = AF_UNIX;
       sock = socket(AF_UNIX, SOCK_STREAM, 0);
       if (sock < 0)
        {
@@ -2072,6 +2077,7 @@
   sin.sin_port = htons(6000 + display_number);
 
   /* Create a socket. */
+  family = sin.sin_family;
   sock = socket(sin.sin_family, SOCK_STREAM, 0);
   if (sock < 0)
     {
@@ -2098,10 +2104,9 @@
   
   /* Allocate a channel for this connection. */
   if (x11_saved_proto == NULL)
-    newch = channel_allocate(SSH_CHANNEL_OPEN, sock, remote_host);
+    newch = channel_allocate(SSH_CHANNEL_OPEN, sock, remote_host, family);
   else
-    newch = channel_allocate(SSH_CHANNEL_X11_OPEN, sock, remote_host);
-  channels[newch].is_x_connection = 1;
+    newch = channel_allocate(SSH_CHANNEL_X11_OPEN, sock, remote_host, family);
   channels[newch].remote_id = remote_channel;
   
   debug("Sending open confirmation to the remote host.");
@@ -2409,7 +2414,7 @@
     
   /* Allocate a channel for the authentication agent socket. */
   newch = channel_allocate(SSH_CHANNEL_AUTH_LISTENER, sock,
-                          xstrdup("auth socket"));
+                          xstrdup("auth socket"), AF_UNIX);
   strcpy(channels[newch].path, channel_forwarded_auth_socket_name);
   return 1;
 }
@@ -2454,7 +2459,7 @@
   dummyname = xstrdup("authentication agent connection");
   
   /* Allocate a channel for this connection. */
-  newch = channel_allocate(SSH_CHANNEL_OPEN, sock, dummyname);
+  newch = channel_allocate(SSH_CHANNEL_OPEN, sock, dummyname, AF_UNIX);
   channels[newch].remote_id = remote_channel;
   
   /* Send a confirmation to the remote host. */







-- 
Paul H. Hargrove                   All material not otherwise attributed
[EMAIL PROTECTED]         is the opinion of the author or a typo.

Reply via email to