Add encrypted LAN mouse and keyboard sharing with four-edge handoff
This commit is contained in:
1 parent
9b565dd55e
commit
e0bfdd9a90
15 files changed
+1093
-104
No files matched your search
+93
-64
@@ -1,79 +1,108 @@
|
||||
# LAN discovery and pairing preview
|
||||
# LAN mouse and keyboard preview
|
||||
|
||||
This development branch starts the built-in replacement for Mouse Without Borders.
|
||||
It adds discovery and authenticated pairing inside the existing KSwitcher resident
|
||||
process. It is **not yet a mouse/keyboard or clipboard transport**. Do not disable
|
||||
MWB on the strength of this preview.
|
||||
KSwitcher discovers other enabled KSwitcher instances, pairs them with the same
|
||||
code on both computers, and shares mouse and keyboard through a screen edge.
|
||||
The module runs inside the resident process. This preview supports **one active
|
||||
pair of computers**, with the neighbour on the left, right, above or below.
|
||||
Several trusted pairs may be saved, but only the selected neighbour is active.
|
||||
Clipboard and file transfer are not implemented yet.
|
||||
|
||||
## Try it on two Windows computers
|
||||
## Set up two computers
|
||||
|
||||
1. Run this development build on both computers, on the same private IPv4 subnet.
|
||||
2. Open Settings → Tools → KSwitcher computers.
|
||||
3. Enable discovery on both. The list contains running LAN-enabled KSwitcher
|
||||
instances, not computers returned by a generic Windows/network scan.
|
||||
4. Match the computer name and eight-character instance-ID prefix displayed on
|
||||
the other computer. Select each other in the lists.
|
||||
5. Generate a code once. Enter that same 32-character code on both computers,
|
||||
then click Pair on both within two minutes. Spaces, hyphens and uppercase
|
||||
hexadecimal characters are accepted. A different code never establishes trust.
|
||||
6. Both sides should report Paired; authenticated presence appears as
|
||||
“Paired / verified”. An offline pair stays listed so it can be forgotten.
|
||||
1. Extract this preview into a separate writable folder on each Windows PC.
|
||||
Exit the regular KSwitcher before starting this copy; only one resident runs
|
||||
per Windows session. Each copy keeps its own data beside the executable.
|
||||
2. Open Settings → Tools → KSwitcher computers and enable discovery on both PCs.
|
||||
Only running LAN-enabled KSwitcher instances appear, not generic network devices.
|
||||
3. Match the computer name and instance-ID prefix displayed on the other PC.
|
||||
Select each other, generate one code, enter that same code on both, then click
|
||||
Pair on both within two minutes. Spaces, hyphens and uppercase hex are accepted.
|
||||
4. Select the paired neighbour and its position relative to this computer.
|
||||
Example: B stands to the right of A, so choose **Right on A** and **Left on B**.
|
||||
For a vertical arrangement choose **Above** on the lower PC and **Below** on
|
||||
the upper PC. Click **Apply position / enable input** on both.
|
||||
5. Stop MWB or another mouse/keyboard router on both computers before trying
|
||||
KSwitcher input sharing, to avoid two tools forwarding the same events.
|
||||
6. Wait for the authenticated input connection. Move the cursor through the
|
||||
configured outer screen edge with no keys or buttons held. After the other
|
||||
computer acknowledges the handoff, both mouse and keyboard control that PC.
|
||||
Crossing its return edge returns control to the source computer.
|
||||
|
||||
Discovery uses UDP 45883 on private IPv4 and link-local interfaces. Windows may
|
||||
require an inbound firewall allowance for KSwitcher on the private network; the
|
||||
preview does not modify firewall rules. Networks that block broadcasts, separate
|
||||
VLANs, public IPv4 and IPv6-only networks are not supported yet. A second build
|
||||
cannot listen on the same discovery port on the same computer.
|
||||
The source cursor is parked and hidden beneath a tiny no-activation window. A
|
||||
small banner identifies remote control; no full-screen layered bitmap is retained.
|
||||
The destination uses its own keyboard layout and runs its own hotkeys/snippets.
|
||||
The source suppresses forwarded events before its local hotkeys, snippets and
|
||||
other low-level hook consumers. Received input is marked so it is not forwarded
|
||||
again. Source recent-input tracking resets when ownership changes.
|
||||
|
||||
Changes in this window apply immediately. Closing the window does not cancel a
|
||||
pending pairing; use Cancel pairing. Disabling discovery stops its worker and
|
||||
closes its socket. Forget pair removes local trust; forget it on both computers
|
||||
for bilateral removal. No input can be sent or received in this milestone.
|
||||
**Ctrl+Alt+Esc** is emergency return, not the normal switching mechanism. Local
|
||||
physical input on a remotely controlled PC takes control back as well. Stop input
|
||||
sharing, disabling discovery, forgetting the active pair, suspension, secure
|
||||
desktop changes and connection loss cancel remote ownership. TCP heartbeat loss
|
||||
is detected after two seconds; a handoff request expires after one second.
|
||||
Held remote keys/buttons are released. Releases blocked by a secure desktop are
|
||||
retried when the ordinary desktop is available. Source key-ups for keys already
|
||||
sent remotely are consumed after return, avoiding stray local modifier events.
|
||||
|
||||
## Identity, pairing and storage
|
||||
## Layout and limitations
|
||||
|
||||
An instance ID belongs to a KSwitcher data directory, not a hostname/IP address.
|
||||
It persists when the LAN configuration is first saved. Discovery announcements
|
||||
contain only protocol/version, instance ID, computer name and a fresh challenge.
|
||||
Discovered names and addresses are untrusted; they never authorize input.
|
||||
- Positions are relative to this PC and must be opposite on the two computers.
|
||||
Inconsistent positions are rejected before input is authorized. Changes apply
|
||||
immediately and reconnect the input channel.
|
||||
- Geometry uses the virtual desktop's outer bounding rectangle, including negative
|
||||
monitor coordinates. Internal monitor boundaries do not transfer control.
|
||||
Different resolutions map the entry position proportionally. Irregular layouts
|
||||
can have gaps on an outer edge; this is not a per-monitor arrangement editor.
|
||||
- Transferring while a key or mouse button is held is intentionally blocked.
|
||||
Dragging works within the controlled computer; dragging objects across PCs is
|
||||
not implemented. There is a short return cooldown to avoid bouncing.
|
||||
- Windows can block SendInput to elevated apps and secure desktops. Run both
|
||||
applications at suitable privilege levels for the target programs. The preview
|
||||
does not install a service, bypass UAC or implement remote Ctrl+Alt+Delete.
|
||||
- This is Windows input injection, not a virtual USB HID device. Raw-input games,
|
||||
exclusive full-screen applications and special device keys need separate testing.
|
||||
|
||||
The generated code has 128 bits of randomness from Windows CNG. It is deliberately
|
||||
not a guessable short PIN. HMAC-SHA256 proofs bind the source/destination IDs and
|
||||
fresh nonces; both endpoints confirm the handshake before saving the pair.
|
||||
Replayed confirmations cannot complete a new attempt. The shared pair key is
|
||||
separate from the setup code. The code is never transmitted or logged.
|
||||
## Network, authentication and storage
|
||||
|
||||
Local identity, enablement and trust records are stored in DPAPI-protected
|
||||
`data/lan-pairing.bin`. They are separate from settings export and OpenBao sync.
|
||||
Do not clone this file between installations: each instance needs its own identity.
|
||||
Unverified/offline status does not remove a previously saved pair. Discovery is
|
||||
bounded to 64 visible instances and stale discoveries expire after 12 seconds.
|
||||
A newly started pairing window lasts two minutes. Presence challenges rotate so
|
||||
captured replies cannot indefinitely keep a disconnected instance verified.
|
||||
Discovery broadcasts on private IPv4 and link-local interfaces using UDP 45883.
|
||||
Input uses TCP 45884. Allow KSwitcher on your private network when Windows asks;
|
||||
the preview does not change firewall rules. Broadcast-blocked networks, separate
|
||||
VLANs, public IPv4 and IPv6-only networks are not supported by discovery yet.
|
||||
A second LAN-enabled KSwitcher cannot use the same ports on one computer.
|
||||
|
||||
Disabled discovery starts no worker and opens no sockets. Enabling it adds one
|
||||
worker thread within KSwitcher; the existing configurator uses local IPC. There
|
||||
is no new executable, service, WebView or runtime dependency.
|
||||
The instance ID belongs to a data directory, not a hostname/IP address. Discovered
|
||||
names and addresses are untrusted. Pairing uses a generated 128-bit code and
|
||||
mutual HMAC-SHA256 challenge proofs bound to both instance IDs. The code is never
|
||||
transmitted or logged. The pair key is separate from the setup code.
|
||||
|
||||
## Next integration milestone
|
||||
The input channel authenticates both peers with the saved pair key and fresh
|
||||
session challenges. Directional AES-256-GCM session keys bind the identities,
|
||||
nonces and screen positions. Fixed-size authenticated frames use strict sequence
|
||||
numbers, so tampering, reflection and replay are rejected. Input is not dispatched
|
||||
until authentication succeeds. This PSK channel does not provide forward secrecy.
|
||||
Queues and frame sizes are bounded; overflow disconnects rather than dropping a
|
||||
key-up and leaving a key pressed. The input worker never injects Windows input;
|
||||
the resident's main thread owns the input state and hooks.
|
||||
|
||||
- An authenticated encrypted input channel using the stored pair key, separate
|
||||
from UDP discovery. Pairing alone must never inject input.
|
||||
- Left/right/top/bottom screen placement and cursor crossing at the screen edge
|
||||
from the first input prototype, not hotkey-based normal switching.
|
||||
- Reuse the resident low-level hooks. Forwarded keys must not expand snippets or
|
||||
invoke actions on the source PC; received keys run through the destination path.
|
||||
- Release pressed keys/buttons and return local control on disconnection, timeout,
|
||||
suspend, lock, disable or process shutdown. Keep an emergency return chord.
|
||||
- Text/image clipboard transport with bounded sizes and loop suppression follows
|
||||
reliable input handoff. File transfer and secure-desktop control are later work.
|
||||
Identity, trust, enablement and screen position stay in DPAPI-protected
|
||||
`data/lan-pairing.bin`, outside settings export and OpenBao sync. Do not clone this
|
||||
file between installations. Forget a pair on both PCs for bilateral removal.
|
||||
Closing the settings window does not cancel pairing or disable sharing.
|
||||
|
||||
Disabled discovery has no socket or worker. Input sharing reuses the single LAN
|
||||
worker; there is no extra resident executable or service. The main input timer
|
||||
runs only while sharing is enabled. The existing configurator talks to the
|
||||
resident through local IPC.
|
||||
|
||||
## Validation
|
||||
|
||||
`KSwitcherLanTests` covers cryptographic test vectors, wrong codes, identity and
|
||||
protocol substitution, mutual confirmation, replay, expiry, DPAPI persistence,
|
||||
and no worker while disabled. `--network` additionally exercises real discovery
|
||||
start/stop/rebind. Settings UI tests cover the child window, disabled actions,
|
||||
empty list, parent reactivation and unchanged Save state. Two physical computers
|
||||
are still required to validate discovery across adapters/firewalls and pairing
|
||||
under real packet loss; this preview does not claim that validation.
|
||||
Tests cover pairing, encrypted frames, replay/tamper rejection, actual loopback
|
||||
TCP authentication and bidirectional delivery, all four edges, ownership races,
|
||||
source suppression, scan codes, clicks/wheel, emergency return, held-key release,
|
||||
blocked injection, secure desktop recovery, exact one-pixel movement and timeout.
|
||||
UI tests check all four positions and preserve an edited choice during refresh.
|
||||
|
||||
Two physical computers still need an end-to-end trial for their adapters,
|
||||
firewalls, displays and application privilege levels. The automated TCP tests
|
||||
use local sockets, and input-state tests use simulated desktop environments;
|
||||
they do not claim a completed two-machine hardware test.
|
||||
Reference in new issue
Block a user