An RFB proxy, written in go that can save and replay FBS files
Go to file
2021-10-04 22:07:23 +02:00
.circleci use circle 2019-06-16 20:38:05 +03:00
.idea added cmdline binaries for proxy and player 2017-07-28 17:48:22 +03:00
.vscode moved and parametrized the recorder 2017-08-03 14:30:39 +03:00
architecture some more house cleaning, updated license & docs 2017-07-15 07:52:23 +03:00
client Added reMarkable 2.10 authentication support. 2021-10-04 20:37:53 +02:00
common global: make the whole package go mod ready 2018-11-30 09:40:45 +01:00
encodings global: make the whole package go mod ready 2018-11-30 09:40:45 +01:00
logger added logger trace level and set it to write all bytes 2018-10-19 08:13:16 +03:00
player fixed cicrleCI testing 2019-06-16 02:59:17 +03:00
proxy Added reMarkable 2.10 authentication support. 2021-10-04 20:37:53 +02:00
recorder global: make the whole package go mod ready 2018-11-30 09:40:45 +01:00
server Added reMarkable 2.10 authentication support. 2021-10-04 20:37:53 +02:00
.gitignore updated gitignore 2017-10-12 01:24:58 +03:00
build.sh fixed proxy cmdline parameters and logs 2018-12-01 14:59:32 +02:00
Dockerfile Added Dockerfile. 2021-10-04 22:07:23 +02:00
go.mod Added reMarkable 2.10 authentication support. 2021-10-04 20:37:53 +02:00
go.sum global: make the whole package go mod ready 2018-11-30 09:40:45 +01:00
LICENSE some more house cleaning, updated license & docs 2017-07-15 07:52:23 +03:00
README.md Added reMarkable 2.10 authentication support. 2021-10-04 20:37:53 +02:00
todo.md starting to create a new file format 2017-08-24 14:33:53 +03:00
vncproxy.iml Added server for web sockets, plus some refactoring 2017-07-01 23:01:58 +03:00

VncProxy CircleCI MIT Licensed

An RFB proxy, written in go that can save and replay FBS files

  • Supports all modern encodings & most useful pseudo-encodings
  • Supports multiple VNC client connections & multi servers (chosen by sessionId)
  • Supports being a "websockify" proxy (for web clients like NoVnc)
  • Produces FBS files compatible with tightvnc's rfb player (while using tight's default 3Byte color format)
  • Can also be used as:
    • A screen recorder vnc-client
    • A replay server to show fbs recordings to connecting clients
    • Authentication proxy for reMarkable tablet (2.10+)
  • Tested on tight encoding with:
    • Tightvnc (client + java client + server)
    • FBS player (tightVnc Java player)
    • NoVnc(web client) => use -wsPort to open a websocket
    • ChickenOfTheVnc(client)
    • VineVnc(server)
    • TigerVnc(client)
    • Qemu vnc(server)

Executables (see releases)

  • proxy - the actual recording proxy, supports listening to tcp & ws ports and recording traffic to fbs files
  • recorder - connects to a vnc server as a client and records the screen
  • player - a toy player that will replay a given fbs file to all incoming connections

Usage:

recorder -recFile=./recording.rbs -targHost=192.168.0.100 -targPort=5903 -targPass=@@@@@
player -fbsFile=./myrec.fbs -tcpPort=5905
proxy -recDir=./recordings/ -targHost=192.168.0.100 -targPort=5903 -targPass=@@@@@ -tcpPort=5903 -wsPort=5905 -vncPass=@!@!@!

Code usage examples

  • player/main.go (fbs recording vnc client)    * Connects as client, records to FBS file
  • proxy/proxy_test.go (vnc proxy with recording)
    • Listens to both Tcp and WS ports
    • Proxies connections to a hard-coded localhost vnc server
    • Records session to an FBS file
  • player/player_test.go (vnc replay server)
    • Listens to Tcp & WS ports
    • Replays a hard-coded FBS file in normal speed to all connecting vnc clients

Examples of using with reMarkable

  • Simply run the proxy with the -reMarkable DEVICE_ID flag
  • To get the DEVICE_ID:
    • Log into reMarkable via SSH
    • Extract the devicetoken string (exclude the @ByteArray wrapper) the string from /etc/remarkable.conf
    • Run the following Python snippet to decrypt the devicetoken:
      pip3 install --user PyJWT
      python3 -c 'import sys,jwt;t=jwt.decode(sys.argv[1],options={"verify_signature":False});print(t)' '(DEVICE TOKEN HERE)'
      
    • In output, you should get a string starting with auth0|. The whole string is your device ID which should be passed to be -reMarkable flag.
  • After you should be able to connect to the reMarkable via the proxy with a normal VNC client (tested with TightVNC)

Architecture

Image of Arch

Communication to vnc-server & vnc-client are done in the RFB binary protocol in the standard ways. Internal communication inside the proxy is done by listeners (a pub-sub system) that provide a stream of bytes, parsed by delimiters which provide information about RFB message start & type / rectangle start / communication closed, etc. This method allows for minimal delays in transfer, while retaining the ability to buffer and manipulate any part of the protocol.

For the client messages which are smaller, we send fully parsed messages going trough the same listener system. Currently client messages are used to determine the correct pixel format, since the client can change it by sending a SetPixelFormatMessage.

Tracking the bytes that are read from the actual vnc-server is made simple by using the RfbReadHelper (implements io.Reader) which sends the bytes to the listeners, this negates the need for manually keeping track of each byte read in order to write it into the recorder.

RFB Encoding-reader implementations do not decode pixel information, since this is not required for the proxy implementation.

This listener system was chosen over direct use of channels, since it allows the listening side to decide whether or not it wants to run in parallel, in contrast having channels inside the server/client objects which require you to create go routines (this creates problems when using go's native websocket implementation)

The Recorder uses channels and runs in parallel to avoid hampering the communication through the proxy.

Image of Arch

The code is based on several implementations of go-vnc including the original one by Mitchell Hashimoto, and the recentely active fork by Vasiliy Tolstov.