* krlogind.c (v4_des_read, v5_des_read): When reading length,
authorMark Eichin <eichin@mit.edu>
Wed, 18 Jan 1995 23:55:49 +0000 (23:55 +0000)
committerMark Eichin <eichin@mit.edu>
Wed, 18 Jan 1995 23:55:49 +0000 (23:55 +0000)
ignore everything before a leading zero (MSB first "reasonable"
value) to compensate for rlogin (mis)use of BSD-OOB data.
* krlogin.c (des_read): same code (in both versions of des_read.)

rlogin -x should be much more reliable now.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@4822 dc483132-0cff-0310-8789-dd5450dbe970

src/appl/bsd/ChangeLog
src/appl/bsd/krlogin.c
src/appl/bsd/krlogind.c

index e4977cad61d53a673eadaffc6fb988f99665a286..b7bbfe44cb03918b1e296069ca6ec8ca90b0a571 100644 (file)
@@ -1,3 +1,10 @@
+Wed Jan 18 14:33:50 1995  Mark Eichin  <eichin@cygnus.com>
+
+       * krlogind.c (v4_des_read, v5_des_read): When reading length,
+       ignore everything before a leading zero (MSB first "reasonable"
+       value) to compensate for rlogin (mis)use of BSD-OOB data.
+       * krlogin.c (des_read): same code (in both versions of des_read.)
+
 Wed Jan 18 01:07:56 1995  Mark Eichin  <eichin@cygnus.com>
 
        * configure.in: undo streams test. It turns out that we want sunos
index 38fa24344565c07682ac42c9ae301d3783f9f064..a03dcdc28739b3a16f7a2c5e34c90bf355694224 100644 (file)
@@ -1685,12 +1685,38 @@ int des_read(fd, buf, len)
        nstored = 0;
     }
     
+#if 0
     if ((cc = krb5_net_read(bsd_context, fd, (char *)&len_buf, 4)) != 4) {
        /* XXX can't read enough, pipe must have closed */
        return(0);
     }
     rd_len =
        ((len_buf[0]<<24) | (len_buf[1]<<16) | (len_buf[2]<<8) | len_buf[3]);
+#else
+       {
+           unsigned char c;
+           int gotzero = 0;
+
+           /* See the comment in v4_des_read. */
+           do {
+               cc = krb5_net_read(bsd_context, fd, &c, 1);
+               /* we should check for non-blocking here, but we'd have
+                  to make it save partial reads as well. */
+               if (cc < 0) return 0; /* read error */
+               if (cc == 1) {
+                   if (c == 0) gotzero = 1;
+               }
+           } while (!gotzero);
+
+           if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
+           rd_len = c;
+           if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
+           rd_len = (rd_len << 8) | c;
+           if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
+           rd_len = (rd_len << 8) | c;
+       }
+
+#endif
     net_len = krb5_encrypt_size(rd_len,eblock.crypto_entry);
     if ((net_len <= 0) || (net_len > sizeof(des_inbuf))) {
        /* preposterous length; assume out-of-sync; only
@@ -1803,12 +1829,37 @@ int des_read(fd, buf, len)
        len -= nstored;
        nstored = 0;
     }
+#if 0
     if ((cc = krb5_net_read(bsd_context, fd, len_buf, 4)) != 4) {
        /* XXX can't read enough, pipe must have closed */
        return(0);
     }
     net_len =
        ((len_buf[0]<<24) | (len_buf[1]<<16) | (len_buf[2]<<8) | len_buf[3]);
+#else
+       {
+           unsigned char c;
+           int gotzero = 0;
+
+           /* See the comment in v4_des_read. */
+           do {
+               cc = krb5_net_read(bsd_context, fd, &c, 1);
+               /* we should check for non-blocking here, but we'd have
+                  to make it save partial reads as well. */
+               if (cc < 0) return 0; /* read error */
+               if (cc == 1) {
+                   if (c == 0) gotzero = 1;
+               }
+           } while (!gotzero);
+
+           if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
+           net_len = c;
+           if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
+           net_len = (net_len << 8) | c;
+           if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
+           net_len = (net_len << 8) | c;
+       }
+#endif
     if (net_len < 0 || net_len > sizeof(des_inbuf)) {
        /* XXX preposterous length, probably out of sync.
           act as if pipe closed */
index 4b1a00b995a344dd8202b45eb41748d6aadd7377..f30f12b0afbc7521893dca022927940b559b28aa 100644 (file)
@@ -1239,6 +1239,7 @@ v5_des_read(fd, buf, len)
        nstored = 0;
     }
     
+#if 0
     if ((cc = krb5_net_read(bsd_context, fd, (char *)len_buf, 4)) != 4) {
        if ((cc < 0)  && ((errno == EWOULDBLOCK) || (errno == EAGAIN)))
            return(cc);
@@ -1250,6 +1251,30 @@ v5_des_read(fd, buf, len)
         ((krb5_ui_4)len_buf[1]<<16) |
         ((krb5_ui_4)len_buf[2]<<8) |
         (krb5_ui_4)len_buf[3]);
+#else
+       {
+           unsigned char c;
+           int gotzero = 0;
+
+           /* See the comment in v4_des_read. */
+           do {
+               cc = krb5_net_read(bsd_context, fd, &c, 1);
+               /* we should check for non-blocking here, but we'd have
+                  to make it save partial reads as well. */
+               if (cc < 0) return 0; /* read error */
+               if (cc == 1) {
+                   if (c == 0) gotzero = 1;
+               }
+           } while (!gotzero);
+
+           if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
+           rd_len = c;
+           if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
+           rd_len = (rd_len << 8) | c;
+           if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
+           rd_len = (rd_len << 8) | c;
+       }
+#endif
     net_len = krb5_encrypt_size(rd_len,eblock.crypto_entry);
     if (net_len < 0 || net_len > sizeof(des_inbuf)) {
        /* XXX preposterous length, probably out of sync.
@@ -1628,7 +1653,8 @@ int len;
                len -= nstored;
                nstored = 0;
        }
-       
+
+#if 0
        if ((cc = krb_net_read(fd, (char *)len_buf, 4)) != 4) {
                /* XXX can't read enough, pipe
                   must have closed */
@@ -1638,6 +1664,40 @@ int len;
                   ((krb5_ui_4)len_buf[1]<<16) |
                   ((krb5_ui_4)len_buf[2]<<8) |
                   (krb5_ui_4)len_buf[3]);
+#else
+       {
+           unsigned char c;
+           int gotzero = 0;
+
+           /* We're fetching the length which is MSB first, and the MSB
+              has to be zero unless the client is sending more than 2^24
+              (16M) bytes in a single write (which is why this code is in
+              rlogin but not rcp or rsh.) The only reasons we'd get something
+              other than zero are:
+                  -- corruption of the tcp stream (which will show up when
+                     everything else is out of sync too)
+                  -- un-caught Berkeley-style "pseudo out-of-band data" which
+                     happens any time the user hits ^C twice.
+              The latter is *very* common, as shown by an 'rlogin -x -d' 
+              using the CNS V4 rlogin.         Mark EIchin 1/95
+             */
+           do {
+               cc = krb_net_read(fd, &c, 1);
+               if (cc < 0) return 0; /* read error */
+               if (cc == 1) {
+                   if (c == 0) gotzero = 1;
+               }
+           } while (!gotzero);
+
+           if ((cc = krb_net_read(fd, &c, 1)) != 1) return 0;
+           net_len = c;
+           if ((cc = krb_net_read(fd, &c, 1)) != 1) return 0;
+           net_len = (net_len << 8) | c;
+           if ((cc = krb_net_read(fd, &c, 1)) != 1) return 0;
+           net_len = (net_len << 8) | c;
+       }
+
+#endif
        if (net_len < 0 || net_len > sizeof(des_inbuf)) {
                /* XXX preposterous length, probably out of sync.
                   act as if pipe closed */