* telnetd assumed 3 bytes width for all commands, but
  SB commands have variable length, ending with IAC SE.

Signed-off-by: Andreas Oberritter <[email protected]>
---
 networking/telnetd.c |   54 ++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/networking/telnetd.c b/networking/telnetd.c
index 33020f1..d42cffb 100644
--- a/networking/telnetd.c
+++ b/networking/telnetd.c
@@ -153,24 +153,48 @@ remove_iacs(struct tsession *ts, int *pnum_totty)
                        break;
                }
                /*
-                * IAC -> SB -> TELOPT_NAWS -> 4-byte -> IAC -> SE
+                * IAC -> SB -> ABC -> <parameters> -> IAC -> SE,
+                * at least 5 bytes
                 */
-               if (ptr[1] == SB && ptr[2] == TELOPT_NAWS) {
-                       struct winsize ws;
-                       if ((ptr+8) >= end)
-                               break;  /* incomplete, can't process */
-                       ws.ws_col = (ptr[3] << 8) | ptr[4];
-                       ws.ws_row = (ptr[5] << 8) | ptr[6];
-                       ioctl(ts->ptyfd, TIOCSWINSZ, (char *)&ws);
-                       ptr += 9;
-                       continue;
-               }
-               /* skip 3-byte IAC non-SB cmd */
+               if (ptr[1] == SB) {
+                       const unsigned char *sbend;
+                       unsigned int plen;
+
+                       if ((ptr + 5) > end)
+                               break;
+                       for (sbend = ptr + 4; sbend < end - 1; sbend++)
+                               if (sbend[0] == IAC && sbend[1] == SE)
+                                       break;
+                       if (sbend == end - 1)
+                               break;
+
+                       plen = sbend - (ptr + 3);
+
+                       if (ptr[2] == TELOPT_NAWS) {
+                               /*
+                                * IAC -> SB -> TELOPT_NAWS -> 4-byte -> IAC -> 
SE
+                                */
+                               struct winsize ws;
+                               if (plen != 4)
+                                       break;  /* incomplete, can't process */
+                               ws.ws_col = (ptr[3] << 8) | ptr[4];
+                               ws.ws_row = (ptr[5] << 8) | ptr[6];
+                               ioctl(ts->ptyfd, TIOCSWINSZ, (char *)&ws);
+                       } else {
+#if DEBUG
+                               fprintf(stderr, "Ignoring IAC SB %s,%s\r\n",
+                                       TELCMD(ptr[1]), TELOPT(ptr[2]));
+#endif
+                       }
+                       ptr += plen + 5;
+               } else {
+                       /* skip 3-byte IAC non-SB cmd */
 #if DEBUG
-               fprintf(stderr, "Ignoring IAC %s,%s\n",
-                               TELCMD(ptr[1]), TELOPT(ptr[2]));
+                       fprintf(stderr, "Ignoring IAC %s,%s\r\n",
+                                       TELCMD(ptr[1]), TELOPT(ptr[2]));
 #endif
-               ptr += 3;
+                       ptr += 3;
+               }
        }
 
        num_totty = totty - ptr0;
-- 
1.7.7

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to