From 206e36008f15d2bbcf2e8607605f3cac47e3036b Mon Sep 17 00:00:00 2001 From: Darius Davis Date: Wed, 21 Jun 2023 21:15:41 -0700 Subject: [PATCH] vSPC: Escape 'sequence' and 'secret' in replies. The values of 'sequence' and 'secret' are arbitrary byte strings which might contain IAC (0xff) or SE (0xf0) in any position. Lack of escaping during transmission might cause receiver confusion and potentially vMotion failures. This change adds escaping of these 'sequence' and 'secret' values before transmission. They are already being unescaped correctly during receipt; Only the transmit side needs to be fixed. Change-Id: I82384424d684b931805ca921d0597ad7642f66ac --- tox.ini | 3 ++- vspc/async_telnet.py | 6 ++++++ vspc/server.py | 5 +++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/tox.ini b/tox.ini index e1222b8..4c1de61 100644 --- a/tox.ini +++ b/tox.ini @@ -15,5 +15,6 @@ commands = flake8 commands = {posargs} [flake8] -ignore = E121,E122,E123,E124,E125,E126,E127,E128,E129,E131,E251,H405 +# W504 skipped since you must choose either W503 or W504 (they conflict) +ignore = E121,E122,E123,E124,E125,E126,E127,E128,E129,E131,E251,H405,W504 exclude = venv,.venv,.git,.tox,dist,doc,*lib/python*,*egg,build diff --git a/vspc/async_telnet.py b/vspc/async_telnet.py index deb40db..980318b 100644 --- a/vspc/async_telnet.py +++ b/vspc/async_telnet.py @@ -44,6 +44,12 @@ class AsyncTelnet: self.sb = 0 # flag for SB and SE sequence. self.sbdataq = b'' + @staticmethod + def escape(data): + """Escape any Telnet IACs with another IAC. + """ + return data.replace(IAC, IAC + IAC) + @asyncio.coroutine def process_rawq(self): """Transfer from raw queue to cooked queue. diff --git a/vspc/server.py b/vspc/server.py index 524e922..39cf053 100755 --- a/vspc/server.py +++ b/vspc/server.py @@ -121,7 +121,7 @@ class VspcServer(object): secret = os.urandom(4) LOG.debug(">> %s VMOTION-GOAHEAD %s %s", peer, data, secret) writer.write(IAC + SB + VMWARE_EXT + VMOTION_GOAHEAD + - data + secret + IAC + SE) + async_telnet.AsyncTelnet.escape(data + secret) + IAC + SE) yield from writer.drain() @asyncio.coroutine @@ -130,7 +130,8 @@ class VspcServer(object): peer = socket.getpeername() LOG.debug("<< %s VMOTION-PEER %s", peer, data) LOG.debug("<< %s VMOTION-PEER-OK %s", peer, data) - writer.write(IAC + SB + VMWARE_EXT + VMOTION_PEER_OK + data + IAC + SE) + writer.write(IAC + SB + VMWARE_EXT + VMOTION_PEER_OK + + async_telnet.AsyncTelnet.escape(data) + IAC + SE) yield from writer.drain() def handle_vmotion_complete(self, socket, data):