cb89312a27
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>
82 lines
3.0 KiB
Rust
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);
|
|
}
|
|
}
|