# Vine Modern Forwarding **Vine** is a next-generation, high-performance Minecraft proxy written in Rust. Designed for ultra-low latency, multi-threading, and enterprise-grade security, Vine introduces modern cryptographic forwarding based on **Ed25519 asymmetric signatures** and **replay attack protection**. Pumpkin provides native support for Vine forwarding in [`crates/pumpkin/src/net/proxy/vine.rs`](https://github.com/Pumpkin-MC/Pumpkin/blob/master/crates/pumpkin/src/net/proxy/vine.rs). --- ## Why Vine Forwarding? While Velocity's HMAC-SHA256 forwarding represents an improvement over legacy BungeeCord, it relies on a **symmetric shared secret**. If one backend server in a network is compromised, an attacker obtains the shared secret and can forge authenticated player logins across the entire server cluster. Vine solves this with: 1. **Asymmetric Public-Key Cryptography (Ed25519)**: The proxy signs player data using its private key. Backend servers only store the proxy's **Public Key** (`public_key`). Even if a backend server is compromised, the attacker cannot forge identities to other servers. 2. **Replay Attack Protection (16-byte Challenge Nonce)**: Pumpkin generates a cryptographic random 16-byte nonce for each connection. The proxy must sign and return this nonce. Replaying a captured login packet is impossible. 3. **Timestamp Drift Window**: Transmits a Unix timestamp that must be within ±30 seconds of the backend's system clock (`MAX_TIMESTAMP_DRIFT_SECS = 30`). --- ## The Handshake Sequence 1. **Connection**: The player connects and authenticates with Vine. Vine opens a backend connection to Pumpkin and sends `SHandshake` and `SLoginStart`. 2. **Challenge Query**: Pumpkin generates a cryptographically random 16-byte nonce and sends `CLoginPluginRequest` on the `vine:player_info` channel. 3. **Asymmetric Signing**: Vine serializes the version, timestamp, the returned 16-byte nonce, the client IP address, and the player GameProfile. It signs this byte stream with its Ed25519 private key. 4. **Tri-fold Validation**: Vine replies with `SLoginPluginResponse`. Pumpkin verifies: - **Clock Skew**: The embedded timestamp is within ±30 seconds of UTC time. - **Nonce Check**: The signed nonce exactly matches the 16-byte challenge generated in step 2. - **Ed25519 Signature**: The signature is cryptographically valid against the configured `public_key`. 5. **Session Success**: If all three checks pass, Pumpkin applies the verified identity and emits `CLoginSuccess`. --- ## Wire Payload Structure The `SLoginPluginResponse` data layout: ```text ┌─────────────────────────────────────────────────────────────┐ │ 64-byte Ed25519 Digital Signature │ ├─────────────────────────────────────────────────────────────┤ │ Forwarding Protocol Version (i32: 1) │ ├─────────────────────────────────────────────────────────────┤ │ Unix Timestamp in Seconds (i64) │ ├─────────────────────────────────────────────────────────────┤ │ 16-byte Challenge Nonce │ ├─────────────────────────────────────────────────────────────┤ │ Client Remote IP Address (String / IPv4 / IPv6) │ ├─────────────────────────────────────────────────────────────┤ │ Player UUID (128-bit / UUID) │ ├─────────────────────────────────────────────────────────────┤ │ Player Username (String) │ ├─────────────────────────────────────────────────────────────┤ │ Profile Properties Count (VarInt) │ │ ├─ Property Name (String) │ │ ├─ Property Value (String) │ │ └─ Optional Signature (String) │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Verification in Pumpkin In `crates/pumpkin/src/net/proxy/vine.rs`: ```rust use ed25519_dalek::{Signature, Verifier, VerifyingKey}; // 1. Validate payload length (64-byte signature + 25-byte headers minimum) if data.len() < 89 { return Err(VineError::DataTooShort); } // 2. Extract signature and signed payload let (sig_bytes, signed_data) = data.split_at(64); let signature = Signature::from_slice(sig_bytes) .map_err(|_| VineError::InvalidSignature)?; // 3. Verify timestamp skew (30 second maximum drift) let skew = (server_now - timestamp).abs(); if skew > MAX_TIMESTAMP_DRIFT_SECS { return Err(VineError::TimestampExpired(skew, MAX_TIMESTAMP_DRIFT_SECS)); } // 4. Verify challenge nonce matches connection state if received_nonce != expected_nonce { return Err(VineError::ChallengeMismatch); } // 5. Verify Ed25519 signature with proxy's public key verifying_key.verify(signed_data, &signature) .map_err(|_| VineError::InvalidSignature)?; ``` --- ## Configuration in `pumpkin.toml` Configure Vine forwarding in `pumpkin.toml`: ```toml [networking.proxy] enabled = true [networking.proxy.vine] enabled = true # 64-character hex-encoded Ed25519 public key of the Vine proxy public_key = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" # Alternatively, if secret is supplied, the public key is derived automatically secret = "" ```