From a9c1459b8601efa5f2d849cd07a0d7639f490c0b Mon Sep 17 00:00:00 2001 From: Izzy Alanis Date: Thu, 24 Feb 2022 17:24:40 -0500 Subject: [PATCH 1/2] Listen for rM's UDP broadcasts through SSH tunnel This allows you to screenshare to a rM that is not on the same subnet as the rmview client. rM's UDP broadcast messages are obtained from the rM device itself. * autoinstall changes to get a decent netcat (nc.traditional) * replace ChallengeReaderProtocol with ssh+netcat --- bin/nc.traditional | Bin 0 -> 22032 bytes resources.qrc | 1 + src/rmview/screenstream/common.py | 1 + src/rmview/screenstream/screenshare.py | 107 +++++++++++++------------ 4 files changed, 57 insertions(+), 52 deletions(-) create mode 100755 bin/nc.traditional diff --git a/bin/nc.traditional b/bin/nc.traditional new file mode 100755 index 0000000000000000000000000000000000000000..a5c443be47bc6219be389846e565e921f25d007d GIT binary patch literal 22032 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 G@_zvS%W<0k literal 0 HcmV?d00001 diff --git a/resources.qrc b/resources.qrc index 801adef..c2b92f7 100644 --- a/resources.qrc +++ b/resources.qrc @@ -5,6 +5,7 @@ assets/dead.svg assets/problem.svg assets/connecting.png + bin/nc.traditional bin/rM1-vnc-server-standalone bin/rM2-vnc-server-standalone diff --git a/src/rmview/screenstream/common.py b/src/rmview/screenstream/common.py index e13d1e3..2fd9e7d 100644 --- a/src/rmview/screenstream/common.py +++ b/src/rmview/screenstream/common.py @@ -81,6 +81,7 @@ def clientConnectionLost(self, connector, reason): reactor.callFromThread(reactor.stop) def clientConnectionFailed(self, connector, reason): + log.warning("Connection failed") if reason.check(ConnectionRefusedError): self.signals.onFatalError.emit(Exception("It seems the tablet is refusing to connect.\nIf you are using the ScreenShare backend please make sure you enabled it on the tablet, before running rmview.")) else: diff --git a/src/rmview/screenstream/screenshare.py b/src/rmview/screenstream/screenshare.py index f284af7..b13368e 100644 --- a/src/rmview/screenstream/screenshare.py +++ b/src/rmview/screenstream/screenshare.py @@ -25,45 +25,6 @@ log = logging.getLogger('rmview') -# the screenshare vnc auth uses udp broadcasts -class ChallengeReaderProtocol(DatagramProtocol): - clients = {} - - def __init__(self, callback): - self.callback = callback - - def datagramReceived(self, datagram, host): - reader = io.BytesIO(datagram) - - # the timestamp is needed for the challenge - timestamp = reader.read(8) - tounx, = unpack("!Q", timestamp) - if timestamp in self.clients: - log.debug(f"skipping challenge {tounx}") - return - log.info(f"received timestamp challenge {tounx}") - - if not self.callback(timestamp): - log.debug("Stopping listening for timestamps") - self.transport.stopListening() - - self.clients[timestamp] = addresses = [] - - ### The rest of the message is ignored for now - # (hashlength,) = unpack("!I", reader.read(4)) - # hash = reader.read(hashlength) - # strhash = hash.hex() - # #TODO: the email hash could be used to filter the broadcasts when multiple devices are on the network - # log.info(f"email hash: {strhash}") - - # #read tablet's listening addresses - # while reader.read(1) == b'\00': - # ip = socket.inet_ntoa(reader.read(4)) - # port, = unpack("!H", reader.read(2)) - # addresses.append(f"{ip}:{port}") - - # log.info(addresses) - class ScreenShareStream(QRunnable): @@ -76,9 +37,17 @@ def __init__(self, ssh): self.signals = ScreenStreamSignals() def needsDependencies(self): - return False + _, out, _ = self.ssh.exec_command("[ -x /usr/bin/nc.traditional ]") + return out.channel.recv_exit_status() != 0 def installDependencies(self): + sftp = self.ssh.open_sftp() + from stat import S_IXUSR + fo = QFile(':bin/nc.traditional') + fo.open(QIODevice.ReadOnly) + sftp.putfo(fo, '/usr/bin/nc.traditional') + fo.close() + sftp.chmod('/usr/bin/nc.traditional', S_IXUSR) pass def stop(self): @@ -96,6 +65,7 @@ def stop(self): reads the usedId from deviceToken from the config file on the rm """ def get_userid(self): + log.info("Getting userid from device for challenge computation...") with self.ssh.open_sftp() as sftp: with sftp.file('/etc/remarkable.conf') as f: file_content = f.read().decode() @@ -109,20 +79,13 @@ def get_userid(self): return(d["auth0-userid"]) def computeChallenge(self, userId, timestamp): + log.info("Computing challenge from userId and timestamp...") userBytes = userId.encode() userIdHash = hashlib.sha256(userBytes).digest() return hashlib.sha256(timestamp + userIdHash).digest() - #Hack to run the vnc with the challenge - def runVnc(self, timestamp): - if not self.factory: - userId = self.get_userid() - challenge = self.computeChallenge(userId, timestamp) - log.info(f"Challenge: {challenge.hex()}, connecting to vnc") - self.startVncClient(challenge) - return False - def startVncClient(self, challenge=None): + log.info("Starting vncClient...") self.factory = VncFactory(self.signals) self.factory.setChallenge(challenge) @@ -130,16 +93,56 @@ def startVncClient(self, challenge=None): #self.vncClient = internet.TCPClient("localhost", 31337, self.factory) self.vncClient = internet.SSLClient(self.ssh.hostname, 5900, self.factory, ssl.ClientContextFactory()) self.vncClient.startService() + log.info("vncClient Started.") + + def readChallengeOverTunnel(self): + log.info("Listening for device broadcast through ssh tunnel...") + stdin, stdout, stderr = self.ssh.exec_command('/usr/bin/nc.traditional -l -u -p 5901 -w 6') + # nc needs its stdin closed before it will return! + stdin.close() + stdout.channel.recv_exit_status() + timestamp = stdout.read(8) + tounx, = unpack("!Q", timestamp) + log.info(f"Timestamp challenge {tounx}") + + ### The rest of the message is ignored for now + # (hashlength,) = unpack("!I", reader.read(4)) + # hash = reader.read(hashlength) + # strhash = hash.hex() + # #TODO: the email hash could be used to filter the broadcasts when multiple devices are on the network + # log.info(f"email hash: {strhash}") + + # #read tablet's listening addresses + # while reader.read(1) == b'\00': + # ip = socket.inet_ntoa(reader.read(4)) + # port, = unpack("!H", reader.read(2)) + # addresses.append(f"{ip}:{port}") + + stderr.close() + stdout.close() + + # TODO: We should check the IP from the packet to ensure it's not a broadcast + # from another rM on the same network, right? + + # compute challenge and start client + userId = self.get_userid() + challenge = self.computeChallenge(userId, timestamp) + log.info(f"Challenge: {challenge.hex()}, connecting to vnc") + + # start the actual vnc client + # this call needs to be done from the main reactor thread (for reasons I don't understand) + reactor.callFromThread(self.startVncClient, challenge) def run(self): log.info("Connecting to ScreenShare, make sure you enable it") try: if self.ssh.softwareVersion > SW_VER_TIMESTAMPS['2.9.1.236']: - log.warning("Authenticating, please wait...") - challengeReader = ChallengeReaderProtocol(self.runVnc) - reactor.listenUDP(5901, challengeReader) + log.info("Authenticating, please wait...") + # do this blocking io in a background thread + reactor.callInThread(self.readChallengeOverTunnel) else: log.warning("Skipping authentication") + # does this work without reactor having been started? self.startVncClient() reactor.run(installSignalHandlers=0) From ae854a418311cb591ba3a76f986db8945734e954 Mon Sep 17 00:00:00 2001 From: Izzy Alanis Date: Thu, 24 Feb 2022 18:13:12 -0500 Subject: [PATCH 2/2] Write empty line to nc to speed up connection --- src/rmview/screenstream/screenshare.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rmview/screenstream/screenshare.py b/src/rmview/screenstream/screenshare.py index b13368e..8827efd 100644 --- a/src/rmview/screenstream/screenshare.py +++ b/src/rmview/screenstream/screenshare.py @@ -99,6 +99,7 @@ def readChallengeOverTunnel(self): log.info("Listening for device broadcast through ssh tunnel...") stdin, stdout, stderr = self.ssh.exec_command('/usr/bin/nc.traditional -l -u -p 5901 -w 6') # nc needs its stdin closed before it will return! + stdin.writelines("\n") stdin.close() stdout.channel.recv_exit_status() timestamp = stdout.read(8)