telnetd: treat all 2-byte IACs in 240..249 range as NOPs.
authorDenys Vlasenko <vda.linux@googlemail.com>
Wed, 12 Oct 2016 17:41:33 +0000 (19:41 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 12 Oct 2016 17:41:33 +0000 (19:41 +0200)
A bit of future-proofing. Some of them can stand just being ignored.

function                                             old     new   delta
telnetd_main                                        1791    1798      +7

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
networking/telnetd.c

index 0da29410e62b519f3dae743bd02e083f0510e20f..eaaf29bce0a6cb93c627c83b197d9b437a74120f 100644 (file)
@@ -169,12 +169,10 @@ safe_write_to_pty_decode_iac(struct tsession *ts)
  handle_iac:
        /* 2-byte commands (240..250 and 255):
         * IAC IAC (255) Literal 255. Supported.
+        * IAC SE  (240) End of subnegotiation. Treated as NOP.
         * IAC NOP (241) NOP. Supported.
         * IAC BRK (243) Break. Like serial line break. TODO via tcsendbreak()?
         * IAC AYT (246) Are you there. Send back evidence that AYT was seen. TODO (send NOP back)?
-        *  Implemented only as part of NAWS:
-        * IAC SB  (250) Subnegotiation of an option follows.
-        * IAC SE  (240) End of subnegotiation.
         *  These don't look useful:
         * IAC DM  (242) Data mark. What is this?
         * IAC IP  (244) Suspend, interrupt or abort the process. (Ancient cousin of ^C).
@@ -182,8 +180,11 @@ safe_write_to_pty_decode_iac(struct tsession *ts)
         * IAC EC  (247) Erase character. The receiver should delete the last received char.
         * IAC EL  (248) Erase line. The receiver should delete everything up tp last newline.
         * IAC GA  (249) Go ahead. For half-duplex lines: "now you talk".
+        *  Implemented only as part of NAWS:
+        * IAC SB  (250) Subnegotiation of an option follows.
         */
-       if (buf[1] == IAC) { /* Literal 255 (emacs M-DEL) */
+       if (buf[1] == IAC) {
+               /* Literal 255 (emacs M-DEL) */
                //bb_error_msg("255!");
                rc = safe_write(ts->ptyfd, &buf[1], 1);
                if (rc <= 0)
@@ -191,7 +192,9 @@ safe_write_to_pty_decode_iac(struct tsession *ts)
                rc = 2;
                goto update_and_return;
        }
-       if (buf[1] == NOP) { /* NOP (241). Ignore (putty keepalive, etc) */
+       if (buf[1] >= 240 && buf[1] <= 249) {
+               /* NOP (241). Ignore (putty keepalive, etc) */
+               /* All other 2-byte commands also treated as NOPs here */
                rc = 2;
                goto update_and_return;
        }
@@ -205,24 +208,27 @@ safe_write_to_pty_decode_iac(struct tsession *ts)
                goto update_and_return;
        }
 
-       /* TELOPT_NAWS support */
-       /* IAC SB, TELOPT_NAWS, 4-byte, IAC SE */
-       if (buf[1] == SB && buf[2] == TELOPT_NAWS) {
-               struct winsize ws;
-               if (wr <= 8) {
+       if (buf[1] == SB) {
+               if (buf[2] == TELOPT_NAWS) {
+                       /* IAC SB, TELOPT_NAWS, 4-byte, IAC SE */
+                       struct winsize ws;
+                       if (wr <= 6) {
 /* BUG: incomplete, can't process */
-                       rc = wr;
+                               rc = wr;
+                               goto update_and_return;
+                       }
+                       memset(&ws, 0, sizeof(ws)); /* pixel sizes are set to 0 */
+                       ws.ws_col = (buf[3] << 8) | buf[4];
+                       ws.ws_row = (buf[5] << 8) | buf[6];
+                       ioctl(ts->ptyfd, TIOCSWINSZ, (char *)&ws);
+                       rc = 7;
+                       /* trailing IAC SE will be eaten separately, as 2-byte NOP */
                        goto update_and_return;
                }
-               memset(&ws, 0, sizeof(ws));
-               ws.ws_col = (buf[3] << 8) | buf[4];
-               ws.ws_row = (buf[5] << 8) | buf[6];
-               ioctl(ts->ptyfd, TIOCSWINSZ, (char *)&ws);
-               rc = 9;
-               goto update_and_return;
+               /* else: other subnegs not supported yet */
        }
 
-       /* Skip 3-byte cmds (assume they are WILL/WONT/DO/DONT 251..254 codes) */
+       /* Assume it is a 3-byte WILL/WONT/DO/DONT 251..254 command and skip it */
 #if DEBUG
        fprintf(stderr, "Ignoring IAC %s,%s\n",
                        TELCMD(buf[1]), TELOPT(buf[2]));