Files
AuraVPN/crates/aura-cli/tests/loopback.rs
T
xah30 cb89312a27 feat(cli): implement Wave 4 — aura binary (PKI, server/client, admin, bench)
aura-cli: clap command tree (pki init/issue-server/issue-client/revoke/list,
server, client, route add/list/remove, status, bench-crypto); TOML config with
~ expansion and split-tunnel rules -> RouteTable; JSON-over-Unix-socket admin
IPC; server/client data paths wiring transport + tunnel (TUN run needs root).
config/{server,client}.toml.example. 15 tests (pki roundtrip, config parse,
admin-socket roundtrip, loopback connection). Verified the real binary: --help,
bench-crypto, and a full CA->server->client cert workflow.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 18:36:13 +03:00

82 lines
3.0 KiB
Rust

//! CLI-level end-to-end loopback (no TUN): mint certs via [`aura_pki::AuraCa`], build proto
//! Client/Server configs, [`AuraServer::bind`] on `127.0.0.1:0`, [`AuraClient::connect`], and
//! exchange packets via the [`PacketConnection`] API, asserting integrity.
//!
//! This is the full CLI integration path short of the privileged TUN device: it proves the crate's
//! wiring of aura-pki + aura-proto + aura-transport works end to end without root or external
//! network.
use std::sync::Arc;
use aura_pki::AuraCa;
use aura_proto::{ClientConfig, PacketConnection, ServerConfig};
use aura_transport::{AuraClient, AuraServer};
const SERVER_NAME: &str = "localhost";
const CAMOUFLAGE_SNI: &str = "cdn.example.com";
#[tokio::test]
async fn cli_loopback_packet_exchange() {
// PKI: CA + server cert (SAN localhost) + client cert.
let ca = AuraCa::generate("Aura CLI Test CA").expect("generate CA");
let server_cert = ca.issue_server_cert(SERVER_NAME).expect("server cert");
let client_cert = ca.issue_client_cert("cli-client").expect("client cert");
let ca_pem = ca.ca_cert_pem();
let server_cfg = ServerConfig {
ca_cert_pem: ca_pem.clone(),
server_cert_pem: server_cert.cert_pem.clone(),
server_key_pem: server_cert.key_pem.clone(),
};
let client_cfg = ClientConfig {
ca_cert_pem: ca_pem.clone(),
client_cert_pem: client_cert.cert_pem.clone(),
client_key_pem: client_cert.key_pem.clone(),
server_name: SERVER_NAME.to_string(),
};
// Bind on an OS-assigned loopback port.
let server = AuraServer::bind(
"127.0.0.1:0".parse().unwrap(),
&server_cert.cert_pem,
&server_cert.key_pem,
server_cfg,
)
.expect("bind server");
let server_addr = server.local_addr().expect("local_addr");
// Accept + connect concurrently.
let accept = tokio::spawn(async move { server.accept().await });
let connect =
tokio::spawn(
async move { AuraClient::connect(server_addr, CAMOUFLAGE_SNI, client_cfg).await },
);
let server_conn = accept.await.expect("accept join").expect("accept");
let client_conn = connect.await.expect("connect join").expect("connect");
// Mutual auth established the client's verified CN on the server side.
assert_eq!(server_conn.peer_id(), Some("cli-client"));
let server_conn: Arc<dyn PacketConnection> = Arc::new(server_conn);
let client_conn: Arc<dyn PacketConnection> = Arc::new(client_conn);
// Client -> server.
for pkt in [
b"ping".to_vec(),
vec![0u8; 1400],
(0..=255u8).collect::<Vec<u8>>(),
] {
client_conn.send_packet(&pkt).await.expect("client send");
let got = server_conn.recv_packet().await.expect("server recv");
assert_eq!(got, pkt);
}
// Server -> client.
for pkt in [b"pong".to_vec(), vec![0x5Au8; 999]] {
server_conn.send_packet(&pkt).await.expect("server send");
let got = client_conn.recv_packet().await.expect("client recv");
assert_eq!(got, pkt);
}
}