103 lines
3.3 KiB
Rust
103 lines
3.3 KiB
Rust
#[path = "../src/config.rs"]
|
|
mod config;
|
|
#[path = "../src/datagram.rs"]
|
|
mod datagram;
|
|
#[path = "../src/protocol/mod.rs"]
|
|
mod protocol;
|
|
#[path = "../src/stats.rs"]
|
|
mod stats;
|
|
#[path = "../src/transport/mod.rs"]
|
|
mod transport;
|
|
|
|
use std::{process::Command, sync::Arc, time::Duration};
|
|
|
|
use bytes::Bytes;
|
|
use config::Config;
|
|
use rustls::RootCertStore;
|
|
use tempfile::tempdir;
|
|
use tokio::time::timeout;
|
|
use transport::{TlsTcpConnector, TlsTcpServer, TransportConnector, TransportSession};
|
|
|
|
const SECRET: &str = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
|
|
|
fn free_port() -> u16 {
|
|
std::net::TcpListener::bind("127.0.0.1:0")
|
|
.unwrap()
|
|
.local_addr()
|
|
.unwrap()
|
|
.port()
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn tls_tcp_authenticates_and_round_trips_opaque_datagrams() {
|
|
if Command::new("openssl").arg("version").output().is_err() {
|
|
return;
|
|
}
|
|
let dir = tempdir().unwrap();
|
|
let cert = dir.path().join("cert.pem");
|
|
let key = dir.path().join("key.pem");
|
|
let generated = Command::new("openssl")
|
|
.args([
|
|
"req",
|
|
"-x509",
|
|
"-newkey",
|
|
"rsa:2048",
|
|
"-nodes",
|
|
"-subj",
|
|
"/CN=localhost",
|
|
"-days",
|
|
"1",
|
|
"-keyout",
|
|
])
|
|
.arg(&key)
|
|
.args(["-out"])
|
|
.arg(&cert)
|
|
.output()
|
|
.unwrap();
|
|
assert!(
|
|
generated.status.success(),
|
|
"openssl failed: {:?}",
|
|
generated
|
|
);
|
|
let port = free_port();
|
|
let server_config = Config::from_str(&format!(
|
|
"[server]\nlisten = \"127.0.0.1\"\n[backend]\ntarget = \"127.0.0.1:51820\"\n[transports.direct_udp]\nenabled = false\n[transports.quic]\nenabled = false\n[transports.http3]\nenabled = false\n[transports.tls_tcp]\nenabled = true\nport = {port}\n[tls]\ncertificate = \"{}\"\nprivate_key = \"{}\"\n[[auth.clients]]\nid = \"test\"\nsecret = \"{SECRET}\"\n",
|
|
cert.display(),
|
|
key.display()
|
|
))
|
|
.unwrap()
|
|
.into_server()
|
|
.unwrap();
|
|
let client_config = Config::from_str(&format!(
|
|
"[client]\nserver = \"localhost\"\nid = \"test\"\nsecret = \"{SECRET}\"\n[transport]\nmode = \"tls_tcp\"\n[transport.tls_tcp]\nport = {port}\n[network]\nmax_datagram_size = 1200\n"
|
|
))
|
|
.unwrap()
|
|
.into_client()
|
|
.unwrap();
|
|
let certs = transport::tls_tcp::load_certificates(&cert).unwrap();
|
|
let mut roots = RootCertStore::empty();
|
|
roots.add(certs[0].clone()).unwrap();
|
|
let client_tls = (*transport::tls_tcp::client_tls_config(roots)).clone();
|
|
let server = Arc::new(TlsTcpServer::bind(&server_config).await.unwrap());
|
|
let accept = {
|
|
let server = server.clone();
|
|
tokio::spawn(async move { server.accept_session().await })
|
|
};
|
|
let client = TlsTcpConnector::with_client_config(client_config, client_tls);
|
|
let client_session = client.connect().await.unwrap();
|
|
let server_session = accept.await.unwrap().unwrap();
|
|
client_session
|
|
.send_datagram(Bytes::from_static(b"tls-opaque"))
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(
|
|
timeout(Duration::from_secs(2), server_session.recv_datagram())
|
|
.await
|
|
.unwrap()
|
|
.unwrap(),
|
|
Bytes::from_static(b"tls-opaque")
|
|
);
|
|
client_session.close().await.unwrap();
|
|
server_session.close().await.unwrap();
|
|
}
|