Update protocol docs with server-side findings from RE
Add server-side implementation notes to KVM_PROTOCOL.md for KeyEvent encryption support, ScreenSetPosition/ScreenCalibration handling, SetScreenUILang desync risk, QoS bandwidth throttling, and PowerControl dispatch. Add server-side architecture section to MOUNT_PROTOCOL.md documenting ikvm_vmass.ko kernel module internals. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
84b22693ce
commit
400d08bc72
2 changed files with 83 additions and 7 deletions
|
|
@ -787,10 +787,18 @@ Total: 10 bytes.
|
|||
|
||||
### KeyEvent (type 0x04) — ATEN Extended
|
||||
|
||||
**IMPORTANT: Keyboard events are NEVER encrypted.** Unlike PointerEvents, the
|
||||
`Sendkey()` function always sends keyboard events in cleartext. The RFBKeyboard
|
||||
object does allocate an `RFBKMCryto` instance (at this+0x20), but `Sendkey()`
|
||||
never calls it. Only mouse events support AES-128-CBC encryption.
|
||||
**IMPORTANT: Keyboard events are NEVER encrypted by the client.** Unlike
|
||||
PointerEvents, the `Sendkey()` function always sends keyboard events in
|
||||
cleartext. The RFBKeyboard object does allocate an `RFBKMCryto` instance
|
||||
(at this+0x20), but `Sendkey()` never calls it.
|
||||
|
||||
**Server-side note**: The server's KeyEvent handler at `0xf8c4` *does* check the
|
||||
encryption flag byte and supports decrypting AES-encrypted keyboard events
|
||||
(same AES-128-CBC scheme as mouse events). If the first byte after type is
|
||||
non-zero, the server treats the remaining 16 bytes as AES ciphertext. However,
|
||||
since the client never encrypts keyboard events, this code path is never
|
||||
exercised in practice. A custom client could encrypt keyboard events for
|
||||
additional security — the server will handle them correctly.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
|
|
@ -1179,6 +1187,11 @@ Total: 9 bytes. Sends a screen position/offset to the server. The x and y
|
|||
values are packed as a 64-bit value split into two 32-bit words.
|
||||
(`RFBScreen::ScreenSetPosition` at 0x001189b0)
|
||||
|
||||
**Server-side note (WPCM450/Hermon)**: The server handler at `0xf7b0` reads the
|
||||
two u32 values and discards them. This message has no effect on the Hermon
|
||||
server — the VCD hardware captures the full video signal regardless of
|
||||
position offset.
|
||||
|
||||
### ScreenCalibration (type 0x17)
|
||||
|
||||
```
|
||||
|
|
@ -1190,6 +1203,12 @@ values are packed as a 64-bit value split into two 32-bit words.
|
|||
|
||||
Triggers a screen recalibration on the BMC.
|
||||
|
||||
**Server-side note (WPCM450/Hermon)**: Type 0x17 is NOT present in the server's
|
||||
ProtocolHandler dispatch switch. The server does not handle this message type.
|
||||
Sending it will trigger the default case and print "ProtocolHandler: Error
|
||||
message type !!". This message type may only be supported on other BMC
|
||||
chipsets (AST, Pilot3).
|
||||
|
||||
### SetPowerOnOff (type 0x1A)
|
||||
|
||||
```
|
||||
|
|
@ -1214,6 +1233,13 @@ All four JNI functions call `SetPowerOnOff(action)` through the RFBScreen vtable
|
|||
(vtable index 7, offset 0x38 from vtable base). `RFBScreen::SetPowerOnOff` at
|
||||
0x00118900 simply writes: type 0x1A, then the action byte, then flushes.
|
||||
|
||||
**Server-side note (WPCM450/Hermon)**: The server handler at `0xfae4` dispatches
|
||||
to libutility.so functions: code 0 → `UtilPowerDown()`, 1 → `UtilPowerUp()`,
|
||||
2 → `UtilPowerReset()`, 3 → `UtilSoftPowerDown()`. Any other code prints
|
||||
"Error Power Control Request!!". No response is sent to the client. Power
|
||||
control requires no special permission — it is in the "always allowed" group
|
||||
in the server's permission filter (alongside KeepAlive, SetBandwidth, etc.).
|
||||
|
||||
### ScreenSetInfo (type 0x32)
|
||||
|
||||
```
|
||||
|
|
@ -1311,6 +1337,14 @@ the Java application and BMC firmware (video quality level, compression ratio,
|
|||
and bandwidth limit are the likely interpretations based on the Java UI
|
||||
option frames).
|
||||
|
||||
**Server-side note (WPCM450/Hermon)**: The server handler at `0xfa10` reads
|
||||
all 3 u32 values and passes them to `SetBandwidthLimits` at `0x13128`, which
|
||||
configures the stream's read and write bandwidth counter objects. These counters
|
||||
implement `select()`-based throttling — when bandwidth exceeds the configured
|
||||
limit, the stream write functions sleep to enforce the cap. The 3 parameters
|
||||
map to: `limit1` (read bandwidth), `limit2` (write bandwidth), `period`
|
||||
(time window for measurement).
|
||||
|
||||
### GetScreenUI (type 0x3C)
|
||||
|
||||
```
|
||||
|
|
@ -1349,6 +1383,12 @@ Java side through the vtable. When the flag is zero (default), only 5 bytes
|
|||
are sent (type + lang_id). When non-zero, 9 bytes are sent (type + lang_id +
|
||||
lang_sub).
|
||||
|
||||
**Server-side note (WPCM450/Hermon)**: The server handler at `0xfaa4` always
|
||||
reads 2 u32 values (8 bytes of payload), regardless of any FW protocol flag.
|
||||
A client sending only 5 bytes (1 u32) will cause the server to block waiting
|
||||
for the second u32, potentially causing a protocol desync. For Hermon servers,
|
||||
always send both u32 values (9 bytes total).
|
||||
|
||||
The `setScreenUILang` JNI method at 0x00121b00 takes two int parameters from
|
||||
Java and calls `ProcSetScreenUI(param_3, param_4)` through the RFBProtocol
|
||||
vtable (offset 0x30).
|
||||
|
|
|
|||
|
|
@ -49,14 +49,50 @@ is the more interesting and complex one.
|
|||
▼ │
|
||||
┌──────────────────────────────────────────────────────────┐
|
||||
│ BMC Firmware │
|
||||
│ - Presents virtual USB device to managed server │
|
||||
│ - Forwards SCSI commands as CBW over TCP │
|
||||
│ - Receives data + CSW responses │
|
||||
│ - Virtual media daemon (userspace) │
|
||||
│ - Reads CBW from ikvm_vmass.ko char device │
|
||||
│ - Writes data + CSW responses back │
|
||||
├──────────────────────────────────────────────────────────┤
|
||||
│ ikvm_vmass.ko (kernel module, WPCM450 USB 2.0 UDC) │
|
||||
│ - USB VID=0x0EA0 (ATEN), PID=0x2168 │
|
||||
│ - Bulk-Only Mass Storage on EP1/EP2 (LUN 0) │
|
||||
│ - Optional second LUN on EP4/EP5 (LUN 1) │
|
||||
│ - 1.3MB coherent DMA buffer for USB transfers │
|
||||
│ - 640KB SCSI data buffer per LUN │
|
||||
│ - USB descriptors supplied by userspace via ioctl │
|
||||
└──────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Server-Side Architecture (WPCM450/Hermon)
|
||||
|
||||
The BMC-side virtual media implementation uses the `ikvm_vmass.ko` kernel
|
||||
module (source: `wpcm450_vmass.c`, NOT stripped, 369 symbols). The module
|
||||
implements a USB 2.0 device controller driver for the WPCM450's on-chip USB
|
||||
hardware. Key details from server firmware RE (`REVERSING_SERVER.md`):
|
||||
|
||||
- **USB identity**: ATEN VID=0x0EA0, PID=0x2168
|
||||
- **Dual-LUN**: Supports up to 2 logical units (devices). LUN 0 uses EP1 (OUT)
|
||||
and EP2 (IN), LUN 1 uses EP4 (OUT) and EP5 (IN).
|
||||
- **Descriptor injection**: USB descriptors (0x520 bytes) are provided by the
|
||||
userspace daemon via ioctl `0xC0085501`. The client's USB descriptor data
|
||||
(sent during plug-in) is forwarded to the kernel module to define the virtual
|
||||
device identity presented to the host.
|
||||
- **Data flow**: The userspace daemon reads CBW packets from the char device
|
||||
(31-byte CBW triggers SCSI dispatch), processes them, and writes response
|
||||
data + CSW back. The kernel module handles USB transfer mechanics, DMA,
|
||||
and endpoint service.
|
||||
- **SCSI dispatch in kernel**: The module parses CBW opcode to determine
|
||||
transfer direction and length — READ_10 (0x28) and READ_CD (0xBE) are IN,
|
||||
WRITE_10 (0x2A) and opcode 0x20 are OUT, all others have no data phase.
|
||||
- **Speed negotiation**: Full-speed (64 byte packets) or high-speed (512 byte
|
||||
packets), auto-negotiated during USB enumeration.
|
||||
- **3 ioctls**: `0xC0085501` (register/set descriptors), `0x40085502`
|
||||
(disconnect USB), `0x40085503` (connect USB).
|
||||
|
||||
---
|
||||
|
||||
## Connection Setup
|
||||
|
||||
### 1. Initialization
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue