132 lines
4.5 KiB
Markdown
132 lines
4.5 KiB
Markdown
# 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>
|
|
```
|