[K42-discussion] rlogin eof patch

Orran Y Krieger okrieg at us.ibm.com
Sat Feb 18 14:44:24 EST 2006


Thanks!  Committed.



Patrick Bozeman <PEBozeman at lbl.gov> 
Sent by: k42-discussion-bounces+okrieg=us.ibm.com at ozlabs.org
02/15/2006 09:12 PM

To
k42-discussion at ozlabs.org
cc

Subject
[K42-discussion] rlogin eof patch






If a new K42 user accidentally tries to rlogin to K42 via ssh rather
than rlogin, they can hang the K42 rlogin daemon.

It is fairly common for linux distributions to symlink rlogin to ssh. 
If a new user tries to run 'rlogin -p <k42-rlogin-port>' on such a
distribution, the login will fail. If they then kill the ssh process,
the K42 rlogin daemon gets stuck in an infinite loop spewing,  "DEBUG:
ReadStr: read() returned 0: Success." to the console because it isn't
properly handling the EOF condition on the socket. (Note, this happened
to me and it took me awhile to figure out why my login was failing.)

This patch adds EOF checking to the ReadStr function in the pty/Login
implementation.  I also added EINTR handling, but I'm not sure if it is
necessary in K42 applications or not.

Since the native recv is being called in two places, I added a new
function, ReadByte, following the semantics and err_printf usage of the
existing ReadStr, e.g. it returns a uval, with 1 indicating success. 
ReadStr was changed to use ReadByte as was the initial handshake read in
HandShake.

Note that this process is pretty inefficient since its only reading one
byte at a time from the socket, but that's how the ReadStr function
worked prior to the patch too.  Since this is only done during the
handshake code, it doesn't seem worth changing.

I also added an err_printf if EOF is detected on the socket during the
rlogin handshake, which would most likely occur at the start when a user
hits ctrl-c from a stuck ssh connection on the rlogin port.  Hopefully,
this is enough to help them figure out what is wrong.

diff -ru kitchsrc.orig/os/servers/pty/Login.C 
kitchsrc/os/servers/pty/Login.C
--- kitchsrc.orig/os/servers/pty/Login.C                 2005-09-20 
10:13:55.000000000 -0700
+++ kitchsrc/os/servers/pty/Login.C              2006-02-15 
17:58:14.000000000 -0800
@@ -205,27 +205,58 @@
     return ret;
 }
 
+static uval
+ReadByte(int fd, char *buf)
+{
+    int ret;
+
+    do {
+        ret = recv(fd, buf, 1, 0);
+        if (ret < 0) {
+            if (errno == EINTR) {
+                continue;
+            } else {
+                err_printf("Rlogind: read failed %d %s\n",
+                           errno, strerror(errno));
+                return 0;
+            }
+        } else if (ret == 0) {
+            err_printf("Rlogind: unexpected EOF on rlogin socket -- 
verify "
+                       "that the rlogin client is really rlogin and not a 
"
+                       "symlink to ssh.\n");
+            return 0;
+        } else if (ret == 1) {
+            return 1;
+        } else {
+            passertMsg(0, "too many bytes from recv: %d\n", ret);
+            return 0;
+        }
+    } while (1);
+
+    passertMsg(0, "unreachable");
+    return 0;
+}
 
 static uval
 ReadStr(int fd, char *buf, char del, int max=256)
 {
     while (max) {
-                int ret = recv(fd, buf, 1, 0);
-                if (ret<0) {
-                    break;
-                }
-                if (ret == 1) {
-                    if (*buf == del) {
-                                *buf = 0;
-                                return 1;
-                    }
-                    ++buf;
-                    --max;
-                } else {
-                    err_printf("DEBUG: ReadStr: read() returned %d: 
%s.\n",
-                                       errno, strerror(errno));
-                }
+        int ret;
+
+        ret = ReadByte(fd, buf);
+        if (!ret) {
+            return 0;
+        }
+
+        if (*buf == del) {
+            *buf = 0;
+            return 1;
+        }
+
+        ++buf;
+        --max;
     }
+
     return 0;
 }
 
@@ -233,7 +264,6 @@
 HandShake(int fd, char *lname, char *rname, char *term, char *speed)
 {
     char buf[256];
-    int ret;
     /*
     ** Expect:
     **          \0
@@ -243,17 +273,15 @@
     ** Response:
     **          \0
     */
-    ret = recv(fd,buf,1,0);
-
-    if (ret<0) {
-                err_printf("Rlogind: read failed %d %s\n", errno, 
strerror(errno));
-                return 0;
+    if (!ReadByte(fd, buf)) {
+        err_printf("Rlogind: first handshake read failed.\n");
+        return 0;
     }
     if (buf[0] != '\0') {
                 err_printf("Rlogind: first handshake byte was not 
nil.\n");
                 return 0;
     }
-    if (!ReadStr(fd, rname, '\0', 256)<0) {
+    if (!ReadStr(fd, rname, '\0', 256)) {
                 err_printf("Rlogind: real name failure.\n");
                 return 0;
     }
_______________________________________________
K42-discussion mailing list
K42-discussion at ozlabs.org
https://ozlabs.org/mailman/listinfo/k42-discussion

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://ozlabs.org/pipermail/k42-discussion/attachments/20060217/c2c867fb/attachment.htm 


More information about the K42-discussion mailing list