From d721d2d9bd49e7fcd399e7fd3b3bb548e077ce3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 5 Jun 2023 01:11:33 +0200 Subject: [PATCH] telnet: Quote IAC on sending MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To send a single IAC in the payload, you have to send two IACs, the first quoting the second. Otherwise the sequence will be interpreted as a command by the other side. Signed-off-by: Uwe Kleine-König --- telnet.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/telnet.c b/telnet.c index c32a2d4..2281012 100644 --- a/telnet.c +++ b/telnet.c @@ -29,7 +29,32 @@ static ssize_t telnet_write(struct ios_ops *ios, const void *buf, size_t count) { - return write(ios->fd, buf, count); + size_t handled = 0; + ssize_t ret; + void *iac; + + /* + * To send an IAC character in the data stream, two IACs must be sent. + * So find the first IAC in the data to be send (if any), send the data + * that can be send unquoted, then send the double IAC. + */ + while ((iac = memchr(buf + handled, IAC, count - handled)) != NULL) { + if (iac - (buf + handled)) { + ret = write(ios->fd, buf + handled, iac - (buf + handled)); + if (ret < 0) + return ret; + handled += ret; + } else { + dprintf(ios->fd, "%c%c", IAC, IAC); + handled += 1; + } + } + + /* Send the remaining data that needs no quoting. */ + ret = write(ios->fd, buf + handled, count - handled); + if (ret < 0) + return ret; + return ret + handled; } static ssize_t telnet_read(struct ios_ops *ios, void *buf, size_t count)