DVX_GUI/proxy
2026-03-11 19:41:17 -05:00
..
stubs Added Linux proxy server to test seclink. 2026-03-10 21:48:08 -05:00
Makefile Added Linux proxy server to test seclink. 2026-03-10 21:48:08 -05:00
proxy.c Encryption and other serial fixes. Terminal cursor not being erased fixed. Ability to auto-size windows added. 2026-03-11 19:41:17 -05:00
README.md Added Linux proxy server to test seclink. 2026-03-10 21:48:08 -05:00
sockShim.c Encryption and other serial fixes. Terminal cursor not being erased fixed. Ability to auto-size windows added. 2026-03-11 19:41:17 -05:00
sockShim.h Added Linux proxy server to test seclink. 2026-03-10 21:48:08 -05:00

SecLink Proxy

Linux-hosted proxy that bridges an 86Box emulated serial port to a remote telnet BBS. The 86Box side communicates using the secLink protocol (packet framing, DH key exchange, XTEA encryption). The BBS side is plain telnet over TCP.

Architecture

86Box (DOS terminal)                              Remote BBS
       |                                              |
  emulated modem                                  telnet:23
       |                                              |
    TCP:2323                                       TCP:23
       |                                              |
       +--- secproxy ----------------------------------+
            secLink ←→ plaintext
            (encrypted, reliable)

The proxy accepts a single TCP connection from 86Box, performs the secLink handshake (DH key exchange), then connects to the BBS. All traffic between 86Box and the proxy is encrypted via XTEA-CTR on channel 0. Traffic between the proxy and the BBS is unencrypted telnet.

Usage

secproxy [listen_port] [bbs_host] [bbs_port]
Argument Default Description
listen_port 2323 TCP port for 86Box connection
bbs_host bbs.duensing.digital BBS hostname
bbs_port 23 BBS TCP port
secproxy                              # all defaults
secproxy 5000                         # listen on port 5000
secproxy 2323 bbs.example.com 23      # different BBS
secproxy --help                       # show usage

Startup Sequence

  1. Listen on the configured TCP port
  2. Wait for 86Box to connect (blocks on accept)
  3. Connect to the remote BBS
  4. Seed the RNG from /dev/urandom
  5. Open secLink and perform the DH handshake (blocks until the DOS side completes its handshake)
  6. Enter the proxy loop

Proxy Loop

The main loop uses poll() with a 10ms timeout to multiplex between the two TCP connections:

  • 86Box → BBS: secLinkPoll() reads from the 86Box socket via the socket shim, decrypts incoming packets, and the receive callback writes plaintext to the BBS socket.
  • BBS → 86Box: read() from the BBS socket, then secLinkSend() encrypts and sends to 86Box via the socket shim.
  • Maintenance: secLinkPoll() also handles packet-layer retransmit timers on every iteration.

The proxy exits cleanly on Ctrl+C (SIGINT), SIGTERM, or when either side disconnects.

86Box Configuration

Configure the 86Box serial port to use a telnet connection:

  1. In 86Box settings, set a COM port to "TCP (server)" or "TCP (client)" mode pointing at the proxy's listen port
  2. Enable "No telnet negotiation" to send raw bytes
  3. The DOS terminal application running inside 86Box uses secLink over this serial port

Socket Shim

The proxy reuses the same packet, security, and secLink source code as the DOS build. A socket shim (sockShim.h/sockShim.c) provides rs232-compatible rs232Read()/rs232Write() functions backed by TCP sockets instead of UART hardware:

rs232 function Socket shim behavior
rs232Open() No-op (socket already connected)
rs232Close() Marks port closed (socket managed by caller)
rs232Read() Non-blocking recv() with MSG_DONTWAIT
rs232Write() Blocking send() loop with MSG_NOSIGNAL

The shim maps COM port indices (0-3) to socket file descriptors via sockShimSetFd(), which must be called before opening the secLink layer.

DOS-specific headers (<pc.h>, <go32.h>, <sys/farptr.h>) are replaced by minimal stubs in stubs/ that provide no-op implementations. The security library's hardware entropy function returns zeros on Linux, which is harmless since the proxy seeds the RNG from /dev/urandom before the handshake.

Building

make        # builds ../bin/secproxy
make clean  # removes objects and binary

Objects are placed in ../obj/proxy/, the binary in ../bin/.

Requires only a standard Linux C toolchain (gcc, libc). No external dependencies.

Files

proxy/
  proxy.c          main proxy program
  sockShim.h       rs232-compatible socket API (header)
  sockShim.c       socket shim implementation
  Makefile         Linux build
  stubs/
    pc.h           stub for DJGPP <pc.h>
    go32.h         stub for DJGPP <go32.h>
    sys/
      farptr.h     stub for DJGPP <sys/farptr.h>